旋转与四元数
摘要
本文主要介绍三维旋转的几类重要表示方式,以及在游戏及其他工程领域最为常用的四元数的相关概念、性质、运算法则和常用公式。
一、三维旋转变换的表示方式
1、欧拉角
直接给出$x$(俯仰)、$y$(偏航)、$z$(滚转)三个轴向的旋转角,优点是表示简单直接,容易理解,但存在万向节死锁的问题(当两个轴重合时,会损失一个自由度)。
2、轴角
顾名思义,用一个轴$n$和一个角$\theta$表示旋转,其中轴是旋转轴,默认用一个过坐标原点的三维向量表示,角表示绕这个轴旋转的角度,轴角表示为一个四元组$(x,y,z,\theta)$。
但轴角也存在明显的缺陷,一方面,因为角度的周期性,任何$2n\pi$的旋转都等价于没有旋转,这在某些情况下是不可接受的;另一方面,由于轴角描述的“四元组”并不是一个空间下的东西,首先$(x,y,z)$是一个3维坐标下的矢量,而$\theta$则是极坐标下的角度,简单的将他们组合到一起并不能保证他们插值结果的稳定性,因为他们无法归一化,所以不能保证最终插值后得到的矢量长度(经过旋转变换后两点之间的距离)相等;此外,轴角形式的旋转不能直接施于点或矢量,必转换为矩阵或者四元数。
3、矩阵
计算机图形学中,一般以矩阵形式表示旋转,对于三维空间的点或向量,将其表示为齐次坐标形式,则绕不同旋转轴的旋转矩阵为:

而对于任意旋转,都可以分解为这三个轴的旋转,可以利用Rodrigues旋转公式将轴角表示的任意旋转转换为矩阵形式:

矩阵表示法可以直接施加于点或向量,计算相对方便,也叫容易理解,但在实际工程中,如果我们要存储一个对象的旋转参数,就要存储这个对象的旋转矩阵,一共16个浮点数,对空间消耗较大,并且矩阵形式同样无法进行简单的插值,因此在实际的游戏开发及其他工程应用中,存储一个对象的旋转,通常采用四元数的形式。
4、四元数
四元数像是轴角表示法的优化版本,但解决了所有轴角可能存在的问题,最大的优势就是便于插值,并且存储时只需要存储4个浮点数,而且求逆、串联等操作比矩阵更方便,相比于轴角和矩阵优势巨大。
对于四元数的理解,可以看作是有一个实部和三个虚部构成的虚数,描述的是四维空间,具体可以看可视化理解四元数。
二、四元数
四元数的全部公式和运算法则以及与矩阵等形式的转化,可以查看四元数(Quaternions),这里对常用的关键公式进行总结。
四元数表示为$(x,y,z,w)$,其中
$$
x=i·q_1·sin(\theta/2) \
y=j·q_2·sin(\theta/2) \
z=k·q_3·sin(\theta/2) \
w=cos(\theta/2)
$$
其中$(iq_1,jq_2,kq_3)$是表示旋转轴的矢量,$\theta$表示绕此轴旋转的角度。对四元数$q_2$左乘一个四元数$q_1$,其作用是将$q_2$拉伸$q_1$的模长,再作用一个特殊的四维旋转。所以我们用单位四元数来表示三维空间中的旋转,因为单位四元数模长为1$(w^2+x^2+y^2+z^2=1)$,而旋转时必须要保证的就是,一个向量旋转前后模长不变。
- 乘法

- 标量乘法


- 加法

- 共轭
$$
q=(w,x,y,z) \
q^*=(w,-x,-y,-z)
$$
- 模

- Identity
$$
i=(0,0,0,1)
$$
- 逆

- 单位四元数表示旋转:单位四元数模为1,因此可以表示为

将一个三维向量$p$写成四元数形式

则运算

表示向量$p$在三维空间中绕轴$u_q$旋转$2\phi$弧度。