Quaternions and 3D rotations

2025-10

三维旋转表示的困境

在计算机图形学、机器人学、航空航天以及物理学的诸多领域中,精确描述和操作三维空间中的物体姿态是一项基本且核心的任务。一个物体的姿态本质上是其相对于某个参考坐标系的旋转状态。因此,寻找一种有效、稳定且无歧义的数学工具来表示旋转,便成为了一个根本性的问题。最符合人类直觉的表示方法是欧拉角 (Euler Angles)。该方法将一个复杂的空间旋转分解为三个沿着正交坐标轴(例如 x, y, z 轴)依次进行的简单旋转,这三个旋转的角度(例如,偏航角 Yaw, 俯仰角 Pitch, 滚转角 Roll)共同构成了对最终姿态的描述。欧拉角因其直观易懂而被广泛应用,然而,这种表示方法存在一个固有的、在关键应用中无法回避的致命缺陷——万向节死锁 (Gimbal Lock)

万向节死锁是一种状态,在此状态下,旋转系统会失去一个自由度。以飞行器为例,当俯仰角为 ±90\pm90 度(即机头垂直朝上或朝下)时,原本用于控制偏航和滚转的两个旋转轴会发生重合。此时,无论系统尝试执行偏航还是滚转操作,都会产生完全相同的几何效果,即绕着同一个垂直轴旋转。这意味着飞行器在此姿态下无法独立完成所有三种类型的旋转,丧失了向任意方向调整姿态的能力。在动画或模拟中,当物体接近或进入万向节死锁状态时,其运动会表现出突然的、不自然的剧烈翻转,因为系统为了从一个姿态平滑插值到另一个姿态,可能需要进行一次幅度极大且不符合物理直觉的旋转。这种不稳定性使得欧拉角在要求高精度和高平滑度的应用中,成为了一种不可靠的表示方法。因此,为了克服这一根本性限制,数学家们寻求一种更高维度的、能够从本质上避免奇异状态的代数结构来描述旋转。

四元数的代数结构与核心性质

为了解决上一节提出的旋转表示困境,我们引入一种新的代数系统四元数 (Quaternion)

从结构上看,一个四元数 qq 是一个由四部分组成的数,其一般形式为 q=qw+qxi+qyj+qzkq = q_w + q_x i + q_y j + q_z k。这里的系数 qw,qx,qy,qzq_w, q_x, q_y, q_z 都是我们熟悉的实数。qwq_w 被称为标量部 (scalar part),而由三个虚数单位 i,j,ki, j, k 构成的 qxi+qyj+qzkq_x i + q_y j + q_z k 则被称为矢量部 (vector part)。所有这些四元数的集合形成了一个数学家所称的、在实数域 R\mathbb{R} 上的四维代数,记为 H\mathbb{H}。这意味着四元数不仅像向量一样可以进行加法和标量乘法,更重要的是,它们之间还定义了一套独特的乘法规则。

这套乘法规则完全由一个核心恒等式所支配:

i2=j2=k2=ijk=1\begin{equation} i^2 = j^2 = k^2 = ijk = -1 \end{equation}

而四元数虚数单位的乘法遵循一个循环规则:ijkii→j→k→i,即正向相乘得正,反向相乘得负。比如说我们在等式 11 右侧同乘以 kk

(ijk)k=(1)k\begin{equation} (ijk)k = (-1)k \end{equation}

利用结合律和 k2=1k^2 = -1,得:

ij(1)=k\begin{align} ij(-1) = -k \end{align} ij=k\begin{equation} ij=k \end{equation}

根据上述推导,我们如果尝试计算 jiji,就会发现结果变成了ji=(ij)=kji = -(ij) = k。这种乘法顺序会影响结果的特性,即非交换性 (non-commutativity),是四元数与我们熟知的实数和复数最根本的区别。正是这种特性,使得四元数能够完美地捕捉三维空间旋转的非交换本质(例如,一个物体先绕垂直轴旋转90度再绕水平轴旋转90度,与颠倒顺序后的最终姿态是不同的)。

为了将这个代数系统应用于几何变换,我们必须定义几个关键的运算和属性,它们是后续所有操作的“零件”。

首先是共轭 (Conjugate)。这个概念是对复数共轭的自然推广。对于一个复数 z=a+biz=a+bi,其共轭是 z=abiz^*=a-bi。类似地,对于四元数 q=qw+qxi+qyj+qzkq = q_w + q_x i + q_y j + q_z k,它的共轭 qq^* 就是将其所有矢量部分(虚部)的符号取反:q=qwqxiqyjqzkq^* = q_w - q_x i - q_y j - q_z k。共轭运算的核心作用,是在不改变标量部的情况下“反转”其矢量方向,这在后续求模和求逆的运算中至关重要。

接下来是模 (Norm),它用于衡量一个四元数的“大小”或“长度”。qq 的模记作 q\|q\|,其定义源于四元数与其自身的共轭之积,q=qq\|q\| = \sqrt{qq^*}。我们可以展开这个乘积来理解其几何意义:

qq=(qw+(qxi+qyj+qzk))(qw(qxi+qyj+qzk))\begin{equation} qq^* = (q_w + (q_xi + q_yj + q_zk))(q_w - (q_xi + q_yj + q_zk)) \end{equation}

展开这个乘积会得到9个项,我们可以将其分为两类:

  • 对角项(同类单位相乘):

    • (qxi)(qxi)=qx2(i2)=qx2(q_x i)(q_x i) = q_x^2 (i^2) = -q_x^2
    • (qyj)(qyj)=qy2(j2)=qy2(q_y j)(q_y j) = q_y^2 (j^2) = -q_y^2
    • (qzk)(qzk)=qz2(k2)=qz2(q_z k)(q_z k) = q_z^2 (k^2) = -q_z^2
  • 交叉项(不同单位相乘):

    • (qxi)(qyj)=qxqy(ij)=qxqyk(q_x i)(q_y j) = q_x q_y (ij) = q_x q_y k
    • (qyj)(qxi)=qyqx(ji)=qyqxk(q_y j)(q_x i) = q_y q_x (ji) = -q_y q_x k
    • ... 以此类推,我们会得到所有两两组合的乘积:
      • qyqz(jk)=qyqziq_y q_z (jk) = q_y q_z iqzqy(kj)=qzqyiq_z q_y (kj) = -q_z q_y i
      • qzqx(ki)=qzqxjq_z q_x (ki) = q_z q_x jqxqz(ik)=qxqzjq_x q_z (ik) = -q_x q_z j

现在,我们将所有9个项相加。每一对交叉项(例如 qxqykq_x q_y kqyqxk-q_y q_x k)都会因为四元数乘法的非交换性 (ij=jiij = -ji) 而精确地相互抵消。所有矢量部(带有 i,j,ki, j, k 的项)都消失了,剩下的只有对角项的和:(qxi+qyj+qzk)2=qx2qy2qz2(q_x i + q_y j + q_z k)^2 = -q_x^2 - q_y^2 - q_z^2。现在我们将这个结果代回到 qqqq^* 的表达式中:

qq=(qw)2((qx2+qy2+qz2))\begin{equation} qq^* = (q_w)^2 - (-(q_x^2 + q_y^2 + q_z^2)) \end{equation} qq=qw2+qx2+qy2+qz2\begin{equation} qq^* = q_w^2 + q_x^2 + q_y^2 + q_z^2 \end{equation}

这个结果是一个纯粹的实数,没有任何虚部。根据我们对模的定义 q=qw2+qx2+qy2+qz2\|q\| = \sqrt{q_w^2 + q_x^2 + q_y^2 + q_z^2},上面这个结果恰好是模的平方,即 q2\|q\|^2

有了共轭和模,我们便可以定义任何非零四元数 qq 的逆 (Inverse) q1q^{-1},它满足乘法单位元的基本性质 qq1=q1q=1qq^{-1} = q^{-1}q = 1。其计算公式为 q1=qq2q^{-1} = \frac{q^*}{\|q\|^2}。我们可以很容易地验证这个定义的正确性:

qq1=qqq2=qqq2=q2q2=1\begin{equation} q \cdot q^{-1} = q \cdot \frac{q^*}{\|q\|^2} = \frac{qq^*}{\|q\|^2} = \frac{\|q\|^2}{\|q\|^2} = 1 \end{equation}

在表示纯粹的旋转时(即不含任何缩放或变形的变换),我们极其关心一类特殊的四元数——单位四元数 (Unit Quaternion)。顾名思义,它们是模为 1 (q=1\|q\|=1) 的四元数。这个单位长度的约束,在几何上直观地对应了旋转操作不应改变物体大小的特性。当一个四元数是单位四元数时,它的求逆运算得到了极大的简化:由于分母 q2=1\|q\|^2=1,其逆就等于它的共轭,即 q1=qq^{-1} = q^*。这个优雅的性质不仅是理论上的一个美妙结果,更是四元数在实时计算机图形学和机器人学中得以高效应用的关键。它将一个可能涉及四次乘法和一次除法的求逆运算,简化为三次符号取反操作,极大地降低了计算成本。

三维旋转的四元数表示

现在任务是利用这些工具,将一个抽象的四元数与一个具体的三维空间旋转操作精确地等同起来。这个过程分为两步:首先,我们需要一种方式在四元数的世界里表示三维向量;其次,我们需要构造一个特定的四元数来编码旋转这个动作本身。

为了让四元数能够对三维向量进行操作,我们必须在三维欧几里得空间 R3\mathbb{R}^3 与四元数空间 H\mathbb{H} 的某个子集之间建立一座桥梁。这个桥梁就是纯四元数 (pure quaternion) 空间,即所有标量部(实部)为零的四元数的集合。任何一个三维向量 v=(vx,vy,vz)\vec{v} = (v_x, v_y, v_z) 都可以被唯一地表示为一个纯四元数 v=0+vxi+vyj+vzkv = 0 + v_x i + v_y j + v_z k。反之,任何纯四元数也对应一个唯一的三维向量。这种对应的关系在数学上被称为同构 (Isomorphism),它意味着我们可以将任何三维向量“嵌入”到四元数空间中进行代数运算,运算结束后再将结果“提取”回三维空间,而不会丢失任何信息。例如,一个向量 v=(2,3,5)\vec{v}=(2, -3, 5) 在四元数的世界中就以 v=2i3j+5kv = 2i - 3j + 5k 的形式存在。

现在我们有了代表“被旋转物体”(向量)的方式,接着需要表示“旋转动作”本身。三维空间中任何一个旋转操作,都可以由两个几何要素唯一确定:一个旋转轴,由一个单位向量 u^R3\hat{u} \in \mathbb{R}^3 表示;以及一个旋转角度 θR\theta \in \mathbb{R},我们通常遵循右手定则,规定逆时针方向为正。我们的目标是构造一个单位四元数 qq,使其能够完整地编码这两个几何信息。该四元数的构造公式如下:

q=cos(θ2)+(uxi+uyj+uzk)sin(θ2)\begin{equation} q = \cos\left(\frac{\theta}{2}\right) + (u_x i + u_y j + u_z k)\sin\left(\frac{\theta}{2}\right) \end{equation}

我们可以将其简洁地记为 q=cos(θ2)+u^sin(θ2)q = \cos(\frac{\theta}{2}) + \hat{u}\sin(\frac{\theta}{2}),其中 u^\hat{u} 被理解为代表轴向量的纯四元数。这个构造式并非任意设计的,它具有一个至关重要的内禀性质:它确保了所构造的 qq 必然是一个单位四元数。我们可以通过计算其模的平方来验证这一点:

q2=(cos(θ2))2+(uxsin(θ2))2+(uysin(θ2))2+(uzsin(θ2))2=cos2(θ2)+(ux2+uy2+uz2)sin2(θ2)\begin{align} \|q\|^2 &= \left(\cos\left(\frac{\theta}{2}\right)\right)^2 + \left(u_x \sin\left(\frac{\theta}{2}\right)\right)^2 \\&+ \left(u_y \sin\left(\frac{\theta}{2}\right)\right)^2 + \left(u_z \sin\left(\frac{\theta}{2}\right)\right)^2 \nonumber \\ & = \cos^2\left(\frac{\theta}{2}\right) + (u_x^2 + u_y^2 + u_z^2)\sin^2\left(\frac{\theta}{2}\right) \end{align}

由于 u^\hat{u} 是单位向量,所以 ux2+uy2+uz2=u^2=1u_x^2 + u_y^2 + u_z^2 = \|\hat{u}\|^2 = 1。因此,上式根据三角函数的平方和定理,结果恒等于1。这个单位模长的性质保证了由该四元数引发的变换将是纯粹的旋转,不包含任何我们不希望的缩放效果。同时,这里会有一个问题是为什么使用半角 θ/2\theta/2 。这并非巧合或近似,笔者在下一节去解释核心旋转算子所做的必要准备。该算子的数学结构将使角度效应被施加两次,因此我们在此预先使用半角,以确保最终的几何效果恰好是我们期望的旋转角度 θ\theta

旋转算子及其数学原理

现在,我们将这两者结合,定义一个能够对三维向量实施旋转的精确数学操作。这个操作被称为共轭变换 (Conjugation),因其在形式上将被操作的向量“包裹”在中间,也常被形象地称为“三明治积”。

定义 (四元数旋转算子):给定一个代表三维向量 v\vec{v} 的纯四元数 vv,以及一个代表某次旋转的单位四元数 qq,旋转后得到的新向量 v\vec{v}' 所对应的纯四元数 vv',由以下公式给出:

v=qvq1\begin{equation} v' = qvq^{-1} \end{equation}

由于我们已经知道单位四元数的逆等于其共轭 (q1=qq^{-1} = q^*),此公式也等价于 v=qvqv' = qvq^*。这个简洁的表达式蕴含了深刻的代数原理,正是这些原理保证了其几何效果的正确性。为了证明这一点,我们必须从数学上严格验证该变换满足旋转的两个基本性质:它必须保持向量的维度(三维向量旋转后仍是三维向量),并且必须保持向量的长度(旋转是刚体变换)。

首先,我们来证明变换后的结果 vv' 仍然是一个纯四元数,即其标量部 S(v)=0S(v')=0。我们可以通过分析 vv' 的共轭 (v)(v')^* 来巧妙地证明这一点。利用四元数乘积的共轭性质 (ab)=ba(ab)^* = b^*a^*,我们得到:

(v)=(qvq)=(q)vq\begin{equation} (v')^* = (qvq^*)^* = (q^*)^* v^* q^* \end{equation}

由于 (q)=q(q^*)^* = q,并且 vv 是一个纯四元数,所以其共轭 v=vv^* = -v。将这两点代入,我们得到:

(v)=q(v)q=qvq=v\begin{equation} (v')^* = q(-v)q^* = -qvq^* = -v' \end{equation}

一个数的共轭等于它自身的相反数((v)=v(v')^* = -v'),这正是纯四元数的定义。因此,我们已经严格证明了 vv' 的标量部必为零,这意味着旋转算子的输出结果始终保持在三维向量空间内,不会产生我们不希望的第四维度分量。

其次,我们来证明该变换保持向量的长度不变。这一点可以通过模的乘法性质 ab=ab\|ab\| = \|a\|\|b\| 来轻松验证。我们计算 vv' 的模:

v=qvq1\begin{equation} \|v'\| = \|qvq^{-1}\| \end{equation}

应用模的乘法性质,我们将其分解为三个模的乘积:

v=qvq1\begin{equation} \|v'\| = \|q\| \cdot \|v\| \cdot \|q^{-1}\| \end{equation}

因为 qq 是代表旋转的单位四元数,所以其模 q=1\|q\|=1。它的逆 q1q^{-1}(也就是它的共轭)同样也是一个单位四元数,所以 q1=1\|q^{-1}\|=1。因此:v=1v1=v\|v'\| = 1 \cdot \|v\| \cdot 1 = \|v\| 这个结果表明,变换前后向量的长度完全相等。这从代数上无可辩驳地证明了四元数共轭变换是一种保距变换 (isometry),它只改变向量的方向而不改变其大小,这与我们对空间旋转的几何直觉完全吻合。

why θ/2{\theta}/2

现在笔者证明为什么构造旋转四元数时必须使用半角 θ/2\theta/2

要证明这一点,最严谨的方法就是将我们第四节定义的旋转算子 v=qvq1v' = qvq^{-1} 进行完全的代数展开,并证明其展开后的最终形式,与公认的、描述三维旋转的权威几何公式——**罗德里格旋转公式 (Rodrigues' Rotation Formula)**完全等价。如果从 θ/2\theta/2 出发的代数,最终能推导出包含完整角 θ\theta 的几何公式,那么半角的必要性就得到了无可辩驳的证明。

首先,我们回顾一下所有需要的元素:

  • 待旋转的向量(纯四元数):vv
  • 旋转轴(单位纯四元数):u^\hat{u}
  • 旋转四元数及其逆(使用 c=cos(θ2),s=sin(θ2)c = \cos(\frac{\theta}{2}), s = \sin(\frac{\theta}{2}) 简化):
    • q=c+su^q = c + s\hat{u}
    • q1=q=csu^q^{-1} = q^* = c - s\hat{u}

我们知道两个纯四元数乘积的几何意义:u1u2=(u1u2)+(u1×u2)u_1 u_2 = -(\vec{u}_1 \cdot \vec{u}_2) + (\vec{u}_1 \times \vec{u}_2) 那我们的目标就是证明 v=qvq1v' = qvq^{-1} 的矢量部分等价于罗德里格公式:

v=vcosθ+(u^×v)sinθ+u^(u^v)(1cosθ)\begin{equation} \vec{v}' = \vec{v}\cos\theta + (\hat{u} \times \vec{v})\sin\theta + \hat{u}(\hat{u} \cdot \vec{v})(1-\cos\theta) \end{equation}

首先我们先展开旋转算子 v=qvq1v' = qvq^{-1}

我们将 qqq1q^{-1} 代入,并进行乘法展开:

v=(c+su^)v(csu^)\begin{equation} v' = (c + s\hat{u}) v (c - s\hat{u}) \end{equation} v=(cv+su^v)(csu^)\begin{equation} v' = (cv + s\hat{u}v)(c - s\hat{u}) \end{equation} v=c2vcs(vu^)+sc(u^v)s2(u^vu^)\begin{equation} v' = c^2v - cs(v\hat{u}) + sc(\hat{u}v) - s^2(\hat{u}v\hat{u}) \end{equation}

现在,我们利用纯四元数乘积的几何意义来替换 u^v\hat{u}vvu^v\hat{u}

u^v=(u^v)+(u^×v)\begin{equation} \hat{u}v = -(\hat{u} \cdot \vec{v}) + (\hat{u} \times \vec{v}) \end{equation} vu^=(vu^)+(v×u^)=(u^v)(u^×v)\begin{equation} v\hat{u} = -(\vec{v} \cdot \hat{u}) + (\vec{v} \times \hat{u}) = -(\hat{u} \cdot \vec{v}) - (\hat{u} \times \vec{v}) \end{equation}

代入展开式中:

v=c2vcs((u^v)(u^×v))+sc((u^v)+(u^×v))s2(u^vu^)\begin{equation} v' = c^2v - cs(-(\hat{u} \cdot \vec{v}) - (\hat{u} \times \vec{v})) + sc(-(\hat{u} \cdot \vec{v}) + (\hat{u} \times \vec{v})) - s^2(\hat{u}v\hat{u}) \end{equation}

整理后,标量部分 (u^v)(\hat{u} \cdot \vec{v}) 的项相互抵消,而矢量叉乘项 (u^×v)(\hat{u} \times \vec{v}) 被加倍:

v=c2v+2cs(u^×v)s2(u^vu^)\begin{equation} v' = c^2v + 2cs(\hat{u} \times \vec{v}) - s^2(\hat{u}v\hat{u}) \end{equation}

接下来,我们处理最复杂的项 u^vu^\hat{u}v\hat{u}。我们可以把它看作 (u^v)u^(\hat{u}v)\hat{u}

u^vu^=((u^v)+(u^×v))u^=(u^v)u^+(u^×v)u^\begin{equation} \hat{u}v\hat{u} = (-(\hat{u} \cdot \vec{v}) + (\hat{u} \times \vec{v}))\hat{u} = -(\hat{u} \cdot \vec{v})\hat{u} + (\hat{u} \times \vec{v})\hat{u} \end{equation}

其中 (u^×v)u^(\hat{u} \times \vec{v})\hat{u} 是两个正交纯四元数(一个向量和另一个与之垂直的向量)的乘积,其结果等于它们的叉乘 (u^×v)×u^(\hat{u} \times \vec{v}) \times \hat{u}。根据向量三重积公式 A×(B×C)=B(AC)C(AB)\vec{A} \times (\vec{B} \times \vec{C}) = \vec{B}(\vec{A}\cdot\vec{C}) - \vec{C}(\vec{A}\cdot\vec{B}),我们有:

(u^×v)×u^=v(u^u^)u^(u^v)\begin{equation} (\hat{u} \times \vec{v}) \times \hat{u} = \vec{v}(\hat{u} \cdot \hat{u}) - \hat{u}(\hat{u} \cdot \vec{v}) \end{equation}

因为 u^\hat{u} 是单位向量,u^u^=1\hat{u} \cdot \hat{u} = 1。所以上式等于 vu^(u^v)\vec{v} - \hat{u}(\hat{u} \cdot \vec{v})。 因此,u^vu^=v2u^(u^v)\hat{u}v\hat{u} = \vec{v} - 2\hat{u}(\hat{u} \cdot \vec{v})

将此结果代回 vv' 的表达式:

v=c2v+2cs(u^×v)s2(v2u^(u^v))\begin{equation} v' = c^2v + 2cs(\hat{u} \times \vec{v}) - s^2(\vec{v} - 2\hat{u}(\hat{u} \cdot \vec{v})) \end{equation}

将所有项按 v\vec{v}(u^×v)(\hat{u} \times \vec{v})u^(u^v)\hat{u}(\hat{u} \cdot \vec{v}) 进行合并:

v=(c2s2)v+(2sc)(u^×v)+(2s2)u^(u^v)\begin{equation} v' = (c^2 - s^2)v + (2sc)(\hat{u} \times \vec{v}) + (2s^2)\hat{u}(\hat{u} \cdot \vec{v}) \end{equation}

现在,我们使用三角函数的倍角公式,将包含半角 θ/2\theta/2 的项 ccss 转换回包含完整角 θ\theta 的形式:

c2s2=cos2(θ2)sin2(θ2)=cos(θ)c^2 - s^2 = \cos^2(\frac{\theta}{2}) - \sin^2(\frac{\theta}{2}) = \cos(\theta)

2sc=2sin(θ2)cos(θ2)=sin(θ)2sc = 2\sin(\frac{\theta}{2})\cos(\frac{\theta}{2}) = \sin(\theta)

2s2=2sin2(θ2)=1cos(θ)2s^2 = 2\sin^2(\frac{\theta}{2}) = 1 - \cos(\theta)

将这些代回到我们推导出的 vv' 的最终表达式中:

v=vcosθ+(u^×v)sinθ+u^(u^v)(1cosθ)\begin{equation} v' = v\cos\theta + (\hat{u} \times \vec{v})\sin\theta + \hat{u}(\hat{u} \cdot \vec{v})(1-\cos\theta) \end{equation}

这个最终结果,一字不差地,正是罗德里格旋转公式。我们从一个完全代数的构造(使用 θ/2\theta/2 的四元数 qq 和共轭运算 v=qvq1v' = qvq^{-1})出发,通过一系列严格的代数展开和替换,最终抵达了一个描述完整角 θ\theta 旋转的、被广泛公认的几何公式。这个过程有力地证明了,在四元数旋转的框架下,使用半角 θ/2\theta/2 不是一个近似或巧合,而是使其代数形式能够精确映射到正确几何现实的数学必然。