For the most part dealing with positions is fairly easy. You hardly need to learn matrices to to complex manipulations of positions. The hard part about 3d transforms is rotations. It took me a long time to really get rotations – and I would hardly describe my understanding of them as mastery, so there is still a long way to go, but what I do understand has been super useful in my everyday work.
Hopefully I’ll be able to convey my understanding of rotations and you’ll also find yourself more useful in your day to day work.
Rotations are hard to work with unless you know how they work together with matrices. Have you ever tried to use a rotation channel as a driver for an SDK? Doesn’t work so hot does it? Sure sometimes it can work, it depends on the specifics of what you’re trying to do. But in general they’re functionally useless.
Again using the maya docs (although this is I believe again fairly universal) we find that a 3d rotation is the result of multiplying three different matrices together – one for X, one for Y and one for Z. The order in which these matrices are multiplied together is the rotation order. So each axis has its own matrix, which look like this:
RX = | 1 0 0 0 | RY = | cy 0 -sy 0 | RZ = | cz sz 0 0 | | 0 cx sx 0 | | 0 1 0 0 | | -sz cz 0 0 | | 0 -sx cx 0 | | sy 0 cy 0 | | 0 0 1 0 | | 0 0 0 1 | | 0 0 0 1 | | 0 0 0 1 | where: cx = cos( x ) sx = sin( x ) etc...
So these are the individual matrices for the X rotation, the Y rotation and the Z rotation. To get the rotation matrix for a transform with XYZ rotation order, you multiply these matrices together in that order. Similarly for other rotation orders etc…
Now when you multiply these three matrices together, you get a big giant mess. But the big giant mess of a matrix can be used to turn euler angles into a rotation matrix, or can be used to figure out how to convert a rotation matrix back to euler angles. How? Well, lets figure out what the matrix for XYZ looks like. Doing the matrix multiplication is arduous – so I won’t do it here (in fact I was so lazy I wrote some code to do the multiplication for me. On a side note, does anyone know of any way to do algebraic matrix multiplication without having to buy matlab or some sort of crazy piece of software?). Anyhoo if you do it yourself, you’ll find the rotation matrix for an XYZ euler rotation looks like this:
XYZ = | cz*cy, sz*cx + cz*sy*sx, sz*sx - cz*sy*cx | | -sz*cy, cz*cx - sz*sy*sx, cz*sx + sz*sy*cx | | sy, -cy*sx, cy*cx |
Kinda ugly looking huh? But clearly this makes it super easy to get the matrix for an XYZ euler rotation. Simply calculate the cos and sin for the x, y and z angles and plug em into the equations here. Bam. You’re done. Like a ram. Or something… In fact if you look at the FromEulerXYZ method on the Matrix class, thats exactly what it does. So constructing a matrix from euler angles is a no brainer.
Converting from the matrix to the euler angles however is a little tricker. Figuring this out boils down to the fact that one of the matrix entries in this case is sy. Which means we can find the Y rotation easily by doing asin( XYZ ). Now using this, we can use the cx*cy and cz*cy entries to figure out rotation values for X and Z. Its not quite this simple, but its not far from it. As it turns out, all the other rotation orders have an entry we can use to figure out the rest. And again, if you check out the ToEulerXYZ on the Matrix class, the code is already written, I just figured it was useful to break down what is happening in there. Incidentally there is a more formal paper here which describes how this works in more detail. I learnt a bunch from it – although its not directly applicable to maya for a few reasons. But its still helpful.
Kinda shortish post I know. Originally this was going to be post number 4, but a few of you suggested that I do a post with some actual code, so I figured a walk through of the rotation mirroring node would do the job. Anyway, I’m not sure if folks are interested in me taking this topic any further. I was thinking of walking through an aim constraint (which I haven’t done yet – it’d be a fun exercise). Anyone have any thoughts?
This is post 5 in the matrix series.
This post is public domain
This entry was posted on Wednesday, October 6th, 2010 at 21:07 and is filed under main, tutorials. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.