0

回転した2DQuads座標を回転したxおよびy座標と比較しようとしても問題はほとんどありません。クワッド内でマウスがクリックされたかどうかを確認しようとしています。

1)rotはこのクラスオブジェクトです:(注:演算子<<はrotate coords funcを使用するためにオーバーロードされています)

class Vector{

private:
std::vector <float> Vertices;

public:

Vector(float, float);


float GetVertice(unsigned int);

void SetVertice(unsigned int, float);

std::vector<float> operator <<(double);

};

Vector::Vector(float X,float Y){
Vertices.push_back(X);
Vertices.push_back(Y);
}

float Vector::GetVertice(unsigned int Index){
return Vertices.at(Index);
}

void Vector::SetVertice(unsigned int Index,float NewVertice){
Vertices.at(Index) = NewVertice;
}

//Return rotated coords:D
std::vector <float> Vector::operator <<(double Angle){
std::vector<float> Temp;

Temp.push_back(Vertices.at(0) * cos(Angle) - Vertices.at(1) * sin(Angle));
Temp.push_back(Vertices.at(0) * sin(Angle) + Vertices.at(1) * cos(Angle));

return Temp;
}

2)座標の比較と回転新しいバージョン

        Vector Rot1(x,y),Rot3(x,y);
        double Angle;
        std::vector <float> result1,result3;


        Rot3.SetVertice(0,NewQuads.at(Index).GetXpos() + NewQuads.at(Index).GetWidth());
        Rot3.SetVertice(1,NewQuads.at(Index).GetYpos() + NewQuads.at(Index).GetHeight());

        Angle = NewQuads.at(Index).GetRotation();
        result1 = Rot1 << Angle;  // Rotate the mouse x and y
        result3 = Rot3 << Angle;  // Rotate the Quad x and y

        //.at(0) = x and .at(1)=y

           if(result1.at(0) >= result3.at(0) - NewQuads.at(Index).GetWidth()  && result1.at(0) <= result3.at(0)  ){ 
        if(result1.at(1) >= result3.at(1) - NewQuads.at(Index).GetHeight()  && result1.at(1) <= result3.at(1) ){

これを実行すると、0の角度で完全に機能しますが、クワッドを回転させると失敗します。失敗すると、アクティベーションエリアが消えたように見えます。

座標の回転は正しく行っていますか?それとも比較ですか?それが比較であるならば、あなたはそれをどのように適切に行うでしょうか、私はifを変更しようとしましたが、運が悪かった...

クワッドの描画を編集します (テストの前に発生します):

void Quad::Render()
{

if(!CheckIfOutOfScreen()){


glPushMatrix();

glLoadIdentity();

glTranslatef(Xpos ,Ypos ,0.f);

glRotatef(Rotation,0.f,0.f,1.f); // same rotation is used for the testing later...

glBegin(GL_QUADS);

glVertex2f(Zwidth,Zheight);
glVertex2f(Width,Zheight);
glVertex2f(Width,Height);
glVertex2f(Zwidth,Height);

glEnd();

if(State != NOT_ACTIVE)
    RenderShapeTools();

glPopMatrix();
}

}

基本的に、このクワッド内でマウスがクリックされたかどうかをテストしようとしています。 画像

4

1 に答える 1

0

目的を達成する方法は複数ありますが、投稿した画像から、2Dグラフィックスのみを使用して画面(またはウィンドウ)と同じサイズの表面に描画したいと思います。

3Dグラフィックスでご存知のように、3つの座標参照について説明します。1つ目は、描画するオブジェクトまたはモデルの座標参照、2つ目はカメラまたはビューの座標参照、3つ目は画面の座標参照です。

OpenGLでは、最初の2つの座標参照はMODELVIEWマトリックスを介して確立され、3番目はPROJECTIONマトリックスとビューポート変換によって実現されます。

あなたの場合、クワッドを回転させて画面上のどこかに配置したいとします。クワッドには独自のモデル座標があります。この特定の2Dクワッドの原点がクワッドの中心にあり、寸法が5 x 5であると仮定します。また、クワッドの中心を見ると、X軸が右を指していると仮定します。 Y軸は上を指し、Z軸は視聴者を指します。

クワッドの回転していない座標は(左下から時計回りに):(-2.5、-2.5,0)、(-2.5,2.5,0)、(2.5,2.5,0)、(2.5、-2.5,0)

次に、既知の寸法の2Dサーフェスをシミュレートするために、カメラと投影行列およびビューポートが必要です。

//Assume WinW contains the window width and WinH contains the windows height

 glViewport(0,0,WinW,WinH);//Set the viewport to the whole window
 glMatrixMode (GL_PROJECTION);
 glLoadIdentity ();
 glOrtho (0, WinW, WinH, 0, 0, 1);//Set the projection matrix to perform a 2D orthogonal projection
 glMatrixMode (GL_MODELVIEW);
 glLoadIdentity ();//Set the camera matrix to be the Identity matrix

これで、WinW、WinHの寸法でこの2Dサーフェスにクワッドを描画する準備が整いました。このコンテキストでは、現在の頂点を使用してクワッドを描画すると、ウィンドウの左下に中央があり、各辺が5ピクセルであるクワッドが描画されるため、実際にはクワッドの4分の1しか表示されません。回転させて移動したい場合は、次のようにします。

//Prepare matrices as shown above
//Viewport coordinates range from bottom left (0,0) to top right (WinW,WinH)
float dX = CenterOfQuadInViewportCoordinatesX, dY = CenterOfQuadInViewportCoordinatesY;
float rotA = QuadRotationAngleAroundZAxisInDegrees;

float verticesX[4] = {-2.5,-2.5,2.5,2.5};
float verticesY[4] = {-2.5,2.5,2.5,-2.5};

//Remember that rotate is done first and translation second
glTranslatef(dX,dY,0);//Move the quad to the desired location in the viewport
glRotate(rotA, 0,0,1);//Rotate the quad around it's origin

glBegin(GL_QUADS);

glVertex2f(verticesX[0], veriticesY[0]);
glVertex2f(verticesX[1], veriticesY[1]);
glVertex2f(verticesX[2], veriticesY[2]);
glVertex2f(verticesX[3], veriticesY[3]);

glEnd();

ここで、マウスのクリックがレンダリングされたクワッド内にあったかどうかを知りたいと思います。ビューポートの座標は左下から始まりますが、ウィンドウの座標は左上から始まります。したがって、マウス座標を取得するときは、次の方法でそれらをビューポート座標に変換する必要があります。

float mouseViewportX = mouseX, mouseViewportY = WinH - mouseY - 1;

ビューポート座標にマウスの位置が決まったら、次の方法でモデル座標に変換する必要があります(私は通常、独自のマトリックスライブラリを使用しており、手動で計算しないため、計算を再確認してください)。

//Translate the mouse location to model coordinates reference
mouseViewportX -= dX, mouseViewportY -= dY;
//Unrotate the mouse location
float invRotARad = -rotA*DEG_TO_RAD;
float sinRA = sin(invRotARad), cosRA = cos(invRotA);

float mouseInModelX = cosRA*mouseViewportX - sinRA*mouseViewportY;
float mouseInModelY = sinRA*mouseViewportX + cosRA*mouseViewportY;

これで、マウスがクワッド内にあるかどうかを最終的に確認できます。これは、クワッド座標で行われていることがわかります。

bool mouseInQuad = mouseInModelX > verticesX[0] && mouseInModelY < verticesX[1] &&
                   mouseInModelY > verticesY[0] && mouseInModelY < verticesY[1];

私があまり多くの間違いをしなかったことを望みます、そしてこれはあなたを正しい軌道に乗せます。より複雑なケースや3Dを処理したい場合は、gluUnprojectを確認する必要があります(おそらく、独自のケースを実装する必要があります)。さらに複雑なシーンの場合は、ステンシルまたは深度バッファーを使用する必要があります。

于 2012-11-19T20:18:03.917 に答える