基于四元数的3D相机是否应该累积四元数或欧拉角?

时间:2008-11-25 22:57:10

标签: math 3d quaternions euler-angles

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

在我开发它时,我首先将用户输入作为欧拉角,然后根据该帧的输入生成一个四元数。然后,我将拍摄相机的四元数并将其乘以我们为输入生成的四元数,理论上应该简单地将输入旋转添加到相机旋转的当前状态,事情就会变得既肥胖又快乐。让我们称之为:积累四元数,因为我们只存储和添加四元数。

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

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

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

3 个答案:

答案 0 :(得分:13)

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

重新计算每帧的四元数是最小的。我不打算尝试优化它。在重新规范化之前,你可能会允许几个四元数累积以恢复精度,但它确实不值得努力。

答案 1 :(得分:4)

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

我想象这样的事情:你的代码已经启动并运行了,但是注意到经过一定程度的导航后你的相机已经过度烦恼了 - 违反了你事先未想到的不变量。实际上,你已经意识到你不希望积累轮换;相反,你想做别的事。

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

这里令人沮丧的是,quaterions似乎已经变得多余(至少对于这种特殊用途)。但是你仍然想要四元数 - 用原始俯仰/偏航/滚动角度进行插值可能很难看。同样,这是一个界面设计问题:你需要弄清楚你需要四元数的位置,以及如何让它们进出......

答案 2 :(得分:1)

我见过两个人都认为。我认为你需要处理的真正问题是你的相机系统的灵活性;在第三人称视角中,IMO偏航通常更有趣(因为你将围绕角色的垂直轴旋转)。虽然你可以说在第一人称视角中围绕垂直方向“偏航”,但我不确定它是否真的是一样的。

但是,我确实认为重新计算每帧的四元数是一种浪费。也许最好存储最新的四元数并在框架收到输入时将它们标记为脏?