- Home /
Some Issue With Quaternions Short Way
Hello!
Actually i'm using one script that i found here to "force" my lerp function to go in the right way... but sometimes it won't work it will take the shortest way also if i set the bool as false.. i'm missing something? there is a better way to do it without using the midpoint way? anyone have some resources where i can study on?
public static class QuaternionExtension
{
public static Quaternion Lerp(Quaternion p, Quaternion q, float t, bool shortWay)
{
if (shortWay)
{
float dot = Quaternion.Dot(p, q);
if (dot < 0.0f)
return Lerp(ScalarMultiply(p, -1.0f), q, t, true);
}
Quaternion r = Quaternion.identity;
r.x = p.x * (1f - t) + q.x * (t);
r.y = p.y * (1f - t) + q.y * (t);
r.z = p.z * (1f - t) + q.z * (t);
r.w = p.w * (1f - t) + q.w * (t);
return r;
}
public static Quaternion Slerp(Quaternion p, Quaternion q, float t, bool shortWay)
{
float dot = Quaternion.Dot(p, q);
if (shortWay)
{
if (dot < 0.0f)
return Slerp(ScalarMultiply(p, -1.0f), q, t, true);
}
float angle = Mathf.Acos(dot);
Quaternion first = ScalarMultiply(p, Mathf.Sin((1f - t) * angle));
Quaternion second = ScalarMultiply(q, Mathf.Sin((t) * angle));
float division = 1f / Mathf.Sin(angle);
return ScalarMultiply(Add(first, second), division);
}
public static Quaternion ScalarMultiply(Quaternion input, float scalar)
{
return new Quaternion(input.x * scalar, input.y * scalar, input.z * scalar, input.w * scalar);
}
public static Quaternion Add(Quaternion p, Quaternion q)
{
return new Quaternion(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w);
}
}
Not quite sure what you're asking... Could you elaborate? Also, the Scalar$$anonymous$$ultiply
thing is striking me as a bit odd. "Proper" Quaternions are normalized... That is, x^2+y^2+z^2+w^2 = 1. $$anonymous$$ultiplying every element is a little strange. Remember that, in a quaternion, refers to an axis, and w refers to rotation around that axis. So, multiplying everything by some scalar would result in the same axis, but the rotation around that axis, W, would be shifted. And, because there are theoretically infinite non-unit quaternions that can refer to the same orientation, that shift in W might not correspond to a shift in rotation that you would expect. This is why Unity (and math in general) likes to use normalized quaternions.
Further, not only do certain builtin quaternion functions normalize for you, but every use of a quaternion in a transform will also auto-normalize it. $$anonymous$$eeping your quaternions normalized is the best way to make the math make sense.
Finally, I'm incredibly confused by what you're defining as "Right way" and "Short way". If by short way you mean the shortest arc between two orientations, then that's pretty much the only arc that's gonna make any sense. There are an infinite number of longer arcs, and if you have some definition of 'longest arc', remember that Quaternions are a rotation in 3D space, so your 'longest arc' is almost certainly NOT what you'd want.