11

四元数可以说是在内部表示对象旋转的合适选择。它们可以简单有效地插值并明确表示单个方向。

但是,在用户界面中呈现四元数通常是不合适的 - 欧拉角通常对用户来说更熟悉,并且它们的值更直观和可预测。

欧拉角在代码级别受到复杂影响 - 它们需要存储旋转顺序,并且使用此顺序和相关角度组成实际方向(无论是矩阵还是四元数)至少可以说很麻烦。

使用四元数表示最方便地执行可靠插值 - 那么这是否意味着我们必须在欧拉表示和四元数表示之间不断转换?这在性能方面可行吗?

我们可以将方向存储为四元数并将它们转换为仅显示给用户吗?这可能是不可能的,因为对于任何给定的方向,只有一个四元数表示,但有许多欧拉表示。我们如何“挑选”对应于最初定义该方向的欧拉表示?这似乎是一项不可能完成的任务——我们在转换为四元数时实际上已经丢失了信息。

我们可以存储为欧拉角,然后根据需要转换为四元数吗?这可能是不可扩展的——从欧拉角到四元数的转换、插值,然后再转换回来可能是相对昂贵的代码。

我们可以简单地存储这两种表示并使用最适合任何给定情况的表示吗?内存方面的大量成本(想象一下具有大约 60 根骨骼的骨骼的动画曲线)并保持这些值同步可能会很昂贵,或者至少很麻烦。

有没有人看到、使用或提出过任何聪明的解决方案?上面的三个选项肯定不是唯一的吗?还有其他类似的问题域已经解决了吗?

4

7 回答 7

19

我是一名航空工程师;三年来,我一直在使用四元数进行航天器姿态控制和导航。以下是对您的情况的一些想法:

  1. 执行任何改变欧拉角方向的过程几乎是不可能的。欧拉角受到奇点的影响——当其他角度通过奇点时,角度会瞬间变化多达 180 度;欧拉角几乎不可能用于连续旋转。四元数不会遇到这些问题
  2. 有 12 种不同的可能的欧拉角旋转序列 - XYZ、XYX、XZY 等。没有一组“最简单”或“正确”的欧拉角。要导出一组欧拉角,您必须知道您正在使用哪个旋转序列并坚持下去。
  3. 我建议您使用四元数执行所有存储和旋转操作,并且仅在需要输出时将四元数转换为欧拉角。当你这样做时,你必须定义你使用的欧拉旋转序列。

我有所有这些操作的算法以及更多:四元数到/从任何旋转序列的欧拉角到/从旋转矩阵(方向余弦矩阵),四元数插值匹配位置,速率等在端点或中间点,刚性和柔性使用四元数的身体动力学和运动学。

如果我可以通过 nhughes1ster@gmail.com 提供帮助,请与我联系

于 2009-06-06T23:16:20.117 回答
2

你 12 年前问过这个问题,我告诉你你检查的答案是完全错误的。那家伙不知道他在说什么。

如果您将欧拉角的域(让我们使用偏航俯仰滚动)限制为 -180 到 180,则每个四元数至少有两组代表它的 YPR(偏航俯仰滚动)。如果没有额外的假设,就无法知道哪个 YPR 是正确的。

最好的解决方案是始终在内部存储 YPR,然后当您需要进行计算时,将 YPR 转换为四元数。这才是正确的答案。

使用四元数进行计算将再次产生多种可能的解决方案,但是因为您只在内部存储了 YPR,您将能够使用原始 YPR 来帮助您找到从四元数派生的正确 YPR。

那家伙 3 年的经验并不意味着杰克。很可能他正在处理一个受限系统。如果 2 个或更多轴的旋转被限制为只能扫过 180 度(在这种情况下为 -90 到 90),那么只有 THEN 才会为每个四元数表示一个 YPR。因为这家伙是一名航空工程师,我很确定这就是他正在处理的问题,因为物理万向节通常具有有限的旋转角度。

于 2021-06-10T23:54:53.677 回答
0

我是四元数的粉丝。为了让它们发挥作用,你能重新考虑你向用户展示的内容吗?您可以选择一些简单的 3D 对象并将四元数旋转应用于对象,以直观地显示旋转的效果,而不是以文本形式向用户呈现旋转的一系列欧拉角。

于 2009-05-07T03:48:46.457 回答
0

为什么不在代码中使用 Quarternions 并在需要显示时将 Q 转换为角度?

于 2009-05-07T03:58:01.597 回答
0

您可以将旋转表示为轴+旋转角度,这与四元数基本相同(最多一个符号)

于 2009-05-07T04:02:56.000 回答
0

我认为在内部使用欧拉角是没有意义的——你会想要在所有计算中使用四元数,而且通常无法承受到处进行的转换。至于将其转换回 UI 的欧拉角 - 如果用户只获得与原始输入等效但表示方式不同的角度,那会不会很糟糕?如果你做正确的转换,你应该得到任何给定四元数的“最简单”的欧拉角。

于 2009-05-07T04:28:18.530 回答
0

我们在谈论多少次转换。看起来您为每次转换支付了大约两个先验操作,在现代硬件上,这些操作以每秒 1 亿次的数量级可用。我会同时存储四元数以确保准确性和美观,并存储欧拉旋转以保留用户信息。也许添加一个标志来指示任何给定对象的首选。最重要的是,您只需为每个轮换成员执行一次转换。一旦你计算了一个变换矩阵,它的乘法相加直到你用完顶点。

于 2009-05-07T04:39:58.313 回答