我试图以相同的量旋转两个四元数(使用相同的四元数)。我有一个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)
应该是平等的。 Quaternion不是仅产生相同的结果,而是非常快速地(在半秒内)迭代地接近(0,0,0,0)四元数。如果我还用11f替换RotateTowards函数(0.5f)的第三个参数,那么我的四元数变为(NaN,NaN,NaN,NaN)。
我现在在这个问题上工作了好几个小时,找不到这个问题的原因,更不用说解决方案:(
答案 0 :(得分:2)
我终于解决了这个问题!!
显然,Unity对四元数有精确的问题 首先,我制作的Quaternion == Quaternion比较并不是非常安全,只是近似(他们甚至在文档中写了它!)。所以我发现两者在一个非常微不足道的数字上实际上是不同的。我猜Unity并没有正确地规范化四元数。
最后,使用
Quaternion.Euler((absRotationChain[0] * modX).eulerAngles)
被证明是一个不错的解决方法 - .-'
编辑:哦,看,知道这是一个规范化问题,这给我带来了同样问题的人的链接:https://gamedev.stackexchange.com/questions/74437/unity-quaternion-rotate-unrotate-error