【问题标题】:normalizing euler angles rotation vector归一化欧拉角旋转向量
【发布时间】:2019-07-18 07:28:52
【问题描述】:

我需要以对象特定轴的欧拉角显示旋转。 我知道以欧拉角检索对象的旋转会产生不一致的结果,其中一些可以通过简单地对结果使用模 360 来解决。然而,在分配具有“transform.localRotation.eulerAngles”值的向量时,unity 有时会进行的一种排列不是检索 Vector3“V”,而是检索“(180, 180, 180) - V”。 据我了解,“(180, 180, 180) - V” 不会导致与 V 相同的真实世界旋转,这与“(180, 180, 180) + V” 不同,它确实使实际旋转不受影响。 该现象的解释是什么,假设我知道其轴之一的期望值和可行值,标准化欧拉角旋转矢量的最佳方法是什么? (例如,对其进行规范化,使其所有值都是 mod 360 并且它的 Z 轴等于 0,假设它确实具有 Z = 0 的表示)

【问题讨论】:

  • “统一有时在......

标签: c# unity3d


【解决方案1】:

我不知道问题的第一部分(它的不同之处足以成为它自己的问题),但我可以回答你的第二部分。

所以,你有这些输入:

Quaternion desiredRotation;
float knownZ;

您正试图找到Vector3 eulers,其中eulers.z 大约是knownZQuaternion.Euler(eulers) == desiredRotation

这是我将使用的程序:


首先确定desiredRotation旋转的向上方向和knownZ滚动旋转的上下方向:

Vector3 upDirEnd = desiredRotation * Vector3.up;

Quaternion rollRotation = Quaternion.Euler(0,0,knownZ);
Vector3 upDirAfterRoll = rollRotation  * Vector3.up;
Vector3 rightDirAfterRoll = rollRotation * Vector3.right;

我们知道desiredRotation 应用后的局部向上方向,并且在滚动knownZ 应用后唯一可以调整向上方向的是欧拉螺距分量完成的旋转。所以,如果我们可以计算出从upDirAfterRollupDirEnd 的角度,是围绕rightDirAfterRoll 轴测量的......

float determinedX = Vector3.SignedAngle(upDirAfterRoll, upDirEnd, rightDirAfterRoll);
// Normalizing determinedX
determinedX = (determinedX + 360f) % 360f;

...我们可以确定eulers的x分量!

然后,我们对eulers的偏航分量做同样的事情,使新的前进方向与末端前进方向对齐:

Vector3 forwardDirEnd = desiredRotation * Vector3.forward;

Quaternion rollAndPitchRotation = Quaternion.Euler(determinedX, 0, knownZ);
Vector3 forwardDirAfterRollAndPitch = rollAndPitchRotation * Vector3.forward;
Vector3 upDirAfterRollAndPitch = upDirEnd; // unnecessary but here for clarity

float determinedY = Vector3.SignedAngle(forwardDirAfterRollAndPitch, forwardDirEnd, upDirAfterRollAndPitch );
// Normalizing determinedY
determinedY = (determinedY + 360f) % 360f;

Vector3 eulers = new Vector3(determinedX, determinedY, knownZ); 

为确保给定的四元数可以用给定的组件生成,您可以检查给定给SignedAngle 的轴是否实际上可以将输入向量旋转到目标向量,或者您可以只比较计算出的欧拉和给定的四元数:

Quaternion fromEuler = Quaternion.Euler(eulerAngles);

if (fromEuler==desiredRotation) 
{
    // use eulerAngles here
}
else 
{
    // component and quaternion incompatible 
}

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    我不太确定我是否正确理解了您的问题,但欧拉角仅表示以特定顺序围绕 3 轴应用的 3 次旋转的角度,对吧?那么为什么要通过在任何地方添加 180 来标准化它呢?您应该通过对它们进行取模将每个角度单独带入 0-360 范围内。

    您的问题似乎暗示您可以通过仅围绕两个轴而不是三个轴旋转来获得任何方向......这就是您想要实现的目标吗? 使用四元数可能会对您有所帮助,实际上可以使用 4 个标量值来定义方向:轴和角度

    【讨论】:

    • 不是我到处加 180。由于从四元数到欧拉角的映射不是单射的,Unity 可能会为同一个四元数给出不同的欧拉角向量,我正在寻找一种方法来克服这个问题。
    • 也许这有帮助? en.wikipedia.org/wiki/…
    猜你喜欢
    • 1970-01-01
    • 2011-02-25
    • 2015-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2021-01-01
    • 1970-01-01
    相关资源
    最近更新 更多