加速和减速平滑地旋转四元数。 max/min 等价于四元数?
Rotating quaternion smoothly with acceleration and deceleration. Equivalent of max/min for quaternion?
我有线性加速和减速的代码。
var currentSpeed = velocity.translation.z;
var decelerationDistance = ((currentSpeed * currentSpeed) / movementSettings.acceleration) * 0.5f;
if (distanceFromTarget > decelerationDistance)
{
velocity.translation = float3(0f, 0f, min(currentSpeed + (movementSettings.acceleration * deltaTime), movementSettings.maxSpeed));
}
else
{
velocity.translation = float3(0f, 0f, max(currentSpeed - (movementSettings.acceleration * deltaTime), 0f));
}
假设物体已经指向目标,这会将物体以其加速度加速到其最大速度,然后将其减慢加速度,使其恰好停在目标上。
我希望将相同的行为应用于旋转(这是一个四元数)。即假设物体是静止的,平滑地旋转到目标旋转,服从加速度和最大旋转速度限制。
我已经开始将此代码转换为适用于四元数:
private static float Magnitude(Unity.Mathematics.quaternion quat)
{
return CalculateQuaternionDifference(Unity.Mathematics.quaternion.identity, quat);
}
private static float CalculateQuaternionDifference(Unity.Mathematics.quaternion a, Unity.Mathematics.quaternion b)
{
float dotProduct = dot(a, b);
return dotProduct > 0.99999f ? 0f : acos(min(abs(dotProduct), 1f)) * 2f;
}
...
var currentRotSpeed = Magnitude(velocity.rotation);
var rotDecelerationDistance = ((currentRotSpeed * currentRotSpeed) / movementSettings.acceleration) * 0.5f;
if (distance > rotDecelerationDistance)
{
velocity.rotation = slerp(Unity.Mathematics.quaternion.identity, mul(rotationDiff, velocity.rotation), movementSettings.acceleration);
}
else
{
velocity.rotation = slerp(Unity.Mathematics.quaternion.identity, mul(inverse(rotationDiff), velocity.rotation), movementSettings.acceleration);
}
我的问题是:
这不遵循任何最大转速限制或停止在 0。四元数的 min/max()
等价于什么?
一旦将四元数分解为 angle/axis 形式,就可以轻松完成一些更实用的限制四元数的方法,然后根据需要限制它们:
float angle;
Vector3 axis;
velocity.rotation.ToAngleAxis(out angle, out axis);
因此,如果您的旋转速度表示为四元数,并且您想限制其大小,您可以限制角度,然后转换回四元数:
// clamp rotational angle to be no more than 90 degrees
float maxRotSpeed = 90f;
// angle should only ever be non-negative but clamping negative shows intent
float clampedAngle = Mathf.Clamp(angle, -maxRotSpeed, maxRotSpeed);
Quaternion clampedRot = Quaternion.AngleAxis(clampedAngle, axis);
夹紧旋转的另一面是夹紧旋转轴。为此,您可以夹紧轴然后转换回来:
// clamp rotational axis to aligned with mainAxis within a certain angle
Vector mainAxis = Vector3.up;
float maxDeviation = 10f;
Vector3 deviationDirection = Vector3.Cross(mainAxis, axis);
float deviation = Vector3.SignedAngle(mainAxis, axis, deviationDirection);
float clampedDeviation = Mathf.Clamp(deviation, -maxDeviation, maxDeviation);
Vector3 clampedAxis = Quaternion.AngleAxis(clampedDeviation, deviationDirection) * mainAxis;
Quaternion clampedRot = Quaternion.AngleAxis(angle, clampedAxis);
我有线性加速和减速的代码。
var currentSpeed = velocity.translation.z;
var decelerationDistance = ((currentSpeed * currentSpeed) / movementSettings.acceleration) * 0.5f;
if (distanceFromTarget > decelerationDistance)
{
velocity.translation = float3(0f, 0f, min(currentSpeed + (movementSettings.acceleration * deltaTime), movementSettings.maxSpeed));
}
else
{
velocity.translation = float3(0f, 0f, max(currentSpeed - (movementSettings.acceleration * deltaTime), 0f));
}
假设物体已经指向目标,这会将物体以其加速度加速到其最大速度,然后将其减慢加速度,使其恰好停在目标上。
我希望将相同的行为应用于旋转(这是一个四元数)。即假设物体是静止的,平滑地旋转到目标旋转,服从加速度和最大旋转速度限制。
我已经开始将此代码转换为适用于四元数:
private static float Magnitude(Unity.Mathematics.quaternion quat)
{
return CalculateQuaternionDifference(Unity.Mathematics.quaternion.identity, quat);
}
private static float CalculateQuaternionDifference(Unity.Mathematics.quaternion a, Unity.Mathematics.quaternion b)
{
float dotProduct = dot(a, b);
return dotProduct > 0.99999f ? 0f : acos(min(abs(dotProduct), 1f)) * 2f;
}
...
var currentRotSpeed = Magnitude(velocity.rotation);
var rotDecelerationDistance = ((currentRotSpeed * currentRotSpeed) / movementSettings.acceleration) * 0.5f;
if (distance > rotDecelerationDistance)
{
velocity.rotation = slerp(Unity.Mathematics.quaternion.identity, mul(rotationDiff, velocity.rotation), movementSettings.acceleration);
}
else
{
velocity.rotation = slerp(Unity.Mathematics.quaternion.identity, mul(inverse(rotationDiff), velocity.rotation), movementSettings.acceleration);
}
我的问题是:
这不遵循任何最大转速限制或停止在 0。四元数的 min/max()
等价于什么?
一旦将四元数分解为 angle/axis 形式,就可以轻松完成一些更实用的限制四元数的方法,然后根据需要限制它们:
float angle;
Vector3 axis;
velocity.rotation.ToAngleAxis(out angle, out axis);
因此,如果您的旋转速度表示为四元数,并且您想限制其大小,您可以限制角度,然后转换回四元数:
// clamp rotational angle to be no more than 90 degrees
float maxRotSpeed = 90f;
// angle should only ever be non-negative but clamping negative shows intent
float clampedAngle = Mathf.Clamp(angle, -maxRotSpeed, maxRotSpeed);
Quaternion clampedRot = Quaternion.AngleAxis(clampedAngle, axis);
夹紧旋转的另一面是夹紧旋转轴。为此,您可以夹紧轴然后转换回来:
// clamp rotational axis to aligned with mainAxis within a certain angle
Vector mainAxis = Vector3.up;
float maxDeviation = 10f;
Vector3 deviationDirection = Vector3.Cross(mainAxis, axis);
float deviation = Vector3.SignedAngle(mainAxis, axis, deviationDirection);
float clampedDeviation = Mathf.Clamp(deviation, -maxDeviation, maxDeviation);
Vector3 clampedAxis = Quaternion.AngleAxis(clampedDeviation, deviationDirection) * mainAxis;
Quaternion clampedRot = Quaternion.AngleAxis(angle, clampedAxis);