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