四元数 3 轴旋转

Posted

技术标签:

【中文标题】四元数 3 轴旋转【英文标题】:Quaternion 3 axis rotation 【发布时间】:2013-03-16 01:47:15 【问题描述】:

这里有点帮助。我从硬件陀螺仪接收每个轴 1 次旋转,因此总共 3 个轴(x,y,z)旋转 3 次。当我使用基于矩阵的旋转时,我得到奇怪的旋转可能是因为乘法顺序 (RotX*RotY*RotZ RotY*RotX*RotZ),我也尝试过 MatrixYawPitchRoll,但出现了相同的效果。因此,我得出结论,我应该使用四元数,但我认为我必须创建 3 个四元数,每次旋转一个,但是当我将它们与乘法相结合时,我会得到与基于矩阵的旋转相同的效果......所以有人可以告诉我如何正确使用 3 次旋转来创建和组合四元数,而不会出现之前的乘法效果?

附: D3DXQuaternionRotationYawPitchRoll 仍然遭受与基于矩阵的旋转相同的效果。

【问题讨论】:

您遇到的问题称为Gimbal lock。链接的***页面详细介绍了如何使用四元数解决它(我想有问题的 DX 函数首先将它们转换为矩阵,这使四元数的属性无效)。 感谢 didierc 的评论,我已经使用了这些转换......据我的理解,我认为 D3DX 就绪功能只是这些的包装...... @ribben:你说的这些“乘法效应”是什么? 当我使用矩阵并执行 RotZRotYRotX 当我按此顺序旋转陀螺仪 X->Y->Z 时,一切似乎都很好......但是陀螺仪必须能够以任何顺序进行评分,所以我得到奇怪的旋转...... @ribben:陀螺仪无法锁定万向节。它也不能改变轮换的顺序。或者如果可以,那么它是一个编码不佳的陀螺仪。当它改变旋转顺序时,它至少会告诉你吗? 【参考方案1】:

四元数并不是一种可以消除旋转问题的神奇药膏。所有四元数都是表示特定方向和进行方向变换的廉价方式。

您的问题是您没有将您的方向表示为四元数;您将其表示为 3 个角度。正是这种表示导致了你的轮换问题。

您需要停止使用角度。将对象的方向表示为 四元数。如果要调整方向,请从调整角度/轴创建一个四元数,然后将其乘以对象的方向。重新规范化四元数,你就完成了。

【讨论】:

请给我一个你认为背后的逻辑......我有 3 个轮换,例如第 1 步:从轴第 2 步创建四元数:....... @user1070700:您的问题第1步。实际上,您的问题是第0步。您确实没有 3转;你有一个方向。只要你认为你的方向是“3 次旋转”,你就会继续遇到这个问题。 好的,我思想开放,全神贯注...但是第 0 步是陀螺仪正在向我发送 3 次旋转...告诉我如何管理它们以使用四元数进行正确的旋转跨度> @ribben:您的问题似乎没有很明确地指定。一个硬件,一个陀螺仪,正在向你发送这些数据。 order 问题是您进行轮换的原因吗?硬件没有告诉您执行它们的顺序吗?您是稍后调整角度,还是这个陀螺仪每帧都向您发送数据? 有一个硬件陀螺仪,通过串口和微处理器,我得到三个径向速度(度/秒),然后通过积分以 60Hz 的采样率将这些值转换为角度(度)。这里的问题是陀螺仪可能在 y 轴上旋转 180 度,然后仅在 z 或 x 处旋转,并且导致矩阵相乘(我的第一种方法)这不会显示正确的旋转。这就是为什么我想使用四元数来摆脱乘法和万向节锁定......再次感谢您的帮助!【参考方案2】:

我看到了 2 个主要问题来源。

    您从 Euler Angels 的转换已中断。 您使用了无效的欧拉角方案。存在 24 种欧拉天使方案 http://en.wikipedia.org/wiki/Euler_angles

简单的欧拉角方案是围绕轴 XYZ、ZYX、ZXZ 的旋转顺序 ...

所有到/从矩阵/四元数的转换都可以在源代码中找到 Ken Shoemake,1993 年的优秀文章。

http://tog.acm.org/resources/GraphicsGems/gemsiv/euler_angle/

【讨论】:

以上是关于四元数 3 轴旋转的主要内容,如果未能解决你的问题,请参考以下文章

在 1 轴上旋转四元数?

将四元数拆分为轴旋转

Unity基础:欧拉角、四元数

如何理解glm中四元数与向量相乘函数的写法

四元数旋转

如何在不使用 transform.Rotate 的情况下在其本地或世界轴上旋转带有第二个四元数的四元数?