Code examples using quaternion for rotation?

I have to look into quaternions. But can anyone provide with a code example of how to use them?

For example rotating an object around a vector, and transforming an object from one plane to another. I know there are plugins that can handle quaternions (Falcon and Pufferfish has it) but I need to be able to code it myself (RhinoCommon quaternions).

I tried a bit but the results doesnā€™t make sense to meā€¦ What I did was creating a vector from two box corners (see fig below) and created a transform with zero radians rotation. That resulted in a box rotated 180 degrees (the green box below). And the quat.MatrixForm() (output to T) results in a weird flattened surface (red).

I obviously donā€™t have a clue. :slight_smile:

Fig 1. The code generating the above:

private void RunScript(double w, Vector3d v, ref object Q, ref object trx)
{
    var vec = cp1 - cp0;
    vec.Unitize();
    var quat = new  Rhino.Geometry.Quaternion(rad, vec.X, vec.Y, vec.Z);

    var out_rad = 0.0;
    var out_vec = Vector3d.Unset;
    quat.GetRotation(out out_rad, out out_vec);

    var xform = Rhino.Geometry.Transform.Rotation(out_rad, out_vec, cp0);
    geo.Transform(xform);

    Geo = geo;   
    T = quat.MatrixForm();  
}

Although totally useless, hereā€™s the script:
Quaternion_test.gh (6.4 KB)

< Embarrassed >

// Rolf

1 Like

Donā€™t know if itā€™s going to be any help for you, but hereā€™s a VB implementation of Silicon Graphics trackball routine which uses quaternions and has some comments and literature references embedded.

trackball.txt (10.7 KB)

1 Like

Pufferfish does have it but I did it the hard way - before I knew about the rhinocommon quaternions :smiley: (I coded what a quaternion does behind the scenes ala a reference from Daniel Piker, not actually using rhinocommon quaternions). @Dani_Abalde has the cleanest code for the rotation Iā€™ve seen using the Rhinocommon quaternions - we compared with Pufferfish vs his Plane interpolation in Peacock and results are the same. Maybe he will be nice enough to share with you :wink:

1 Like

I always thought that quaternions are only used to convert in between axis angle, euler and rotation matrices. ā€¦and interpolating/lerp in between.
However Iā€™m also having trouble understanding quaternionsā€¦ In case you need a c# implementation:

I found this here:

http://www.technologicalutopia.com/sourcecode/xnageometry/quaternion.cs.htm

2 Likes

@DanielPiker also has a nice Quaternion script that seems to have gone through some Obfuscation :wink: but I bet he can shed some light on the topic as well.

2 Likes

I only can help with this, interpolating two planes:

Quaternion q0 = Quaternion.Zero;
q0.SetRotation(Plane.WorldXY, fromPlane);

Quaternion q1 = Quaternion.Zero;
q1.SetRotation(Plane.WorldXY, toPlane);

Quaternion q2 = Slerp(q0, q1, st);

Plane slerpPlane = Plane.Unset;
q2.GetRotation(out slerpPlane);

And I hope no one asks me why it works xD
I get the slerp from three.js

2 Likes

.Netā€™s Media3d namespace also has Quaternion.Slerp.

Thank you guys, you are wesome, all of you! I wonder if you really are aware of how special this community is?

Iā€™m quite confident that I will find my way through the dark valley of quaternion with the help of all your hints and links. I will not have to dive all the way to the bottom of the swamp, but being able to utilize the concept in practice, and doing all the conversions, seems to lay whithin reach for my level of math. With this help.

Thank you all for all the valuable links, starting from @AlWā€™s uploaded code examples (I already refactored it to make it ā€œhuman readableā€ (ā€¦) and @TomTomā€™s link, @Michael_Pryorā€™s hint about the Obfuscated Quaternion (to make this challenge a bit more interesting) to @Dani_Abaldeā€™s elegant snippet of how to apply the quaternions for common tasks.

An last but not the least, Slerping is essential, Lerping too, although I didnā€™t know that before three or four days ago when I still thought that Euler or Spherical coordinate system would solve all the worldā€™s problems. :slight_smile:

Thanks. I will let you know if I come out of this with the hairy end in the euclidian Z+ direction. :slight_smile:

// Rolf

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: http://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_Quaternion_GetRotation_1.htm
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:
QuaternionSpline2.gh (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:
QuaternionSpline.gh (4.9 KB)

5 Likes

I get a ā€œcertificate errorā€ on this from MIT. Is it just me, or is there a general reason?

Edit: Nevermind. I subsequently went just to https://web.mit.edu and then searched for QuaternionReport1.pdf and found it. Thanks for the reference.

I will use it for shoulder simulations. 3 DOF (actually more, but to start with). IK-like problems follows, since Iā€™m also making a UI where you grab the hand and twist the arm around, until it dislocates (due to injuries on the humeral head and glenoid. Mesh surface collisions involved).

So yes, I will need to apply all the math I can force myself into. :slight_smile:

Thank you very much also for the last example. You already guessed why SLERP is of interest in this context.

I will also have to convert (series of) angle and position data into euclidian dittoā€™s, both World and CPlanes, oriented to the skeletal joints involved (this to be recorded as simulation results).

This is only one example (of several examples) of why Bongo fails to serve my needs - I cannot log, or record, the positions and orientations while in motion (I needed it for another purely ā€œmechanicalā€ project as well butā€¦ never mind). Nor can I script-feed Bongo with motion paths. And thus it cannot produce the ā€œresearch dataā€ (nor log-data for post-op analysis) which Iā€™m after.

But with GH I can.

In short, I will have to make my own IK Solver. (therefore, hints on existing .NET libraries for rigidbody IK chains is also welcome, saving me timeā€¦ ).

So detailed output data is one reason to why I need access to source code at all times. It follows that cheating isnā€™t an option. :sweat_smile: (so, itā€™s not that I dislike existing plugins, no no, Iā€™d love to jump fences, but closed source components just donā€™t ā€œlet me inā€ so to speak).

Have a good one.

// Rolf

Stumbled upon this, couldnā€™t resist :

"Quaternions came from Hamilton after his really good work had been done, and though beautifully ingenious, have been an unmixed evil to those who have touched them in any way." ~Lord Kelvin

And why anyone would still consider taking the pain:

// Rolf

3 Likes