本文最后更新于:2025年4月17日 晚上
由于使用欧拉角进行旋转时会存在万向锁的问题,同时,用欧拉角进行插值也不尽方便,而基于四元数的旋转既解决了万向锁的问题,又能非常方便地进行插值。本文将对在学习过程中遇到的四元数的定义、推导、性质、插值等问题进行总结归纳。
复数
我们先来简要讨论一下复数的一些性质以及它与 2D 旋转之间的关系,四元数的很多性质都与复数非常类似,所以理解复数的一些性质对理解四元数非常有帮助。
定义
任意一个复数 z∈C 都可以表示为 z=a+bi 的形式,其中 a,b∈R 而且 i2=−1。我们将 a 称为复数 z 的实部,表示为 a=Re(z),b 称为复数 z 的虚部,表示为 b=Im(z)。
因为 z=a+bi 其实就是对于 1,i 这个基(Basis)的线性组合(Linear Combination),我们也可以用向量来表示一个复数:
z=[ab]
因为这个向量有两个元素,我们可以使用复平面上的一个点来表示一个复数。复平面的横坐标代表它的实部,纵坐标代表它的虚部:

复数的加减法
如果我们有两个复数 z1=a+bi,z2=c+di,它们的和就是分量相加的结果:
z1+z2=(a+c)+(b+d)i
同理,如果要对它们相减,直接将分量相减就可以了。
z1−z2=(a−c)+(b−d)i
复数的乘法
如果有两个复数 z1=a+bi,z2=c+di,我们可以使用分配律来计算它们的乘积
z1z2=(a+bi)(c+di)=ac+adi+bci+bdi2=ac−bd+adi+bci=ac−bd+(bc+ad)i
如果仔细观察可以发现,复数相乘的结果其实也是一个矩阵与向量相乘的结果,也就是说:
z1z2=ac−bd+(bc+ad)i=[ab−ba][cd]
右侧的 [cd] 是用向量的形式来表示的 z2,而左侧的 [ab−ba] 则是 z1 的矩阵形式。我们可以发现,复数相乘这个运算,其实是与 [ab−ba] 则是 z1 这个矩阵所代表的变换是等价的。
那么在矩阵形式下,复数与复数的相乘也可以表示为矩阵的相乘,如果我们有两个复数 z1=a+bi,z2=c+di,那么与 z1z2 所代表的变换则可以表示为
z1z2=[ab−ba][cd−dc]=[ac−bdbc+ad−(bc+ad)ac−bd]
复数的相乘满足交换律,即 z1z2 与 z2z1 是等价的
z2z1=[cd−dc][ab−ba]=[ac−bdbc+ad−(bc+ad)ac−bd]=z1z2
除此之外,我们来看一下一些特殊的矩阵形式:
1=[1001]=I(a=1,b=0)
i=[01−10](a=0,b=1)
实数单位 1 与矩阵单位矩阵是等价的,而虚数单位 i 则等价于 [01−10],如果我们尝试对它进行平方,可以发现:
i2=i⋅i=[01−10][01−10]=[−100−1]=−I=−1
即便实在矩阵形式下,i2 与 -1 其实也是等价的,这进一步展示了复数与这一矩阵形式的关联。
复数的模长与共轭
复数 z=a+bi 的模长(Magnitude)定义为
∥z∥=a2+b2
复数 z=a+bi 的共轭(Conjugate)定义为
zˉ=a−bi
如果尝试计算 zzˉ,我们就会发现
zzˉ=(a+bi)(a−bi)=a2−abi+abi+b2=a2+b2=∥z∥2
所以,一个复数的模长又可以通过下面的方式计算
∥z∥=zzˉ
复数与二维旋转
注意观察复数 z 的矩阵形式 [ab−ba],我们可以把它变换为下述形式:
[ab−ba]=a2+b2[a2+b2aa2+b2ba2+b2−ba2+b2a]

可以看到,∥z∥ 正是复数 z 与坐标轴所形成的三角形的斜边长,而 a,b 分别为三角形的两个直角边.如果将斜边与实数轴正方向的夹角记为 θ 的话,按照三角函数的定义可以得出 a2+b2a=cos(θ) 且 a2+b2b=sin(θ),这个角度 θ 其实就是 atan2(b,a)。知道了这些,原矩阵就可以变形为
[ab−ba]=a2+b2[cos(θ)sin(θ)−sin(θ)cos(θ)]=∥z∥[cos(θ)sin(θ)−sin(θ)cos(θ)]=∥z∥⋅I[cos(θ)sin(θ)−sin(θ)cos(θ)]=[∥z∥00∥z∥][cos(θ)sin(θ)−sin(θ)cos(θ)]
其中,左边的 [∥z∥00∥z∥] 是缩放矩阵,而右边的 [cos(θ)sin(θ)−sin(θ)cos(θ)] 是 2D 旋转矩阵。
让我们看看这个矩阵对两个基 [10] 和 [01] 的变换效果,首先是 [10]:
[ab−ba][10]=[∥z∥00∥z∥][cos(θ)sin(θ)−sin(θ)cos(θ)][10]=[∥z∥00∥z∥][cos(θ)sin(θ)]
第一步首先将 [10] 变换到了 [cos(θ)sin(θ)] 的位置,也就是逆时针旋转了 θ 度,接下来
[∥z∥00∥z∥][cos(θ)sin(θ)]=[∥z∥cos(θ)∥z∥sin(θ)]
缩放矩阵将 [cos(θ)sin(θ)] 缩放了 ∥z∥ 倍,变为 [∥z∥cos(θ)∥z∥sin(θ)]。总的来说,就是对 [10] 旋转了 θ 度,并缩放了 ∥z∥ 倍。
接下来是 [01]:
[ab−ba][01]=[∥z∥00∥z∥][cos(θ)sin(θ)−sin(θ)cos(θ)][01]=[∥z∥00∥z∥][−sin(θ)cos(θ)]
这里,第一步将 [01] 变换到了 [−sin(θ)cos(θ)] 的位置,这同样是逆时针旋转了 θ 度,见下图:

第二步变换同样会将 [−sin(θ)cos(θ)] 缩放为 [−∥z∥sin(θ)∥z∥cos(θ)]。这样等于是将整个坐标系逆时针旋转了 θ 度,并缩放了 ∥z∥ 倍。
换句话说,复数相乘的几何意义就是旋转与缩放变换的复合。如果有一个复数 z=a+bi,那么 z 与任意一个复数 c 相乘都会将 c 逆时针旋转 θ=atan2(b,a) 度,并将其缩放 ∥z∥=a2+b2 倍。
如果复数的模长为 1,那么它的几何意义就只有旋转。
z=[cos(θ)sin(θ)−sin(θ)cos(θ)]
如果我们想让 2D 空间中任意一个向量 v 旋转 θ 度,那么我们就可以使用这个矩阵对 v 进行变换:
Theorem 1:2D 旋转公式(矩阵型)
v′=[cos(θ)sin(θ)−sin(θ)cos(θ)]v
其实 [cos(θ)sin(θ)−sin(θ)cos(θ)] 这个旋转矩阵如果写成复数形式的话就是 cos(θ)+isin(θ)
如果我们将向量 v=[xy] 看作是一个复数 v=x+yi,其中实部为 x,虚部为 y。那么我们可以构造一个复数 z=cos(θ)+isin(θ),并将它与 v 相乘来进行旋转,旋转 θ 度之后的向量 v′ 可以用等价的复数乘法来表示:
Theorem 2:2D 旋转公式(复数积型)
v′=zv=(cos(θ)+isin(θ))v
复数的极坐标型
cos(θ)+isin(θ) 还可以进行下一步的变形,根据欧拉公式(Euler’s Formula),
cos(θ)+isin(θ)=eiθ
欧拉公式的证明:
令 f(θ)=eiθcos(θ)+isin(θ)=e−iθ(cos(θ)+isin(θ)),对实数 θ,对 f(θ) 求导,得到 f′(θ)=e−iθ(icos(θ)−sin(θ))−ie−iθ(cos(θ)+isin(θ))=0,因此 f(θ) 是常数。又因为 f(0)=1,所以 f(θ)≡1。欧拉公式得证。
有了这个等式,我们就能将复数表示为
z=∥z∥[cos(θ)sin(θ)−sin(θ)cos(θ)]=∥z∥(cos(θ)+isin(θ))=∥z∥eiθ
如果我们定义 r=∥z∥,我们就得到了复数的极坐标形式:
z=reiθ
现在复数的定义就与实部与虚部的两个分量 a,b 无关了,我们可以使用一个缩放因子 r 和旋转角度 θ 的形式来定义任意一个复数,而且它旋转与缩放的性质仍然存在。如果我们想对 2D 空间中的向量 v=[xy] 进行旋转并缩放,我们可以类似地将这个向量看作是一个复数 v=x+yi,那么,经过旋转 θ 度,缩放 r 倍之后的向量 v′ 就可以这样计算:
v′=reiθv
如果仅需要旋转 θ 度的话,可以令缩放因子 r=1,那么变换后的结果就是
Theorem 3:2D 旋转公式(指数型)
v′=eiθv
复数的几种表示形式总结
- 代数形式一:z=a+bi
- 代数形式二:z=r(cos(θ)+isin(θ))
- 向量形式:z=[ab]
- 矩阵形式一:[ab−ba]
- 矩阵形式二:[∥z∥00∥z∥][cos(θ)sin(θ)−sin(θ)cos(θ)]
- 极坐标形式:z=reiθ
这几种形式完全等价
旋转的复合
如果我们有两个代表 2D 旋转的单位复数 z1=cos(θ)+isin(θ),z2=cos(ϕ)+isin(ϕ) 以及一个向量 v=x+yi,我们可以先对 v 进行 z1 的旋转
v′=z1v
在此基础上,我们对 v′ 进行 z2 的旋转
v′′=z2(z1v)=(z2z1)v
如果我们将这两次旋转所作出的等效变换称为 znet,那么
v′′znet=(z2z1)v=znetv=z2z1
因为复数的相乘遵守交换律,所以
znet=z2z1=z1z2
如果尝试计算一下 znet,会发现
znet=(cos(θ)+isin(θ))(cos(ϕ)+isin(ϕ))=cos(θ)cos(ϕ)+i(cos(θ)sin(ϕ))+i(sin(θ)cos(ϕ))−sin(θ)sin(ϕ)=(cos(θ)cos(ϕ)−sin(θ)sin(ϕ))+(cos(θ)sin(ϕ)+sin(θ)cos(ϕ))i
这个式子可以利用三角恒等式化简为:
znet=(cos(θ)+isin(θ))(cos(ϕ)+isin(ϕ))=cos(θ+ϕ)+isin(θ+ϕ)
所以,当我们对两个 2D 旋转进行复合时,所得到的变换 znet 仍是一个旋转,而且与施加的次序无关。这个等效变换的旋转角是 $z_{1} 与 $z_{2} 旋转角之和。
轴角式旋转
假设我们有一个经过原点的(如果旋转轴不经过原点我们可以先将旋转轴平移到原点,进行旋转,再平移回原处)旋转轴 u=(x,y,z)T,我们希望将一个向量 v,沿着这个旋转轴旋转 θ 度,变换到 v′

我们使用右手坐标系统,并且将使用右手定则来定义旋转的正方向。你可以将右手拇指指向旋转轴 u 的正方向,这时其他四个手指弯曲的方向即为旋转的正方向。在上图中即为逆时针方向。
为了消除旋转轴 u 模长这个多余的自由度,我们可以规定 u 的模长为 1,即 u 是一个单位向量。规定 u 为单位向量后能为我们带来很多便利,这也是数学和物理中对方向定义的惯例。如果 u 不是一个单位向量,我们可以通过下面的公式将它转化为一个单位向量
u^=∥u∥u
旋转的分解
我们可以将 v 分解为平行于旋转轴 u 以及正交于 u 的两个分量,v∥ 和 v⊥,即
v=v∥+v⊥
我们可以分别旋转这两个分量,再将它们旋转的结果相加获得旋转后的向量
v′=v∥′+v⊥′
下面是分解的示意图:

可以看到,v∥ 其实就是 v 在 u 上的正交投影,根据正交投影公式,我们可以得出:
v∥=proju(v)=u⋅uu⋅vu=∥u∥2u⋅vu=(u⋅v)u
因为 v=v∥+v⊥,我们可以得到
v⊥=v−v∥=v−(u⋅v)u
v∥ 的旋转
从之前的图示中可以看到,v∥ 其实没有被旋转,仍然与旋转轴 u 重合,所以
Theorem 4:3D 旋转公式(向量型,平行情况)
当 v∥ 平行于旋转轴 u 时,旋转 θ 角度之后的 v∥′ 为:
v∥′=v∥
v⊥ 的旋转
接下来,我们需要处理正交于 u 的 v⊥。因为这两个向量是正交的,这个旋转可以看作是平面内的一个旋转。因为旋转不改变 v⊥ 的长度,所以路径是一个园。下面是这个旋转的示意图,右侧的为俯视图:

现在,3D 的旋转就被我们转化为了 2D 平面上的旋转,由于在这个平面上我们只有一个向量 v⊥,用它来表示一个旋转是不够的,我们还需构造一个同时正交于 u 和 v⊥ 的向量 w,这个可以通过叉乘来获得
w=u×v⊥
注意叉乘的顺序,因为我们使用的是右手坐标系统,按右手定则这个新的向量 w 指向 v⊥ 逆时针旋转 π/2 后的方向,并且和 v⊥ 一样也处于正交于 u 的平面内,因为 ∥u∥=1,我们可以发现:
∥w∥=∥u×v⊥∥=∥u∥⋅∥v⊥∥⋅sin(π/2)=∥v⊥∥
w 和 v⊥ 的模长相同,且 w 也位于圆上,我们可以将 w 和 v⊥ 作为平面内的两个坐标轴,我们现在可以把 v⊥′ 投影到 w 和 v⊥ 上,将其分解为 vv′ 和 vw′,利用三角形的知识我们可以得到:
v⊥′=vv′+vw′=cos(θ)v⊥+sin(θ)w=cos(θ)v⊥+sin(θ)(u×v⊥)
Theorem 5:3D 旋转公式(向量型,正交情况)
当 v⊥ 正交于旋转轴 u 时,旋转 θ 角度之后的 v⊥′ 为:
v⊥′=cos(θ)v⊥+sin(θ)(u×v⊥)
v 的旋转
将上面两个结果组合可以获得:
v′=v∥′+v⊥′=v∥+cos(θ)v⊥+sin(θ)(u×v⊥)
因为叉乘遵守分配律,
u×v⊥=u×(v−v∥)=u×v−u×v∥=u×v(u平行于v∥,所以u×v∥=0)
最后,将 v∥=(u⋅v)u 和 v⊥=v−(u⋅v)u 代入
v′=(u⋅v)u+cos(θ)(v−(u⋅v)u)+sin(θ)(u×v)=cos(θ)v+(1−cos(θ))(u⋅v)u+sin(θ)(u×v)
这样我们就得到了一般形式的旋转公式:
Theorem 6:3D 旋转公式(向量型,一般情况)
3D 空间中任意一个 v 沿着单位向量 u 旋转 θ 角度之后的 v⊥′ 为:
v′=cos(θ)v+(1−cos(θ))(u⋅v)u+sin(θ)(u×v)