如何匹配另一个物体的旋转增量?
How to match another object's rotation delta?
我试图让一个对象与另一个对象的旋转增量相匹配。因此,如果对象 A 绕 Y 轴旋转 90 度,我希望对象 B 也绕 Y 轴旋转 90 度。因为我想每一帧都这样做,所以我保存了两个对象的初始旋转。我试着这样做,基于这个 forum post:
objectB.transform.localRotation = (initialObjectARotation * Quaternion.Inverse(objectA.transform.localRotation)) * initialObjectBRotation;
问题是现在旋转是相反的(我不确定这是不是正确的术语,但是如果我向右旋转 objectA
然后 objectB
向左旋转等等)。我该如何解决这个问题?
如果你有上一帧的B(匹配对象)和A(被匹配的目标)的绝对旋转和A的新绝对旋转,你可以求解B的新绝对旋转解释每个对象沿 局部轴 的 A 差异:
Quaternion oldB; // previous global rotation of subject
Quaternion oldA; // previous global rotation of target
Quaternion newA = transformA.rotation; // current global rotation of target
// solve for new global rotation of subject
Quaternion newB = oldB * Quaternion.Inverse(oldA) * newA;
如果这给了你不喜欢的结果,你可以尝试解释沿全局轴的差异:
// solve for new global rotation of subject
Quaternion newB = newA * Quaternion.Inverse(oldA) * oldB;
最后,如果你真的想要它相对于每个对象父对象的轴,它会有点复杂,因为它涉及以前的父旋转(绝对),以前的局部对象的旋转,以及 A 的当前绝对旋转为您提供 B 的当前绝对旋转。:
Quaternion oldBParent; // previous global rotation of subject's parent
Quaternion oldBLocal; // previous local rotation of subject
Quaternion oldAParent; // previous global rotation of target's parent
Quaternion oldALocal; // previous local rotation of target
// solve for new global rotation of subject
Quaternion newB = oldBParent * Quaternion.Inverse(oldAParent) * newA
* Quaternion.Inverse(oldALocal) * oldBLocal;
请注意,如果没有父级,则父级旋转为Quaternion.identity
,相当于全局轴形式。整洁!
当然,一旦您拥有 newB
,您只需应用 transformB.rotation = newB;
的新旋转。
我试图让一个对象与另一个对象的旋转增量相匹配。因此,如果对象 A 绕 Y 轴旋转 90 度,我希望对象 B 也绕 Y 轴旋转 90 度。因为我想每一帧都这样做,所以我保存了两个对象的初始旋转。我试着这样做,基于这个 forum post:
objectB.transform.localRotation = (initialObjectARotation * Quaternion.Inverse(objectA.transform.localRotation)) * initialObjectBRotation;
问题是现在旋转是相反的(我不确定这是不是正确的术语,但是如果我向右旋转 objectA
然后 objectB
向左旋转等等)。我该如何解决这个问题?
如果你有上一帧的B(匹配对象)和A(被匹配的目标)的绝对旋转和A的新绝对旋转,你可以求解B的新绝对旋转解释每个对象沿 局部轴 的 A 差异:
Quaternion oldB; // previous global rotation of subject
Quaternion oldA; // previous global rotation of target
Quaternion newA = transformA.rotation; // current global rotation of target
// solve for new global rotation of subject
Quaternion newB = oldB * Quaternion.Inverse(oldA) * newA;
如果这给了你不喜欢的结果,你可以尝试解释沿全局轴的差异:
// solve for new global rotation of subject
Quaternion newB = newA * Quaternion.Inverse(oldA) * oldB;
最后,如果你真的想要它相对于每个对象父对象的轴,它会有点复杂,因为它涉及以前的父旋转(绝对),以前的局部对象的旋转,以及 A 的当前绝对旋转为您提供 B 的当前绝对旋转。:
Quaternion oldBParent; // previous global rotation of subject's parent
Quaternion oldBLocal; // previous local rotation of subject
Quaternion oldAParent; // previous global rotation of target's parent
Quaternion oldALocal; // previous local rotation of target
// solve for new global rotation of subject
Quaternion newB = oldBParent * Quaternion.Inverse(oldAParent) * newA
* Quaternion.Inverse(oldALocal) * oldBLocal;
请注意,如果没有父级,则父级旋转为Quaternion.identity
,相当于全局轴形式。整洁!
当然,一旦您拥有 newB
,您只需应用 transformB.rotation = newB;
的新旋转。