三维旋转
在数学中“orientation”和“direction”两词定义上存在区别,后者代表的是物体指向的朝向,物体在三维空间中移动或指向的具体方向。前者代表的是物体自身的旋转状态。有时我们使用"定向"和"方向"在中文语义里区分两词的细微差别。
矩阵形式
描述 3D 坐标空间方向的一种方法是判断该坐标空间的基向量,否无论坐标空间处于什么方向。我们必须使用其他坐标空间来描述基向量。通过这样做,我们建立了两个坐标空间的相对方向。使用这些基向量形成的 3X 3 矩阵的行,就以矩阵形式表达了定向。 同时他是一个旋转矩阵:我们可以将行向量乘以该矩阵,将这些向量从对象空间坐标转换为直立空间坐标。
方向余弦矩阵 Direction Cosines Matrix
非常古老的)术语“方向余弦”。方向余弦矩阵与旋转矩阵相同;该术语只是指解释(或构造)矩阵的特殊方式。仔细观察会发现旋转矩阵中的每个元素等于一个空间中的基轴与另一空间中的基轴的点积,然而两个单位向量的点积正好等于它们之间角度的余弦。
矩阵形式优劣势
优势 :旋转向量易于计算,矩阵是图形 API 使用的格式,多个转换可以连接成一个矩阵,反向计算旋转只需要使用逆矩阵做乘法
劣势:更多的内存占用,不利于直接阅读,并非任意值都可以形成有效的矩阵,误差容易放大错误结果
欧拉角 Euler Angles
该技术以开发该技术的著名数学家 Leonhard Euler(1707-1783)命名。
欧拉角背后的基本思想是将角位移定义为围绕三个相互垂直的轴的三个旋转的序列。 关于描述互相垂直的三个旋转轴概念定义不是唯一的,常见的有航空航天领域流行的偏航-俯仰-横滚(yaw-pitch-roll)。这与第七章中我们定义球坐标中使用的航向-俯仰-组(heading-pitch-bank)是相同的系统。 不止是名称定义上不同,有时出现它们的出现顺序会不同,比如横滚-俯仰-偏航。
定轴系统与欧拉角系统关系非常密切。在欧拉角系统中,旋转围绕主体轴发生,每次旋转后主体轴都会发生变化,在定轴系统中,旋转轴始终相同——直立轴。只要旋转顺序相反,这两个系统是等效的。 在计算机内部,当将矢量从直立空间旋转到物体空间时,我们实际上使用的是定轴系统。 固定轴约定也称为外在约定(extrinsic),典型的欧拉角约定称为内在约定(intrinsic)。
欧拉角形式优劣势
优势:表达直观,容易使用,内存占用低,任意组合都有效
劣势:给定方向的表示不是唯一的,在两个欧拉角之间进行插值是有问题的,万向节锁
一个常见的误解是,由于万向节锁,某些方向无法使用欧拉角来描述。实际上,3D 空间中的任意一个角度都可以用欧拉角表示。
规范欧拉角能够解决一部分角度重叠造成插值问题,但是角度的循环性质仍然会造破坏。这种问题的解决方案是将插值方程中使用的角度之间的插值包含在 范围内,以便找到最短的路径。为此我们引入符号:
其中 表示下取整函数。
轴角 Axis-Angle 和指数映射 Exponential Map
欧拉旋转定义基本表明任何 3D 角位移都可以通过绕精心选择的轴进行单次旋转来实现。表示为将物体按旋转角度 和穿过原点并平行于单位向量 的旋转轴。 这里存在两个值 和 ,由于 具有单位长度,其可以乘以 而不丢失信息,从而产生单个向量 。换句话说,,旋转轴通过归一化 获得。
和 就是以轴角的方式表示角位移, 代表的是指数映射方式。
指数映射和欧拉角相比同样存在奇点,但它的插值特性比欧拉角更好,对于某些应用程序,例如动画数据的存储,未被充分重视的指数图可能是一个可行的替代方案。
但指数映射最重要和最频繁的使用不是存储角位移,而是存储角速度。这是因为指数图区分得很好(这在某种程度上与其更好的插值属性有关)并且可以轻松表示多个旋转。 于欧拉角一样,添加 360 度的倍数会产生角位移,从而导致相同的结束方向,出现混叠。但这并不完全是一个坏事,指数映射描述角速度的方式,这种表示这种“额外”旋转的能力是一个重要且有用的属性。
F. Sebastin Grassia. “Practical Parameterization of Rotations Using the Exponential Map.” J. Graph. Tools 3 (1998), 29–48. http://jgt.akpeters.com/papers/Grassia98/.
四元数 Quaternions
四元数通过使用四个数字来表示方向(因此称为四元数)来避免欧拉角问题。
表示方法
四元数包含标量分量和 3D 向量分量。我们通常将标量组件称为 𝑤。我们可以将向量分量称为单个实体 或单独的分量 𝑥、 𝑦和 𝑧。以下是这两种表示法的示例:
表示含义
四元数形式与轴角和指数映射形式密切相关。四元数还包含轴和角度,但是 和 并不是简单地直接存储在四元数的四个数字中,因为它们是轴角度。
与 相关,但它们不是同一件事。同样, 和 相关,但不相同。
四元数否定 Quaternion Negation
四元数可以取反
四元数 和 描述相同的角位移。 3D 中的任何角位移在四元数格式中都有两种不同的表示形式,并且它们互为负数。如果我们将 360 度添加到 ,它不会改变 表示的角位移,但它会否定 的所有四个分量。
恒等四元数 Identity Quaternion
在几何上,有两个“同一”四元数代表“无角位移”。它们是
四元数大小 Quaternion Magnitude
计算四元数的大小,就像计算向量和复数一样
四元数在几何上意味着什么:
为了我们使用四元数表示方向的目的,所有四元数都是所谓的单位四元数,其大小等于单位。
四元数共轭和逆 Quaternion Conjugate and Inverse
四元数的共轭,表示为 ,是通过对四元数的向量部分取负来获得的:
四元数的逆表示为 ,定义为四元数除以其大小的共轭:
与实数 不同四元数 。 如果您只对表示纯旋转的四元数感兴趣,就像我们在本书中一样,那么所有四元数都是单位四元数,因此共轭和逆是等效的。出于反转的目的否定 ,保持 不变也是可行的,但共轭在复数中具有特殊意义,所以不使用这种方式来混淆共轭概念。
四元数乘法 Quaternion Multiplication
四元数可以相乘。结果类似于向量的叉积,因为它产生另一个四元数(不是标量),并且它不可交换。
四元数积也称为汉密尔顿积。 四元数乘法满足结合律,但不满足交换律:
四元数乘积的大小等于大小的乘积:
四元数乘积的倒数等于按相反顺序取的倒数的乘积:
如何使用代表旋转的四元数 旋转向量 ,首先要把 从标准三维向量扩展到四元数空间 ,旋转得到新坐标 :
四元数乘法可用于连接多个旋转,就像矩阵乘法一样。多个旋转的串联将始终从右到左“从内到外”地读取。
四元数“差” Quaternion “Difference”
计算两个四元数之间的差异,其中“差异”意味着从一个方向到另一个方向的角位移。
表示的是四元数 和 的角位移。
四元数点积 Quaternion Dot Product
点积运算是为四元数定义的。此操作的符号和定义与向量点积非常相似:
与向量点积一样,结果是标量。对于单位四元数 𝑎和 𝑏、 −1≤𝑎⋅𝑏≤1。
点积几何解释
差异四元数 中的 分量等于 。四元数点积给出将一个四元数旋转到另一个四元数所需的一半角度的余弦。 四元数点积具有与向量点积类似的解释。四元数点积绝对值越大, 和 表示的角位移越“相似”。
四元数对数 Quaternion log、指数 exp 和标量乘法 Multiplication by a Scalar
通过引入变量 𝛼来重新表述四元数的定义,以等于半角 𝜃/2:
的对数定义为,我们使用符号 来表示定义上的相等。一般来说, log𝑞不是单位四元数。
指数函数的定义正好相反:
也就是说:
四元数可以乘以标量,结果以将每个分量乘以标量的明显方式计算:
❗这通常不会产生单位四元数,这就是为什么在表示角位移的情况下乘以标量并不是非常有用的运算。
四元数取幂 Quaternion Exponentiation
四元数可以求幂,这意味着我们可以将四元数提高到标量幂。四元数取幂,表示为 ,和指数函数区分,四元数取幂有两个参数:四元数 和标量指数 𝑡。
四元数取幂很有用,因为它允许我们提取角位移的“分数”。例如,要计算表示四元数 𝑞所表示的角位移三分之一的四元数,我们将计算 , 表示两倍角位移。
四元数使用最短弧表示角位移。无法表示多次旋转。如果需要累计旋转总量,更好的是改用指数映射或者轴角。
四元数插值 Quaternion Interpolation, a.k.a. Slerp
四元数在游戏和图形中存在的理由是一种称为 slerp 的运算,它代表球面线性插值。
slerp 函数 返回从 插值到 方向 [0 , 1] 之间的值。
标准线性插值如下:
推导四元数插值公式:
- 四元数之间的差
- 取这个差异的一小部分
- 取原始值并根据差值的这一部分进行调整
这是理论上的计算公式,实际上会使用等效但计算效率更高的公式。
设定所有四元数都是单位四元数,它们存在 4D 超球面的表面上,其基本思想是沿着 4D 超球面的表面围绕连接两个四元数的孤进行插值。(因此得名球面线性插值。)
想象一下2D 存在夹角为 弧度的两个二维向量 和 都是单位向量。 是两向量平滑 的插值得到新单位向量。从另一个视角看存在非负常数 和 使得 满足线性组合:
根据三角函数,应用于 作为斜边的三角形:
同理可得:
因此:
将思想扩展到四元数空间,重新表示 slerp:
四元数优劣势
优势:slerp 提供的插值提供了方向之间的平滑插值,四元数共轭提供了一种非常有效地计算相反角位移的方法,四元数与矩阵形式之间的转换速度比欧拉角要快一些,由于四元数包含四个标量值,因此它比使用九个数字的矩阵要经济得多
劣势:四元数是人类最难直接使用的,由于错误的输入数据或累积的浮点舍入误差导致四元数可能会失效,比欧拉角存储占用稍大
四元数作为复数 Quaternions as Complex Numbers
大多数文章都是将四元数当作复数讨论,如果只是用于旋转的四元数,那么可以不用深究复数理解。但是以下内容可以解释 和 的由来。
本章遵循德保罗大学的约翰·麦克唐纳提出的方法
复数对是由 定义了 ,数字 是一个特殊数, 这在实数中并不存在,所以使用"虚数"或“复合(complex)”,我们使用 2 X 2 矩阵集表示复数。 对于任何标量矩阵集嵌入表示如下,复数对中的实部(real)同样表示:
保留了所有普通的加法、减法和乘法的代数定律:结合律、分配律、零的不可分解性。 扩展 2X 2矩阵空间中的嵌入数字系统以包含复数:
该方式能够很好验证复数的加、减和乘法。以及 同样成立。
复数有以下运算法则:
不要将 𝑖视为 −1的平方根,而不要将复数 𝑎+𝑏𝑖视为具有两个自由度的数学实体。 现在发现 2D 旋转角度的矩阵刚好能用复数形式求得:
❗注意该矩阵和第五章节求得矩阵有细微出入,应为该矩阵用于左乘。 🔍i 的乘法被解释为 90 度旋转。 四元数的共轭表示反角位移。对于转置旋转矩阵来说,相应的事实是正确的:由于它们是正交的,因此它们的转置等于它们的逆矩阵。 普通的二维向量如何适应这个方案?我们将向量 解释为复数 ,然后我们可以解释两个复数的乘法
作为执行旋转。这相当于矩阵乘法
以上推导了 2D 中向量解释为复数并使用复数乘法对其旋转的计算过程。 为了将四元数和 3D 向量相乘,需要进行类似的转换。
从 2 D 到 3 D 无法使用相同的技巧扩展。威廉·罗文·汉密尔顿 1843 年意识到该扩展方式需要的不是两个虚部而是三个,他在扫帚桥(布鲁姆桥)上刻下了定义这种新型复数属性的方程,于是四元数就被发明了。
四元素中通过三个虚数 i 、j 和 k 扩展了复数系统,这三个虚数与 Hamilton 著名的方程相关:
表示四元数 对应复数 。现在重新将四元数嵌入矩阵集合当中。
结合上述关联,我们可以将任意四元数映射到 4 X 4矩阵:
省略 2 D 到四元数的矩阵计算推导,这里直接给出结论。将向量 转化为四元数 。将向量围绕 旋转角度 的直接方法是创建四元数 ,然后执行左乘 旋转。但乘法会产生一些不需要的旋转, 右侧乘以共轭 获得所需相同的旋转,并且产生相反且一样的需要旋转,所以 得到双倍的正确旋转并且中和了不需要的旋转,解决方案简单的使用角度的一半计算 。第一次旋转旋转到目标的一半,加上一些涉及 𝑤的不需要的旋转。第二次旋转完成所需的旋转,同时取消不需要的旋转。
四元数总结
- 从概念上讲,四元数通过使用旋转轴和绕该轴的旋转量来表达角位移。
- 四元数包含标量分量 和向量分量 。它们与旋转角度 和旋转轴 的关系为
- 3 D 中的每个角位移在四元数空间中都有两种不同的表示,并且它们互为负数
- 表示“无角位移”的恒等四元数是
- 所有表示角位移的四元数都是“单位四元数”,其大小等于 1。
- 四元数的共轭表示相反的角位移,并通过对向量部分 v 求反来计算。四元数的倒数是共轭除以大小。如果仅使用四元数来描述角位移,那么共轭和倒数是等效的。
- 四元数乘法可用于将多个旋转连接成单个角位移。理论上,四元数乘法也可以用来进行 3 D 向量旋转,但这实用价值不大。
- 四元数求幂可用于计算角位移的倍数。这总是捕获正确的最终结果;然而,由于四元数总是采用最短的弧,因此无法表示多次旋转。
- 四元数可以解释为 4 D 复数,这在数学和几何之间创造了有趣而优雅的相似之处。
表示形式转换
将欧拉角转换为矩阵 Euler Angles to a Matrix
物体到直立旋转矩阵的生成是三个简单旋转矩阵的直接串联
其中 B、p 和 H 是坡度、俯仰和航向的旋转矩阵,他们分别围绕 z、x 和 y 轴旋转。
串联后得到
为了将向量从直立空间旋转到对象空间,我们将使用该对象到直立矩阵的逆矩阵。
将矩阵转换为欧拉角 Matrix to Euler angles
根据对象空间转直立空间的矩阵
从 求解 p:
然后我们根据 p ,也得到了 ,根据矩阵其他元素求得:
根据 atan2 计算角度的值:
Bank 的计算方式类似:
如果 ,将出现 这就意味着出现万向节锁定,在这种情况下,我们任意的将所有绕垂直轴的旋转分给“heading”,并将 “Bank” 设置为 0,也就是只求解 h。
带入旋转矩阵得到:
现在我们可以从 和 计算 h,它们分别包含航向的正弦和余弦。
将四元数转换为矩阵 Quaternion to a Matrix
由于四元数本质上是轴角旋转的编码版本,因此根据绕任意轴的构造矩阵进行推导。
四元数的分量计算公式
最终得到,如果感兴趣这部分推理过程,请深入阅读Equation (8.20).
将矩阵转换为四元数 Matrix to a Quaternion
这是对 QtM 矩阵的逆向工程。检查对角线元素的总和(称为矩阵的迹),我们得到
所以
其他三个元素可以用类似的方式计算,通过对跟踪中三个元素中的两个求反:
不能对所有四个分量使用这个技巧,因为平方根总是会产生正结果。 另一种推导方式是检查对角相反的矩阵元素的和与差:
利用上一个方法求得的任意一个值推导出其他分量,有四种选择。
选择其中任意一行,其他的的三个分量都会受第一个分量影响,产生数值不稳定。 Shoemake 建议首先确定 𝑤、 𝑥、 𝑦和 𝑧中哪一个具有最大绝对值的策略(我们可以在不执行任何平方根的情况下完成),使用矩阵的对角线计算该分量,然后选择计算公式。
肯·舒梅克。 “欧拉角转换。” 《Graphics Gems IV》,Paul S. Heckbert 编辑。圣地亚哥:学术出版社专业人士,1994 年。
将欧拉角转换为四元数 Euler Angles to a Quaternion
将欧拉角分配给变量 h、 p 和 b。令 h、 p 和 b 为四元数,它们执行围绕 𝑦、 𝑥和 𝑧- 轴分别为:
从直立空间到对象空间的四元数就是共轭:
将四元数转换为欧拉角 Quaternion to Euler Angles
根据矩阵转转欧拉角的解
以及四元数转矩阵求解
将后者带入前者并化简得到,它将对象到直立四元数转换为欧拉角。
要将直立到对象四元数转换成欧拉角格式,使用几乎相同的方式,是需要将 x、y 和 z 值取反。