c++ - 欧拉旋转应该存储为三个矩阵还是一个矩阵?

标签 c++ matrix rotation euler-angles

我正在尝试用 C++ 创建一个简单的矩阵库,希望以后能够在游戏开发中使用它。

我已经完成了基本的实现,但我刚刚意识到每个对象只存储一个矩阵的问题:旋转顺序很快就会混淆。

据我所知:AB != BA

因此,如果我不断地将任意旋转乘以我的矩阵,那么旋转就会混淆,对吗?在我的例子中,我需要在 Y 轴上全局旋转,在 X 轴上局部旋转(在 Z 轴上局部也不错)。这些似乎是普通第一人称射击游戏的品质。因此,所谓“混合”,我的意思是如果我在 Y 轴(或 Z 轴)上旋转,那么它将开始围绕局部 X 轴旋转,而不是预期的轴(如果这有意义的话)。

所以,这些是我想出的解决方案:

  1. 保留3个欧拉角,当其中一个角发生变化时,按照正确的顺序重建矩阵
  2. 保留 3 个矩阵,每个轴一个
  3. 以某种方式在乘法期间破坏矩阵,并在之后正确地重建它(?)

还是我什么都不担心?我的疑虑是错误的吗?订单会以某种方式神奇地自行解决?

最佳答案

您说得对,旋转矩阵的顺序在这里可能是个问题。

特别是如果您使用欧拉角,您可能会遇到 gimbal lock 的问题:假设您的第一次旋转是 +90° 正“俯仰”,这意味着您正向上看;那么如果下一个旋转是+45°“滚动”,那么你仍然只是直视。但是如果你以相反的顺序进行旋转,你最终会看到完全不同的地方。 (请参阅维基百科链接以获得更清楚的插图。)

游戏开发中的一个常见答案是 (1) 中的内容:独立存储欧拉角,然后 build the rotation matrix out of all three of them at once每次您想获取对象在世界空间中的方向时。

另一种常见的解决方案是将旋转存储为 an angle around a single axis , 而不是欧拉角。 (这对于动画师和玩家 Action 来说通常不太方便。)

我们也经常使用quaternions作为存储和组合旋转的更有效方式。

上面的每个链接都应该将您带到一篇说明相关数学的文章。我也喜欢Eric Lengyel's Mathematics for 3D Game Programming and Computer Graphics这本书很好地解释了整个主题。

关于c++ - 欧拉旋转应该存储为三个矩阵还是一个矩阵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10793598/

相关文章:

c++ - std::throw_with_nested 需要 C++11 中的多态类型?

c++ - 无法看到导致核心转储终止的异常

javascript - 在 Angular 传单指令中旋转标记

c# - 团结 |按指定角度(0~360度)旋转游戏对象

java - 旋转 Java Graphics2D 矩形?

c++ - 现代计算机上的 double 和浮点内存分配

c++ - 如何检查一个类型是否直接派生自另一个类型?

r - cor() 函数的完整.obs

matrix - 如何在 golang 中找到 (2,3 或者如果可能的话 n) 维 slice 的维度并验证它是否是矩阵?

r - 矩阵操作: set all elements to 0 except for row maximum (maxima)