我试图使用 gluLookAt 围绕以原点为中心的立方体移动,而不是直接在对象上执行 R*T 转换。起初,我不知道如何解决这个问题。然后我意识到(在圆形坐标中实现了一半的解决方案之后),我应该尝试使用球面坐标系表示。我能够编写一些代码来做到这一点,但我(相机的"眼睛")在立方体周围旋转得非常快。另外,我注意到我也在靠近立方体,而不是保持恒定的半径。当我使用旋转*平移方法时,它会以更合适的速度以相同的距离旋转。
我的旋转方法是使用球面坐标,但我不确定这是否正确。我根据维基百科页面上的图表计算两个角度。我计算我所在的当前点的大小(distX,distY,distZ)。我们最初在 XY 平面上查看负 Z 平面)。我还得到了两个角度,一个用于指定围绕 x 轴的旋转角度,另一个用于指定 y 轴。这五个值是根据我的鼠标点击方式计算的。
我根据一些三角计算θ和phi,最后计算新位置。这些公式可以在前面的链接中找到。最后一步是将其插入gluLookAt。同样,在运行这个程序时,我能够围绕立方体旋转,但它非常快并且可以平移相机。我做错了什么?
下面列出了我的代码,以防您想要引用它。引用"y"和"up"的部分是我计算围绕 Z 轴旋转的尝试。我能描述这种旋转的最好方法是,如果你看着一个物体,想象自己是相机,然后左右倾斜你的头。我没有在给gluLookAt的电话中包括它,因为我也无法让它工作。
编辑:它现在以似乎是正确的速率旋转,但它没有完全旋转。我的意思是,在旋转时,"眼睛"以一定角度向立方体移动,但随后会旋转回来,取消旋转。但是这个循环,所以眼睛走的路径看起来类似于弯曲的无限符号。
void sceneTransformation(){
glLoadIdentity( );
//Using the R*T approach. Works flawlessly
//glTranslatef(-distX, distY, -distZ);
//glRotatef( anglex, 1.0, 0.0, 0.0 );
//glRotatef( angley, 0.0, 1.0, 0.0 );
GLdouble radx = anglex*PI/180.;
GLdouble rady = angley*PI/180.;
GLdouble l = sqrt(pow(distX, 2) + pow(distY, 2) + pow(distZ, 2));
GLdouble phi = atan(distY/distZ) + radx;
GLdouble theta = acos(distZ/l) + radx;
GLdouble deltaZ = l*sin(theta)*cos(phi);
GLdouble deltaY = l*sin(theta)*sin(phi);
GLdouble deltaX = l*cos(theta);
GLdouble ytheta = atan(distX/distY);
GLdouble y = sqrt(pow(distX,2) + pow(distY, 2));
GLdouble yangle = PI/2.-ytheta-rady;
GLdouble up_y = y*sin(yangle);
GLdouble up_x = y*cos(yangle);
gluLookAt((distX - deltaX), (distY - deltaY), (distZ - deltaZ), 0, 0, 0, 0,1,0);
}
数学函数如sin()
、cos()
和朋友期望输入弧度,而不是度。 看起来你假设的是度数,所以你的旋转速度比预期的快了大约 57.3 倍(确切地说:360/(2 * pi))。
您需要使移动基于时间,这意味着将旋转角度乘以开始最后一帧和当前帧之间的增量。
angle += 90 * timeDelta; // Rotate by 90 degree each second
您的问题有一个很好的解决方案。 做一些调查,但我认为它会满足您的需求。四元数
它的一些代码
适合将矢量转换为旋转和向后转换