# 导语

        在计算机图形学的学习中,几何变换(Transformations)是一块重要的内容,我们使用齐次坐标描述点和向量,使用变换矩阵描述平移、旋转等变换。而在平移、旋转、缩放这几种变换中,又以旋转的情况最为复杂。实际上,计算机图形学中三维空间的旋转不仅仅有旋转矩阵一种表达形式,欧拉角(Euler angles)四元数(Quaternions)也是常用的方法。

# 旋转矩阵

        这里再复习一下在计算机图形学:(一)基础中提到的旋转矩阵,假设绕XYZ三个轴旋转的角度分别为 α,β,γ ,则这三次旋转的旋转矩阵计算方法如下:

        最终的旋转矩阵为:

# 欧拉角

        旋转矩阵表面上看起来依赖于 9 个参数,实际上只有三个是独立的。为了更直接地指出这三个独立参数,欧拉(Euler)证明了如下事实:任何一个旋转都可以由连续施行的三次绕轴旋转来实现,这三次绕轴旋转的旋转角(α,β,γ )就是三个独立参数,称为欧拉角。

        欧拉角,这一数学概念,是描述物体在三维空间中绕坐标系三个轴(x, y, z轴)的旋转角度。它将方位(角位移)分解为绕这三个互相垂直轴的旋转,且这种分解具有任意性,即任意三个轴和旋转顺序都可以组成一个有效的欧拉角。

        🎈注:不同软件/引擎的默认坐标系不同,Heading(Yaw)通常指绕垂直轴的旋转(即取决于坐标系是Y-up还是Z-up)。如在Z-up系统中,heading-pitch-roll即为绕ZYX旋转;在GLM库中,eulerAngleYXZ()函数与yawPitchRoll()函数结果一致 [链接]。

偏航heading(蓝)--俯仰pitch(红)--滚转roll(绿)

        不同的旋转顺序会导致旋转结果不同,因此需要按照特定的旋转顺序进行欧拉角的计算和使用。在不考虑使用两种不同的约定来定义旋转(内旋或外旋,注:在后文再提及)的可能性下,存在12种可能得旋转轴序列,分为两组:

        (一)Proper Euler angles:也称为真欧拉角或者经典欧拉角。经典欧拉角中第一旋转轴和第三旋转轴是相同的,共有6种可能序列:

        (二)Tait–Bryan angles:也称为泰特-布莱恩角,万向角,航海角度,或者直接描述三个角(航向,海拔和高度或者偏航,俯仰和滚动) 。泰特-布莱恩角中三个角分别绕三个不同的轴转动,共有6种可能得序列:

        在实际使用中,为了简单起见,广泛采用“heading-pitch-roll”约定(注:heading有时也用yaw表示),它让物体从“标准”方位开始旋转,即物体坐标轴与惯性坐标系原点对齐。这种旋转顺序能通过依次作heading、pitch和roll旋转,使物体到达我们想要描述的方位。

        欧拉角可分为两种情况:①静态欧拉角(又称为外旋欧拉角)②动态欧拉角(又称为内旋欧拉角)

  • 静态欧拉角

        静态欧拉角是指物体绕世界坐标系三个轴的旋转,在这种情况下物体坐标轴保持静止。

        若按X-Y-Z旋转顺序(指先绕固定轴X,再绕固定轴Y,最后绕固定轴Z),可得旋转矩阵:

  • 动态欧拉角

        动态欧拉角则是指物体在自身坐标系中的旋转,这种旋转的复杂之处在于其坐标轴会随物体一起转动。

        若按Z-Y-X旋转顺序(指先绕自身轴Z,再绕自身轴Y,最后绕自身轴X),可得旋转矩阵:

        看到这里时泛起了迷糊,其他教程里以一句“外旋是左乘,内旋是右乘”草草带过,那么为什么是这样呢?

        这里来推导一下。首先,因为已经假设了物体自身轴对齐世界轴,所以绕物体X轴等价于绕世界的X旋转。若旋转顺序是XYZ,绕自身Y旋转的时候,已经存在X旋转了,已经被X轴的旋转影响到了。那么为了得到绕Y的旋转矩阵,我们先撤销绕自身X轴的旋转,进行Y旋转,再恢复X轴旋转。同理,为了得到绕Z的旋转矩阵,需要撤销Y轴旋转,再撤销X轴旋转,再进行Z轴旋转,再恢复X、Y轴旋转 [链接]。

        则内旋转最终表示为:

        那么若旋转顺序是ZYX,同理可得到:

        明白这点后,回到推导前,可以看到R_1=R_2。这个结论说明Z-Y-X顺序的内旋等价于X-Y-Z顺序的外旋任何的外旋都等于角度相同但元素旋转顺序相反的内旋,反之亦然

        用图片演示一下,最终下面两图表示了相同的旋转结果:

图1中表示的是使用zxz外旋转, (45°, 30°, -60°) 
图2中表示的是使用z-x'-z″内旋转, (−60°, 30°, 45°)

         内旋动画版(① 物体绕Z_{0}轴旋转 α 角度, 旋转后得到 X_{1}Y_{1}Z_{0}​;② 物体绕 X_{1}​ 轴旋转 β 角度,旋转后得到X_{1}Y_{2}Z_{2};③​ 物体绕 Z_{2}轴旋转 γ 角度,旋转后得到X_{3}Y_{3}Z_{2}):

# 万向节锁(Gimbal Lock)

        通过欧拉角我们可以直观地理解物体的旋转,但其缺点在于可能面临万向锁问题。我们使用平衡环来动态演示该问题:

        一开始承载物体的三个环互相垂直,构成直角坐标系,如将位于中间的红环旋转 90 度(顺/逆时针),就会发现最内侧的蓝环就会和最外侧的绿环环处于同一个平面上(即物体的两个旋转轴指向了同一个方向),导致整个系统丢失了一个“自由度”,也就是说现在内外侧的环对于物体施加的旋转效果是等效的。

        从代数意义来看,对于zyx轴顺序的旋转(内旋),按β=±90°,代入矩阵计算:

        那么对于任意沿zyx转 (γ,π/2,α) 的组合,都等价于 (0,π/2,γ−α) ,而前者有两个自由度( α 和 γ ),后者只有一个自由度( γ 与 α 的差值 γ−α ),这就是万向节锁的问题。

# 四元数

        四元数作为一种替代方案,更高效地描述了旋转,并避免了万向节锁问题。虽然四元数的概念较为复杂抽象,但它在计算机图形学中被广泛应用于物体的旋转。

        四元数是一种特殊的复数,通过结合旋转向量和旋转角度,提供了高效的旋转表示方法。

        先通过二维旋转来复习一下复数。

        我们把形如z = a+bi 的数称为复数,其中a,b均为实数,a称为实部,b称为虚部,i 称为虚数单位, i*i= -1; 模长|z| = \sqrt{a^2 + b^2},辐角\theta = arctan(b/a)

        a 决定了点在实轴上的位置,而 b 决定了点在虚轴上的位置。复数(实数+虚数)是可以表示旋转的,比如一个数字乘 i 就相当于它在坐标轴上的位置逆时针旋转90°,乘以-i可以顺时针旋转90°。

4  →  4i  →  4*i*i = -4

        复数乘法在几何上表现为向量的旋转和伸缩。比如一个复数乘另一个复数,相当于缩放一个倍数,再旋转一个角度。如一个数字乘3+4i,就相当于这个数字放大到原来的5倍(\sqrt{3^2+4^2} = 5),再逆时针旋转arctan(4/3)

        将一个复数 z 乘以 e^{i\theta}(欧拉公式),相当于将 z 对应的向量逆时针旋转 θ 角度。

        两个实部相等,虚部互为相反数的复数互为共轭复数,如a+bi和a-bi。对于复数z=a+bi,a,b∈R,复数到特定形式二阶矩阵的同构映射

        二维旋转矩阵其实也对应着一个类似四元数的一个向量表达形式:

        在此基础上,我们可以将其扩展到三维空间,在三维空间中我们使用四元数表示,除了虚数i之外,在四元数中额外加入了两个虚数,它的一般形式为:q = xi + yj + zk + w,其中x、y、z代表向量的三维坐标,而w代表角度。四元数表达了物体绕某向量轴旋转一定角度,在描述物体旋转时只需关注这些关键值。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐