Conversion between quaternions and Euler angles: Difference between revisions

Content deleted Content added
WikiCleanerBot (talk | contribs)
m v2.05b - Bot T20 CW#61 - Fix errors for CW project (Reference before punctuation)
Replace all q_0/1/2/3 with q_w/x/y/z (vector rotation section needs some work)
Line 4:
==Definition==
There are two representations of quaternions. Hamilton (where w is the first component) and [[JPL]] (where w is the last component).<ref>W. G. Breckenridge, "Quaternions proposed standard conventions," NASA Jet Propulsion Laboratory, Technical Report, Oct. 1979.</ref> This article uses Hamilton for some formulas. A unit [[quaternion]] can be described as:
:<math>\mathbf{q} = \begin{bmatrix} q_0 & q_1 & q_2 & q_3 \end{bmatrix}^T = \begin{bmatrix} q_w & q_x & q_y & q_z \end{bmatrix}^T</math>
:<math>|\mathbf{q}|^2 = q_0^2 + q_1^2 + q_2^2 + q_3^2 = q_w^2 + q_x^2 + q_y^2 + q_z^2 = 1</math>
 
We can associate a [[quaternion]] with a rotation around an axis by the following expression
 
:<math>\mathbf{q}_0 = \mathbf{q}_w = \cos(\alpha/2)</math>
:<math>\mathbf{q}_1 = \mathbf{q}_x = \sin(\alpha/2)\cos(\beta_x)</math>
:<math>\mathbf{q}_2 = \mathbf{q}_y = \sin(\alpha/2)\cos(\beta_y)</math>
:<math>\mathbf{q}_3 = \mathbf{q}_z = \sin(\alpha/2)\cos(\beta_z)</math>
where α is a simple rotation angle (the value in radians of the [[angle of rotation]]) and cos(β<sub>''x''</sub>), cos(β<sub>''y''</sub>) and cos(β<sub>''z''</sub>) are the "[[direction cosine]]s" of the angles between the three coordinate axes and the axis of rotation. (Euler's Rotation Theorem).
 
Line 18:
To better understand how "[[direction cosine]]s" work with quaternions:
 
:<math>\begin{array}{lcr} \mathbf{q}_0 = \mathbf{q}_w = \cos(\text{rotation angle}/2)\\
\mathbf{q}_1 = \mathbf{q}_x = \sin(\text{rotation angle}/2)\cos(\text{angle between axis of rotation and x axis})\\
\mathbf{q}_2 = \mathbf{q}_y = \sin(\text{rotation angle}/2)\cos(\text{angle between axis of rotation and y axis})\\
\mathbf{q}_3 = \mathbf{q}_z = \sin(\text{rotation angle}/2)\cos(\text{angle between axis of rotation and z axis})\end{array}</math>
 
If the [[axis of rotation]] is the ''x''-axis:
 
:<math>\begin{array}{lcr} \mathbf{q}_0 = \mathbf{q}_w = \cos(\alpha/2)\\
\mathbf{q}_1 = \mathbf{q}_x = \sin(\alpha/2)\cdot1\\
\mathbf{q}_2 = \mathbf{q}_y = \sin(\alpha/2)\cdot0\\
\mathbf{q}_3 = \mathbf{q}_z = \sin(\alpha/2)\cdot0\end{array}</math>
 
If the [[axis of rotation]] is the ''y''-axis:
 
:<math>\begin{array}{lcr} \mathbf{q}_0 = \mathbf{q}_w = \cos(\alpha/2)\\
\mathbf{q}_1 = \mathbf{q}_x = \sin(\alpha/2)\cdot0\\
\mathbf{q}_2 = \mathbf{q}_y = \sin(\alpha/2)\cdot1\\
\mathbf{q}_3 = \mathbf{q}_z = \sin(\alpha/2)\cdot0\end{array}</math>
 
If the [[axis of rotation]] is the ''z''-axis:
 
:<math>\begin{array}{lcr} \mathbf{q}_0 = \mathbf{q}_w = \cos(\alpha/2)\\
\mathbf{q}_1 = \mathbf{q}_x = \sin(\alpha/2)\cdot0\\
\mathbf{q}_2 = \mathbf{q}_y = \sin(\alpha/2)\cdot0\\
\mathbf{q}_3 = \mathbf{q}_z = \sin(\alpha/2)\cdot1\end{array}</math>
 
If the [[axis of rotation]] is a [[Vector_(mathematics_and_physics)|vector]] located 45° ({{sfrac|{{pi}}|4}} radians) between the ''x'' and ''y'' axes:
 
:<math>\begin{array}{lcr} \mathbf{q}_0 = \mathbf{q}_w = \cos(\alpha/2)\\
\mathbf{q}_1 = \mathbf{q}_x = \sin(\alpha/2)\cdot0.707 \ldots\\
\mathbf{q}_2 = \mathbf{q}_y = \sin(\alpha/2)\cdot0.707 \ldots\\
\mathbf{q}_3 = \mathbf{q}_z = \sin(\alpha/2)\cdot0\end{array}</math>
 
Therefore, the ''x'' and ''y'' axes "share" influence over the new [[axis of rotation]].
Line 63:
 
== Rotation matrices ==
The [[orthogonal matrix]] (post-multiplying a column vector) corresponding to a clockwise/[[Right-hand rule|left-handed]] (looking along positive axis to origin) rotation by the unit [[quaternion]] <math>q=q_0q_w+iq_1iq_x+jq_2jq_y+kq_3kq_z</math> is given by the [[Quaternions and spatial rotation#Quaternion-derived rotation matrix|inhomogeneous expression]]:
 
:<math>R = \begin{bmatrix}
1- 2(q_2q_y^2 + q_3q_z^2) & 2(q_1q_x q_2q_y - q_0q_w q_3q_z) & 2(q_0q_w q_2q_y + q_1q_x q_3q_z) \\
2(q_1q_x q_2q_y + q_0q_w q_3q_z) & 1 - 2(q_1q_x^2 + q_3q_z^2) & 2(q_2q_y q_3q_z - q_0q_w q_1q_x) \\
2(q_1q_x q_3q_z - q_0q_w q_2q_y) & 2( q_0q_w q_1q_x + q_2q_y q_3q_z) & 1 - 2(q_1q_x^2 + q_2q_y^2)
\end{bmatrix}</math>
 
Line 74:
 
:<math>R = \begin{bmatrix}
q_0q_w^2 + q_1q_x^2 - q_2q_y^2 - q_3q_z^2 & 2(q_1q_x q_2q_y - q_0q_w q_3q_z) & 2(q_0q_w q_2q_y + q_1q_x q_3q_z) \\
2(q_1q_x q_2q_y + q_0q_w q_3q_z) & q_0q_w^2 - q_1q_x^2 + q_2q_y^2 - q_3q_z^2 & 2(q_2q_y q_3q_z - q_0q_w q_1q_x) \\
2(q_1q_x q_3q_z - q_0q_w q_2q_y) & 2( q_0q_w q_1q_x + q_2q_y q_3q_z) & q_0q_w^2 - q_1q_x^2 - q_2q_y^2 + q_3q_z^2
\end{bmatrix}</math>
 
If <math>q_0q_w+iq_1iq_x+jq_2jq_y+kq_3kq_z</math> is not a unit quaternion then the homogeneous form is still a scalar multiple of a rotation matrix, while the inhomogeneous form is in general no longer an orthogonal matrix. This is why in numerical work the homogeneous form is to be preferred if distortion is to be avoided.
 
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:<ref name=nasa-rotation>{{cite web|last=NASA Mission Planning and Analysis Division|title=Euler Angles, Quaternions, and Transformation Matrices|date=July 1977 |url=https://ntrs.nasa.gov/citations/19770024290|publisher=[[NASA]]|accessdate=24 May 2021}}</ref>
Line 196:
\end{bmatrix} =
\begin{bmatrix}
\mbox{arctan} \left(\dfrac {2(q_0q_w q_1q_x + q_2q_y q_3q_z)} {1 - 2(q_1q_x^2 + q_2q_y^2)}\right)\\
- \pi/2 + 2 \, \mbox{arctan} \sqrt{\dfrac {1 + 2(q_0q_w q_2q_y - q_1q_x q_3q_z)} {1 - 2(q_0q_w q_2q_y - q_1q_x q_3q_z)}} \\
\mbox{arctan} \left(\dfrac {2(q_0q_w q_3q_z + q_1q_x q_2q_y)} {1 - 2(q_2q_y^2 + q_3q_z^2)}\right)
\end{bmatrix} </math>
 
Line 207:
\end{bmatrix} =
\begin{bmatrix}
\mbox{atan2} \left(2(q_0q_w q_1q_x + q_2q_y q_3q_z),1 - 2(q_1q_x^2 + q_2q_y^2)\right) \\
- \pi/2 + 2 \, \mbox{atan2} \left(\sqrt{1 + 2(q_0q_w q_2q_y - q_1q_x q_3q_z)}, \sqrt{1 - 2(q_0q_w q_2q_y - q_1q_x q_3q_z)}\right) \\
\mbox{atan2} \left(2(q_0q_w q_3q_z + q_1q_x q_2q_y),1 - 2(q_2q_y^2 + q_3q_z^2)\right)
\end{bmatrix} </math>
 
Moreover, typical implementations of arctan also might have some numerical disadvantages near zero and one. Some implementations use the equivalent expression:<ref>{{cite journal|last1=Blanco|first1=Jose-Luis|title=A tutorial on se (3) transformation parameterizations and on-manifold optimization|journal=University of Malaga, Tech. Rep|date=2010|citeseerx=10.1.1.468.5407}}</ref>
:<math> \theta = \mbox{arcsin} (2(q_0q_w q_2q_y - q_1q_x q_3q_z)) </math>
 
=== Source code ===
Line 261:
== Vector rotation ==
 
Let us define scalar <math>q_0</math> and vector <math>\vec{q}</math> such that <math>\mathbf{q} = (q_0,\vec{q}) = q_0+iq_1iq_x+jq_2jq_y+kq_3kq_z</math>.
 
Note that the canonical way to rotate a three-dimensional vector <math>\vec{v}</math> by a quaternion <math>q</math> defining an [[#Conversion|Euler rotation]] is via the formula
:<math>\mathbf{p}^{\,\prime} = \mathbf{qpq}^\ast</math>
where <math>\mathbf{p} = (0,\vec{v}) = 0+iv_1iv_x+jv_2jv_y+kv_3kv_z</math> is a quaternion containing the embedded vector <math>\vec{v}</math>, <math>\mathbf{q}^\ast=(q_0,-\vec{q})</math> is a [[Quaternion#Conjugation, the norm, and reciprocal|conjugate quaternion]], and <math>\mathbf{p}^{\,\prime} = (0,\vec{v}^{\,\prime})</math> is the rotated vector <math>\vec{v}^{\,\prime}</math>. In computational implementations this requires two quaternion multiplications. An alternative approach is to apply the pair of relations
:<math>\vec{t} = 2\vec{q} \times \vec{v}</math>
:<math>\vec{v}^{\,\prime} = \vec{v} + q_0 \vec{t} + \vec{q} \times \vec{t}</math>
Line 274:
:<math>
\begin{align}
\mathbf{q_1q_2q_xq_y} & = (r_1,\vec{v}_1_x)(r_2,\vec{v}_2_y) \\
& = (r_1 r_2 - \vec{v}_1_x \cdot \vec{v}_2_y, r_1 \vec{v}_2_z + r_2 \vec{v}_1_x +
\vec{v}_1_x \times \vec{v}_2_y) \\
\end{align}
</math>