5
\$\begingroup\$

Across my travels on the internet I have came across two different ways of integrating a scaled axis angular velocity into a quaternion.

The first way converts the angular velocity into an axis angle quaternion like so

Quaternion q = new Quaternion(vector.normalised(), vector.getLength());

Where the constructor looks like:

float sinHalfAngle = (float) Math.sin(angle / 2);
float cosHalfAngle = (float) Math.cos(angle / 2);

this.x = axis.x * sinHalfAngle;
this.y = axis.y * sinHalfAngle;
this.z = axis.z * sinHalfAngle;
this.w = cosHalfAngle;

And then multiplies the existing quaternion by that new quaternion

this.rotateSelf(q);

The second approach also converts the velocity into a quaternion, but uses a different method:

Quaternion change = Quaternion.mul(
    new Quaternion(x * 0.5f, y * 0.5f, z * 0.5f, 0),
    this
);

It then adds the quaternions together, scaled by delta T:

this.w += change.w * scale;
this.x += change.x * scale;
this.y += change.y * scale;
this.z += change.z * scale;

Both approaches produce a rotation, however the first approach rotates the object much faster than the second. I was wondering which is the 'more' correct way, or if they are just different methods used for different units perhaps? (ie: degrees vs radians?)

Thanks very much if you can help.

\$\endgroup\$
  • \$\begingroup\$ “Both approaches produce a rotation” really? The second method does not produce a unit quaternion in general, but since you say it’s from a reputable source there must be a lot of missing information in your question. \$\endgroup\$ – sam hocevar Jul 7 '15 at 5:14
  • \$\begingroup\$ What is the method "Quaternion.mul" doing, exactly? \$\endgroup\$ – Pieter Geerkens Apr 4 '16 at 0:08
1
\$\begingroup\$

When Microsoft created the XNA framework (I know you're using Java, but the math is the same), they created a built in method to create a Quaternion from an axis and angle. The method they used (and you can "reflect" their managed code to verify it, see below) is the same as your first snippet:

public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle)
{
    Quaternion quaternion;
    float num2 = angle * 0.5f;
    float num = (float) Math.Sin((double) num2);
    float num3 = (float) Math.Cos((double) num2);
    quaternion.X = axis.X * num;
    quaternion.Y = axis.Y * num;
    quaternion.Z = axis.Z * num;
    quaternion.W = num3;
    return quaternion;
}
\$\endgroup\$
  • \$\begingroup\$ Thanks for the verification, but I was fairly confident about the axis-angle to quaternion part of method 1, my doubts mostly came from the this.rotateSelf(q) part. \$\endgroup\$ – neon64 Apr 8 '15 at 2:26
  • \$\begingroup\$ Although now I think about it multiplying 2 quaternions gives a rotation of both of them so that should work. I think the real question now is why does the other method (which is arguably from a more reputable source [game physics book]) produces a different result. \$\endgroup\$ – neon64 Apr 8 '15 at 2:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.