Having some basic Matrix math operations available in OpenScad has been a wonderful thing. I found my life to be somewhat lacking though because rotations are a royal pain in the...
This thing adds Quaternion support to OpenScad
Besides sounding like a cool name for an 80s rock band, or a futuristic diabolical planetary leader, quaternions are a math construct that make doing rotations a fairly painless task.
basically: myquat = quat(axis, angle);
So, to do a 30 degree rotation around the z-axis for example, would look like this:
rotz = quat([0,0,1], 30);
Now, that's not going to do you much good in OpenScad by itself, so you need to turn it into a matrix that OpenScad can easily consume and apply as a transform, so you do this:
rotzmatrix = quat_to_mat4(rotz);
Once you have this, you can use it with multmatrix()
Ok, so wow, big deal!!
OK. So, combinations can be done like this:
q1 = quat([0,0,1],30);
q2 = quat([0,1,0], 15);
combo = quat_mult(q1, q2);
This will combine the 30 degree rotation around the z-axis, followed by the 15 degree rotation about the y-axis, or visa versa.
This is nice, because you can apply this transform anywhere you like, without having to go through gyrations such as:
If you've used an instance of this math library in the past, I've made a couple of changes. I've added more vecxxx calls, to support vec2, and vec3 more explicitly. The biggest change is to the mat4 (matrix4x4) routines. Basically, I was storing the data in 'row order' previously, which required a transpose of the matrix before using it with the multmatrix() module. So, I changed the ordering to be column major ordering (for those in the know). That aligns better with what OpenScad expects, so life gets easier as you don't need the transpose in the end.
At any rate, another batch of goodness for OpenScad.
NOTE: the 'quat_to_mat4()' function is an interesting piece of work. The equivalent 'C' code utilizes a lot of variables, which are not a part of OpenScad functions (as opposed to modules). This poses quite a challenge. So, how it's broken down into a cascade of functions demonstrates a general methodology for dealing with 'variables' in functions. Just turn each 'variable' into a function.
I left a few routines out from the first release of this thing, so I've added them in:
quat_conj(q) - conjugate of the quaternion
quat_distance(q1, q2) - distance between two quaternions
quat_norm(q) - the 'length' if you will.
quat_normalize(q) - normalize the quaternion
There is one more monster function to add: quat_slerp (spherical interpolation). As this one is more complex than the 'to_mat4', I'm having to think about it for a while. Not too bad, and it will come. Perhaps this will warrant a new version.