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

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.