Quaternions§
splines.quaternion.UnitQuaternion
[1]:
from helper import angles2quat, plot_rotation
Quaternion Representations§
Algebraic§
where \(\mathbf{i}^2 = \mathbf{j}^2 = \mathbf{k}^2 = \mathbf{ijk} = -1\).
The order matters: \(\mathbf{ij} = \mathbf{k}\), \(\mathbf{ji} = -\mathbf{k}\).
Scalar and Vector§
Sometimes, the scalar and vector parts are also called “real” and “imaginary” parts, respectively.
4D Space§
Quaternions can also be imagined as four dimensional vector space with some additional operations.
More Representations§
There are even more ways to represent quaterions, for example as 4x4 real matrices or as 2x2 complex matrices.
Quaternion Operations§
TODO
Unit Quaternions as Rotations§
Given a (normalized) rotation axis \(\vec{n}_i\) and a rotation angle \(\alpha_i\) (in radians), we can create a corresponding quaternion (which will have unit length):
Quaternions are a double cover over the rotation group (a.k.a. SO(3)), which means that each rotation can be associated with two distinct quaternions. More concretely, the antipodal points \(q\) and \(-q\) represent the same rotation.
More information can be found on Wikipedia.
[2]:
identity = angles2quat(0, 0, 0)
[3]:
a = angles2quat(90, 0, 0)
b = angles2quat(0, 35, 0)
[4]:
plot_rotation({
'identity': identity,
'a': a,
'b': b,
}, figsize=(6, 2));
[4]:
[<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x7f28a2f4af50>,
<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x7f28a5068550>,
<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x7f28a2f2c310>]
[5]:
identity
[5]:
UnitQuaternion(scalar=1.0, vector=(0.0, 0.0, 0.0))
Unit Quaternion Operations§
quaternion multiplication: \(q_1 q_0\)
rotation \(q_0\) followed by rotation \(q_1\) (read from right to left)
\(q_0 q_1 \ne q_1 q_0\) (except if the rotation axis is the same)
[6]:
plot_rotation({'a b': a * b, 'b a': b * a}, figsize=(5, 2));
[6]:
[<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x7f28a2b7fe90>,
<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x7f28a2b57450>]
inverse: \(q^{-1}\)
same rotation axis, negated angle
\(q q^{-1} = q^{-1} q = (1, (0, 0, 0))\)
[7]:
plot_rotation({'b': b, 'b$^{-1}$': b.inverse()}, figsize=(5, 2));
[7]:
[<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x7f28a2a61350>,
<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x7f28a2e9c950>]
Relative Rotation (Global Frame of Reference)§
Given two rotations \(q_0\) and \(q_1\), we can try to find a third rotation \(q_{0,1}\) that rotates \(q_0\) into \(q_1\).
Since we are considering the global frame of reference, \(q_{0,1}\) must be left-multiplied with \(q_0\):
Now we can right-multiply both sides with \({q_0}^{-1}\):
\(q_0 {q_0}^{-1}\) cancels out and we get:
Relative Rotation (Local Frame of Reference)§
If \(q_{0,1}\) is supposed to be a rotation in the local frame of \(q_0\), we have to change the order of multiplication:
Now we can left-multiply both sides with \({q_0}^{-1}\):
\({q_0}^{-1} q_0\) cancels out and we get: