目录

关于 Quaternion 旋转正确性的学习资料推荐

正文

用 Quaternion 做旋转有省空间、连续多个 Quaternion 旋转和矩阵一样可以复合成单个 Quaternion 、复合操作的计算量比矩阵少、不受 Gimbal Lock 影响、更容易做插值等特点,因此在图形学领域被广泛使用。

本文将推荐 Quaternion 的学习资料,这些资料专注于把 Quaternion 用于旋转,而不专注于 Quaternion 作为一个代数系统的属性,特别的,我们仅使用到该代数系统的非常小一部分子集。

首先推荐阅读的是 Quaternions for Computer Graphics 2nd ,专门为图形学领域讲解的 Quaternion ,这本书我的评价不是很高,等下讲原因,首先这本书可以肯定的是, Quaternion 的历史背景讲的很丰富,还穿插了很多其他的、相关的、有用的信息,但是很多地方讲解比较生硬,解释也比较含糊,让我对这本书评分骤降的地方在于,在第8章 Quaternions in Space 中讲解 Quaternion 如何用于旋转的时候,作者是用特例进行来“说服”读者 Quaternion 可以用来旋转的,而不是用代数的方法去证明,或者你至少举个一般的例子,不管怎么样,这本书仍然很值得一读,有用的信息很多。

然后推荐阅读的是 Eric Arnebäck 的文章: Showing the Correctness of Quaternion Rotation ,正如这篇文章说的, Rodrigues 旋转公式的正确性远比 Quaternion 旋转更符合直觉,所以这篇文章选择使用代数的方法证明 Quaternion 旋转公式等价于 Rodrigues 旋转公式,从而证明 Quaternion 旋转公式的正确性,读者需要先看 Rodrigues 旋转公式的推导,在信任 Rodrigues 旋转公式的正确性后,再去看 Eric Arnebäck 的文章, Wikipedia 中有 Rodrigues 旋转公式的详细推导,见: Rodrigues' rotation formula

综上,推荐阅读顺序是:

  1. Quaternions for Computer Graphics 2nd
  2. Rodrigues' rotation formula
  3. Showing the Correctness of Quaternion Rotation

其中可以跳过 Quaternions for Computer Graphics 2nd 直接按顺序阅读后两篇文章,但是如果跳过第一本书的话,读者在阅读 Showing the Correctness of Quaternion Rotation 看到 Simplifying Quaternion Rotation 的时候需要注意:

上面利用到了 \( \vec{v} = 0 + \vec{v} \) ,即向量等于标量项为 \( 0 \) 的 Quaternion ,这个关键点文章的作者漏了提到。

最后,读者可以阅读 Mathematics for 3D Game Programming and Computer Graphics 3rd 的章节 4.6 : Quaternions ,里面一样以代数的方法给了 Quaternion 旋转非常简洁的推导(同时也省略了很多细节,读者要自己补上),虽然该推导最终和 Showing the Correctness of Quaternion Rotation 一样,还是证明了 Quaternion 旋转公式和 Rodrigues 旋转公式(书中直接叫它绕任意轴旋转公式)的等价性,但是推导的前半部分是比较不一样的,该推导前半部分对于读者是否可信,取决于读者是否相信所有同时保长度、直线之间的角度、手性的变换就是旋转变换(注:平移变换不考虑,因为我们这里处理的对象是向量,是被我们视为仅有方向,没有位置的对象,由于没有位置的概念,自然没有平移这个操作,当然,在引入基向量,即有了坐标系后,你可以把向量的坐标认为是它的“位置”而不认为是它的“方向”,但此时平移量不为\( 0 \)的平移操作就一定会改变向量的“位置”,进而不保向量的模长,也就是我们所谓的“长度”)。需要注意的是,书中的推导有个小错误,接下来,我将一步步说明错误在哪,为什么 我觉得 这是个错误,具体的:书上说在要求变换 \( \varphi \) 满足 \( \varphi(s + \vec{v}) = s + \varphi(\vec{v}) \) 的前提下,以下等式 4.41 :

\[ \varphi(\vec{P_1}) \cdot \varphi(\vec{P_1}) = \vec{P_1} \cdot \vec{P_2} \qquad \text{(4.41)} \]

可以改写成以下等式 4.43 :

\[ \varphi(\vec{P_1}) \cdot \varphi(\vec{P_1}) = \varphi(\vec{P_1} \cdot \vec{P_2}) \qquad \text{(4.43)} \]

这点是没问题的,因为等式 4.41 右侧是标量 \( \vec{P_1} \cdot \vec{P_2} \) ,加上如果\( \varphi \)真的是旋转变换的话,则旋转变换是线性变换,会将\( \vec{0} \)映射到\( \vec{0} \),因此可得 \( \varphi(\vec{P_1} \cdot \vec{P_2}) = \varphi((\vec{P_1} \cdot \vec{P_2}) + \vec{0}) = (\vec{P_1} \cdot \vec{P_2}) + \varphi(\vec{0}) = (\vec{P_1} \cdot \vec{P_2}) + 0 = \vec{P_1} \cdot \vec{P_2} \) 。

紧接着,书上说利用等式 \( \vec{P_1}\vec{P_2} = -\vec{P_1} \cdot \vec{P_2} + \vec{P_1} \times \vec{P_2} \) (1) (这里把向量看成标量项为 \( 0 \) 的 Quaternion ,用的是 Quaternion 乘法),以及之前要求的 \( \varphi(s + \vec{v}) = s + \varphi(\vec{v}) \) (2) ,就可以把等式 4.42 和 等式 4.43 合并成等式 4.44 ,这里先补充下等式 4.42 和等式 4.44 ,如下:

\[ \varphi(\vec{P_1} \times \vec{P_2}) = \varphi(\vec{P_1} \times \vec{P_2}) \qquad \text{(4.42)} \]

\[ \varphi(\vec{P_1}) \varphi(\vec{P_2}) = \varphi(\vec{P_1} \vec{P_2}) \qquad \text{(4.44)} \]

很容易证明等式 4.42 加上等式 4.43 可以推出等式 4.44 ,但反过来,单靠 (1)(2) ,等式 4.44 似乎无法推出等式 4.42 和等式 4.43 ,也就是等式 4.42 和等式 4.43 并不等价于等式 4.44 ,但是额外要求 \( \varphi \) 满足将纯向量(标量项为 \( 0 \) 的 Quaternion )映射到纯向量,即要求 \( \varphi(\vec{P}) \) 也为纯向量的话,则等式 4.44 就也能推出等式 4.42 和等式 4.43 了,此时等式 4.42 和等式 4.43 才等价于等式 4.44 ,之后很容易验证变换 \( \varphi_q(\vec{P}) = q \vec{P} q^{-1} \) 确实同时满足 \( \varphi(s + \vec{v}) = s + \varphi(\vec{v}) \) 以及会将纯向量映射到纯向量,故我认为应该额外要求变换 \( \varphi \) 将纯向量映射到纯向量。

以上就是我认为的、书中的错误点,读者需要留意下。

额外的, Mathematics for 3D Game Programming and Computer Graphics 3rd 的章节 4.3 : Rotation Transforms 中也给了 Rodrigues 旋转公式的证明(书中直接叫它绕任意轴旋转公式),证明的阐述比 Wikipedia 的简洁不少,且只要你顺着章节 4.3 读下来,也很容易读懂。

附件

这里为了避免两篇文章链接失效,这里保存成图片,作为附件:

  1. rodrigues_ rotation_formula_wikipedia.zip
  2. showing_the_correctness_of_quaternion_rotation.png

参考文章

  1. Quaternions for Computer Graphics 2nd
  2. Rodrigues' rotation formula
  3. Showing the Correctness of Quaternion Rotation
  4. Mathematics for 3D Game Programming and Computer Graphics 3rd