0

尝试将旋转的 2D Quads 坐标与旋转的 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)坐标的比较和旋转THE NEW VERSION

        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 个坐标参考。第一个是要绘制的对象或模型的坐标参考,第二个是相机或视图的坐标参考,第三个是屏幕的坐标参考。

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

在您的情况下,您想旋转一个四边形并将其放置在屏幕上的某个位置。您的四边形有自己的模型坐标。假设对于这个特定的 2D 四边形,原点位于四边形的中心,尺寸为 5 x 5。还假设如果我们看四边形的中心,则 X 轴指向 RIGHT, Y 轴指向 UP,Z 轴指向观察者。

四边形的未旋转坐标将是(从左下角顺时针):(-2.5,-2.5,0), (-2.5,2.5,0), (2.5,2.5,0), (2.5,-2.5,0)

现在我们想要一个相机和投影矩阵和视口,以便模拟一个已知尺寸的二维表面。

//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

您现在可以在这个 2D 表面上绘制四边形,尺寸为 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(也许您会想要实现自己的),对于更复杂的场景,您可能需要使用模板或深度缓冲区

于 2012-11-19T20:18:03.917 回答