【问题标题】:Combine more than 3 rotations (Quaternions)组合超过 3 个旋转(四元数)
【发布时间】:2019-07-09 17:57:06
【问题描述】:

我有一个 3D 点和该点的 x,y,z 旋转 (qInitial)。 我想围绕 y 轴 (qYextra) 旋转那个点 more (从 0 到 360 度数)。 如何计算最终的欧拉旋转 (qResult.eulerAngles)这是这 4 个旋转 (x-y-z-y) 的组合

我已经尝试计算初始四元数旋转,以及要应用的额外旋转。然后将这两个四元数相乘。但是,我得到奇怪的结果(可能是万向节锁定)

C# 中的代码。团结。

1.Quaternion qX = Quaternion.AngleAxis(rotationFromBvh.x,Vector3.right);

2.Quaternion qY = Quaternion.AngleAxis(rotationFromBvh.y,Vector3.up);

3.Quaternion qZ = Quaternion.AngleAxis(rotationFromBvh.z,Vector3.forward);

4.Quaternion qYextra = Quaternion.AngleAxis(angle,Vector3.up);

Quaternion qInitial = qY * qX * qZ; // Yes. This is the correct order.

qY*qX*qZ 具有 完全相同的欧拉 x,y,z 结果 Quaternion.Euler(rotationFromBvh)

Quaternion qResult = qInitial * qYextra;

return qResult.eulerAngles;

我可以确认第 4 次旋转为 0 度qYextra = identity)时,代码工作正常(没有万向节锁定)。这意味着qInitial 是正确的。因此,错误可能是由于 这 2 个旋转的组合qInitialqYextra由于转换从四元数到欧拉。

示例:qYextra 角度为 120 度)

结果:

qInitial.eulerAngles 给出这些结果:applying_qInitial_rotation

qResult.eulerAngles 给出这些结果:applying_qResult_rotation

预期结果:

预期结果应该类似于qInitial,但围绕 y 旋转了 120 度。

有什么建议吗?我还没有找到解决方案,可能不会。

【问题讨论】:

  • 有什么建议吗?
  • 对我来说正确的顺序应该是“qResult = qYextra * qInitial”
  • 谢谢@MauricioCeleLopezBelon。我刚试了下,结果还是很奇怪(万向锁)。
  • 问题可能出在我将四元数转换为欧拉qResult.eulerAngles;?
  • 转换为欧拉角可能是问题所在。欧拉角创建具有环面拓扑的地图,四元数创建具有球体拓扑的地图(从 4d 线性空间投影)。从四元数到欧拉角的映射就像从 Sphere 到 Torus 的映射,它不是单射的(一对一)并且具有奇点(万向节锁定)。以下站点详细解释了奇点euclideanspace.com/maths/geometry/rotations/conversions/…我建议坚持使用四元数并避免转换为欧拉角。

标签: c# unity3d quaternions euler-angles


【解决方案1】:

在你的问题中,你写:

如何计算由这 4 个旋转 (x-y-z-y) 组合而成的最终欧拉旋转?

然而,在你的代码中,你写

Quaternion qInitial = qY * qX * qZ; // Multiply them in the correct order.

我不知道统一,但我希望您希望旋转的顺序匹配 x、y、z,而不是 y、x、z。

你说它在 y-rotation 为 0 时起作用,在这种情况下,y-rotation 在顺序中的位置变得无关紧要。

如果你改写下面的代码,你会得到正确的结果吗?

Quaternion qInitial = qX * qY * qZ; // Multiply them in the correct order.

【讨论】:

  • Unity 句柄的欧拉角,在处理四元数时,按照 Z、X、Y 的顺序,所以按 Y、X、Z 的顺序乘以 3 个四元数,然后请求结果的 eulerAngles 属性将与在单个 Vector3 中提供这些旋转作为 Quaternion.Euler 中的参数相同。
  • 这两行代码:Quaternion qInitial = qY * qX * qZ;Quaternion qAfter = qInitial * qRotationToBeApplied; 表明我想组合4个旋转。前 3 个初始旋转是 (qY, qX, qZ)。第 4 次旋转是 qRotationToBeApplied。谈到乘法的顺序将同意@Foggzie。另外,我要说的是,当(第 4 次旋转)qRotationToBeApplied 是身份(0 度旋转)时,代码可以正常工作。
  • 我已经编辑了我的问题,以避免任何歧义。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 2017-07-06
  • 1970-01-01
相关资源
最近更新 更多