简单整理下四元数旋转相关的一些概念:

  • 欧拉角:旋转顺序与内外旋
  • 万向节死锁:旋转轴共面与自由度丢失
  • 四元数:表示与计算、几何意义与球形插值

欧拉角(Euler-Angles)

欧拉角使用$\alpha,\beta,\gamma$分别表示物体与坐标系(参考坐标系)中三个轴的夹角,来表示一个6自由度的旋转。

但仅有一组欧拉角并不能确定一个物体(刚体)在空间中姿态,还需要确定旋转顺序(顺规)参考坐标系(世界/物体)

旋转顺序

在各个轴上的旋转顺序(sequence, 即顺规)会影响最终的效果。

举个例子,下面两种旋转后得到的姿态(世界坐标系下)是不同的:

  1. 先绕x轴旋转$\alpha$度,再绕y轴旋转$\beta$度
  2. 先绕y轴旋转$\beta$度,再绕x轴旋转$\alpha$度

若从数学计算的角度来理解可以认为是由于矩阵乘法不满足交换律

在给定旋转角度后,根据选择的旋转轴(rotation axe)差异,可以分为两大类:

  1. 经典欧拉角(Proper Euler angles): 第一个旋转轴和最后一个旋转轴相同
  2. 泰特布莱恩角(Tait–Bryan angles): 参考三个不同的轴

在满足任何两个连续的旋转,必须绕着不同的转动轴旋转的条件下,每种表示法中都各有六种顺规:

  1. 经典欧拉角顺规: z-x-z, x-y-x, y-z-y, z-y-z, x-z-x, y-x-y
  2. 泰特布莱恩角顺规: x-y-z, y-z-x, z-x-y, x-z-y, z-y-x, y-x-z

车体、飞行器中常用的roll(横滚), pitch(俯仰), yaw(偏航)表示则对应Tait–Bryan angles中的xyz顺规。

参考坐标系

欧拉角的参考坐标系可以有两种:

  1. 世界坐标系,保持不变
  2. 固有坐标系,即物体自身坐标系

一般使用xyz表示原始坐标系,使用XYZ表示旋转后的坐标系,使用N表示xy平面与XY平面的交点线。

根据旋转坐标系的不同,分为:

  1. 内旋(intrinsic rotations): 采用物体固有坐标系,在每一次旋转时,物体的坐标系相对世界坐标系发生变化,也称为动态欧拉角。
  2. 外旋(extrinsic rotations): 采用世界坐标系,始终根据固定世界坐标系进行旋转,也称为静态欧拉角。

以zxz顺规的内旋为例(不分经典欧拉角还是泰特布莱恩角,下面同理):

  1. x-y-z(初始状态)
  2. x′-y′-z′(一次旋转后)
  3. x″-y″-z″(两次旋转后)
  4. X-Y-Z(最终状态)

则欧拉角中的$\alpha,\beta,\gamma$分别对应与z轴、x′轴和z″轴的夹角

以zxz顺规的外旋为例:

由于采用固定世界坐标系,则xyz固定,XYZ初始状态与xyz相同。采用如下步骤进行旋转:

  1. XYZ系统绕z轴旋转$\gamma$,此时X轴与x轴夹角为$\gamma$
  2. XYZ系统绕x轴旋转$\beta$,此时Z轴与z轴夹角为$\beta$
  3. XYZ系统绕z轴旋转$\alpha$

对于经典欧拉角来说,6种顺规对应的内外旋旋转轴:

  • z1-x′-z2″ | z2-x-z1
  • x1-y′-x2″ | x2-y-x1
  • y1-z′-y2″ | y2-z-y1
  • z1-y′-z2″ | z2-y-z1
  • x1-z′-x2″ | x2-z-x1
  • y1-x′-y2″ | y2-x-y1

总结一下,使用欧拉角描述物体的旋转姿态时,为了确保唯一性,需要确定三个因素:

  1. 旋转角度: $\alpha,\beta,\gamma$
  2. 旋转顺序: 经典欧拉角与泰特布莱恩角
  3. 旋转方式: 内旋与外旋

万向节死锁(Gimbal lock)

Wiki上的相关介绍:

The angles α, β and γ are uniquely determined except for the singular case that the xy and the XY planes are identical, i.e. when the z axis and the Z axis have the same or opposite directions. Indeed, if the z axis and the Z axis are the same, β = 0 and only (α + γ) is uniquely defined (not the individual values), and, similarly, if the z axis and the Z axis are opposite, β = π and only (α − γ) is uniquely defined (not the individual values). These ambiguities are known as gimbal lock in applications.

火炮与飞机示例:

若用平衡环(gimbal)来操作每个方向的旋转,则需要三个嵌套的环来模拟三维空间中的三个轴。当三个环相互垂直时,每个环的行为是独立的,控制各自的自由度。而当其中两个环共面时,则会丢失一个方向上的旋转自由度(Degree of Freedom),即万向节死锁现象。

总结一下:

  • 使用欧拉角出现的万向节死锁问题:两个旋转轴平面共面时,丢失一个方向的自由度
  • 该问题的出现并不是说不能旋转了,而是旋转时不自然了
  • 可以通过调节顺规或使用四元数来规避该问题。

四元数(Quaternion)

表示与运算

二维平面中的复数应该很熟悉,其表示形式为:$a+bi$。而四元数相当于四维空间中的复数,具有三个虚部,其表示为: $w+xi+yj+zk$,满足$i^2=j^2=k^2=ijk=-1$。

虚部乘法表如下:

✖️ i j k
i -1 k -j
j -k -1 i
k j -i -1

几何意义

三维空间的任意旋转,都可以用绕三维空间的某个轴旋转过某个角度来表示,即轴角表示(axis-angle)。空间中任一位置的轴角表示是唯一的,不存在使用欧拉角时的Ambiguity问题。

在使用轴角表示方向时,需要4个参数,3个表示旋转轴的分量,1个表示旋转角度。若规定表示旋转轴的向量是单位向量,考虑到$\sqrt{x^2+y^2=z^2}=1$,则总共需要3个参数就可以(第三个分量通过计算得出)。

二维空间中的复数,每个复数对应复平面中的一个点,当给这个复数乘以i,相等于将其绕原点旋转了90度。而四元数将虚部扩展成了三个,根据前面的乘法表有如下计算公式:

  • $ij=k$, $ji=-k$
  • $jk=i$, $kj=-i$
  • $ki=j$, $ik=-j$

可以将i,j,k视为三个方向的单位向量,则可以将上式理解为两个相互垂直的单位向量的叉乘等于垂直于它们的单位向量。

若存在一个沿着旋转轴方向的单位向量$v=(\beta_x,\beta_y,\beta_z)$和旋转角度$\alpha$,可以通过下式计算四元数的各个分量:

  • $w=cos(\alpha/2)$
  • $x=sin(\alpha/2)*\beta_x$
  • $y=sin(\alpha/2)*\beta_y$
  • $z=sin(\alpha/2)*\beta_z$

其中$\alpha$为绕旋转轴旋转的角度,$\beta_x$、$\beta_y$、$\beta_z$为旋转轴在x,y,z方向的分量(由此确定了旋转轴)。具体证明与推导可查阅相关资料。

为何要引入四元数?

四元数的引用是为了减少计算量和计算时存储占用的空间。

  1. 3×3矩阵需要存储6个单位数据,四元数为4个
  2. 在多重变换情况下,四元数可以利用3次易号运算代替n次四元数相乘运算,而欧拉角矩阵计算需要多个3×3矩阵相乘。

对于三维空间的旋转,可以通过四元数乘法直接操作,与旋转矩阵操作可以等价,但是表示方式更加紧凑,计算量也可以小一些。

万向节死锁问题

由于该问题是在使用欧拉角时由于旋转轴共面才会出现的问题,而在使用四元数时不会丢失旋转自由度,因此不会出现该问题。

需要注意的是,如果仅仅在欧拉角与旋转矩阵间中间表示的转换计算时使用四元数,则该问题依然存在。

球面插值 - slerp

  • 线性插值(lerp): 仅仅为距离插值
  • 球面插值(slerp): 将Vector3作为方向向量,返回的Vector3的长度是两点之前的距离插值,方向是两个向量之间的夹角度数的插值。

参考