无法在 Unity3D 中创建相对四元数
Unable to create relative Quaternion in Unity3D
我正在尝试将两个四元数旋转相同的量(使用相同的四元数)。我有一个 absoluteRotation 和一个 relativeRotation(相对于它的父级),我想将 absoluteRotation 旋转到另一个 Transform 的 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,事实上,上面的代码从未打印出 "Unequal!"。但是,当我替换
时,这会发生变化
absRotationChain[0] = newAbsRotation
与
absRotationChain[0] = (absRotationChain[0] * modX)
这应该是相等的。四元数不是仅仅产生相同的结果,而是非常快速地(在半秒内)迭代地逼近 (0, 0, 0, 0) 四元数。如果我随后也将 RotateTowards 函数 (0.5f) 的第三个参数替换为 11f,那么我的四元数将变为 (NaN, NaN, NaN, NaN)。
我现在在这个问题上工作了几个小时,找不到这个问题的原因,更不用说解决方案了:(
我终于解决了这个问题!!
显然 Unity 存在四元数的精度问题。
首先,我所做的四元数 == 四元数比较并不是很安全,只是一个近似值(他们甚至在文档中写了它!)。所以我发现两者实际上在非常非常微不足道的数字上有所不同。我猜 Unity 没有正确规范化四元数。
最后,使用
Quaternion.Euler((absRotationChain[0] * modX).eulerAngles)
证明是一个不错的解决方法-.-'
编辑:哦,看,知道这是一个规范化问题让我从一个有同样问题的人那里 link 得到了这个:https://gamedev.stackexchange.com/questions/74437/unity-quaternion-rotate-unrotate-error
我正在尝试将两个四元数旋转相同的量(使用相同的四元数)。我有一个 absoluteRotation 和一个 relativeRotation(相对于它的父级),我想将 absoluteRotation 旋转到另一个 Transform 的 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,事实上,上面的代码从未打印出 "Unequal!"。但是,当我替换
时,这会发生变化absRotationChain[0] = newAbsRotation
与
absRotationChain[0] = (absRotationChain[0] * modX)
这应该是相等的。四元数不是仅仅产生相同的结果,而是非常快速地(在半秒内)迭代地逼近 (0, 0, 0, 0) 四元数。如果我随后也将 RotateTowards 函数 (0.5f) 的第三个参数替换为 11f,那么我的四元数将变为 (NaN, NaN, NaN, NaN)。
我现在在这个问题上工作了几个小时,找不到这个问题的原因,更不用说解决方案了:(
我终于解决了这个问题!!
显然 Unity 存在四元数的精度问题。
首先,我所做的四元数 == 四元数比较并不是很安全,只是一个近似值(他们甚至在文档中写了它!)。所以我发现两者实际上在非常非常微不足道的数字上有所不同。我猜 Unity 没有正确规范化四元数。
最后,使用
Quaternion.Euler((absRotationChain[0] * modX).eulerAngles)
证明是一个不错的解决方法-.-'
编辑:哦,看,知道这是一个规范化问题让我从一个有同样问题的人那里 link 得到了这个:https://gamedev.stackexchange.com/questions/74437/unity-quaternion-rotate-unrotate-error