Search code examples
3drotation

What is the difference between a "unit" quaternion and an "identity" quaternion?


I have been using the guide at www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/ for learning OpenGL. This guide says that...

glm::quat q;

...creates an identity quaternion (no rotation).

Experimentation shows that q = [0, 0, 0, 0]. Using this as the parent orientation of the root bone causes none of the bones to rotate at all. They lose all rotation.

The guide says that...

A quaternion is a set of 4 numbers, [x y z w], which represents rotations the following way:

// RotationAngle is in radians

x = RotationAxis.x * sin(RotationAngle / 2)

y = RotationAxis.y * sin(RotationAngle / 2)

z = RotationAxis.z * sin(RotationAngle / 2)

w = cos(RotationAngle / 2)

... and ...

[0 0 0 1] (w=1) means that angle = 2*acos(1) = 0, so this is a unit quaternion, which makes no rotation at all.

I have been experimenting with a skeleton system where each bone inherits its parents' orientation before applying its own rotations on top of that.

If I use an "identity" quaternion as the "parent" orientation for the root bone, then none of the bones are rotated at all. If I use the "unit" rotation all is well.

When I set a bone's initial orientation to either the "identity" or "unit" quaternion it displays as I want to. However when I convert user entered Euler angles to an orientation I get a 180 degree rotation. The conversion I did was:

        glm::vec3 eulers(glm::radians(pose.lng_rotate),
                         glm::radians(pose.lat_rotate),
                         glm::radians(pose.att_rotate));

        pose.orientation = glm::quat(eulers);

Note: I use "lng", "lat", and "att" rotate here because by the time a bone has inherited a parent rotation the "x" axis is probably no longer the "x" axis any more.

The last weird thing I noticed was that I used glm::mat4_cast on each type of quaternion and then multiplied by an identity glm::vec4. The "identity" quaternion left the vector unrotated, but the "unit" quaternion caused the vector to invert (multiply by -1) the x and y components of the vector.

I want to understand quaternions better, especially with respect to their use in code.

Conceptually, how is a "unit" quaternion different to an "identity" quaternion?

Where should I use a "unit" quaternion and where should I use an "identity" quaternion?

Am I just being confused by a badly written guide?


Solution

  • A unit quaternion is NOT the same as an identity quaternion. A quaternion is just any number in 'quaternion space', like 3 + 2i - 7j + 6k.

    When we are using quaternions to calculate rotations we are always talking about unit quaternions and always have a length of 1, just like a unit vector. Multiplying unit quaternions is a very efficient way of calculating a rotation, but the length must stay the same, 1.

    An identity quaternion is a quaternion that doesn't change any quaternion it is multiplied with, thus 1 + 0i + 0j + 0k or 1. An identity quaternion is thus a unit quaternion with a rotation of nothing.