通过旋转另一个四元数来旋转一个四元数
Rotating one quaternion via the rotation of another
上下文
我正在使用混合现实和 Unity,并试图用我的双手控制游戏对象的 3d 旋转。
这是我目前的情况:
Vector3 _lefthand = new Vector3(Left.x, Left.y, Left.z);
Vector3 _righthand = new Vector3(Right.x, Right.y, Right.z);
_myObject.transform.rotation = Quaternion.FromToRotation(Vector3.right, _righthand - _lefthand));
该块包含在 IEnumerator
协程中,该协程在满足 Update
中的 if
语句时启动。 if
检查特定的手部姿势,因此当手部姿势处于活动状态时旋转 'starts',当手部姿势不活动时旋转 'stops'。
我有的对于一个小的旋转效果很好,但是如果我想旋转物体几次就会失败,因为 _myObject
的旋转刚好匹配当前创建的当前四元数 Vector3
我手的位置。
问题
我如何将 _myObject
从 当前旋转 旋转到新的旋转,我的手开始和结束位置之间的差异幅度?
在每帧开始时,缓存旋转和左手 -> 右手方向然后使用 Quat B * Quat A
在世界 space 中将 A 旋转 B 或使用 transform.Rotate
与 Space.World
.
IEnumerator DoRotate()
{
Vector3 previousLeftHand = new Vector3(Left.x, Left.y, Left.z);
Vector3 previousRightHand = new Vector3(Right.x, Right.y, Right.z);
Vector3 previousFromLeftToRight = previousRightHand - previousLeftHand;
while (!doneFlag)
{
yield return null;
Vector3 newLeftHand = new Vector3(Left.x, Left.y, Left.z);
Vector3 newRightHand = new Vector3(Right.x, Right.y, Right.z);
Vector3 newFromLeftToRight = newRightHand - newLeftHand;
Quaternion deltaRotationWorld = Quaternion.FromToRotation(
previousFromLeftToRight, newFromLeftToRight);
_myObject.transform.rotation = deltaRotationWorld * _myObject.transform.rotation;
// or _myObject.transform.Rotate(deltaRotationWorld, Space.World);
previousFromLeftToRight = newFromLeftToRight;
}
}
除了仅缓存起始旋转和起始手位置外,您可以使用此技术,但它通常会导致沿局部轴在手之间进行意外旋转。使用每帧增量可以最大限度地减少这种情况。
上下文
我正在使用混合现实和 Unity,并试图用我的双手控制游戏对象的 3d 旋转。
这是我目前的情况:
Vector3 _lefthand = new Vector3(Left.x, Left.y, Left.z);
Vector3 _righthand = new Vector3(Right.x, Right.y, Right.z);
_myObject.transform.rotation = Quaternion.FromToRotation(Vector3.right, _righthand - _lefthand));
该块包含在 IEnumerator
协程中,该协程在满足 Update
中的 if
语句时启动。 if
检查特定的手部姿势,因此当手部姿势处于活动状态时旋转 'starts',当手部姿势不活动时旋转 'stops'。
我有的对于一个小的旋转效果很好,但是如果我想旋转物体几次就会失败,因为 _myObject
的旋转刚好匹配当前创建的当前四元数 Vector3
我手的位置。
问题
我如何将 _myObject
从 当前旋转 旋转到新的旋转,我的手开始和结束位置之间的差异幅度?
在每帧开始时,缓存旋转和左手 -> 右手方向然后使用 Quat B * Quat A
在世界 space 中将 A 旋转 B 或使用 transform.Rotate
与 Space.World
.
IEnumerator DoRotate()
{
Vector3 previousLeftHand = new Vector3(Left.x, Left.y, Left.z);
Vector3 previousRightHand = new Vector3(Right.x, Right.y, Right.z);
Vector3 previousFromLeftToRight = previousRightHand - previousLeftHand;
while (!doneFlag)
{
yield return null;
Vector3 newLeftHand = new Vector3(Left.x, Left.y, Left.z);
Vector3 newRightHand = new Vector3(Right.x, Right.y, Right.z);
Vector3 newFromLeftToRight = newRightHand - newLeftHand;
Quaternion deltaRotationWorld = Quaternion.FromToRotation(
previousFromLeftToRight, newFromLeftToRight);
_myObject.transform.rotation = deltaRotationWorld * _myObject.transform.rotation;
// or _myObject.transform.Rotate(deltaRotationWorld, Space.World);
previousFromLeftToRight = newFromLeftToRight;
}
}
除了仅缓存起始旋转和起始手位置外,您可以使用此技术,但它通常会导致沿局部轴在手之间进行意外旋转。使用每帧增量可以最大限度地减少这种情况。