Quaternion

Definition

A quaternion {\bf q} is represented as a 4-tuple (a,b,c,d), with basis \{1,i,j,k\} written as

(1){\bf q} = (a,b,c,d) = a + b\ i + c\ j + d\ k.

The basis elements have multiplication property

i^2 = j^2 = k^2 = ijk = -1, \\
ij = k,\ jk = i,\ ki = j, \\
ji = -k,\ kj = -i,\ ik = -j.

The Hamilton product of two general quaternion is

(2)( & a_1, b_1, c_1, d_1)(a_2, b_2, c_2, d_2) \\
= ( & a_1 a_2 - b_1 b_2 - c_1 c_2 - d_1 d_2,  \\
    & a_1 b_2 + b_1 a_2 + c_1 d_2 - d_1 c_2,  \\
    & a_1 c_2 - b_1 d_2 + c_1 a_2 + d_1 b_2,  \\
    & a_1 d_2 + b_1 c_2 - c_1 b_2 + d_1 a_2).

A quaternion can be divided into a scalar part and a vector part

{\bf q} = (r, {\bf v}),\quad
\textrm{with}\ r\in\mathbb{R}, {\bf v}\in\mathbb{R}^3.

We also consider scalar r and 3-vector {\bf v} as special forms of quaternion

{\bf q}_r = (r, {\bf 0}),\quad
{\bf q}_{\bf v} = (0, {\bf v}),

and write {\bf q}_r and r ({\bf q}_{\bf v} and {\bf v}) interchangably in this note.

For quaternion {\bf q} defined in (1), its conjugate is

{\bf q}^* = a - b\ i - c\ j - d\ k,

its norm is

(3)\|{\bf q}\| = \sqrt{{\bf q}{\bf q}^*} = \sqrt{{\bf q}^*{\bf q}} =
\sqrt{a^2 + b^2 + c^2 + d^2},

and its reciprocal is

(4){\bf q}^{-1}=\frac{{\bf q}^*}{\|{\bf q}\|^2},\quad
{\bf q}{\bf q}^{-1} = {\bf q}^{-1}{\bf q} = 1.

Note that the multiplications in (3) and (4) are Hamilton product defined in (2).

Spatial Rotation

Given a unit vector \widehat{\bf u}=(u_x,u_y,u_z) with a scalar angle \theta, we define quaternion

{\bf q} =
\exp\left(\frac{\theta}{2}(u_x{\bf i}+u_y{\bf j}+u_z{\bf k})\right) =
\cos\left(\frac{\theta}{2}\right) +
\sin\left(\frac{\theta}{2}(u_x{\bf i}+u_y{\bf j}+u_z{\bf k})\right)

then for any given vector {\bf p}, its rotation across axis \widehat{\bf u} for angle \theta is

{\bf p}' = {\bf q}{\bf p}{\bf q}^{-1},

using Hamilton product (2). Note that both {\bf q} and -{\bf q} performs the same rotation.

Conversion between rotation matrics

Given a unit quaternion {\bf q}=(a,b,c,d), it can be converted to a rotation matrix as

\boldsymbol{R} = \left[\begin{array}{ccc}
1-2c^{2}-2d^{2} & 2bc-2ad & 2bd+2ac \\
2bc+2ad & 1-2b^{2}-2d^{2} & 2cd-2ab \\
2bd-2ac & 2cd+2ab & 1-2b^{2}-2c^{2}
\end{array}\right]

To convert from a rotation matrix \boldsymbol{R} to a quaternion,

{\bf q} = \Big(
& \frac{1}{2}\sqrt{R_{11}+R_{22}+R_{33}+1}, \\
& \frac{1}{2}\sqrt{R_{11}-R_{22}-R_{33}+1}\ \mbox{sign}(R_{32}-R_{23}), \\
& \frac{1}{2}\sqrt{-R_{11}+R_{22}-R_{33}+1}\ \mbox{sign}(R_{13}-R_{31}), \\
& \frac{1}{2}\sqrt{-R_{11}-R_{22}+R_{33}+1}\ \mbox{sign}(R_{21}-R_{12})
\ \Big).

This conversion can be implemented with a single square root, but one needs to take special care on numerical stability when doing so.

API References

Utility functions for quaternion and spatial rotation.

A quaternion is represented by a 4-vector q as:

q = q[0] + q[1]*i + q[2]*j + q[3]*k.

The validity of input to the utility functions are not explicitly checked for efficiency reasons.

Abbr. Meaning
quat Quaternion, 4-vector.
vec Vector, 3-vector.
ax, axis Axis, 3- unit vector.
ang Angle, in unit of radian.
rot Rotation.
rotMatx Rotation matrix, 3x3 orthogonal matrix.
HProd Hamilton product.
conj Conjugate.
recip Reciprocal.
quaternion.quatConj(q)[source]

Return the conjugate of quaternion q.

quaternion.quatFromAxisAng(ax, theta)[source]

Get a quaternion that performs the rotation around axis ax for angle theta, given as:

q = (r, v) = (cos(theta/2), sin(theta/2)*ax).

Note that the input ax needs to be a 3x1 unit vector.

quaternion.quatFromRotMatx(R)[source]

Get a quaternion from a given rotation matrix R.

quaternion.quatHProd(p, q)[source]

Compute the Hamilton product of quaternions p and q.

quaternion.quatRecip(q)[source]

Compute the reciprocal of quaternion q.

quaternion.quatToRotMatx(q)[source]

Get a rotation matrix from the given unit quaternion q.

quaternion.rotVecByAxisAng(u, ax, theta)[source]

Rotate the 3-vector u around axis ax for angle theta (radians), counter-clockwisely when looking at inverse axis direction. Note that the input ax needs to be a 3x1 unit vector.

quaternion.rotVecByQuat(u, q)[source]

Rotate a 3-vector u according to the quaternion q. The output v is also a 3-vector such that:

[0; v] = q * [0; u] * q^{-1}

with Hamilton product.