I have been trying to wrap my mind around the SQUAD algorithm (sometimes called "Spherical Cubic Interpolation", sometimes called "Spherical Quadratic Interpolation").
You can find implementations and algorithms here, here and here.
If I understand it correctly it's supposed to smooth out rotations using 4 quaternions that are in sequential order in an animation with rotation keyframes.
Now I do get SLERP and I claim to have a fairly good visualization of the hypersphere and how quaternions describe it's "surface" (does the term "surspace" exist?)
However I was confused as to why the SQUAD algorithm should work. To understand it better I simply took some paper and drew the algorithm in 0.2 steps using 2d points and LERP, pretending the paper is the surface (surspace?) of the unit hypersphere. The curves I am getting look like they are exact mirror images of what I think I actually want to have.
Maybe I am still lacking some fundamental knowledge of quaternions. I have attached a scan of my drawings:
So, my concrete questions:
- Am I doing something wrong?
- Am I misunderstanding what SQUAD does or
what it is for? - Am I fundamentally misunderstanding quaternions and
the curves I get are actually super fine?
Best Answer
Okay, so
SQUAD
does exactly what I did on paper. But it's also not broken.My mistake was:
SQUAD
doesn't expect 4 consecutive quaternionsq0
,q1
,q2
andq3
.SQUAD
expectsq1
andq2
, together with 2 helper quaternionsa
andb
that have to be calculated beforehand.The helper quaternions
a
andb
will form a quadrangle withq1
andq2
that will result in curves resembling the mirrored curves in my drawing. Therefore using SQUAD onq1
,q2
,a
andb
will result in smooth interpolations over a list of rotation keyframes.I haven't found any detailed documentation or explanation on this unfortunately, but the
DirectX SDK
from Microsoft has a SquadSetup method that helped me figure this out. The open source library Cesium JS also has an implementation Quaternion.computeInnerQuadrangle for finding the helper quaternionsa
andb
to be used withSQUAD
.I haven't really understood why the helper quaternions are calculated in the way they are, but when I implement it, the result doesn't look wrong. Considering my original question is answered, this specific issue can be adressed in a separate question.
To help me get a better understanding for what's going on, I made a simple WebGL demo comparing different interpolation methods, including
SQUAD
the correct way and as I previously wrongly used/understood it. The demo generates 10 random unit quaternions and then interpolates between them indefinitely. It shows 12 WebGL canvas instances, 2 per algorithm. The top canvas displays the quaternions in 4d space and the current interpolated quaternion, the bottom canvas displays a cube that is being rotated by the current quaternion.