最近由于需要做一个陀螺产品的姿态演示系统,虽然目前还有问题尚待解决,但还是先做个记录吧。
由于水平有限,可能写出来的东西问题也很多,望网友指正。
1.表示旋转的方法主要有:欧拉角、旋转矩阵和四元数
欧拉角:比较直观、较易理解。陀螺的输出就是这种形式的数据,也就是将物体的旋转分解为沿XYZ三个轴向的旋转。问题在于“万向节锁”,即由于旋转顺序的原因,在某些情况下,会导致两个旋转轴向面重合(这个好像说的比较玄乎,优酷上有个视频上详细介绍的,有兴趣的可以看一下http://v.youku.com/v_show/id_XNzkyOTIyMTI=.html)
旋转矩阵:这个在OpenGL里面基本躲不开,考虑矢量的旋转,以变换矩阵的形式表示。
四元数:我也是这次才接触到这个概念。定义是:q=w+xi+yj+zk,物理意义可以理解为:(x,y,z)表示一个向量,物体绕这个向量旋转w角度。
2.欧拉角转换到四元数,与前一个四元数相乘,然后再转回欧拉角,这样是可以表示旋转的。问题有两点:
一,四元数转换到欧拉角的时候,Pitch只能在[-π/2,π/2]之间,要想全角度,必须针对各种情况分析;
二,即使全角度转换正确,最后在OpenGL中操作的时候还是会遇到万向节锁的问题,并未能避免。
3.参考Nehe的OpenGL教程中轨迹球的那一章,来实现旋转。目前碰到的问题就出在这了。
Nehe教程的主要处理过程是这样的:
Quat4fT ThisQuat; ArcBall.drag(&MousePt, &ThisQuat); // Update End Vector And Get Rotation As Quaternion Matrix3fSetRotationFromQuat4f(&ThisRot, &ThisQuat); // Convert Quaternion Into Matrix3fT Matrix3fMulMatrix3f(&ThisRot, &LastRot); // Accumulate Last Rotation Into This One Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot); // Set Our Final Transform's Rotation From This One
首先将鼠标拖拽的起始点和终止点的坐标转换为三维向量,再根据这两个向量生成一个四元数ThisQuat,这个四元数的(x,y,z)是两个向量的叉乘,w是两个向量的点乘。
我觉得奇怪的地方在下面那三句:为什么要先把四元数转换成3*3的矩阵相乘,再转换成4*4的矩阵?而不是直接转成4*4的矩阵相乘呢?因为我在查阅相关资料的时候,有直接将四元数转换为4*4矩阵的函数,但是我这样做的结果是,旋转度数远远超过预想的值。
目前我的程序就卡在这里了,明天继续分析。