16

所以我编写了一个面向新程序员的基于四元数的 3D 相机,因此他们非常容易集成和开始使用。

在我开发它时,起初我会将用户输入作为欧拉角,然后根据该帧的输入生成一个四元数。然后,我将获取相机的四元数并将其乘以我们为输入生成的四元数,理论上这应该只是将输入旋转添加到相机旋转的当前状态,然后一切都会变得又胖又快乐。让我们称之为:累积四元数,因为我们只存储和添加四元数。

但我注意到这种方法存在问题。我使用它的次数越多,即使我只在一个欧拉角上旋转,比如 Yaw,它也会在一些迭代中开始流血到另一个,比如 Pitch。这是轻微的,但相当不可接受。

所以我做了更多的研究,发现一篇文章说累积欧拉角更好,所以相机将它的当前旋转存储为欧拉角,并且输入只是在每一帧添加到它们。然后我每帧从它们生成一个四元数,然后用来生成我的旋转矩阵。这解决了旋转渗入不当轴的问题。

那么有任何 Stackoverflow 成员对这个问题有任何见解吗?这是一种正确的做事方式吗?

4

3 回答 3

13

乘以四元数将遭受浮点舍入问题的累积(即使是像 45 度这样的简单角度也不准确)。这是一种复合旋转的好方法,但是每个四元数组件的精度都会随着时间的推移而下降。渗透是一个副作用,视觉上更糟糕的是你的四元数可以开始合并一个比例因子 - 为了恢复它,你必须在任何情况下重新归一化回欧拉角。定点欧拉角不会累积舍入。

每帧重新计算四元数是最少的。我不会费心去优化它。在重新归一化以恢复准确性之前,您可能允许积累一些四元数,但这确实不值得付出努力。

于 2008-11-25T23:26:57.403 回答
4

积累是一个不精确的过程。无论您使用四元数还是矩阵,累积大量增量旋转都会累积舍入误差。

我想象这样的事情:你的代码启动并运行,但注意到在一定量的导航之后,你的相机令人讨厌地倾斜——违反了你事先没有想到的不变量。实际上,您已经意识到您不想累积轮换;相反,您想做其他事情。

您可以将其视为界面设计问题,而不是数值准确性问题。基本上,人们期望相机根据俯仰、偏航和滚动进行导航,因此选择直接控制和表示角度可以避免很多问题。

令人遗憾的是,四元数似乎变得多余(至少对于这种特殊用法)。不过,您仍然需要四元数 - 用原始俯仰/偏航/滚动角度进行插值可能很难看。同样,这是一个界面设计问题:你需要弄清楚你需要四元数的地方,以及如何让它们进出……

于 2008-11-26T00:11:31.620 回答
1

我见过两者都在争论。我认为您必须处理的真正问题是相机系统的灵活性。IMO 偏航通常在第三人称视角中更有趣(因为您将围绕角色的垂直轴旋转)。虽然您也可以在第一人称视角中围绕垂直方向“偏航”,但我不确定这是否真的是一回事。

但是,我确实认为重新计算每帧的四元数有点浪费。如果您的框架接收到输入,存储最新的四元数并将它们标记为脏可能会更好?

于 2008-11-25T23:19:21.617 回答