比较旋转坐标

时间:2012-11-18 19:41:24

标签: c++ opengl glut

我在尝试将旋转的2D四元组坐标与旋转的x和y坐标进行比较时遇到的麻烦一点儿。我正在尝试确定鼠标是否在四边形内部被点击。

1)rot是这个类对象:(注意:运算符<<<<<<<<<<<<<<<<<<<<<<

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();
}

}

基本上我正在尝试测试鼠标是否在此四边形内部被点击: Image

1 个答案:

答案 0 :(得分:0)

有多种方法可以实现您想要的效果,但是从您发布的图像中我假设您想要仅使用2D图形绘制与屏幕(或窗口)大小相同的表面。

正如您在3D图形中所知,我们讨论了3个坐标参考。第一个是要绘制的对象或模型的坐标参考,第二个是摄像机或视图的坐标参考,第三个是屏幕的坐标参考。

在OpenGL中,前两个坐标参考是通过MODELVIEW矩阵建立的,第三个是通过PROJECTION矩阵和视口转换实现的。

在您的情况下,您想要旋转四边形并将其放置在屏幕上的某个位置。你的四边形有它自己的模型坐标。让我们假设对于这个特定的2D四边形,原点位于四边形的中心,它的尺寸为5乘5.另外,我们假设如果我们查看四边形的中心,那么X轴指向右边, Y轴指向UP,Z轴指向观察者。

四边形的未旋转坐标(从左下方顺时针):( - 2.5,-2.5,0),( - 2.5,5.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的四维表面绘制四边形。在这种情况下,如果您只是使用它的当前顶点绘制四边形,您将使用窗口左下角的中心绘制四边形,每边测量5个像素,因此您实际上只能看到四分之一的四边形。如果你想旋转并移动它,你会做这样的事情:

//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(也许你会想要实现自己的),对于更复杂的场景,你可能需要使用模板或深度缓冲区