12. Complex Numbers and Quaternions#

In 10. Quaternions we explored how we can make use of quaternions to perform rotation calculations. You don’t need to know exactly how the various equations are derived in order to use them in your programs, however, if you are curious their derivations are provided here.

12.1. Complex numbers#

The imaginary number \(i\) is defined as \(i = \sqrt{-1}\). A complex number is a real number plus a multiple of an imaginary number

\[ z = x + yi.\]

The following arithmetic operations can be applied to complex numbers.

Operation

Result

Addition

\((a + bi) + (c + di) = a + c + (b + d)i\)

Subtraction

\((a + bi) - (c + di) = a - c + (b - d)i\)

Scalar multiplication

\(k(a + bi) = ak + bki\)

Multiplication

\((a + bi)(c + di) = ac - bd + (ad - bc)i\)

For example, given the complex numbers \(z_1 = 1 + 2i\) and \(z_2 = 3 + 4i\)

\[\begin{split} \begin{align*} z_1 + z_2 &= 1 + 3 + (2 + 4)i = 4 + 6i, \\ z_1 - z_2 &= 1 - 3 + (2 - 4)i = -2 - 2i, \\ 3z_1 &= 3 \times 1 + 3 \times 2i = 3 + 6i, \\ z_1z_2 &= (1 + 2i) (3 + 4i) = 1 \times 3 - 2 \times 4 + (1 \times 4 - 2 \times 3) = -5 - 2i. \end{align*} \end{split}\]

12.1.1. The complex plane#

Complex numbers can be represented using a 2D graph called a complex plane (also known as an Argand diagram) where the real part is mapped to the horizontal axis and the imaginary part mapped to the vertical axis. For example, consider the complex number \(x + yi\)

../_images/10_Complex_plane.svg

12.1.2. Absolute value of a complex number#

The absolute value of a complex number \(z = x + yi\) is denoted by \(|z|\) and is the distance of the complex number from the origin of the complex plane. It is calculated using Pythagoras’ theorem

\[ |z| = \sqrt{x^2 + x^2}. \]

12.1.3. Complex conjugate#

The complex conjugate of a complex number \(z = x + yi\) is denoted by \(z^*\) and is the complex number with the imaginary part negated

\[ z^* = a - bi. \]

When plotted on the complex plane the complex conjugate of \(x + yi\) is reflected about the real axis.

../_images/10_Complex_conjugate.svg

Multiplying a complex number by its conjugate gives

\[\begin{split} \begin{align*} zz^* &= (x + yi)(a - bi) \\ &= x^2 + abi - abi + x^2 \\ &= x^2 + x^2 \\ &= |z|^2. \end{align*} \end{split}\]

which leads to the following definition of the multiplicative inverse of a complex number

\[\begin{split} \begin{align*} zz^* &= |z|^2 \\ z &= \frac{|z|^2}{z^*} \\ \therefore z^{-1} &= \frac{z^*}{|z|^2}. \end{align*} \end{split}\]

12.2. Rotation using complex numbers#

We can rotate a complex number by multiplying by \(i\). Consider the complex number \(z = 2 + i\) when multiplied recursively by \(i\)

\[\begin{split} \begin{align*} z &= 2 + i, \\ z i &= (2 + i)i = -1 + 2i, \\ z i^2 &= (-1 + 2i)i = -2 - i, \\ z i^3 &= (-2 - i)i = 1 - 2i, \\ z i^4 &= (1 - 2i)i = 2 + i, \\ &\vdots \end{align*} \end{split}\]

Since \(zi^4 = z\) then this sequence will repeat every four multiples of \(i\). Plotting on the complex plane gives

../_images/10_Complex_rotation.svg

So multiplying a complex number by \(i\) rotates it by 90\(^\circ\) anti-clockwise about the origin.

Given a complex number \(r = x + yi\) on the complex plane which has an absolute value of \(|r|=1\), if \(\theta\) is the angle between the real axis and the vector pointing from the origin to \(r\), then the length of an adjacent side is \(\cos(\theta)\) and the length of the opposite side is \(\sin(\theta)\).

../_images/B_Unit_complex_number.svg

Using the sin and cosine trigonometric ratios we can write \(r\) as

\[ r = \cos(\theta) + \sin(\theta)i.\]

Multiplying a complex number by \(r\) rotates it by \(\theta\) anti-clockwise in the complex plane.


12.3. Quaternions#

The general form of a quaternion is

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

where \(w\), \(x\), \(y\) and \(z\) are real numbers and \(i\), \(j\) and \(k\) are imaginary numbers defined by

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

Let’s examine the relationships between \(i\), \(j\) and \(k\). Since \(ijk = -1\) then

\[ \begin{align*} ij &= -\frac{1}{k} = -k^{-1} = -\left( \frac{k^*}{|k|^2} \right) = k, \end{align*} \]

and doing similar for the other combinations of \(i\), \(j\) and \(k\) gives

\[\begin{split} \begin{align*} ij &= k, & jk &= i, & ki &= j, \\ ji &= -k, & kj &= -i, & ik &= -j. \end{align*} \end{split}\]

Consider the cross products between the three unit vectors pointing in the \(x\), \(y\) and \(z\) directions \(\mathbf{i}\), \(\mathbf{j}\) and \(\mathbf{k}\)

\[\begin{split} \begin{align*} \mathbf{i} \times \mathbf{j} &= \mathbf{k}, & \mathbf{j} \times \mathbf{k} &= \mathbf{i}, & \mathbf{k} \times \mathbf{i} &= \mathbf{j}, \\ \mathbf{j} \times \mathbf{i} &= -\mathbf{k}, & \mathbf{k} \times \mathbf{j} &= -\mathbf{i}, & \mathbf{i} \times \mathbf{k} &= -\mathbf{j}. \end{align*} \end{split}\]
../_images/B_Cross_product_1.svg
../_images/B_Cross_product_2.svg
../_images/B_Cross_product_3.svg

So the three imaginary numbers \(i\), \(j\) and \(k\) can be used to represent the three unit vectors pointing in the \(x\), \(y\) and \(z\) directions and multiplying the imaginary numbers is equivalent to the cross product.

12.3.1. Scalar-vector form of a quaternion#

Quaternions can be expressed more conveniently as an ordered-pair consisting of the real part \(w\) and a vector of the imaginary parts

\[ q = [w, \mathbf{v}], \]

where \(\mathbf{v} = x\mathbf{i} + y \mathbf{j} + z \mathbf{k}\). For example, the quaternion \(q = 1 + 2i + 3j + 4k\) can be represented in scalar-vector form as

\[q = [1, (2, 3, 4)].\]

12.3.2. Absolute value of a quaternion#

The absolute value of a quaternion \(q = [w, (x, y, z)]\) is denoted by \(|q|\) and calculated using

\[ |q| = \sqrt{w^2 + x^2 + y^2 + z^2}.\]

12.3.3. Unit quaternion#

A unit quaternion, denoted by \(\hat{q}\), is a quaternion that has an absolute value of 1. We can normalise a quaternion by dividing by its absolute value to give a unit quaternion

\[ \hat{q} = \frac{q}{|q|}. \]

Proving that \(|\hat{q}| = 1\)

12.3.4. Pure and real quaternions#

A pure quaternion is a quaternion where the real part has a value of zero, i.e.,

\[ q = [0, \mathbf{v}]. \]

A pure quaternion is equivalent to a 3-element vector.

A real quaternion is a quaternion where the vector part is the zero vector \(\mathbf{0} = 0\mathbf{i} + 0\mathbf{j} + 0\mathbf{k}\), i.e.,

\[ q = [w, \mathbf{0}]. \]

A real quaternion is equivalent to a real number.

12.3.5. Quaternion dot product#

The dot product between two quaternions \(q_1 = [w_1, (x_1, y_1, z_1)]\) and \(q_2 = [w_2, (x_2, y_2, z_2)]\) is denoted by \(q_1 \cdot q_2\) and is calculated using

(12.1)#\[ q_1 \cdot q_2 = w_1w_2 + x_1x_2 + y_1y_2 + z_1z_2,\]

and the angle \(\theta\) between \(q_1\) and \(q_2\) is

(12.2)#\[ \theta = \cos^{-1} \left( \frac{q_1 \cdot q_2}{|q_1||q_2|} \right).\]

12.3.6. Multiplying quaternions#

Let \(q_1 = x_1i + y_1j + z_1k + w_1\) and \(q_2 = x_2i + y_2j + z_2k + w_2\) be two quaternions then

\[\begin{split} \begin{align*} q_1q_2 &= (w_1 + x_1i + y_1j + z_1k)(w_2 + x_2i + y_2j + z_2k) \\ &= (w_1x_2 + w_2x_1 + y_1z_2 - y_2z_1)i \\ & \qquad + (w_1y_2 + w_2y_1 + z_1x_2 - z_2x_1)j \\ & \qquad + (w_1z_2 + w_2z_1 + x_1y_2 - x_2y_1)k \\ & \qquad + (w_1w_2 - x_1x_2 - y_1y_2 - z_1z_2). \end{align*} \end{split}\]

Substituting in the pure quaternions \([0,\mathbf{i}]\), \([0,\mathbf{j}]\) and \([0,\mathbf{k}]\) as well as the real quaternion \([1,\mathbf{0}]\) then

\[\begin{split} \begin{align*} q_1q_2 &= (w_1x_2 + w_2x_1 + y_1z_2 - y_2z_1) [0,\mathbf{i}] \\ & \qquad + (w_1y_2 + w_2y_1 + z_1x_2 - z_2x_1) [0,\mathbf{j}] \\ & \qquad + (w_1z_2 + w_2z_1 + x_1y_2 - x_2y_1) [0,\mathbf{k}] \\ & \qquad + (-x_1x_2 - y_1y_2 - z_1z_2 + w_1w_2) [1,\mathbf{0}] \\ &= [0, (w_1x_2 + w_2x_1 + y_1z_2 - y_2z_1) \mathbf{i}] \\ & \qquad + [0,(w_1y_2 + w_2y_1 + z_1x_2 - z_2x_1) \mathbf{j}] \\ & \qquad + [0,(w_1z_2 + w_2z_1 + x_1y_2 - x_2y_1) \mathbf{k}] \\ & \qquad + [-x_1x_2 - y_1y_2 - z_1z_2 + w_1w_2, \mathbf{0}] \\ &= [(w_1w_2 - x_1x_2 - y_1y_2 - z_1z_2 + w_1w_2), \\ & \qquad w_1(x_2\mathbf{i} + y_2\mathbf{j} + z_2\mathbf{k}) + w_2(x_1 \mathbf{i} + y_1 \mathbf{j} + z_1\mathbf{k}) \\ & \qquad + (y_1z_2 - y_2z_1)\mathbf{i} + (z_1x_2 - z_2x_1)\mathbf{j} + (x_1y_2 - x_2y_1)\mathbf{k} ] \end{align*} \end{split}\]

Substituting the dot and cross products

\[\begin{split} \begin{align*} \mathbf{v}_1 \cdot \mathbf{v}_2 &= x_1x_2 + y_1y_2 + z_1z_2, \\ \mathbf{v}_1 \times \mathbf{v}_2 &= (y_1z_2 - y_2z_1)\mathbf{i} + (z_1x_2 - z_2x_1)\mathbf{j} + (x_1y_2 - x_2y_1)\mathbf{k} \end{align*} \end{split}\]

results in

(12.3)#\[ \begin{align*} q_1q_2 &= [w_1w_2 - \mathbf{v}_1\cdot \mathbf{v}_2, w_1 \mathbf{v}_2 + w_2 \mathbf{v}_1 + \mathbf{v}_1 \times \mathbf{v}_2]. \end{align*} \]

Equation (12.3) is the equation for the multiplication of two quaternions \(q_1 = [w_1, \mathbf{v}_1]\) and \(q_2 = [w_2, \mathbf{v}_2]\).

12.3.7. Quaternion conjugate#

The conjugate of a quaternion \(q\), denoted by \(q^*\), is found by negating the vector part. For example, given the quaternion \(q = [w, \mathbf{v}]\) then

\[ q^* = [w, -\mathbf{v}].\]

12.3.8. Quaternion inverse#

The inverse of a quaternion \(q\), denoted by \(q^{-1}\), is defined by

\[ qq^{-1} = 1.\]

If we multiply both sides of this equation by \(q^*\) then

\[\begin{split} \begin{align*} q^*qq^{-1} &= q^* \\ |q|^2q^{-1} &= q^* \\ q^{-1} &= \frac{q^*}{|q|^2}. \end{align*} \end{split}\]

If \(q\) is a unit quaternion then \(|q|=1\) and

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

12.4. Quaternion rotation#

In 5. Transformations we saw that we can rotate about a vector \(\mathbf{v}\) by an angle \(\theta\) using a combination of a translation and rotations about the \(x\), \(y\) and \(z\) axes. The resulting matrix shown in equation (5.3) is quite complicated and requires lots of floating point computations. Quaternions gives us a away of performing similar calculation in a way that uses fewer computations and also does not suffer from gimbal lock.

../_images/05_axis_angle_rotation.svg

Fig. 12.1 Axis-angle rotation#

We have seen above that we can rotate a complex number by multiplying by the complex number \(z = \cos(\theta) + \sin(\theta)i\). Since quaternions are an extension of complex numbers the quaternion equivalent to this is

\[ q = \cos(\theta) + \sin(\theta) i + \sin(\theta) j + \sin(\theta) k, \]

or in scalar-vector form

\[ q = [\cos(\theta), \sin(\theta) \mathbf{v}]. \]

To demonstrate rotation using quaternion rotation consider the rotation of the vector \(\mathbf{p} = (2, 0, 0)\) by 45\(^\circ\) about the \(z\)-axis. The rotation quaternion for this is

\[ q = [\cos(45^\circ), \sin(45^\circ)(0, 0, 1)] = [0.707, (0, 0, 0.707)], \]

and expressing \(\mathbf{p}\) as a pure quaternion we have \(p = [0, (2, 0, 0)]\). Multiplying \(p\) and \(q\) using equation (12.3) gives

\[ \begin{align*} qp &= [0.707, (0, 0, 0.707)] [0, (2, 0, 0)] = [0, (1.414, 1.414, 0)] \end{align*} \]

Since the scalar part is zero then this is a pure quaternion and the absolute value of the rotated quaternion is

\[ \begin{align*} |qp| &= \sqrt{0 ^ 2 + 1.414^2 + 1.414^2 + 0^2} = 2, \end{align*} \]

which is the same as the absolute value of \([0, (2, 0, 0)]\). This rotation is shown in shown in Fig. 12.2.

../_images/B_Quaternion_rotation_1.svg

Fig. 12.2 The quaternion \(p = [0, (2, 0, 0)]\) is rotated \(45^\circ\) by multiplying by the rotation quaternion \(q = [\cos(45^\circ), \sin(45^\circ)(1, 0, 0)]\).#

In the rotation example shown above used a quaternion that was perpendicular to the vector being rotated. What happens when we rotate by a quaternion that isn’t perpendicular to the vector? Consider the rotation of the same vector \(\mathbf{p} = (2, 0, 0)\) by angle 45\(^\circ\) about the unit vector \(\hat{\mathbf{v}} = (0.707, 0, 0.707)\) which is not perpendicular to \(\mathbf{p}\). The rotation quaternion is

\[ \begin{align*} q = [\cos(45^\circ), \sin(45^\circ)(0.707, 0, 0.707)] = [0.707,(0.5, 0, 0.5)] \end{align*} \]

and multiplying by \(p = [0, (2, 0, 0)]\)

\[ \begin{align*} qp &= [0.707,(0.5, 0, 0.5)] [0, (2, 0, 0)] = [-1, (1.414, 1, 0)]. \end{align*} \]

Now we no longer have a pure quaternion since the scalar part is \(-1.414\) which is non-zero. However, if we multiply \(qp\) by the quaternion conjugate \(q^*\) on the right we have

\[\begin{split} \begin{align*} qpq^* &= [0.707,(0.5, 0, 0.5)] [0, (2, 0, 0)] [0.707, (-0.5, 0, -0.5)] \\ &= [0, (1, 1.414, 1)] \end{align*} \end{split}\]

So \(qpq^*\) is a pure quaternion and its absolute value is

\[ |qpq^*| = \sqrt{1^2 + (1.414)^2 + 1^2} = \sqrt{4} = 2,\]

which is the same as \(|p|\).

../_images/B_Quaternion_rotation_2.svg

Fig. 12.3 Rotating the quaternion \(p=[0, (2, 0, 0)]\) using \(qpq^*\) where \(q = [\cos(45^\circ), \sin(45^\circ) \hat{\mathbf{v}}]\)#

Plotting \(p\) and \(qpq^*\) we see that we have rotated by \(90^\circ\) instead of the desired \(45^\circ\) (Fig. 12.3). This is because we have multiplied the quaternion \(p\) by two rotation quaternions each using the angle \(45^\circ\). So to rotate a quaternion \(p\) about a vector \(\hat{\mathbf{v}}\) by angle \(\theta\) whilst ensuring that we get a pure quaternion we perform \(qpq^*\) where the rotation quaternion is

(12.4)#\[ q = [\cos(\tfrac{1}{2}\theta), \sin(\tfrac{1}{2}\theta) \hat{\mathbf{v}}].\]

Returning to our example of rotating \(\mathbf{p} = (2, 0, 0)\) by \(45^\circ\) about the vector \(\hat{\mathbf{v}} = (0.707, 0, 0.707)\) using equation (12.4) we have a rotation quaternion of

\[q = [\cos(\tfrac{45^\circ}{2}), \sin(\tfrac{45^\circ}{2})(0.707, 0, 0.707)] = [0.924, (0.271, 0, 0.271)]\]

so calculating \(qpq^*\) we have

\[\begin{split} \begin{align*} qpq^* &= [0.924, (0.271, 0, 0.271)] [0,(2,0,0)] [0.924, (-0.271, 0, -0.271)] \\ &= [0, (1.707, 1, 0.293)]. \end{align*}\end{split}\]

The effect of this rotation is shown in Fig. 12.4.

../_images/B_Quaternion_rotation_3.svg

Fig. 12.4 Rotating the quaternion \(p=[0, (2, 0, 0)]\) using \(qpq^*\) where \(q = [\cos(\frac{45^\circ}{2}), \sin(\frac{45^\circ}{2}) \hat{\mathbf{v}}]\).#

12.4.1. Rotation matrix#

To be able to combine quaternion rotation with other transformations we need to express the quaternion \(qpq^*\) as a \(4 \times 4\) matrix. Consider the multiplication of the axis vector quaternion \(p = [p_w, (p_x, p_y, p_z)]\) on the left by the rotation unit quaternion \(q = [w, (x, y, z)]\)

\[\begin{split} \begin{align*} qp &= [w, (x, y, z)] [p_w, (p_x, p_y, p_z)] \\ &= [wp_w - (x, y, z) \cdot (p_x, p_y, p_z), w(p_x, p_y, p_z) + p_w(x, y, z) + (x, y, z) \times (p_x, p_y, p_z)] \\ &= [wp_w - xp_x - yp_y - zp_z, \\ &\qquad (wp_x - zp_y - yp_z + xp_w, zp_x + wp_y - xp_z + yp_w, -yp_x + xp_y + wp_z + zp_w)]. \end{align*} \end{split}\]

If we write the quaternion \(p\) as a 4-element vector of the form \(\mathbf{p} = (p_x, p_y, p_z, p_w)^\mathsf{T}\) (note that \(p_w\), is now at the end of the vector which is synonymous with homogeneous coordinates) then we have

\[\begin{split} \begin{align*} qp &= \begin{pmatrix} wp_x - zp_y + yp_z + xp_w \\ zp_x + wp_y - xp_z + yp_w \\ -yp_x + xp_y + wp_z + zp_w \\ -xp_x - yp_y - zp_z + wp_w \end{pmatrix}, \end{align*} \end{split}\]

and we can express the rotation \(qp\) as the matrix equation

(12.5)#\[\begin{split} qp = \begin{align*} \begin{pmatrix} w & -z & y & x \\ z & w & -x & y \\ -y & x & w & z \\ -x & -y & -z & w \end{pmatrix} \begin{pmatrix} p_x \\ p_y \\ p_z \\ p_w \end{pmatrix} \end{align*} \end{split}\]

Doing similar for multiplying \(p\) on the right by \(q^* = [w, (-x, -y, -z)]\)

\[\begin{split} \begin{align*} pq^* &= [p_w, (p_x, p_y, p_z)][w, (-x, -y, -z)] \\ &= [wp_w - (p_x, p_y, p_z) \cdot ( -x, -y, -z), \\ & \qquad p_w(-x, -y, -z) + w(p_x, p_y, p_z) + (p_x, p_y, p_z) \times (-x, -y, -z)] \\ &= [xp_x + yp_y + zp_z + wp_w, \\ & \qquad (wp_x - zp_y + yp_z - xp_w, zp_x + wp_y - xp_z - yp_w, -yp_x + xp_y + wp_z - zp_w)]. \end{align*} \end{split}\]

Writing \(p\) the form \(\mathbf{p} = (p_x, p_y, p_z, p_w)\) as before gives

\[\begin{split} \begin{align*} pq^* = \begin{pmatrix} wp_x - zp_y + yp_z - xp_w \\ zp_x + wp_y - xp_z - yp_w \\ -yp_x + xp_y + wp_z - zp_w \\ xp_x + yp_y + zp_z + wp_w \end{pmatrix} \end{align*} \end{split}\]

which can be expressed by the matrix equation

(12.6)#\[\begin{split} \begin{align*} pq^* &= \begin{pmatrix} w & -z & y & -x \\ z & w & -x & -y \\ -y & x & w & -z \\ x & y & z & w \end{pmatrix} \begin{pmatrix} p_x \\ p_y \\ p_z \\ p_w \end{pmatrix} \end{align*} \end{split}\]

The two matrices for \(qp\) and \(pq^*\) from equations (12.5) and (12.6) can be combined to give a single matrix \(R\) that performs the quaternion rotation \(qpq^*\)

\[\begin{split} \begin{align*} R &= qp \cdot pq^* = \begin{pmatrix} w & -z & y & -x \\ z & w & -x & -y \\ -y & x & w & -z \\ x & y & z & w \end{pmatrix} \begin{pmatrix} w & -z & y & x \\ z & w & -x & y \\ -y & x & w & z \\ -x & -y & -z & w \end{pmatrix} \\ &= \begin{pmatrix} x^2 - y^2 - z^2 + w^2 & 2(xy - zw) & 2(xz + yw) & 0 \\ 2(xy + zw) & -x^2 + y^2 - z^2 + w^2 & 2(yz - xw) & 0 \\ 2(xz - yw) & 2(xw + yz) & -x^2 - y^2 + z^2 + w^2 & 0 \\ 0 & 0 & 0 & x^2 + y^2 + z^2 + w^2 \end{pmatrix}. \end{align*} \end{split}\]

Recall that \(q\) is a unit quaternion so \(x^2 + y^2 + z^2 + w^2 = 1\). We can use this to simplify the main diagonal elements of \(R\), for example, consider the element in row 1 column 1 of \(R\)

\[ \begin{align*} x^2 - y^2 - z^2 + w^2 = 1 - 2(y^2 + z^2). \end{align*} \]

Doing this for the other main diagonal elements \(R\) simplifies to

(12.7)#\[\begin{split} \begin{align*} R &= \begin{pmatrix} 1 - 2(y^2 + z^2) & 2(xy - zw) & 2(xz + yw) & 0 \\ 2(xy + zw) & 1 - 2(x^2 + z^2) & 2(yz - xw) & 0 \\ 2(xz - yw) & 2(xw + yz) & 1 - 2(x^2 + y^2) & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}. \end{align*} \end{split}\]

To demonstrate this lets return to our example of rotating the vector \(\mathbf{p} = (2, 0, 0)\) about the unit vector \(\hat{\mathbf{v}} = (0.707, 0, 0.707)\) by \(45^\circ\). Recall that the rotation quaternion was

\[ \begin{align*} q &= [\cos(\tfrac{45^\circ}{2}), \sin(\tfrac{45^\circ}{2}) (0.707, 0, 0.707)] = [0.924, (0.271, 0, 0.271)]. \end{align*} \]

From \(q\) we have \(w = 0.924\), \(x = 0.271\), \(y = 0\) and \(z = 0.271\). Substituting these into \(R\) from equation (12.7) gives

\[\begin{split} \begin{align*} R = \begin{pmatrix} 0.854 & -0.5 & 0.146 & 0 \\ 0.5 & 0.707 & -0.5 & 0 \\ 0.146 & 0.5 & 0.854 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}. \end{align*} \end{split}\]

Applying the rotation to \(p = (p_x, p_y, p_z, p_w) = (2, 0, 0, 0)\)

\[\begin{split} \begin{align*} R \cdot p = \begin{pmatrix} 0.854 & -0.5 & 0.146 & 0 \\ 0.5 & 0.707 & -0.5 & 0 \\ 0.146 & 0.5 & 0.854 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} 2 \\ 0 \\ 0 \\ 0 \end{pmatrix} = \begin{pmatrix} 1.707 \\ 1 \\ 0.293 \\ 0 \end{pmatrix}. \end{align*} \end{split}\]

So the rotated vector is \((1.707, 1, 0.293)\) which was shown in Fig. 12.4. We can see that the vector \(\mathbf{p}\) has now been rotated \(45^\circ\) about the vector \(\mathbf{v}\).

12.4.2. Euler angles to quaternion#

Euler angles are the rotations around the three coordinates axes \(x\), \(y\) and \(z\) so equation (12.4) can be used to give three quaternions for yaw, pitch and roll rotations

\[\begin{split}\begin{align*} q_p &= [\cos(\tfrac{pitch}{2}), \sin(\tfrac{pitch}{2}) (1, 0, 0)], \\ q_y &= [\cos(\tfrac{yaw}{2}), \sin(\tfrac{yaw}{2}) (0, 1, 0)], \\ q_r &= [\cos(\tfrac{roll}{2}), \sin(\tfrac{roll}{2}) (0, 0, 1)]. \end{align*} \end{split}\]

Let \(c_p = \cos(\tfrac{pitch}{2})\) and \(s_p = \sin(\tfrac{pitch}{2})\) for brevity, and do similar for the cosines and sines of \(yaw\) and \(roll\), then the single rotation quaternion that combines rotation about the three coordinates axes is

\[\begin{split} \begin{align*} q &= [c_p, s_p(1, 0, 0)] [c_y, s_y(0, 1, 0)] [c_r, s_r(0, 0, 1)] \\ &= [c_pc_yc_r - s_ps_ys_r, (s_pc_yc_r + c_ps_ys_r, c_ps_yc_r - s_pc_ys_r, c_pc_ys_r + s_ps_yc_r)]. \end{align*} \end{split}\]

This means we can define a quaternion based on the three Euler angles and then use equation (12.7) to generate the rotation matrix. A camera only requires the \(pitch\) and \(yaw\) angles. If \(roll = 0^\circ\) then \(\cos(roll) = 1\) and \(\sin(roll) = 0\) and so the quaternion simplifies to

\[ \begin{align*} q &= [c_pc_y, (s_pc_y, c_ps_y, s_ps_y)]. \end{align*} \]