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\$
2
  • \$\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\$ Commented Jul 7, 2015 at 5:14
  • \$\begingroup\$ What is the method "Quaternion.mul" doing, exactly? \$\endgroup\$ Commented Apr 4, 2016 at 0:08

1 Answer 1

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\$
2
  • \$\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
    Commented Apr 8, 2015 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
    Commented Apr 8, 2015 at 2:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .