Code examples using quaternion for rotation?

Hi Rolf,

A little late to this quaternion party,
I’m not sure why you say you have to use quaternions, but not what you want to do with them - it seems a strange way round to start to me :thinking:
They do certainly have their uses, but depending on the problem may not be the only or best solution.

Anyway, assuming this is something to do with rotation, to throw another example into the mix, I’ve included below a simple linear interpolation, and also something I did using Quaternions to interpolate smoothly through a sequence of orientations.

If you just want to interpolate between one orientation and another, then you can use Slerp. Equivalently using (and I think perhaps more intuitive), just using RhinoCommon you can convert the rotation to axis and angle form using:
then just rotate by multiples of this angle to interpolate.

Here’s an example of this to interpolate between planes P1 and P2 by a factor of t:

Quaternion q = Quaternion.Rotation(P1, P2);
double angle = new double();
Vector3d axis = new Vector3d();
q.GetRotation(out angle, out axis);
Plane OutputPlane = new Plane(P1);
angle = (angle > Math.PI) ? angle - 2 * Math.PI : angle;
OutputPlane.Rotate(t * angle, axis, OutputPlane.Origin);
Vector3d Translation = new Vector3d(P2.Origin - P1.Origin);
OutputPlane.Translate(Translation * t);

However, if you have more than 2 orientations (such as a camera path that has to pass through a number of locations/targets), using Slerp between each one and the next will result in sudden changes of angular velocity.
To avoid this, you can build up quaternion splines by combining slerps, more or less like how you would make a bezier curve using straight lines.
This paper is a nice reference:

As an alternative to that though, I once tried out an idea for generating quaternion splines via stereographic projection from the 3-sphere of unit quaternions to regular 3d space, then using Rhino’s splines in 3d, and projecting back up into quaternion space to get the rotation.
Here’s a gh definition showing this: (24.4 KB)
It’s an unconventional approach, but seems to work reasonably well.

and here’s the code version of the same thing Michael was referring to: (4.9 KB)