欧拉角与万向节锁

欧拉角与万向节锁之理论解析

  翻了一大堆博客,很少有对万向节锁介绍清楚的。这里谈谈我对万向节锁的通俗认识。

前提

  1. 我们这里采用左手坐标系(与Direct3D所使用的一样)。左手坐标系如下图:
    欧拉角与万向节锁_第1张图片
  2. 我们使用的点用行向量来表示(与Direct3D所使用的一样),所以只能是vector*matrix,而不能是matrix*vector。
  3. 由于只考虑旋转,所以这里行向量是三维的,矩阵也是3x3的(在Direct3D中,由于要考虑平移,所以行向量是四维的,矩阵是4x4的)。

欧拉角的相关知识

  1. 所谓欧拉角就是绕x轴、y轴、z轴旋转的角度。(嗯,通俗易懂==)
  2. 由于绕轴的旋转顺序不同,得到的结果也不一定一样;
    比如我们把点(1,0,0)绕x、y、z轴顺序分别旋转pi/2、pi/2、0,得到的结果为(0,0,-1);
    如果我们把点(1,0,0)绕y、x、z轴顺序分别旋转pi/2、pi/2、0,得到的结果为(0,1,0);
    所以为了方便分析,我们这里以x、y、z的顺序来对点进行旋转

矩阵计算

  1. 前面我们旋转一个点是自己在脑子里想象着转的,如果使用矩阵计算的话该如何计算
      我们都知道可以使用旋转矩阵来计算,我这里把绕x、y、z分别旋转θ1、θ2、θ3的旋转矩阵贴在下面:
    欧拉角与万向节锁_第2张图片欧拉角与万向节锁_第3张图片欧拉角与万向节锁_第4张图片
      我们用Mat1、Mat2、Mat3来表示上面三个矩阵,用Pos来表示要旋转的点的坐标,最后旋转后的结果应该为Pos*Mat1*Mat2*Mat3。
  2. 矩阵计算所绕的轴是固定于世界的坐标轴还是物体自身的坐标轴
    • 可以用点(0,0,1)绕x、y、z轴顺序分别旋转pi/6、pi、0,来验证,使用上面介绍的矩阵计算得到的结果为(0,-0.5,-0.866),这跟使用固定于世界的坐标轴计算的结果是一致的。如果使用自身的坐标轴,结果应该为(0,0.5,-0.866)。所以这里使用的确实是固定于世界的坐标轴
    • 虽然是固定于世界的坐标轴,但是有一点要注意,就是后面的旋转轴不但会旋转前面得到的点坐标,同样也会旋转前面已经用过的旋转轴。所以严谨来说,应该是当前旋转矩阵使用的是固定于世界的坐标轴
  3. 矩阵计算与万向节的对应关系
    • Pos*Mat1*Mat2*Mat3是有层级关系的,Mat1(绕x轴)处于内层,Mat3(绕z轴)处于外层,外层会影响内层的结果;
    • 万向节也是相似的,内层的旋转轴对应于内层的旋转矩阵,外面的旋转轴对应外层的矩阵。外层的旋转轴会改变内层的旋转结果(这与矩阵运算也是一致的);这里给张万向节的图:
      欧拉角与万向节锁_第5张图片
    • 万向节的旋转结果与矩阵计算的结果是一样的,给定三个旋转角度,矩阵计算与旋转万向节可以得到一致的结果;
    • 万向节与矩阵计算的区别在于:矩阵计算只能是从左向右计算!这是由数学计算规则决定的(计算矩阵合并最后也还是要左乘)。而万向节可以在给定旋转角度的情况下,以任意次序旋转(当然,前提是万向节的层级关系必须和矩阵计算一致)。比如:可以先旋转外层再旋转内层,也可以先旋转内层再旋转外层(这与矩阵计算的次序一致)。

万向节锁产生的原因

  1. 对于矩阵运算Pos*Mat1*Mat2*Mat3,旋转角分别为θ1(绕x)、θ2(绕y)、θ3(绕z),我们可以合并右边的三个矩阵,假设Mat = Mat1*Mat2*Mat3,当θ2 = PI/2的时候,Mat的值为:
    欧拉角与万向节锁_第6张图片
    可以看到此时旋转矩阵只与θ1-θ3有关,也就是只能影响一个维度的旋转,也就是丢失了一个旋转自由度,这就是所谓的万向节锁。
  2. 对于万向节旋转来产生万向节锁更简单(因为不用推导==),只需要将处于中间层的旋转轴旋转PI/2,就能得到万向节锁,此时不论旋转内层旋转轴还是旋转外层旋转轴,都只能在同一个自由度上旋转。可以看这个视频来见识一下真正的万向节锁!

后记

有些博客说欧拉角是绕自身的x、y、z轴旋转的,我也不知道是怎么得出这个结论的==
这些都是我自己的理解,如有错误还请大家指正。

你可能感兴趣的:(欧拉角与万向节锁)