Rotations & Quaternions
TL;DR
General rotation
A general rotation about a given angle \(\varphi\) around an arbitrary axis, defined by an unit vector \(r\), can be described by the quaternion \(q\) as
\(q = \cos \frac\varphi 2 + r_x \sin \frac\varphi 2 i + r_y \sin \frac\varphi 2 j + r_z \sin \frac\varphi 2 k = \begin{pmatrix} \cos \frac\varphi 2 \\ r_x \sin \frac\varphi 2 \\ r_y \sin \frac\varphi 2 \\ r_z \sin \frac\varphi 2 \end{pmatrix}\)
Alternatively, using a rotation vector \(\varphi\) with the length definining the angle and the direction defining the axis of rotation, the rotation can be described by the quaternion \(q\) as
\(q = \cos \frac{|\varphi|} 2 + \frac{\varphi_x}{|\varphi|} \sin \frac{|\varphi|} 2 i + \frac{\varphi_y}{|\varphi|} \sin \frac{|\varphi|} 2 j + \frac{\varphi_z}{|\varphi|} \sin \frac{|\varphi|} 2 k = \frac{1}{|\varphi|} \begin{pmatrix} |\varphi| \cos \frac\varphi 2 \\ \varphi_x \sin \frac\varphi 2 \\ \varphi_y \sin \frac\varphi 2 \\ \varphi_z \sin \frac\varphi 2 \end{pmatrix}\)
Applying a rotation
Given a quaternion \(q\) describing a rotation and a vector \(v\).
Writing a vector \(v\) as a quaterion \(p\)
\(p = v_x i + v_y j + v_z k = \begin{pmatrix} 0 \\ v_x \\ v_y \\ v_z \end{pmatrix}\)
The transformed quaterion is given as
\(R_q(p) = qpq^{-1}\)
Having \(q = a + bi + cj + dk\) this means
\(R_q(p) = (a + bi + cj + dk)(v_x i + v_y j + v_z k) (a - bi - cj - dk)\)
\(\phantom{R_q(p)} = (a + bi + cj + dk)(v_x i + v_y j + v_z k) (a - bi - cj - dk)\)
Rq(p)=qpq−1Rq(p)=qpq−1
You can verify that this for the general rotation quaternion \(q\) actually gives the same formula by calculation the application of the general rotation quaternion to an arbitrary vector:
\(R_q(p) = qpq^{-1}\)
\(\phantom{R_q(p)} = (\cos \frac\varphi 2 + r_x \sin \frac\varphi 2 i + r_y \sin \frac\varphi 2 j + r_z \sin \frac\varphi 2 k)(v_x i + v_y j + v_z k)(\cos \frac\varphi 2 - r_x \sin \frac\varphi 2 i - r_y \sin \frac\varphi 2 j - r_z \sin \frac\varphi 2 k)\)
There is another way to write the rotation matrices using the exponentiation of matrices:
\(\exp(\varphi\cdot G_x) = \exp\left(\varphi \begin{pmatrix} 0 & 0 & 0\\ 0 & 0 & -1\\ 0 & 1 & 0 \end{pmatrix}\right) = \begin{pmatrix} 1 & 0 & 0 \\ 0 & \cos(\varphi) & -\sin(\varphi) \\ 0 & \sin(\varphi) & \cos(\varphi) \end{pmatrix} = R_x(\varphi)\)
\(\exp(\varphi\cdot G_y) = \exp\left(\varphi \begin{pmatrix} 0 & 0 & 1\\ 0 & 0 & 0\\ -1 & 0 & 0 \end{pmatrix}\right) = \begin{pmatrix} \cos(\varphi) & 0 & \sin(\varphi) \\ 0 & 1 & 0 \\ -\sin(\varphi) & 0 & \cos(\varphi)\end{pmatrix} = R_x(\varphi)\)
\(\exp(\varphi\cdot G_z) = \exp\left(\varphi \begin{pmatrix} 0 & -1 & 0\\ 1 & 0 & 0\\ 0 & 0 & 0 \end{pmatrix}\right) = \begin{pmatrix} \cos(\varphi) & -\sin(\varphi) & 0\\ \sin(\varphi) & \cos(\varphi) & 0\\ 0 & 0 & 1 \end{pmatrix} = R_z(\varphi)\)
\(G_x\), \(G_y\) and \(G_z\) are called the generators for rotations around the \(x\), \(y\) and \(z\) axis, respectively.
\([G_x, G_y] = G_z \hspace{2cm} [G_y, G_z] = G_x \hspace{2cm} [G_z, G_x] = G_y\)
\([G_y, G_x] = -G_z \hspace{1.6cm} [G_z, G_y] = -G_x \hspace{1.6cm} [G_x, G_z] = -G_y\)
General rotation formula
There is also a general formula for arbitrary rotation about a given angle \(\varphi\) around an arbitrary axis, defined by an unit vector \(r\), Rodrigues’ rotation formula:
\(R_r(\varphi) = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} + \sin\varphi\begin{pmatrix} 0 & -r_z & r_y \\ r_z & 0 & -r_x \\ -r_y & r_x & 0 \end{pmatrix} + (1-\cos\varphi)\begin{pmatrix} -r_y^2-r_x^2 & r_x r_y & r_x r_z \\ r_x r_y & -r_x^2 -r_z^2 & r_y r_z \\ r_x r_z & r_y r_z & -r_x^2 - r_y^2 \end{pmatrix}\) \(\phantom{R_r(\varphi)} = \begin{pmatrix} 1 + (\cos\varphi-1)(r_y^2+r_z^2) & -\sin\varphi\cdot r_z & \sin\varphi\cdot r_y \\ \sin\varphi\cdot r_z & 1 + (\cos\varphi-1)(r_x^2+r_z^2) & -\sin\varphi\cdot r_x \\ -\sin\varphi\cdot r_y & \sin\varphi\cdot r_x & 1 + (\cos\varphi-1)(r_x^2+r_y^2) \end{pmatrix}\)
Quaternions
The quaternions consist of \(1\), \(i\), \(j\), \(k\) where \(i\), \(j\) and \(k\) behave like the imaginary unit:
\(i \cdot i = -1 \hspace{2cm} j \cdot j = -1 \hspace{2cm} k \cdot k = -1\)
Furthermore, their products are defined as:
\(i \cdot j = k \hspace{2.4cm} j \cdot k = i \hspace{2.4cm} k \cdot i = j\)
And also, they anti-commute, so:
\(j \cdot i = -k \hspace{2cm} k \cdot j = -i \hspace{2cm} i \cdot k = -j\)
Note, that the products of Quaternions behave a lot like the commutations of the generators of the rotations matrices. This is sort of a handwavy explanation of why quaternions are able to represent rotations at all.
Quaternion Examples
To see how quaternions work, lets define two quaternions \(q\) and \(r\):
\(q = 1 + 2i + 3j + 4k \hspace{1cm} r = 5i - 4k\)
We can add them:
\(q + r = 1 + 2i + 3j + 4k + 5i - 4k \\ \phantom{q + r} = 1 + (2+5)i + 3j + (4-4)k \\ \phantom{q + r} = 1 + 7i + 3j\)
We can multiply them:
\(q\cdot r = (1 + 2i + 3j + 4k)(5i - 4k) \\ \phantom{q\cdot r} = (5i - 4k) + 2(5i - 4k)i + 3(5i - 4k)j + 4(5i - 4k)k \\ \phantom{q\cdot r} = 5i - 4k + 10i^2 - 8 ki + 15 ij - 12 kj + 20 ik - 16 k^2 \\ \phantom{q\cdot r} = 5i - 4k - 10 - 8 j + 15 k + 12 i - 20 j + 16 \\ \phantom{q\cdot r} = (-10 + 16) + (5 + 12)i + (-8 - 20)j + (-4 + 15) k \\ \phantom{q\cdot r} = 6 + 17 i - 28j + 11 k \)
And that’s basically all we will ever need.
The absolute value of a quaternion \(q = a + bi + cj + dk\) is defined as
\(|q| = a^2 + b^2 + c^2 + d^2\)
Unit quaternions and inverse quaternions
Every rotation is equivalent to exactly one unit quaternion1 2 and only the unit quaternions represent rotations.
The helpful thing about unit quaterions is, that taking the inverse of a unit-quaternion is easy. With
\(q = a + bi + cj + dk\) and \(|q| = 1\)
we have
\(q^{-1} = a - bi - cj - dk\)
To prove it:
\(q^{-1}q = (a - bi - cj - dk)(a + bi + cj + dk)\)
\(\phantom{q^{-1}q} = (a^2 + abi + acj + adk - abi - b^2i^2 - bcij - bdik - acj - bcji - c^2 j^2 -cdjk -adk - bdki - cdkj - d^2 k^2)\)
\(\phantom{q^{-1}q} = (a^2 + abi + acj + adk - abi + b^2 - bck + bdj - acj + bck + c^2 -cdi - adk - bdj + cdi + d^2)\)
\(\phantom{q^{-1}q} = (a^2 + b^2 + c^2 + d^2) \)
\(\phantom{q^{-1}q} = |q| = 1\)
This can be verified in the same way for \(qq^{-1}\).
Actually using quaternions for rotation
Writing a vector \(v\) as a quaterion \(p\)
\(p = v_x i + v_y j + v_z k = \begin{pmatrix} 0 \\ v_x \\ v_y \\ v_z \end{pmatrix}\)
The transformed quaterion is given as
\(R_q(p) = qpq^{-1}\)
Having \(q = a + bi + cj + dk\)
General rotation
A general rotation about a given angle \(\varphi\) around an arbitrary axis, defined by an unit vector \(r\), can be described by the quaternion \(q\) as
\(q = \cos \frac\varphi 2 + r_x \sin \frac\varphi 2 i + r_y \sin \frac\varphi 2 j + r_z \sin \frac\varphi 2 k = \begin{pmatrix} \cos \frac\varphi 2 \\ r_x \sin \frac\varphi 2 \\ r_y \sin \frac\varphi 2 \\ r_z \sin \frac\varphi 2 \end{pmatrix}\)
You can verify that this for the general rotation quaternion \(q\) actually gives the same formula by calculation the application of the general rotation quaternion to an arbitrary vector:
\(R_q(p) = qpq^{-1}\)
\(\phantom{R_q(p)} = (\cos \frac\varphi 2 + r_x \sin \frac\varphi 2 i + r_y \sin \frac\varphi 2 j + r_z \sin \frac\varphi 2 k)(v_x i + v_y j + v_z k)(\cos \frac\varphi 2 - r_x \sin \frac\varphi 2 i - r_y \sin \frac\varphi 2 j - r_z \sin \frac\varphi 2 k)\)
Angular velocities
Note that while we can represent rotations with quaternions, we cannot represent angular velocities with quaternions. This is easy to see: Because a rotation around an axis with an angle \(\varphi\) will for an increasing angle \(\varphi\) at some point be equal to no rotation at all ( e.g. for \(\varphi = 360^\circ\). But a angular velocity \(\omega)\) that is not zero will never be equal to no angular velocity, if we keep increasing the rotation speed.
Thus, angular velocities are best represented either
- with a unit vector describing the rotation axis and an absolute value describing the angular velocity, or
- with a general vector, where the direction is describing the rotation axis and the length is describing the angular velocity.
It is easy to see that both representations are fully equivalent.
Using the formulas above we can apply the angular velocity for a timestep by
\[\mathrm dq = \cos(\mathrm dt \cdot |\omega| / 2) + \frac{\vec{\omega}}{|\omega|} \cos(\mathrm dt\cdot |\omega| / 2). \]
Then for a timestep \(\mathrm dt\), the rotation state \(q\) of an object changes as
\[q \rightarrow q + \mathrm dq. \]
Angular accelerations
Angular accelerations on the other hand are quite simple to handle, as they just add up to angular rotations:
\[\mathrm d\omega = \mathrm dt \cdot \alpha. \]
Then for a timestep \(\mathrm dt\), the angular velocity \(\omega\) of an object changes as
\[\omega \rightarrow \omega + \mathrm d\omega = \omega + \mathrm dt \cdot \alpha. \]
-
Actually, this is not true; every rotation can be represented by exactly two unit quaternions. If the quaternion ((q\)) describes a rotation, then the negative quaternion \(-q\) also describes the same rotation. The reason is that the space of unit quaternions (\(\mathrm{SU}(2)\)) actually double covers the space of rotations (\(\mathrm{SO}(3)\)). Btw. if you’re into physics: Some particles like electrons can be described by spinors, which are equivalent to quaternions. This is the reason why two full rotations are needed until they look the same again. That makes them spin-1/2 particles. ↩
-
Furthermore note that, since every rotation can be represented by two unit quaternions, you cannot directly compare quaternions to see if two rotations states are the same! You will need to always compare with \(q\) and \(-q\) if you want to compare two quaternions. ↩