Interpolating Rotations in Geometric Algebra

A Concrete Implementation of Linear Interpolation

Our senior programmer, Jason Wood, is currently working on implementing geometric algebra (GA) into our gaming engine and animation software!


Below is a sample of his code: note how he makes use of a simplified API.

Rotor3 interpolate(Rotor3 const& a, Rotor3 const& b, Real t) {
 return a * exp(t * log(b / a));
}

What it's doing is first using geometric division (b/a) to compute the rotation between a and b (which itself is a rotor). Then it takes the logarithm of that, which returns a 3-d bivector, which is then multiplied by the t parameter (which varies between 0 and 1). We then take this scaled bivector and exponentiate it, which returns a rotor in the global frame. To make this useful, it's pre-multiplied by rotor a to place it in the frame of the rotation (i.e., to make it 'start at a').

This gives the same results as calling slerp(qa, qb, t) using quaternions.

It's easy to make a higher-order interpolation function, for example cubic interpolation between 4 rotors. First define a function to perform quadratic interpolation:

Rotor3 interpolate(Rotor3 const& a, Rotor3 const& b, Rotor3 const& c, Real t) {
 return interpolate(interpolate(a, b, t), interpolate(b, c, t), t);
}

Then define the cubic version:

Rotor3 interpolate(Rotor3 const& a, Rotor3 const& b, Rotor3 const& c, Rotor3 const& d, Real t) {
 return interpolate(interpolate(a, b, t), interpolate(b, c, t), interpolate(c, d, t), t);
}

This is basically doing a version of de Casteljau 'corner cutting' for Bezier curves, i.e., recursively breaking the problem into sub-problems and combining results.

May not be the fastest in the world, but it is pretty clean. A slightly less clean but possibly faster version could use cubic Hermite interpolation instead.

- Jason Wood

 

Previous
Previous

Inverse of a 3x3 or 4x4 matrix using the progressive product