A practical look at quaternions and dual quats

What is a rotation vector?

Imagine a 3D vector from the origin

 

Magnitude of the vector is the angle of rotation

 

Direction of the vector is the axis to rotate around

 

Minimum representation of rotation

 

Forms a linear (but periodic) space

What is a quaternion?

First we make some algebraic elements with specific properties:

ii = -1 \quad jj = -1 \quad kk = -1 \quad ijk = -1
\Phi = xi + yj + zk

Then write our rotation vector as:

\exp(\frac{\Phi}{2}) = \cos(\frac{\theta}{2}) + \sin(\frac{\theta}{2})\frac{\Phi}{\theta}

We pass this through the exponential function:

w coef of the quat

x,y,z coefs of the quat

How do I use a quaternion?

We apply a quaternion to a point with a double sided sandwich operation:

p = xi + yj + zk

Let's make a point:

p' = qpq^{-1}

And a quat:

q = \cos(\theta/2) + \sin(\theta/2)v
q^{-1} = \cos(\theta/2) - \sin(\theta/2)v

(In fact there is a slightly faster formula)

How to convert a quat to a rotation matrix?

Imagine some quat rotates a vector:

p' = qpq^{-1}

All we have to do to get the rotation matrix is to apply the quat to each basis vector in turn:

Q[:, 0] = qiq^{-1}\\ Q[:, 1] = qjq^{-1}\\ Q[:, 2] = qkq^{-1}

How to convert Euler angles to a quat?

To convert Euler angles to a quat we will use the fact that they compose:

q_x = \exp(ix/2)\\ q_y = \exp(jy/2)\\ q_z = \exp(kz/2)\\ q = q_zq_yq_x

Just choose your ordering to match your Euler angle convention

(note we can of course expand this formula out for efficiency)

How could we represent translation?

We know we need 6 degrees of freedom

We could stack a rotation vector with a translation vector

\begin{bmatrix} r_i\\ r_j\\ r_k\\ t_i\\ t_j\\ t_k \end{bmatrix}

Rotation vector

Translation vector

}

}

This is a really good way of storing a transform

It is minimal (exactly 6dof)

It is intuitive

The relationship between rotation and translation

Imagine a line in 3D space, we will call it L

This line encodes a rotation about that line with the magnitude of the line as the angle of rotation:

We are now rotating about something that does not pass through the origin

\theta = |L|

How do we write a line?

Consider a line through a point a, and with a certain direction m, we could just stack them up:

L = \begin{bmatrix} m\\ a \end{bmatrix}

This is not unique, any point on the line produces a different numerical L despite being the same 3D line...

L = \begin{bmatrix} m\\ a\times m \end{bmatrix}

Do this instead:

This representation is called Plücker coordinates!

What happens if we add two lines together?

Consider two lines and add them together:

L_1 = \begin{bmatrix} m_1\\ a_1\times m_1 \end{bmatrix}

The pitch represents translation in the direction of the line!

L_2 = \begin{bmatrix} m_2\\ a_2\times m_2 \end{bmatrix}
L_1 + L_2 = \begin{bmatrix} m_1 + m_2\\ a_1\times m_1 + a_2\times m_2 \end{bmatrix} = \begin{bmatrix} m_3\\ a_3\times m_3 \end{bmatrix} + \begin{bmatrix} 0\\ hm_3 \end{bmatrix}

This thing is called a screw

Line bit (axis)

Not line bit (pitch)

We can always break up a screw into an axis and a pitch

What is a dual quaternion?

Write a screw like this:

s = ai + bj + ck + \epsilon(di + ej + fk)
ii = -1 \quad jj = -1 \quad kk = -1 \quad ijk = -1
\epsilon^2 = 0

Where:

BUT ALSO:

Again we just run it through the exponential function to get something we can apply to points:

q_\epsilon = \exp(s/2)

Why use dual quaternions?

q_{ij} = q_iq_j

They compose with a single multiplication

They are by default orthogonal

They are great for interpolation of poses

q_\alpha = \exp(s_1(1-\alpha) + s_2\alpha)

They are very easy to invert

q = \exp(s)\\ q^{-1} = \exp(-s)

They are numerically efficient

They have very neat formulations of kinematics and dynamics

Researchers love them

Dual quat to quat and translation vector

Consider a dual quat \(q_\epsilon\) and you want to break it into a quat \(q\) and a translation \(t\)

q_\epsilon =

We can read off the quat directly, q = w + xi + yj + zk

+ \epsilon(ai + bj + ck + d)
w + xi + yj + zk
q_t = q_\epsilon q^{-1} = \lambda(1 + \epsilon t/2)

To get the translation vector we then get rid of the rotation bit, grab the \(\epsilon i , \epsilon j, \epsilon k\) coefs and divide by the scalar bit

Quat and translation vector to dual quat

q_\epsilon =
q_t
q
q = w + xi + yj + zk
q_t = 1 + \epsilon(t_xi + t_yj + t_zk)/2

Make a standard quat to do the rotation

Make a dual quat that does translation only

Compose them

Summary

Rotations only:

  • Rotation vectors are great
  • Quats are intuitive (basically just rotation vectors)

 

Rotation and translation (6dof pose):

  • Rotation vector + translation is great

  • Screws are just made up of adding rotations about 3D lines

  • Dual quats are not so scary (just screws basically, and easy to convert to other formats)

Bonus: Why do the algebra rules for quats seem so arbitrary?

The quat rules are hiding the geometry of the rotation!

We can recover the quaternion multiplication rules if we compose reflections together.

 

Too long to go into here, but check out this video.