C# 无法在Unity3D中创建相对四元数

C# 无法在Unity3D中创建相对四元数,c#,unity3d,rotation,quaternions,C#,Unity3d,Rotation,Quaternions,我尝试将两个四元数旋转相同的量(使用相同的四元数)。我有一个absoluteRotation和一个relativeRotation(相对于其父级),我想将absoluteRotation旋转到另一个变换的absoluteRotation,然后更改存储的相对位置以及存储的absoluteRotation以再次匹配: void LateUpdate() { Quaternion newAbsRotation = Quaternion.RotateTowards(absRotationChai

我尝试将两个四元数旋转相同的量(使用相同的四元数)。我有一个absoluteRotation和一个relativeRotation(相对于其父级),我想将absoluteRotation旋转到另一个变换的absoluteRotation,然后更改存储的相对位置以及存储的absoluteRotation以再次匹配:

void LateUpdate()
{
    Quaternion newAbsRotation = Quaternion.RotateTowards(absRotationChain[0], boneChain[0].rotation, 0.5f);
    Quaternion modX = Quaternion.Inverse(absRotationChain[0]) * newAbsRotation;
    if(newAbsRotation == (absRotationChain[0] * modX)) {
        Debug.Log("Equal!");
    } else {
        Debug.Log("Unequal!");
    }
    absRotationChain[0] = newAbsRotation;
    // absRotationChain[0] = (absRotationChain[0] * modX) // doesn't work
}
但是,我无法为两个绝对四元数之间的旋转创建相对四元数。我在多个源代码上读到,它应该是q'=q1-1*q2,事实上,上面的代码从来没有打印出“不等!”。但是,当我替换

absRotationChain[0] = newAbsRotation

这应该是平等的。四元数不是只产生相同的结果,而是以非常快的迭代方式(在半秒钟内)逼近(0,0,0,0)四元数。如果我还将RotateTowards函数的第三个参数(0.5f)替换为11f,那么我的四元数将变成(NaN,NaN,NaN,NaN)


我花了好几个小时来解决这个问题,但找不到问题的原因,更不用说解决方案了:(

我终于解决了这个问题

显然,四元数的精度存在统一性问题。
首先,我做的四元数==四元数比较不是很安全,只是一个近似值(他们甚至在文档中写了它!)。所以我发现两者实际上在一个非常不重要的数字上是不同的。我想Unity并没有正确地规范化四元数

最后,使用

Quaternion.Euler((absRotationChain[0] * modX).eulerAngles)
事实证明,这是一个不错的解决办法

编辑:哦,看,知道这是一个规范化问题,我从一个有同样问题的家伙那里得到了这个链接:

Quaternion.Euler((absRotationChain[0] * modX).eulerAngles)