在计算机图形学的学习中,几何变换(Transformations)是一块重要的内容,我们使用齐次坐标(Homogeneous coordinates)描述点和向量,使用变换矩阵描述平移、旋转等变换。
而在平移、旋转、缩放这几种变换中,又以旋转的情况最为复杂。实际上,计算机图形学中三维空间的旋转不仅仅有旋转矩阵一种表达形式,欧拉角(Euler angles)和四元数(Quaternions)也是常用的方法。
旋转矩阵
三维空间中的一个点 P ,我们用齐次坐标表示:
我们首先考虑分别绕 X 轴、Y 轴、Z 轴旋转一定角度的情况。
设 P 绕 X 轴、Y 轴、Z 轴的旋转角度分别为 α 、 β 和 θ 。
我们使用右手坐标系,旋转角度的正向由右手定则确定。
点绕坐标轴旋转可以考虑点在相应坐标平面上投影的旋转。比如绕 Y 轴旋转,那么考虑点 P 在 X-Z 平面上的投影的旋转,如下图所示:
假设点 P 在 X-Z 平面上的投影点与坐标原点连成的向量长度为 L ,那么根据简单的平面几何知识,我们可以得到:
用齐次坐标表示绕Y轴的旋转为:
同理可分别得到绕X轴与绕Y轴的情况。
绕X轴旋转:
绕Z轴旋转:
我们可以将绕X、Y和Z坐标轴的旋转矩阵分别记为 Rx(α),Ry(β),Rz(θ) ,则有:
旋转矩阵可以通过其他旋转矩阵复合得到(矩阵乘法)。
四元数
从前面的讨论我们发现三角度系统(three-angle system)无法很好地处理旋转的插值。下面介绍四元数(Quaternions)以及如何利用四元数描述旋转。
四元数的定义
四元数是由数学家 William Rowan Hamilton 于1843年所发明的数学概念,是复数的推广,可以说是“三维的复数”,形式为 w+x i+y j+z k ,其中 i,j,k 的关系如下:
假设有两个四元数:
四元数的加法定义如下:
四元数的乘法定义,利用简单的分配律定义如下:
为了方便表示,我们将四元数记为:
注意,这里四元数的表示形式和“齐次坐标”长得一样,但是它们之间没什么关系!
四元数常常用来表示旋转,很多人将其理解为“w表示旋转角度,v表示旋转轴”,也是错误的!
正确的理解应为:“w与旋转角度有关,v与旋转轴有关”。
四元数的模(norm)定义为
模为1的四元数称为单位四元数(Unit quaternions)。
四元数的共轭(conjugate)定义为:
四元数的倒数定义为:
四元数与旋转
这里直接给出结论:如果把单位四元数表示为:
的形式,那么该单位四元数可以表示绕轴
n⃗
进行
θ
角的旋转。
该单位四元数对应的旋转矩阵为
这里的推导用到了轴-角旋转表示中的Rodrigues’ rotation formula,具体证明这里不展开了,有兴趣的可以查阅相关资料。
我们发现用四元数描述旋转需要的存储空间很小,更为关键的是可以使用被称为球面线性插值(Slerp Algorithm)的方法对四元数进行插值运算,从而解决了平滑旋转的插值问题。
在 OpenGL 或者 DirectX 中我们通常使用模型视图矩阵来进行几何变换,当我们希望实现光滑旋转、对旋转进行插值时,就可以利用四元数这一工具。处理过程为:
- 模型视图矩阵 -> 四元数
- 使用四元数进行运算
- 四元数 -> 模型视图矩阵