为什么三个数来表达3D方位一定会导致如方向锁这样的问题?这是有数学原因的,它涉及到一些非常高级的数学概念,如”簇“。四元数通过使用四个数来表达方位(因此命名为四元数),从而避免了这些问题。
四元数的记法:一个四元数包含一个标量和一个3D向量分量。经常标量分量为W,记向量分量为单一的V或分开的X,Y,Z。两种记法分别如下:
[w,v]
[w,(x,y,z)]
在某些情况下,用V这样的段记法更方便,但另一些情况下,”扩展“的记法会更清楚。
四元数的优点;
平滑插值,slerp和squard提供了方位间的平滑插值,没有其他方法能提供平滑插值。
快速连接和角位移求逆:四元数叉乘能将角位移序列转换为单个角位移,用矩阵作同样的操作明显会慢一些。四元数共轭提供了一种有效计算反角位移的方法,通过转置旋转矩阵也能达到同样的目的,但不如四元数来的容易。
能喝矩阵形式快速转换。四元数和矩阵间的转换比欧拉角与矩阵之间的转换稍微快一点。
仅用四个数。四元数仅包含四个数,而矩阵用了9个数,它比矩阵“经济”得多。
要获得这些优点是要付出代价的。四元数也有和矩阵相关的问题,只不过问题程度较轻:
比欧拉角稍微大一些。这个额外的数似乎没有太大关系,但在需要保存大量角位移时,如存储动画数据,这额外的33%也是数量可观的。
四元数可能不合法。坏的输入数据过浮点数舍入误差积累都可能使四元数不合法(能通过四元数标准化解决这个问题,确保四元数为单位大小)。
难于使用。在所有三种形式中,四元数最难于直接使用的。
不同的方位表示方法使用于不同的情况。
欧拉角最容易使用。当需要为世界中的物体指定方位时,欧拉角能大大地简化人机交互,包括直接的键盘输入方位、在代码中指定方位(如为渲染设定摄像机)、在调试中测试。这个优点不应被忽略,不要以“优化”为名义而牺牲易用性,除非您确定这种优化的确有效果。
如果需要在坐标系之间转换向量,那么就旋转矩阵形式。当然这并不意外这您就不能用其他格式来保存方位,并在需要的时候转换到矩阵格式。另一种方法时用欧拉角作为方位的“主拷贝”,但同时维护一个旋转矩阵,当欧拉角发生改变时矩阵也要同时进行更新。
当需要保存方位数据(如动画)时,就使用欧拉角或四元数。欧拉角将少占用25%的内存。但它在转换到矩阵时要稍微慢一些。如果动画数据需要嵌套坐标系之间的链接,四元数可能是最好的选择。
平滑的插值只能用四元数完成。如果您用其他形式,也可以先转换到四元数然后再插值,插值完毕后再转换回原来的形式。
表达形式之间的转换:
从欧拉角转换到矩阵:欧拉角描述了一个旋转序列。分别计算出每个旋转的矩阵再将它们连接成一个矩阵,这个矩阵就代表了整个角位移。
当 然,它饿我偶们是想要物体到惯性坐标系的变换矩阵还是惯性到物体坐标的变换矩阵是相关的。我们对欧拉的定义式一个旋转序列,该旋转序列将物体(和它的坐标空间)从惯性坐标空间转换到物体坐标空间。如果要从物体坐标空间变换到惯性坐标空间,应该使用惯性-----物体旋转矩阵的逆。因为旋转矩阵是正交,所以求它的逆就是求它的转置。
从矩阵转换到欧拉角:
必须清楚矩阵代表什么旋转:物体----惯性还是惯性----物体。
对任意给定角位移,存在无穷多个欧拉角可以用来表示它。因为“别名”问题,这里讨论的技术总是返回“限制欧拉角”,heading 和 bank的范围为
+-180度,pitch 的范围为+-90.
矩阵可能是病态的,我们必须忍受浮点精度的误差。有些矩阵还包括旋转外的变换。如缩放,镜像等。
从四元数转换到矩阵:
从矩阵转换到四元数:
从欧拉角转到四元数:为了将角位移从欧拉角形式转换到四元数,可以先将三个旋转分别转换为四元数,这是一个简单的运算。再将这三个四元数连接成一个四元数。和矩阵一样,有两种情况需要考虑:第一种是惯性---物体四元数,第二种是物体-----惯性四元数。
从四元数转换到欧拉角: