C++ 让虚拟轨迹球从任何视角工作

C++ 让虚拟轨迹球从任何视角工作,c++,opengl,glut,C++,Opengl,Glut,我目前正试图让我的虚拟轨迹球从任何角度工作。当我从z轴看它时,它似乎工作得很好。我按住鼠标,然后向上移动鼠标。。。旋转将相应地移动 现在,如果我改变相机的视角/位置并尝试移动鼠标。旋转会发生,就像我从z轴看一样。我想不出一个好办法让它发挥作用 代码如下: void Renderer::mouseMoveEvent(QMouseEvent *e) { // Get coordinates int x = e->x(); int y

我目前正试图让我的虚拟轨迹球从任何角度工作。当我从z轴看它时,它似乎工作得很好。我按住鼠标,然后向上移动鼠标。。。旋转将相应地移动

现在,如果我改变相机的视角/位置并尝试移动鼠标。旋转会发生,就像我从z轴看一样。我想不出一个好办法让它发挥作用

代码如下:

 void Renderer::mouseMoveEvent(QMouseEvent *e)
 {

         // Get coordinates
         int x = e->x();
         int y = e->y();

         if (isLeftButtonPressed)
         {
                 // project current screen coordinates onto hemi sphere
                 Point sphere = projScreenCoord(x,y);

                 // find axis by taking cross product of current and previous hemi points
                 axis = Point::cross(previousPoint, sphere);

                 // angle can be found from magnitude of cross product
                 double length = sqrt( axis.x * axis.x + axis.y * axis.y + axis.z * axis.z );

                 // Normalize
                 axis = axis / length;

                 double lengthPrev = sqrt( previousPoint.x * previousPoint.x + previousPoint.y * previousPoint.y + previousPoint.z * previousPoint.z );
                 double lengthCur = sqrt( sphere.x * sphere.x + sphere.y * sphere.y + sphere.z * sphere.z );
                 angle = asin(length / (lengthPrev * lengthCur));
                 // Convert into Degrees
                 angle = angle * 180 / M_PI;

                 // 'add' this rotation matrix to our 'total' rotation matrix
                 glPushMatrix(); // save the old matrix so we don't mess anything up
                 glLoadIdentity();
                 glRotatef(angle, axis[0], axis[1], axis[2]); // our newly calculated rotation
                 glMultMatrixf(rotmatrix); // our previous rotation matrix
                 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*) rotmatrix); // we've let OpenGL do our matrix mult for us, now get this result & store it
                 glPopMatrix(); // return modelview to its old value;
}

//将屏幕坐标投影到单位半球上
点渲染器::projscreencood(int x,int y)
{
//查找投影的x&y坐标
双x球面=((双)x/宽度)*2.0-1.0;
双y球面=(1-((双)y/高度))*2.0-1.0;
双温度=1.0-xSphere*xSphere-ysSphere*ysSphere;
//做一个检查,这样你就不会做一个负数的sqrt
双球面;
如果(温度<0){zSphere=0.0;}
其他的
{zSphere=sqrt(temp);}
点球面(X球面、Y球面、Z球面);
//返回球体上的点
返回球;
}

在这方面我还是个新手。很抱歉给您添麻烦,谢谢您的帮助。

通常的方法是四元数。例如,最初来自SGI。

请参见此处的重复问题:
// Project screen coordinates onto a unit hemisphere
 Point Renderer::projScreenCoord(int x, int y)
 {
         // find projected x & y coordinates
         double xSphere = ((double)x/width)*2.0 - 1.0;
         double ySphere = ( 1 - ((double)y/height)) * 2.0 - 1.0;
         double temp = 1.0 - xSphere*xSphere - ySphere*ySphere;

         // Do a check so you dont do a sqrt of a negative number
         double zSphere;
         if (temp < 0){ zSphere = 0.0;}
         else
         {zSphere = sqrt(temp);}

         Point sphere(xSphere, ySphere, zSphere);



        // return the point on the sphere
         return sphere;
 }