Game Math: Quaternion Basics

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:

    \[ q = w + xi + yj + zk,  \]

where w is the real part, (i, j, k) denotes the three imaginary axes, and (x, y, z) denotes the three imaginary components.

For brevity, I will use the notation below to represent a quaternion:

    \[ q = [w, \overrightarrow{v}], where \overrightarrow{v} = (x, y, z). \]

The Fundamental Formula for Quaternions

Below is the fundamental formula that governs the arithmetics of quaternions:

    \[ i^2 = j^2 = k^2 = ijk = -1 \]

With this formula, we can derive the following identities:

     \begin{flalign*}   ij &= k \\   jk &= i \\   ki &= j \\   ji &= -k \\   kj &= -i \\   ik &= -j \\ \end{flalign*}

Thus, if we expand the product of two quaternions, we will arrive at the quaternion multiplication formula:

     \begin{flalign*}   q_1 q_2 &= (w_1 + x_1 i + y_1 j + z_1 k) (w_2 + x_2 i + y_2 j + z_2 k) \\           &= [w_1, \overrightarrow{v_1}] [w_2, \overrightarrow{v_2}] \\           &= [(w_1 w_2 - \overrightarrow{v_1} \cdot \overrightarrow{v_2}), \, (w_1 \overrightarrow{v_2} + w_2 \overrightarrow{v_1} + \overrightarrow{v_1} \times \overrightarrow{v2})] \\ \end{flalign*}

Note that quaternion multiplication is associative:

    \[ q_1 q_2 q_3 = (q_1 q_2) q_3 = q_1 (q_2 q_3) \]

but generally not commutative:

    \[ q_1 q_2 \neq q_2 q_1 \]

Adding and subtracting two quaternions are just like adding and subtracting two 4D vectors:

    \[ q_1 \pm q_2 = [w_1 \pm w_2, \overrightarrow{v_1} \pm \overrightarrow{v_2}] \]

Multiplying a quaternion by a scalar is as simple as multiplying individual component by the scalar:

    \[ c q = [ c w, c \overrightarrow{v}] \]

The dot product of two quaternions is the sum of products of corresponding components:

    \[ q_1 \cdot q_2 = w_1 w_2 + x_1 x_2 + y_1 y_2 + z_1 z_2 \]

Unit Quaternions

The length of a quaternion is calculated as follows:

    \[ |[w, \overrightarrow{v}]| = \sqrt{w^2 + x^2 + y^2 + z^2} \]

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.

Quaternion Inverses

For a quaternion q, its multiplicative inverse (or inverse for short) is denoted q^{-1} and satisfies the property below:

    \[ q q^{-1} = q^{-1} q = 1 \]

If the quaternion q = [w, \overrightarrow{v}] is a unit quaternion, then its inverse is just its conjugate:

    \[ q^{-1} = \overline{q} = [w, -\overrightarrow{v}] \]

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.

3D Orientations

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 \overrightarrow{n} and an angle \theta, the corresponding unit quaternion is:

    \[ q = [cos\frac{\theta}{2}, \overrightarrow{n} sin\frac{\theta}{2}] \]

When we have a 3D vector \overrightarrow{r} and would like to rotate it by the orientation represented by a quaternion q, we simply have to perform two quaternion multiplications:

    \[ [0, \overrightarrow{r}'] = q [0, \overrightarrow{r}] q^{-1},  \]

where \overrightarrow{r}' is the rotated vector.

Slerp

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 q_1 to another quaternion q_2 using an interpolation parameter t:

    \[ Slerp(q_1, q_2, t) = \frac{sin((1 - t)\Omega)}{sin\Omega}q_1 + \frac{sin(t\Omega)}{sin\Omega}q_2, \, 0 \le t \le 1,  \]

where \Omega is the “angle” between the two unit quaternions:

    \[ \Omega = cos^{-1}(q_1 \cdot q_2) \]

One nice thing about slerp is the linearity of interpolation with respect to the parameter t. If t = 0.5, then the slerp result is a quaternion that represents an orientation exactly 50% between the two quaternions. If t 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”.

About Allen Chou

Physics / Graphics / Procedural Animation / Visuals
This entry was posted in Gamedev, Math. Bookmark the permalink.

One Response to Game Math: Quaternion Basics

  1. Nice blog as always, I feeling lost at quaternion multiplication formula dot and cross product, my math completely rusted. 🙂

Leave a Reply