为什么四元数用于旋转?

我是一个物理学家,正在学习一些编程,遇到过很多人用四元数进行旋转,而不是用矩阵/向量的形式写东西。

In physics, there are very good reasons we don't use quaternions (despite the bizarre story that's occasionally told about Hamilton/Gibbs/etc). Physics requires that our descriptions have good analytic behavior (this has a precisely defined meaning, but in some rather technical ways that go far beyond what's taught in normal intro classes, so I won't go into any detail). It turns out that quaternions don't have this nice behavior, and so they aren't useful, and vectors/matrices do, so we use them.

然而,限于刚性旋转和描述,不使用任何分析结构,三维旋转可以等价地描述任何一种方式(或其他一些方式)。

一般来说,我们只需要一个点 X = (x,y,z)到一个新点 X’= (x’,y’,z’)的映射,这个映射受到 X2 = X’ABC 0的约束。有很多东西可以做到这一点。

最简单的方法就是画出这个定义的三角形,然后使用三角法,或者使用点(x,y,z)和向量(x,y,z)与函数 f (X) = X’和矩阵 MX = X’之间的同构,或者使用四元数,或者使用其他方法(x,y,z) T将旧向量的分量投影到新向量上。(a,b,c)(x’,y’,z’)等。

从数学的角度来看,这些描述在这个设置中都是等价的(作为一个定理)。它们都有相同数量的自由度,相同数量的约束,等等。

那么为什么四元数似乎比向量更受青睐呢?

我看到的通常原因是没有万向节锁或数字问题。

没有万向节锁参数似乎很奇怪,因为这只是一个欧拉角的问题。它也只是一个坐标问题(就像极坐标系中 r = 0的奇异点(雅可比松散秩)) ,这意味着它只是一个局部问题,可以通过切换坐标、从简并中旋转出来或者使用两个重叠的坐标系来解决。

I'm less sure about numerical issues, since I don't know in detail how both of these (and any alternatives) would be implemented. I've read that re-normalizing a quaternion is easier than doing that for a rotation matrix, but this is only true for a general matrix; a rotation has additional constraints that trivializes this (which are built into the definition of quaternions) (In fact, this has to be true since they have the same number of degrees of freedom).

那么,为什么要在向量或其他选择上使用四元数呢?

49381 次浏览

万向节锁是一个原因,虽然如你所说,这只是一个欧拉角度的问题,很容易解决。欧拉角仍然使用时,内存是一个问题,因为你只需要存储3个数字。

对于四元数和3 × 3的旋转矩阵,四元数在大小(4个标量比9个)和速度(四元数乘法比3 × 3的矩阵乘法快得多)上有优势。

Note that 所有 of these representations of rotations are used in practice. Euler angles use the least memory; matrices use more memory but don't suffer from Gimbal lock and have nice analytical properties; and quaternions strike a nice balance of both, being lightweight, but free from Gimbal lock.

我看到的通常原因是没有金属锁或数字问题。

这些都是很好的理由。

As you already seem to understand, quaternions encode a single rotation around an arbitrary axis as opposed to three sequential rotations in Euler 3-space. This makes quaternions 免疫万向节锁定.

此外,一些形式的插值变得很好,很容易做,如 SLERP

...or using two overlapping coordinate systems.

从性能角度来看,为什么您的解决方案更好?

我还可以继续,但是四元数只是一个可以使用的工具。如果它们不适合你的需要,那么就不要使用它们。

没有万向节锁参数似乎很奇怪,因为这只是一个欧拉角的问题。它也只是一个坐标问题(就像极坐标系中 r = 0的奇异点(雅可比松散秩)) ,这意味着它只是一个局部问题,可以通过切换坐标、从简并中旋转出来或者使用两个重叠的坐标系来解决。

许多3D 应用程序喜欢使用欧拉角来定义一个物体的方向。特别是对于飞行模拟器,它们代表了一种理论上有用的方法,以一种容易修改的方式存储方向。

您还应该意识到,像“切换坐标,从简并度中旋转出来,或者使用两个重叠的坐标系统”这样的事情都需要努力。努力就是代码。代码意味着性能。对于许多3D 应用程序来说,如果不使用 就会失去性能,这不是一件好事。毕竟,如果仅仅使用四元数就可以得到所需的一切,那么所有这些技巧将带来什么好处呢。

我对数字问题不太确定,因为我不知道如何具体实现这两个问题(以及任何替代方案)。我曾经读到过,对一个四元数进行重新标准化比对一个旋转矩阵进行重新标准化要容易,但这只适用于一般矩阵; 旋转有额外的约束,使之变得无足轻重(这些约束构成了四元数的定义)(事实上,这必须是真的,因为它们具有相同的自由度数)。

当处理一个方向的多个连续旋转时,会出现数值问题。想象一下你在太空中有一个物体。每一个时间片,你应用一个小变化的偏航到它。在每次更改之后,您需要重新规范化方向; 否则,精度问题将悄然出现并把事情搞砸。

If you use matrices, each time you do matrix multiplication, you must re-orthonormalize the matrix. The matrix that you are orthonormalizing is not yet a rotation matrix, so I wouldn't be too sure about that easy orthonormalization. However, I can be sure about this:

它不会像4D 矢量归一化那样快,这是四元数在连续旋转后用来归一化的方法。

四元数归一化很便宜。即使是专门的旋转矩阵归一化也不会便宜。同样,性能很重要。

还有一个矩阵不容易做到的问题: 两个不同方向之间的插值。

当处理一个3D 角色时,通常有一系列的转换来定义角色中每块骨头的位置。这种骨骼的层次结构代表了特定姿势下的角色。

In most animation systems, to compute the pose for a character at a particular time, one interpolates between transformations. This requires interpolating the corresponding transformations.

Interpolating two matrices is... non-trivial. At least, it is if you want something that resembles a rotation matrix at the end. After all, the purpose of the interpolation is to produce something part-way between the two transformations.

对于四元数,所有您需要的是一个4D lep,然后是一个规范化。这就是全部: 取两个四元数并对组件进行线性插值。使结果正常化。

如果你想要更好的质量插值(有时你这样做) ,你可以把 球形虫。这使得插值对于更多不同的方向表现得更好。这个数学是 很多更困难,需要更多的运算矩阵比四元数。

在物理学中,我们有很好的理由不使用四元数(尽管关于汉密尔顿/吉布斯/等的奇怪故事时有发生)。物理学要求我们的描述具有良好的分析行为(这有一个精确定义的意义,但在一些相当技术性的方式,远远超出了什么是在正常的介绍类教学,所以我不会进入任何细节)。事实证明四元数没有这种好的行为,所以它们没有用,向量/矩阵有用,所以我们使用它们。

我也是个物理学家。有些情况下,四元数简直就是摇滚!比如球谐函数。有两个原子散射,交换一个电子,轨道自旋转移是多少?对于四元数,它只是乘法,即将 SH 基函数的指数总结为四元数。(将勒让德多项式转换成四元数符号有点乏味)。

但是我同意,它们不是一个通用的工具,特别是在刚体力学中,它们使用起来非常麻烦。然而,引用一个学生的问题的伯特兰·罗素,一个物理学家需要知道多少数学:

无论如何: 为什么我们喜欢计算机图形学中的四元数?因为它们有很多吸引人的属性。第一个可以很好地插值它们,这是很重要的,如果一个是动画旋转的东西,如四肢周围的关节。对于四元数,它只是标量乘法和规范化。用一个矩阵表示它需要计算 sin 和 cos,然后构建一个旋转矩阵。然后用一个四元数乘一个向量仍然是便宜的,通过一个完整的向量矩阵乘,它也更便宜,如果一个加上一个平移后。如果你考虑一个人类角色的骨骼动画系统,在这个系统中必须对大量顶点进行大量的平移/旋转,这会产生巨大的影响。

使用四元数的另一个好的副作用是,任何变换本质上都是正交的。使用平移矩阵,由于数值舍入误差,每两个动画步骤都必须重新正交化。

一般来说,我们只需要一个点 X = (x,y,z)到一个新点 X’= (x’,y’,z’)的映射,这个映射受到 X ^ 2 = X’^ 2的约束。有很多东西可以做到这一点。

我们绝对不希望 只是这样做。有一个非常重要的微妙之处,很多人都失手了。你正在谈论的结构(绘制三角形和使用三角形等)将正确地旋转一个向量到另一个向量。但是有无限多的旋转可以做到这一点。特别是,我可以在你完成旋转之后跟着你,然后围绕着 X 的向量旋转整个系统。这根本不会改变 X’的位置。你的旋转和我的旋转的组合相当于另一个单一的旋转(自从旋转 组成一个小组)。通常,您需要能够表示任何这样的旋转。

原来 可以只用一个矢量就可以做到这一点。这是 旋转轴角但是在轴角中结合旋转是很困难的。四元数和许多其他的东西使它变得容易。基本上,四元数具有其他表示的所有优点,没有缺点。(尽管我承认,可能有一些特定的应用程序,其他一些代理可能更好。)


我认为很多人忽略的另一点是,当您需要执行 在旋转本身操作时,四元数通常更好。即使到了我们可以将旋转应用到矢量的地步,我们也需要知道那个旋转应该是什么。通常我们将需要 作曲旋转,反转旋转,和 插值延伸旋转。所有这些都可以通过四元数非常有效和准确地完成。对于其中一个操作,其他表示可能几乎与四元数一样好,但肯定不是所有的操作。

观点: 四元数很好。

轮换矩阵: Minor disadvantage: Multiplication of matrices is ~2 times slower than quaternions. 次要优势 : 矩阵向量的乘法速度快约2倍,而且很大。 巨大的 不利条件: 规范化!格拉姆-施密特是不对称的,在求解微分方程时不能给出高阶精确解。更复杂的方法是非常复杂和昂贵的。

Axis (angle = length of axis) Minor advantage: Small. 中等劣势 : 乘法和应用到向量是三角慢。 中等劣势 : 长度上的北极奇点 = 2 * pi,因为所有的轴方向没有任何作用。更多的代码(和调试)可以在接近2pi 时自动重新缩放。

值得记住的是,所有与旋转相关的属性并非真正的四元数属性: 它们是 欧拉-罗德里格斯参数化的属性,欧拉-罗德里格斯参数化是用于描述3D 旋转的实际4元素结构。

他们与 Quaternions 的关系纯粹是因为凯利的一篇论文《关于与四元数相关的某些结果》 ,作者在这篇论文中观察了四元数乘法和欧拉-罗德里格斯参数化组合之间的相关性。这使得四元数理论的各个方面可以应用于旋转的表示,特别是它们之间的插值。

你可以在这里阅读报纸: https://archive.org/details/collmathpapers01caylrich。但是在当时,四元数和旋转之间没有联系,凯利很惊讶地发现它们之间有联系:

事实上,这些公式正是奥林德先生给出的这种转换的公式 罗德里格斯 · 刘维尔(Rodrigues Liouville) ,电视节目,“几何学的法律,记录了一个人的移动 系统固体[ ... ]”(或梳子。数学。杂志,第三卷第224页[6]) 这些系数出现的先验性问题。

然而,四元数本身并没有给旋转带来任何好处。四元数不能避免万向节锁,但欧拉-罗德里格斯参数可以。很少有执行旋转的计算机程序可能真正实现四元数类型,这些类型是一流的复杂数学值。不幸的是,对四元数角色的误解似乎已经在某个地方泄露出来,导致相当一部分困惑的图形学生学习复杂数学的细节与多个虚构常数,然后困惑为什么这解决了旋转的问题。

An answer that someone might read: 所有表示都存在乏味的问题。四元数比矩阵小,但是四元数乘法不仅仅是向量点积之类的,事实上在计算机上所花的时间比两个3x3矩阵的点积还要多。(计算机非常擅长使用普通矩阵)

矩阵还有其他恼人的特性。例如,从长远来看,它们不是稳定的生物。当在三维空间中建立旋转模型时,通常会将一个旋转叠加到另一个旋转的方向矩阵中,这只是一个存储参考框架方向的旋转矩阵。 这个过程将在数以百万计的添加过程中导致 O 矩阵偏离严格的旋转矩阵形式。 This can be circumvented by periodically reconfiguring the matrix, but there are conditions when this is nontrivial. Namely the no-rotation case of identity matrix.

你需要找到一个旋转的轴角(或四元数表示) ,然后为它重现一个矩阵。大多数算法产生一个零向量,然后在这种情况下遇到零除。 In these kinds of cases it is also generally a poor idea to try to avoid such cases with "if 0 then..." -type of solutions, since a) forks are slow and b) you can still end up machine epsilon apart from singularity and end up with horrendous errors.

单位四元数为三维正交群 O (3) ,特别是其子群三维特殊正交群 SO (3)提供了一种简洁的表示。这有许多用途,但我知道最好的是它在惯性导航系统使用捷联式安排加速器和陀螺仪的用途。SO (3)元素用来表示车辆在地球上的“位置”(或者更确切地说是接近地球表面的球体)另一种是用来指定飞行器的“姿态”,也就是说飞行器的车身与当地切平面的关系。这两者都是“集成”的小变化(10Hz 或更小的时间增量) ,以更新他们与新的数据。“姿态”和“位置”旋转形成一个“耦合”的微分系统,因为施加在车体上的力在局部切平面上得到解析,以更新车辆的“位置”旋转。

四元数很容易以这种方式集成(添加四个四元数)在“积分”之后,结果将不再是 SO (3)的成员,而是一个简单的重标准化“投射”积分四元数到 SO (3)上。每个四元数只使用并保留4个值。

利用四元数集成来实现惯性导航在20世纪80年代就已经是一个行业标准。我所知道的第一篇提出这个建议的论文是在1973年发表的。当时,数学专业的学生只是把四元数作为代数(一个非交换除环)中的一个“奇数”例子来学习

然而,四元数现在是 SO (3)在许多应用(例如,计算机图形学)中的首选表示形式从数学的角度来看,它甚至更有趣,因为它提供了可能的最简单的例子’微积分流形!(球面是一个简单流形,SO (3)是李群。)