2021SC@SDUSC
在上一节中学习了关于骨骼的数据结构,接下来我们会继续学习在动画系统中,骨骼是如何相对某参考系进行收收放,平移和旋转的。而这也被称为骨骼(关节)的姿势。
关节的姿势是通过SQT数据结构,一个4*3或4*4的矩阵表示(缩放,scale;四元数旋转,quaternion;矢量平移(方向,距离(坐标)),translation)。其中旋转是最复杂的一部分。
矩阵旋转
优点:
旋转轴可以是任意向量;
缺点:
旋转其实只需要知道一个向量+一个角度,一共4个值的信息,但矩阵法却使用了16个元素;
而且在做乘法操作时也会增加计算量,造成了空间和时间上的一些浪费;
欧拉旋转
优点:
很容易理解,形象直观;
表示更方便,只需要3个值(分别对应x、y、z轴的旋转角度);但按我的理解,它还是转换到了3个3*3的矩阵做变换,效率不如四元数;
缺点:
之前提到过这种方法是要按照一个固定的坐标轴的顺序旋转的,因此不同的顺序会造成不同的结果;
会造成万向节锁(Gimbal Lock)的现象。这种现象的发生就是由于上述固定坐标轴旋转顺序造成的。理论上,欧拉旋转可以靠这种顺序让一个物体指到任何一个想要的方向,但如果在旋转中不幸让某些坐标轴重合了就会发生万向节锁,这时就会丢失一个方向上的旋转能力,也就是说在这种状态下我们无论怎么旋转(当然还是要原先的顺序)都不可能得到某些想要的旋转效果,除非我们打破原先的旋转顺序或者同时旋转3个坐标轴。这里有个视频可以直观的理解下;
由于万向节锁的存在,欧拉旋转无法实现球面平滑插值;
四元数旋转
优点:
可以避免万向节锁现象;
只需要一个4维的四元数就可以执行绕任意过原点的向量的旋转,方便快捷,在某些实现下比旋转矩阵效率更高;
可以提供平滑插值;
缺点:
比欧拉旋转稍微复杂了一点点,因为多了一个维度;
理解更困难,不直观;
而在学习SQT数据结构之前,先学习一下四元数旋转。
四元数是对复数的扩充,它使用三个虚部i,j,k它们的关系如下:
i² = j² = k² = –1
四元数形式:
[w v]或[ w (x y z) ].
四元数定义了一个复数
w + xi + yj + zk
四元数只能用来代替矩阵保存旋转信息,平移无法代替,旋转我们有 矩阵,欧拉角,四元数,
四元数是里面最复杂的一个但它可以在保证效率的同时减小矩阵1/4的内存占有量,同时又能避免欧拉角的万向锁问题,
无法用语言表达清楚万向锁的现象只有碰到过才能理解。。。
四元数和轴——角对:
设O为旋转角度,N为旋转轴(绕任意轴n旋转O度):
Q = [cos(O/2) sin(O/2)N] = [ cos(O/2) ( sin(O/2)Nx sin(O/2)Ny sin(O/2)Nz ) ]
负四元数:
-Q = –[w (x y z)] = [-w (-x -y -z)] = –[w v] = [-w -v]
Q和-Q代表的是相同的角位移,如果我们将O加上360°的倍数,不会改变Q代表的角位移,但它使Q的四个分量都变负了。
因此,3D中的任意角位移都有两种不同的四元数表示方法,它们互为负数。
单位四元数:
几何上存在两个“单位”四元数,它们没有角位移, [1, 0]和[-1,0] 0代表0向量,让我们看看原因:
当O为360°的偶数倍时,有第一种形式,cos(O/2) = 1;
当O为360°的奇数倍时,有第二种形式,cos(0/2) =-1;
在这两种形势下都有sin(O/2) = 0,所以和旋转轴N是无关的,他的意义是,当旋转角O是360°的整数倍时,方位没有改变,并且旋转轴也是关紧要的.
注意:
数学上只有一个单位四元数[1, 0],用四元数q乘以单位四元数[1,0],结果认识q。任意四元数q乘以另一个“几何单位”四元数[-1,0]时得到-q。几何上,因为q和-q代表的角位移相同,可
认为结果是相同。但在数学上,q和-q不相等,所以[-1,0]斌不是“真正”的单位四元数。
四元数的模:
公式:
|| q || = || [w (x y z)] || = √(w² + x² + y²