Spatial rotations in three dimensions can be parametrized using both Euler angles and unit quaternions. This article explains how to convert between the two representations. Actually this simple use of "quaternions" was first presented by Euler some seventy years earlier than Hamilton to solve the problem of magic squares. For this reason the dynamics community commonly refers to quaternions in this application as "Euler parameters".
There are two representations of quaternions. This article uses the more popular Hamilton.
A quaternion has 4 scalar values: (the real part) and (the imaginary part).
Defining the norm of the quaternion as follows:
A unit quaternion satisfies:
We can associate a quaternion with a rotation around an axis by the following expression
qw=\cos(\alpha/2)
qx=\sin(\alpha/2)\cos(\betax)
qy=\sin(\alpha/2)\cos(\betay)
qz=\sin(\alpha/2)\cos(\betaz)
To better understand how "direction cosines" work with quaternions:
\begin{array}{lcr}qw=\cos(rotationangle/2)\\ qx=\sin(rotationangle/2)\cos(anglebetweenaxisofrotationandxaxis)\\ qy=\sin(rotationangle/2)\cos(anglebetweenaxisofrotationandyaxis)\\ qz=\sin(rotationangle/2)\cos(anglebetweenaxisofrotationandzaxis)\end{array}
If the axis of rotation is the x-axis:
\begin{array}{lcr}qw=\cos(\alpha/2)\\ qx=\sin(\alpha/2) ⋅ 1\\ qy=\sin(\alpha/2) ⋅ 0\\ qz=\sin(\alpha/2) ⋅ 0\end{array}
If the axis of rotation is the y-axis:
\begin{array}{lcr}qw=\cos(\alpha/2)\\ qx=\sin(\alpha/2) ⋅ 0\\ qy=\sin(\alpha/2) ⋅ 1\\ qz=\sin(\alpha/2) ⋅ 0\end{array}
If the axis of rotation is the z-axis:
\begin{array}{lcr}qw=\cos(\alpha/2)\\ qx=\sin(\alpha/2) ⋅ 0\\ qy=\sin(\alpha/2) ⋅ 0\\ qz=\sin(\alpha/2) ⋅ 1\end{array}
If the axis of rotation is a vector located 45° (radians) between the x and y axes:
\begin{array}{lcr}qw=\cos(\alpha/2)\\ qx=\sin(\alpha/2) ⋅ 0.707\ldots\\ qy=\sin(\alpha/2) ⋅ 0.707\ldots\\ qz=\sin(\alpha/2) ⋅ 0\end{array}
Therefore, the x and y axes "share" influence over the new axis of rotation.
Similarly for Euler angles, we use the Tait Bryan angles (in terms of flight dynamics):
\psi
\theta
\phi
q=qw+iqx+jqy+kqz
R=\begin{bmatrix} 1-
2 | |
2(q | |
y |
+
2) | |
q | |
z |
&2(qxqy-qwqz)&2(qwqy+qxqz)\\ 2(qxqy+qwqz)&1-
2 | |
2(q | |
x |
+
2) | |
q | |
z |
&2(qyqz-qwqx)\\ 2(qxqz-qwqy)&2(qwqx+qyqz)&1-
2 | |
2(q | |
x |
+
2) \end{bmatrix} | |
q | |
y |
or equivalently, by the homogeneous expression:
R=
2 | |
\begin{bmatrix} q | |
w |
+
2 | |
q | |
x |
-
2 | |
q | |
y |
-
2 | |
q | |
z |
&2(qxqy-qwqz)&2(qwqy+qxqz)\\ 2(qxqy+qwqz)&
2 | |
q | |
w |
-
2 | |
q | |
x |
+
2 | |
q | |
y |
-
2 | |
q | |
z |
&2(qyqz-qwqx)\\ 2(qxqz-qwqy)&2(qwqx+qyqz)&
2 | |
q | |
w |
-
2 | |
q | |
x |
-
2 | |
q | |
y |
+
2 | |
q | |
z |
\end{bmatrix}
If
qw+iqx+jqy+kqz
The direction cosine matrix (from the rotated Body XYZ coordinates to the original Lab xyz coordinates for a clockwise/lefthand rotation) corresponding to a post-multiply Body 3-2-1 sequence with Euler angles (ψ, θ, φ) is given by:[1]
\begin{align} \begin{bmatrix} x\\ y\\ z\\ \end{bmatrix} &= Rz(\psi)Ry(\theta)Rx(\phi)\begin{bmatrix} X\\ Y\\ Z\\ \end{bmatrix} \\ &=\begin{bmatrix} \cos\psi&-\sin\psi&0\\ \sin\psi&\cos\psi&0\\ 0&0&1\\ \end{bmatrix} \begin{bmatrix} \cos\theta&0&\sin\theta\\ 0&1&0\\ -\sin\theta&0&\cos\theta\\ \end{bmatrix} \begin{bmatrix} 1&0&0\\ 0&\cos\phi&-\sin\phi\\ 0&\sin\phi&\cos\phi\\ \end{bmatrix} \begin{bmatrix} X\\ Y\\ Z\\ \end{bmatrix} \\ &=\begin{bmatrix} \cos\theta\cos\psi&-\cos\phi\sin\psi+\sin\phi\sin\theta\cos\psi&\sin\phi\sin\psi+\cos\phi\sin\theta\cos\psi\\ \cos\theta\sin\psi&\cos\phi\cos\psi+\sin\phi\sin\theta\sin\psi&-\sin\phi\cos\psi+\cos\phi\sin\theta\sin\psi\\ -\sin\theta&\sin\phi\cos\theta&\cos\phi\cos\theta\\ \end{bmatrix}\begin{bmatrix} X\\ Y\\ Z\\ \end{bmatrix} \\ \end{align}
By combining the quaternion representations of the Euler rotations we get for the Body 3-2-1 sequence, where the airplane first does yaw (Body-Z) turn during taxiing onto the runway, then pitches (Body-Y) during take-off, and finally rolls (Body-X) in the air. The resulting orientation of Body 3-2-1 sequence (around the capitalized axis in the illustration of Tait–Bryan angles) is equivalent to that of lab 1-2-3 sequence (around the lower-cased axis), where the airplane is rolled first (lab-x axis), and then nosed up around the horizontal lab-y axis, and finally rotated around the vertical lab-z axis (lB = lab2Body):
\begin{align} qlB |
&=\begin{bmatrix}\cos(\psi/2)\ 0\ 0\ \sin(\psi/2)\ \end{bmatrix} \begin{bmatrix}\cos(\theta/2)\ 0\ \sin(\theta/2)\ 0\ \end{bmatrix} \begin{bmatrix}\cos(\phi/2)\ \sin(\phi/2)\ 0\ 0\ \end{bmatrix} \\ &=\begin{bmatrix} \cos(\phi/2)\cos(\theta/2)\cos(\psi/2)+\sin(\phi/2)\sin(\theta/2)\sin(\psi/2)\\ \sin(\phi/2)\cos(\theta/2)\cos(\psi/2)-\cos(\phi/2)\sin(\theta/2)\sin(\psi/2)\\ \cos(\phi/2)\sin(\theta/2)\cos(\psi/2)+\sin(\phi/2)\cos(\theta/2)\sin(\psi/2)\\ \cos(\phi/2)\cos(\theta/2)\sin(\psi/2)-\sin(\phi/2)\sin(\theta/2)\cos(\psi/2)\\ \end{bmatrix}\\ \end{align}
Other rotation sequences use different conventions.
Below code in C++ illustrates above conversion:
// This is not in game format, it is in mathematical format.Quaternion ToQuaternion(double roll, double pitch, double yaw) // roll (x), pitch (y), yaw (z), angles are in radians
A direct formula for the conversion from a quaternion to Euler angles in any of the 12 possible sequences exists.[2] For the rest of this section, the formula for the sequence Body 3-2-1 will be shown.If the quaternion is properly normalized, the Euler angles can be obtained from the quaternions via the relations:
\begin{bmatrix} \phi\ \theta\ \psi \end{bmatrix}= \begin{bmatrix} atan2\left(2(qwqx+qyqz),1-
2 | |
2(q | |
x |
+
2)\right) | |
q | |
y |
\\ -\pi/2+2atan2\left(\sqrt{1+2(qwqy-qxqz)},\sqrt{1-2(qwqy-qxqz)}\right)\\ atan2\left(2(qwqz+qxqy),1-
2 | |
2(q | |
y |
+
2)\right) \end{bmatrix} | |
q | |
z |
Note that the arctan functions implemented in computer languages only produce results between −π/2 and π/2, which is why atan2 is used to generate all the correct orientations. Moreover, typical implementations of arctan also might have some numerical disadvantages near zero and one.
Some implementations use the equivalent expression:[3]
\theta=arcsin(2(qwqy-qxqz))
The following C++ program illustrates conversion above:
struct Quaternion ;
struct EulerAngles ;
// this implementation assumes normalized quaternion// converts to Euler angles in 3-2-1 sequenceEulerAngles ToEulerAngles(Quaternion q)
One must be aware of singularities in the Euler angle parametrization when the pitch approaches ±90° (north/south pole). These cases must be handled specially. The common name for this situation is gimbal lock.
Code to handle the singularities is derived on this site: www.euclideanspace.com
Let us define scalar
qw
\vec{q}
q=(qw,\vec{q})
Note that the canonical way to rotate a three-dimensional vector
\vec{v}
q
v\prime=qvq\ast
v=(0,\vec{v})
\vec{v}
\ast=(q | |
q | |
w,-\vec{q}) |
v\prime=(0,\vec{v}\prime)
\vec{v}\prime
\vec{t}=2\vec{q} x \vec{v}
\vec{v}\prime=\vec{v}+qw\vec{t}+\vec{q} x \vec{t}
x
The general rule for quaternion multiplication involving scalar and vector parts is given by
\begin{align} pq&=(pw,\vec{p})(qw,\vec{q})\\ &=(pwqw-\vec{p} ⋅ \vec{q},pw\vec{q}+qw\vec{p}+\vec{p} x \vec{q})\\ \end{align}
v=(0,\vec{v})
\begin{align} vq\ast |
&=(0,\vec{v})(qw,-\vec{q})\\ &=(\vec{v} ⋅ \vec{q},qw\vec{v}-\vec{v} x \vec{q})\\ \end{align}
\begin{align} qvq\ast |
&=(qw,\vec{q})(\vec{v} ⋅ \vec{q},qw\vec{v}-\vec{v} x \vec{q})\\ &=(0,
2 | |
q | |
w |
\vec{v}+qw\vec{q} x \vec{v}+(\vec{v} ⋅ \vec{q})\vec{q}+qw\vec{q} x \vec{v}+ \vec{q} x (\vec{q} x \vec{v}))\\ \end{align}
\vec{q} ⋅ \vec{v} x \vec{q}=0
q
2 | |
q | |
w |
=1-\vec{q} ⋅ \vec{q}
\vec{q} x (\vec{q} x \vec{v})=(\vec{q} ⋅ \vec{v})\vec{q}-(\vec{q} ⋅ \vec{q})\vec{v}
\begin{align} v\prime&=
qvq\ast |
=(0,\vec{v}+2qw\vec{q} x \vec{v}+2\vec{q} x (\vec{q} x \vec{v}))\\ \end{align}
\vec{t}=2\vec{q} x \vec{v}
(0,\vec{v}\prime)=(0,\vec{v}+qw\vec{t}+\vec{q} x \vec{t}).