首页 > 解决方案 > 将 x86 四元数组装到欧拉角输出错误的顺序

问题描述

我在将四元数转换为欧拉角时遇到了一些麻烦。

我遵循了在维基百科上找到的这个 C++ 代码,我认为我在汇编中复制它做得很好,问题是我的代码将 WXYZ 值转换为 ZYX 而不是 XYZ 顺序。

C++ 代码:https ://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Source_Code_2

(提供的 asm 代码只计算 Roll 轴)

//ROLL
finit
fld dword ptr [WRot]
fld dword ptr [ZRot]
fmulp st(1),st(0)
fld dword ptr [XRot]
fld dword ptr [YRot]
fmulp st(1),st(0)
faddp st(1),st(0)
mov dword ptr [Math],40000000 //2
fld dword ptr [Math]
fxch
fmulp st(1),st(0)
fstp dword ptr [sinr_cosp] //sinr_cosp

finit
fld dword ptr [YRot]
fld dword ptr [YRot]
fmulp st(1),st(0)
fld dword ptr [ZRot]
fld dword ptr [ZRot]
fmulp st(1),st(0)
faddp st(1),st(0)
mov dword ptr [Math],40000000 //2
fld dword ptr [Math]
fxch
fmulp st(1),st(0)
mov dword ptr [Math],3F800000 //1
fld dword ptr [Math]
fxch
fsubp st(1),st(0)
fstp dword ptr [cosr_cosp] //cosr_cosp

finit
fld dword ptr [sinr_cosp]
fld dword ptr [cosr_cosp]
fpatan
mov dword ptr [Math],42652EE1 //57.29577951308232
fld dword ptr [Math]
fxch
fmulp st(1),st(0)
fstp dword ptr [Roll] //Roll value

使用https://quaternions.online/我设置了如下值:

w:  0.549
x:  0.747
y:  0.092
z:  0.363

应用时,它应该输出的 XYZ 订单:

x:  100.000
y:  40.000
z:  20.000

But my code produces:

x:  98.527
y: -26.213
z:  36.644

我怎么能解决这个问题?我在哪里可以找到合适的 C++ 代码作为将 Quat 转换为 XYZ 的参考?

我不认为这是内存分配的问题,每个浮点值彼此相距 8 字节。

我还发现了这个有趣的回复https://stackoverflow.com/a/27496984/13741865,它显示了不同的可能情况,但对我来说理解起来有点复杂,因为它没有评论,我很想知道哪个公式应用于哪个旋转(对于 XYZ 情况)。

我仍处于组装的早期开发阶段,我可能对术语没有足够的了解。

我希望我已经添加了所有可能的细节,我提前感谢您的关注。

标签: assemblyx86quaternionseuler-anglesx87

解决方案


问题出在公式本身,维基百科中提供的源代码是为 ZYX 订单制作的(上面的代码有注释,我没有注意到)。

我所做的是花时间阅读此处提供的答案https://stackoverflow.com/a/27496984/13741865,分析代码并修复我所做的那个。

这给出了正确的输出

finit
fld dword ptr [WRot]
fld dword ptr [WRot]
fmulp
fld dword ptr [XRot]
fld dword ptr [XRot]
fmulp
faddp
fld dword ptr [YRot]
fld dword ptr [YRot]
fmulp
fsubp
fld dword ptr [ZRot]
fld dword ptr [ZRot]
fmulp
fsubp
fld dword ptr [XRot]
fld dword ptr [YRot]
fmulp
fld dword ptr [WRot]
fld dword ptr [ZRot]
fmulp
fsubp
mov dword ptr [Math],0 //hex of 0
fld dword ptr [Math]
mov dword ptr [Math],40000000 //hex of 2
fld dword ptr [Math]
fsubp
fxch
fmulp
fxch
fpatan
mov dword ptr [Math],42652ee1 //hex of 57.29577951308232
fld dword ptr [Math]
fxch
fmulp
fstp dword [Roll] //Roll value

感谢大家


推荐阅读