This post is part of my Game Math Series.
A quaternion is a very useful mathematical object devised by Sir William Rowan Hamilton as an extension to complex numbers. It is often used to compactly represent 3D orientations with just four floating-point numbers, as opposed to using a 3-by-3 matrix that contains nine floating-point numbers, and it has other nice properties that I will talk about later.
As its name suggests, a quaternion is composed of four components, one in the real part, and the other three in the imaginary part. A quaternion is usually denoted as:
where is the real part, denotes the three imaginary axes, and denotes the three imaginary components.
For brevity, I will use the notation below to represent a quaternion:
The Fundamental Formula for Quaternions
Below is the fundamental formula that governs the arithmetics of quaternions:
With this formula, we can derive the following identities:
Thus, if we expand the product of two quaternions, we will arrive at the quaternion multiplication formula:
Note that quaternion multiplication is associative:
but generally not commutative:
Adding and subtracting two quaternions are just like adding and subtracting two 4D vectors:
Multiplying a quaternion by a scalar is as simple as multiplying individual component by the scalar:
The dot product of two quaternions is the sum of products of corresponding components:
The length of a quaternion is calculated as follows:
A unit quaternion has a length of one. The product of two unit quaternions is also a unit quaternion. To normalize a quaternion means dividing each quaternion component by the quaternion’s length.
For conveniences, game developers usually work with unit quaternions. After many multiplications, a quaternion can become non-normalized, so we sometimes need to re-normalize a quaternion to make sure it stays normalized. The approximation technique described in this post can be used to re-normalize an almost-normalized quaternion without using the square root function and floating-point division.
For a quaternion , its multiplicative inverse (or inverse for short) is denoted and satisfies the property below:
If the quaternion is a unit quaternion, then its inverse is just its conjugate:
Just like that, as easy as negating the imaginary part. This is one of the many reasons why game developers prefer working with unit quaternions. Otherwise, the inversion process would involve a floating-point division by the length of the quaternion.
Every orientation in 3D can be represented using the axis-angle representation, and there is a mapping between an axis-angle pair and a unit quaternion.
For an orientation represented by an axis and an angle , the corresponding unit quaternion is:
When we have a 3D vector and would like to rotate it by the orientation represented by a quaternion , we simply have to perform two quaternion multiplications:
where is the rotated vector.
Slerp (spherical linear interpolation) is a very important quaternion operation. It allows you to interpolate between two orientations along the “shortest path” if the two quaternions used are of the same length (another good reason to work with only unit quaternions). This is a non-trivial task if you represent 3D orientations using rotation matrices or Euler angles. Below is the formula for slerping from a quaternion to another quaternion using an interpolation parameter :
where is the “angle” between the two unit quaternions:
One nice thing about slerp is the linearity of interpolation with respect to the parameter . If , then the slerp result is a quaternion that represents an orientation exactly 50% between the two quaternions. If varies at a constant rate, then the orientation represented by the slerp result also varies at a constant angular velocity.
End of Quaternion Basics
That’s it. I have covered the basic operations for quaternions, how to represent a 3D orientation using a quaternion, how to rotate a point using quaternions, and a nice tool called “slerp” to interpolate between two 3D orientations along the “shortest path”.