2010-10-04 52 views
0

我目前正试图让我的虚拟轨迹球从任何角度工作。当我从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; 

}

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

我仍然在这个相当新。对不起,感谢所有的帮助=)

+0

在这里看到重复的问题: http://stackoverflow.com/questions/4039664/trackball-rotation-in-opengl/4676910#4676910 – 2011-01-13 04:57:41

回答

0

通常的方式涉及四元数。例如,最初来自SGI的sample code