![]() |
amino
1.0-beta2
Lightweight Robot Utility Library
|
\[ \newcommand{\normtwo}[1]{\left| #1 \right|} \newcommand{\MAT}[1]{\boldsymbol{#1}} \newcommand{\unitvec}[1]{\boldsymbol{\hat{#1}}} \newcommand{\ielt}[0]{\unitvec{\imath}} \newcommand{\jelt}[0]{\unitvec{\jmath}} \newcommand{\kelt}[0]{\unitvec{k}} \newcommand{\quat}[1]{\mathcal{#1}} \newcommand{\qmul}[0]{\otimes} \newcommand{\dotprod}{\boldsymbol{\cdot}} \]
This tutorial covers three-dimensional (3D) rotations. We begin by relating complex numbers and two-dimensional (planar) rotation. Then, we extend to 3D rotations represented using quaternions, a 3D analogue to the complex numbers. Finally, we discuss matrix representations for rotation.
Complex numbers provide a representation of planar (2D) rotations. The imaginary unit \(\ielt\) is defined as a number whose square is -1:
\[ \ielt^2 = -1 \]
Euler's Formula relates complex numbers and planar angles. If we expand the Taylor series for the complex exponential, we can rearrange the terms into the Taylor series for \(\sin\) and \(\cos\):
\[ \begin{array}{ccl} {e}^{\theta \ielt} & = & \overbrace{ \frac{1}{0!} + \frac{(\theta \ielt)^1}{1!} + \frac{(\theta \ielt)^2}{2!} + \frac{(\theta \ielt)^3}{3!} + \frac{(\theta \ielt)^4}{4!} + \frac{(\theta \ielt)^5}{5!} + \ldots }^{\textrm{Taylor Series Expansion of } e^{\theta \ielt}} \\ & = & \overbrace{ \left(\frac{1}{0!} - \frac{\theta^2}{2!} + \frac{\theta^4}{4!} + \ldots\right) }^{\cos \theta} + \ielt \overbrace{ \left(\frac{\theta}{1!} - \frac{\theta^3}{3!} + \frac{\theta^5}{5!} + \ldots\right) }^{\sin \theta} \\ & = & \cos \theta + \ielt \sin \theta \end{array} \]
The complex plane illustrates Euler's formula:
We can apply Euler's formula to rotate points in the plane by viewing the point in polar coordinates as radius \(r\) and angle \(\theta_1\):
\[ x_1 + y_1 \ielt = r \left(\cos \theta_1 + \ielt \sin \theta_1 \right) = r e^{\theta_1\ielt} \]
where \(r = \sqrt{{x_1}^2 + {y_1}^2}\) and \(\theta_1 = \tan^{-1} \frac{y_1}{x_1}\).
To rotate the polar coordinate point, we may add the rotation angle \(\theta_r\) to the original polar coordinate angle \(\theta_1\), yielding the new angle \(\theta_2\)
Addition of the polar coordinate angle and rotation angle corresponds to multiplication of the exponential coordinates:
\[ x_2 + \ielt y_2 = r\left(\cos \left(\theta_1 + \theta_r\right) + \ielt \sin \left(\theta_1 + \theta_r\right) \right) = re^{\left(\theta_1+ \theta_r\right)\ielt} = re^{\theta_1\ielt} e^{\theta_r\ielt} \]
Though Euler's formula is (at the least) a "neat trick," the advantages of representing angles in the plane using imaginary numbers and exponentials may be less certain. In the plane, all angles are about the z-axis, so we can apply successive rotations by summing the angles. However, when we move the 3D rotations—where we can rotate about arbitrary axes—then we can no longer merely sum angles and the benefits of the exponential formulation are more definitive.
In the plane, all rotations are about the axis orthogonal to the plane. For example, in the XY plane, all rotations are about the Z axis:
When we rotate in 3D, there are now three axes we can rotate about (all at the same time!):
Thus, one seemingly obvious representation of 3D rotations is to use three angles for three different axes. However, using angles in 3D is problematic. First, we must adopt a specific convention: what are the axes and order we use, and do we keep axes fixed or do axes vary with each successive rotation? (There are 24 different combinations of axis order and fixed/varying axes!) Second, we can no longer chain rotations by adding angles, since axes will change as we rotate. Finally, singularities are possible when aligned axes remove a degree of freedom ("gimbal lock").
Thus, while Euler angles may be easy to visualize, they are a poor choice for computation.
A visually-meaningful representation of 3D rotation is the Axis-Angle form, given by the unit axis \(\unitvec{u}\) about which we rotate and the angle \(\theta\) by which we rotate:
While the axis-angle form is easy enough to visualize, it is not especially efficient for computation, for example, if we want to chain to successive rotations. For efficient computation, we move on to the Quaternions and Rotation Matrices, both of which we can construct from the axis-angle form.
Quaternions offer a particularly compact and efficient representation for rotations. The quaternions generalize complex numbers to three dimensions. Whereas in the plane we needed one imaginary unit to describe rotation about one axis, quaternions describe rotations about three possible axes using three imaginary units, plus a real part, giving four (quaternary) elements total. The quaternion axiom is:
\[ \ielt^2 = \jelt^2 = \kelt^2 = \ielt\jelt\kelt = -1 \]
The four elements of the quaternion are the imaginary unit factors (the vector part) and the real term (the scalar part):
\[ h = \overbrace{x \ielt + y \jelt + z \kelt}^{\textrm{vector}} + \overbrace{w}^{\textrm{scalar}} = \vec{v} + w = |v| \unitvec{u} + w \]
Computationally, we may represent the quaternion as an array of four elements or as a struct with the four parts. Either form (array or struct) will have the same memory layout.
From the quaternion axiom, we can derive the products of pairs of quaternion elements. For example, the derivation of \(\ielt\jelt\):
\[ \left\lgroup \ielt\jelt\kelt=-1 \right\rgroup \leadsto \left\lgroup \ielt\jelt\kelt^2=-\kelt \right\rgroup \leadsto \left\lgroup -\ielt\jelt=-\kelt \right\rgroup \leadsto \left\lgroup \ielt\jelt=\kelt \right\rgroup \]
Following a similar derivation for the other products, we obtain the following relations:
\[ \begin{array}{cccc} \ielt\jelt &=& -\jelt\ielt &=& \kelt \\ \jelt\kelt &=& -\kelt\jelt &=& \ielt \\ \kelt\ielt &=& -\ielt\kelt &=& \jelt \end{array} \]
(An informed reader may notice that multiplication of quaternion units corresponds to cross products of the standard basis vectors. In fact, the vector cross product is itself based on quaternion multiplication!)
From the quaternion unit products, we can expand and simplify the multiplication of two quaternions:
\[ \begin{array} \quat{a} \qmul \quat{b} & = & (a_w + a_x\ielt + a_y \jelt + a_z \kelt) \qmul (b_w + b_x\ielt + b_y \jelt + b_z \kelt) \\ & = & \phantom{+\ }(a_wb_w - a_xb_x - a_yb_y - a_zb_z)\\ & & +\ ( a_w b_x + a_xb_w + a_yb_z - a_zb_y ) \ielt\\ & & +\ ( a_wb_y - a_xb_z + a_yb_w + a_zb_x )\jelt\\ & & +\ ( a_wb_z + a_xb_y - a_y b_x + a_zb_w )\kelt \end{array} \]
A single quaternion multiply actually performs both a cross product and dot product. We can restate the quaternion multiply as:
\[ \begin{array} \quat{a} \qmul \quat{b} & = & (a_w + \vec{a}_v) \qmul (b_w + \vec{b}_v) \\ & = & \underbrace{\left( \vec{a}_v \times \vec{b}_v + a_w\vec{b}_v + b_w\vec{a}_v \right)}_{\textrm{vector}} + \underbrace{ \left( a_w b_w - \vec{a}_v \dotprod \vec{b}_v \right) }_{\textrm{scalar}} \end{array} \]
We construct a quaternion representing a rotation analogously to the planar, complex number case. For quaternions, the imaginary part is now constructed from the axis of rotation. We must also scale the angle by one half.
\[ e^{\theta \unitvec{u}} = \unitvec{u} \sin \frac{\theta}{2} + \cos \theta \]
While it is more challenging to directly visualize a four element quaternion than a two element complex number, we can still find some insight by projecting the quaternion onto a plane. We take the scalar (real) quaternion part as one plane axis and the magnitude of the vector (imaginary) part as the other plane axis:
The matrix representation of rotations is especially efficient for rotating points, thought not as compact or efficient for chaining as quaternions.
The planar (2D) rotation matrix is constructed as:
\[ R(\theta) = \begin{bmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{bmatrix} \]
Rotation matrices offer a direct, visual interpretation. The columns of the rotation matrix are the principal axes of the child (rotated) coordinate frame in the parent (non-rotated) frame:
Planar rotation using a rotation matrix corresponds to rotation using Euler's formula. While Euler's formula essentially operates on polar coordinates, rotation matrices operate on rectangular coordinates.
\[ \begin{bmatrix} x_1 \\ y_1 \end{bmatrix} = r \begin{bmatrix} \cos \theta_1\\ \sin \theta_1\\ \end{bmatrix} \]
Then we ran can derive the rotation operation through some trigonometric identities and factoring:
\[ \begin{bmatrix} x_2 \\ y_2 \end{bmatrix} = r \begin{bmatrix} \cos \left( \theta_1 + \theta_r \right) \\ \sin \left(\theta_1 + \theta_r \right) \\ \end{bmatrix} = r \begin{bmatrix} \cos \theta_1 \cos \theta_r - \sin \theta_1 \sin \theta_r \\ \cos \theta_1 \sin \theta_r + \sin \theta_1 \cos \theta_r \end{bmatrix} = \begin{bmatrix} \cos \theta_r & - \sin \theta_r \\ \sin \theta_r & \cos \theta_r \end{bmatrix} \begin{bmatrix} x_1 \\ y_1 \end{bmatrix} \]
In 3 dimensions, we construct rotation matrix as:
\[ \MAT{R} = e^{[\theta \unitvec{u}]} = \MAT{I} + \left({\sin{\theta}}\right) [\unitvec{u}] + \left({1 - \cos{\theta}}\right) [\unitvec{u}]^2, \quad{\rm where}\quad [\unitvec{u}] = \begin{bmatrix} 0 & -u_z & u_y \\ u_z & 0 & -u_x \\ -u_y & u_x & 0 \\ \end{bmatrix} \; . \]
3D rotation matrices again offer a visual interpretation: the columns of the rotation matrix are the principal axes of the child (rotated) coordinate frame in the parent (non-rotated) frame.
Rotation is analgous to the 2D case:
\[ \begin{bmatrix} x_2 \\ y_2 \\ z_2 \end{bmatrix} = \MAT{R} \begin{bmatrix} x_1 \\ y_1 \\ z_1 \end{bmatrix} \; . \]
We store the rotation matrix in memory using column-major order:
\[ \begin{bmatrix} r_{11} & r_{12} & r_{13} \\ r_{21} & r_{22} & r_{23} \\ r_{31} & r_{32} & r_{33} \\ \end{bmatrix} \leadsto \begin{array}{|c|c|} \hline r_{11} & r_{21} & r_{31} & r_{12} & r_{22} & r_{32} & r_{13} & r_{23} & r_{33} \\ \hline \end{array} \; . \]