矩阵、欧拉角、轴-角对、四元数随笔
一、矩阵
在 3D 游戏中,可以使用矩阵来表示一个物体的旋转。
1) 优点:
个人认为,理解起来最为直观。
像现成的DXSDK库中也提供了十分完善的相关接口
一个矩阵即可表示多种变换的组合
2) 缺点:
每次计算都会产生误差,因此,需要经常规范化。
耗的内存较多些。
二、欧拉角
欧拉角指的是:以世界坐标系为参考坐标系(一定记住是世界坐标系),使用x,y,z三个值来分别表示绕(世界的)x轴、y轴、z轴旋转的角度量值。其取值是在[0, 360]间。一般用roll, pitch, yaw来表示这些分量的旋转值。因为是以世界坐标系为参考坐标系,因此每一次的旋转都不会影响到后续的旋转转轴。即:它无法表示任意轴的旋转。
1) 优点:
理解起来很直观。
2) 缺点:
会有万向锁问题。
三、轴-角对
其实轴-角对与欧拉角(个人认为)是有一定的关系的。因为欧拉角说的是分别(注意:是分别)绕(以世界坐标系为参考坐标系的)三个轴旋转一定的角度。其实这三次的旋转可以最终转换到一次变换。即:最终可表示为:绕某一旋转轴旋转一定角度的变换。(意思就是说:那三次变换我们最终可以计算出旋转轴以及绕该旋转轴旋转的角度量)。
1) 缺点:
轴-角对表示法:插值不平滑,可能会有跳跃。(文档上说,欧拉角同样存在这个问题)
2) 优点:
可解决欧拉角的万向锁问题。
四、四元数
四元数定义:q = w + xi + yj + zk
注意:
1) 四元数可以归一化,并且只有归一化的四元数才用来描述旋转
2) 四元数与轴-角对很像。因为四元数描述的也是一个旋转轴与一个绕着该旋转轴旋转的量值(即:角度或弧度)。但四元数与轴-角对不等价。它们的关系如下:
假如:轴-角对的值如下:
轴为:n
角为:theta
则,对应的四元数中的w、x、y、z的值分别为:
w = cos(theta / 2)
x = nx * sin(theta / 2) // nx 是轴 n 的 x 分量
y = ny * sin(theta / 2) // ny 是轴 n 的 y 分量
z = nz * sin(theta / 2) // nz 是轴 n 的 z 分量
3) 四元数的乘法意义:
Q = Q1 * Q2表示的是:Q先做Q2的旋转,再做Q1的旋转的结果,而且多个四元数的旋转也是要以合并的。
4) 四元数做一次乘法需要16次乘法和加法,而3x3矩阵需要27次。所以有多次旋转操作时,使用四元数计算效率更高些。
5) 四元数的插值过度平滑。最常用的是线性插值。
关于轴-角对的理解可参照Alex四元数解算的程序(角度+每轴的分量)。
在3D图形学中,最常用的旋转表示方法便是四元数和欧拉角,比起矩阵来具有节省存储空间和方便插值的优点。本文主要归纳了两种表达方式的转换,计算公式采用3D笛卡尔坐标系:
图1 3D Cartesian coordinate System (from wikipedia)
定义分别为绕Z轴、Y轴、X轴的旋转角度,如果用Tait-Bryan angle表示,分别为Yaw、Pitch、Roll。
图2 Tait-Bryan angles (from wikipedia)
一、四元数的定义
通过旋转轴和绕该轴旋转的角度可以构造一个四元数 :
其中是绕旋转轴旋转的角度,
为旋转轴在x,y,z方向的分量(由此确定了旋转轴)。
二、欧拉角到四元数的转换
三、四元数到欧拉角的转换
arctan和arcsin的结果是,这并不能覆盖所有朝向(对于
角
的取值范围已经满足),因此需要用atan2来代替arctan。
四、在其他坐标系下使用
在其他坐标系下,需根据坐标轴的定义,调整一下以上公式。如在Direct3D中,笛卡尔坐标系的X轴变为Z轴,Y轴变为X轴,Z轴变为Y轴(无需考虑方向)。