旋转四元素的应用

一般我们所熟知的旋转是指x, y, z轴旋转,即围绕着坐标轴旋转。这种表示形式的优点是容易理解和手动控制,在设计软件中可以非常方便地调整元素的旋转。同时,这种表示方式也存在一些局限。

坐标轴旋转的局限

最典型的局限是万向节锁。我们使用一个具体的例子说明。在AE软件中导入一个鸟的模型,然后将其y轴旋转设置为90度。再调整x轴、z轴旋转,会发现这两个轴的调整效果是一样的,如下面动图所示。

也就是说,3个旋转轴失去了一个自由度。为什么会这样呢?我查了很多资料都无法得到一个直观的解释,最后发现其实挺好理解的。在AE中默认的坐标轴的方向是这样的:

在绕着y轴旋转90度后,绕着z轴旋转就是上面动图中侧翻的效果。而绕着x轴旋转不应该是俯仰的效果吗,预期效果应如下图所示:

造成问题的原因是,x轴、y轴、z轴这3轴的旋转应用的顺序是固定的(不同的顺序会影响最终旋转的效果)。在AE中,应用的顺序固定为按x轴 -> y轴 -> z轴。

在最开始的状态,各轴旋转角度为0,是下面的效果:

然后将x轴旋转角度设置为-10度,则会增加其仰角(鸟头朝上),如下图所示:

接下来,将y轴旋转角度调整为90度后,就会转变成侧翻的效果:

注意观察坐标轴的变化过程,最开始的x轴旋转,最后转化成了z轴旋转。

在下图右侧的坐标轴状态下,因为z轴的旋转角度是最后被应用的,因此调整它的效果与当前坐标轴的状态吻合。而x轴是最先被应用的,调整它的效果需要使用下图左侧初始状态的坐标轴。下图左侧的x轴与右侧的z轴是同一条轴,因此调整它俩的效果一致。

这应该是万向节锁“最直接、最不绕弯”的解释。

在AE中,应当如何突破万向节锁的限制呢?方法很简单,再套一个父容器就好了,然后去修改父容器的z轴旋转。因为父容器又是一个处于初始状态的坐标轴(即上图左侧),如下图所示:

在实际编码中,我们不可能每次调整一个轴的旋转时就给元素套一个父容器。因此需要使用到旋转的另外一种表示形式:旋转四元素。

旋转四元数

围绕着x轴、y轴、z轴旋转,等价于围绕着(1, 0, 0)、(0, 1, 0)、(0, 0, 1)这个向量旋转,如下图所示:

在欧拉旋转理论中,元素是可以围绕任意向量旋转的,如下图所示:

我们将绕着向量旋转表示为(θ, x0, y0, z0)。这样绕着y轴旋转90度就表示为:q1 = (90, 0, 1, 0)。

这个时候,想要让它绕着(上图右侧)x轴旋转45度,造成仰角效果,应该怎么办呢?这个旋转表示为q2 = (45, 1, 0, 0)。方法是将q1乘以q2得到新的向量即为表示叠加的旋转效果的向量(具体的数学原理不展开讨论)。如果想用上图左侧初始状态的坐标轴,则应该绕着z轴旋转45度,用q3 = (45, 0, 0, 1)表示,然后将q3乘以q1也可以得到相同的结果。(注意到,旋转四元素的复合乘法不满足交换率,q1乘q2与q2乘q1的结果是不一样的。所以上面前者q1在左侧,而后者q1在右侧)

注意到实际的旋转四元素并非上面表示的形式,而是用下面的形式:

旋转矩阵表示为:

可见,使用旋转四元素表示的旋转矩阵中的元素都是使用基础四则运算就可以算出来,避免了大量耗时的三角函数的计量。这也是旋转四元数的另外一个好处。

需要注意的是,旋转四元素并没有增加信息,它只是旋转的另外一种表示形式。

除了可基于当前状态继续旋转外,旋转四元素的其他常见应用还有:

  1. 旋转插值:比如我们要做个动画,让元素从某个旋转角度自然过渡到另一个旋转角度。那么使用旋转四元素可以很方便计算两个角度之间的插值。从一个向量旋转过渡到另一个向量旋转。而使用复合坐标轴旋转角度的形式,则不太好计算。特别是在进入、离开万向节锁的时候,角度的变化可能会很大(虽然视觉上变化不大)。
  2. 移动相机的旋转角度,让相机看向元素(具体不展开)。

 

综上,在设计软件中,经常使用坐标轴旋转,直观且方便控制。在3D编程中,旋转四元素则是更好用的表示形式。可将用户设定的坐标轴旋转,转化为旋转四元素数后再继续进行运算。

 

参考:

  1. Rotation Quaternions, and How to Use Them
  2. Everything you need to know about Quaternions for Game Development

 

发表评论

邮箱地址不会被公开。