四元数与三维旋转

发布于 2020-11-02  394 次阅读


问题介绍

这是在读 QCQI 的过程中遇到的一个问题: 证明三维空间中, 将一个物体以向量 \(\overrightarrow{u_1}\) 旋转 \(\theta_1\), 再以 \(\overrightarrow{u_2}\) 为轴旋转 \(\theta_2\), 最终的结果等价于沿着 \(\overrightarrow{u_3}\) 旋转 \(\theta_3\), 而且参数之间有这样的一个关系:

\[\begin{aligned}
\cos{\frac{\theta_3}{2}} &= \cos{\frac{\theta_1}{2}}\cos{\frac{\theta_2}{2}} - \sin{\frac{\theta_1}{2}}\sin{\frac{\theta_2}{2}}\overrightarrow{u_1}\cdot\overrightarrow{u_2} \\
\sin{\frac{\theta_3}{2}}\overrightarrow{u_3} &= \sin{\frac{\theta_1}{2}}\cos{\frac{\theta_2}{2}}\overrightarrow{u_1} + \cos{\frac{\theta_1}{2}}\sin{\frac{\theta_2}{2}}\overrightarrow{u_2} - \sin{\frac{\theta_1}{2}}\sin{\frac{\theta_2}{2}}\overrightarrow{u_1}\times\overrightarrow{u_2}
\end{aligned}\]

这个式子本身可能比较复杂, 含义也不直观, 但是证明这个式子需要我们对于三维旋转的本质有一个认识:

究竟该如何表示三维旋转变换本身(而不是旋转变换作用于某个向量的旋转结果)?

这个问题实际上在计算机图形学中应用很广泛.

四元数的引入

旋转对于一个向量而言肯定是线性变换, 变换作用于一个坐标向量就对应于旋转操作. 然后最终旋转的合成表示为了变换的乘法, 好像是可以证明出上述结论的. 然而实际上的问题是: 算不出来. 查了蛮多资料最后发现其实只有四元数最适合计算这个结论(不过根据四元数的结论, 那个旋转矩阵确实可以写出来).

表示

任何四元数都表示为 \(q = a + bi + cj + dk\), 其中 \(a, b, c, d \in \mathbb{R}\), 它具有这样结构:

\[
i^2=j^2=k^2=ijk=-1
\]

相当于有三个虚部的复数. \(i, j, k\) 之间的乘法不是交换的, 而满足这样的规律

\[\begin{aligned}    ij &= k \\    jk &= i \\    ki &= j \\    ij &= -ji \\    kj &= -jk \\    ik &= -ki\end{aligned}\]

这几条性质都可以根据上面的式子推出来.

四元数一般把实部表示为一个实数, 虚部表示为一个三维实向量, 写作 \((s, \overrightarrow{u}), s \in \mathbb{R}, \overrightarrow{u} \in \mathbb{R}^3\)

模长

定义 \(\lVert q \rVert = \sqrt{a^2+b^2+c^2+d^2}\)

加法

加法就是逐部分相加:

\[
(s, \overrightarrow{u}) + (t, \overrightarrow{v}) = (s+t, \overrightarrow{u}+\overrightarrow{v})
\]

乘法

四元数的乘法是结合的, 而且满足分配律, 实数对于四元数的乘法是随意交换的. 三个虚单位之间的乘法是反交换的, 利用性质将交叉项化简到只包含一个虚单位, 得到这样的式子:

\[
\begin{aligned}
(s, \overrightarrow{u})(t, \overrightarrow{v}) &= (s+u_1i+u_2j+u_3k)(t+v_1i+v_2j+v_3k) \\
&= st - u_1v_1 - u_2v_2 - u_3v_3 + \\
&\quad i(sv_1 + tu_1 + u_2v_3 - u_3v_2) + \\
&\quad j(sv_2 + tu_2 + u_3v_1 - u_1v_3) + \\
&\quad k(sv_3 + tu_3 + u_1v_2 - u_2v_1) \\
&= (st - \overrightarrow{u}\cdot\overrightarrow{v}, s\overrightarrow{v} + t\overrightarrow{u} + \overrightarrow{u}\times\overrightarrow{v})
\end{aligned}
\]

一般而言四元数的乘法不是交换的.

共轭

共轭定义为三个虚部符号取反:

\((s, \overrightarrow{u})^* = (s, -\overrightarrow{u})\)

共轭有个很特别的性质, 就是它自然的关联于模长:

\[qq^* = q^*q = \lVert q \rVert^2\]

(类比负数模长, 埃尔米特内积)

一个很容易验证的关于共轭的性质:

\[(ab)^* = b^*a^*\]

逆元

根据共轭, 可以直接验证

\[
\frac{qq^*}{\lVert q \rVert^2} = 1
\]

因此任何非零的四元数都存在逆元

\[
q^{-1} = \frac{q^*}{\lVert q \rVert^2}
\]

被旋转向量的分解

旋转变化是线性的, 所以被旋转的向量可以被分解后各自旋转再合成. 假定向量 \(\overrightarrow{v}\) 以单位向量 \(\overrightarrow{u}\) 为轴旋转 \(\theta\) 角度. 首先, 将 \(\overrightarrow{v}\) 按照平行于/垂直于 \(\overrightarrow{u}\) 的方向进行分解. 这样分解的好处在于不考虑坐标系, 也就是不依赖于坐标的选取.

\[
\overrightarrow{v} = \overrightarrow{v_{\parallel}} + \overrightarrow{v_{\bot}}
\]

显然, 平行于 \(\overrightarrow{u}\) 的分量旋转前后不变. 因此我们只需要考虑垂直分量的旋转相应角度就足够表示出旋转后的向量了:

\[
\overrightarrow{v'} = \overrightarrow{v_{\parallel}} + \overrightarrow{v_{\bot}'}
\]

垂直于 \(\overrightarrow{u}\) 的分量 \(\overrightarrow{v_{\bot}}\) 绕着 \(\overrightarrow{u}\) 的旋转实际上是在一个平面内的旋转, 如下图.

(此处是一个还没画好的图)

转过的角度是 \(\theta\) 时, 利用三角函数将旋转的结果 \(\overrightarrow{v_{\bot}'}\) 分解到 \(\overrightarrow{v_{\bot}}\) 和 \(\overrightarrow{w}\) 两个方向上, 其中 \(\overrightarrow{w}\) 是一个和 \(\overrightarrow{u}, \overrightarrow{v_{\bot}}\) 都垂直的向量, 而且它的长度等于 \(\overrightarrow{v_{\bot}}\).

\[
\overrightarrow{v_{\bot}'} = \cos{\theta}\overrightarrow{v_{\bot}} + \sin{\theta}\overrightarrow{w}
\]

\(\overrightarrow{w}\) 的方向很特别, 它和 \(\overrightarrow{u}, \overrightarrow{v_{\bot}}\) 都垂直, 实际上就是它俩叉积的方向. 当 \(\overrightarrow{u}\) 是一个单位向量时, 甚至长度条件都满足, 也就是说实际上:

\[
\overrightarrow{w} = \overrightarrow{u} \times \overrightarrow{v_{\bot}}
\]

总结一下, 当向量 \(\overrightarrow{v}\) 以 \(\overrightarrow{u}\) 为轴旋转 \(\theta\) 角度时, 旋转后的向量是:

\[
\overrightarrow{v} = \overrightarrow{v_{\parallel}} + \cos{\theta}\overrightarrow{v_{\bot}} + \sin{\theta}\overrightarrow{u} \times \overrightarrow{v_{\bot}} = \overrightarrow{v_{\parallel}} + \cos{\theta}\overrightarrow{v_{\bot}} + \sin{\theta}\overrightarrow{u} \times \overrightarrow{v}
\]

最后一步利用了叉积的一点性质.

更进一步地, 由于 \(\overrightarrow{u}\) 是一个单位向量, \(\overrightarrow{v_{\parallel}} = (\overrightarrow{u}\cdot\overrightarrow{v})\overrightarrow{u}\), \(\overrightarrow{v_{\bot}} = \overrightarrow{v} - \overrightarrow{v_{\parallel}} = \overrightarrow{v} - (\overrightarrow{u}\cdot\overrightarrow{v})\overrightarrow{u}\)

上面的式子原本看着还挺简洁的, 但是一旦试图只用 \(\overrightarrow{u}, \overrightarrow{v}\) 来表示垂直/平行分量, 式子就变得比较复杂了. 而且, 实际上我们只是表示出了旋转的结果, 还有一个最根本的问题没有得到解决:

这个旋转变换本身究竟是什么样的?

我们必须想办法表示出这个旋转变换本身对应的代数上的结构, 我们才能知道旋转对于向量的作用是什么, 旋转的合成是什么. 换句话讲, 我们需要知道算子 \(A = (\cos{\theta} + \sin{\theta}\vec{u}\times)\) 的表达式究竟是什么, 旋转的计算才可以进行. 上面的式子看起来解决了三维旋转问题, 然而实际上还有挺长的一段距离.

四元数表示的旋转

将三维实向量 \(\vec{v}\) 看作是一个纯四元数(类比纯虚数) \(v = (0, \vec{v})\). 这种处理最最精妙的地方在于: 相互正交的两个向量的叉积(按照这种对应的四元数)就等于他们两个各自对应的四元数的乘积! 从这个角度而言这个处理非常的自然, 真是巧妙.

详细地说, 其实是这样的一件事情:

\[
uv_{\bot} = (0, \vec{u})(0, \overrightarrow{v_{\bot}}) = (-\vec{u}\cdot\overrightarrow{v_{\bot}}, \vec{u}\times\overrightarrow{v_{\bot}}) = (0, \vec{u}\times\overrightarrow{v_{\bot}})
\]

因此, 之前的结果可以改写为:

\[
\begin{aligned}
v_{\bot}' &= (\cos{\theta}, 0)(0, \overrightarrow{v_{\bot}}) + \sin{\theta}(0, \vec{u})(0, \overrightarrow{v_{\bot}}) \\
&= [(\cos{\theta}, 0) + \sin{\theta}(0, \vec{u})](0, \overrightarrow{v_{\bot}}) \\
&= (\cos{\theta, \sin{\theta}\vec{u}})(0, \overrightarrow{v_{\bot}})
\end{aligned}
\]

记 \(q=(\cos{\theta}, \sin{\theta}\vec{u})\), 则绕 \(\vec{u}\) 旋转 \(\theta\) 角等价于对向量的垂直于 \(\vec{u}\) 的分量左乘 \(q\). 此处, 四元数统一了旋转和向量两种对象, 并且赋予了它合理的一个乘法.

更进一步, 记 \(p=(\cos{\frac{\theta}{2}}, \sin{\frac{\theta}{2}}\vec{u})\), 可以验证:

\[
pp^* = p^*p = 1 \
p^2 = pp = q
\]

由于平行向量叉积为零, 垂直向量点积为零, 形如 \(p, q\) 这样的四元数和 \(v_{\bot}, v_{\parallel}\) 之间的乘法必然有比较特别的性质. 更加细致的计算可以得到:

\[\begin{aligned}    pv_{\parallel} &= v_{\parallel}p \\    (p^*v_{\parallel} &= v_{\parallel}p^*) \\    pv_{\bot} &= v_{\bot}p^* \\     (p^*v_{\bot} &= v_{\bot}p)\end{aligned}\]

简言之, 平行分量和 \(p\) 乘法交换, 垂直分量的乘法"共轭交换". 因此有:

\[\begin{aligned}    v' &= v_{\parallel} + qv_{\bot} \\    &= pp^*v_{\parallel} + ppv_{\bot} \\    &= pv_{\parallel}p^* + pv_{\bot}p^* \\    &= p(v_{\parallel} + v_{\bot})p^* \\    &= pvp^*\end{aligned}\]

这个式子虽然几乎没有了几何的直观, 但是代数的直观却非常明显: 旋转操作是对向量(四元数)左乘相应算子, 右乘算子的共轭, 换句话讲, 这个线性算子是:

\[R_{u, \theta}(v) = pvp^*, \; where\; p=(\cos{\frac{\theta}{2}}, \sin{\frac{\theta}{2}}\vec{u})\]

旋转的复合可以这样理解:

\[f(gvg^*)f^* = (fg)v(g^*f^*) = (fg)v(fg)^*\]

最开头要证明的结论和上面这个小式子说的就是一件事.

附录

1

上面的形如 \((\cos{\frac{\theta}{2}}, \sin{\frac{\theta}{2}}\vec{u})\) 的四元数表示了全体单位四元数. 而全体单位四元数和 SU(2) 之间存在同构:


\[\left(    \begin{aligned}        &a+bi &c+di \\        &-c+di & a-bi    \end{aligned}    \right) \leftrightarrow a\hat{1}+b\hat{i}+c\hat{j}+d\hat{k}\]

\(i=\sqrt{-1}\), 而 \(\hat{1}, \hat{i}, \hat{j}, \hat{k}\) 表示四元数的单位.

(更进一步地, Pauli 矩阵和三维旋转天然就有联系)

2

上面推导的 \(p=(\cos{\frac{\theta}{2}}, \sin{\frac{\theta}{2}}\vec{u})\), 其实还有另一个选择, 即不取 \(\theta'=\frac{\theta}{2}\), 而是 \(\theta'=\frac{\theta}{2} + \pi\), 这样两种取法都能满足后续的推导, 没有任何区别. 这两种选择在几何上的直观是: 一个把垂直分量旋转了 \(\theta\), 一个旋转了 \(\theta + 2\pi\). 所以其实从这里也能看出来 \(SU(2)\) 和 \(SO(3)\) 之间的这个 2 对 1 的同态映射(当然不严谨就是了).


终有一日, 仰望星空