【问题标题】:Should Euler rotations be stored as three matrices or one matrix?欧拉旋转应该存储为三个矩阵还是一个矩阵?
【发布时间】:2012-05-29 05:40:18
【问题描述】:

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

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

据我所知:AB != BA

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

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

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

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

【问题讨论】:

    标签: c++ matrix rotation euler-angles


    【解决方案1】:

    您是正确的,旋转矩阵的顺序在这里可能是一个问题。

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

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

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

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

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

    【讨论】:

    • 四元数不会遇到我的问题中描述的相同问题吗?或者这个问题只是因为我坚持使用欧拉角而相关吗?目前,我倾向于独立存储欧拉角,并希望获得最好的结果。
    • @JamieSyme 局部轴上的旋转本质上对顺序很敏感。向左转九十度然后向上看三十度不同于向上看三十度然后向左转九十度(用模型飞机试试)。四元数可以帮助您的是堆栈中只有一个旋转 - 您不会单独存储俯仰/偏航/滚动,它只是一个轴和角度。但这不是考虑球员运动的自然方式,这就是为什么大多数人更喜欢欧拉角的原因。只需在应用它们的顺序上保持一致即可。
    • 好的,我想我现在明白了。我将把我的角度存储为欧拉角,因为它们暂时更容易理解。如果我碰巧遇到万向节锁定,我会尝试采用“四元数”旋转方法或类似的方法,并收起我的欧拉角。谢谢:)
    • @JamieSyme 你仍然可以使用欧拉角来修改旋转(如果你真的想要的话),没有什么能阻止你一个接一个地沿着三个坐标轴旋转,但你真的应该考虑另一种表示存储旋转并用它们计算。矩阵或四元数是最自然的(至少对计算机而言,如果不是对我们人类而言,但无论如何我们不想用它们计算)。
    【解决方案2】:

    我不知道其他人通常是怎么做的,但我一般只是存储角度,然后在必要时重建一个矩阵。

    你是对的,如果你有一个矩阵并不断在上面乘以一些东西,你最终会把事情搞砸。但同样,我不认为这是你可能想要采取的路线。

    我不知道您想使用哪种图形系统,但是使用 OpenGL,您甚至不必担心矩阵表示(除非您正在做一些对性能非常关键的事情),并且可以只需使用一些调用 glRotate 等。

    【讨论】:

    • 感谢您的回复!这实际上是我选择采用的方法(存储角度并在需要时构建矩阵)。我之所以选择 Crashworks 的答案是因为建议的替代方法,但我仍然非常感谢您的回答 :)
    猜你喜欢
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    相关资源
    最近更新 更多