Rotations in Three Dimensions

Part Two: Rotation Matrices

Written by: Confuted

Okay, so Iassume going intothis tutorial that you know how to perform matrix multiplication. I don'tcare to explain it, and it's available all over the Internet. However,once you know how to perform that operation, you should be good to gofor thistutorial.

The way presented for doing rotations in the last tutorial wasn'treally a goodone. It works just fine in two dimensions, but as soon as youwant torotate around the X or Y-axes, it becomes more difficult. Sure,it's easyto make equations that will represent a rotation on any one of thoseaxes, butjust go ahead and try to make equations that will represent changes onthreeaxes at once. If you manage to pull that off, make sure to let usknow. Meanwhile, I'll present a way to do the rotations withmatrices.

Matrices might seem scary, especially to someone who has never usedthembefore. However, they really aren't too difficult to use. They'realso very powerful. The first thing to note is that it ispossible to usea vector to specify a point in 3d space. Basically, every pointis adisplacement from the origin by a certain amount, which is described bythevector. Vectors are useful for lots of other things as well, andperhapssomeday I'll write about some of those. Meanwhile, we'll just usethemfor storing points.

A vector can be multiplied by a matrix, and after the multiplication,you'llget a new vector. This may seem useless, but when you multiplythe vectorby the *right* matrix, you'll get a point that has beentransformed by thematrix. This can mean rotated on any axis (including arbitraryones! that will come later), translated, or both. You see,thething with matrices is this: If you have one matrix representingrotationon the X axis, and another matrix representing rotation on the Y axis,you canmultiply them together to get a new matrix which represents therotation onboth axes. However, incase you didn't catch this in any tutorialsyouread about matrices, please note that if **A** and **B** arematrices, **A*****B**!= **B*****A**. This will cause us some problems later,but fornow, just keep it in the back of your mind.

I'm not going to derive these matrices that I'm about to give youhere. One reason is that it's been done other places. Another reason isthat itwould involve me explaining a lot of things that have also beenexplainedbetter elsewhere. The most important reason is because Ican't. However, that doesn't matter. You don't need to be able to derivethesematrices; you just need to know how to use them. You'll also needto knowwhich coordinate system you're using: left-handed orright-handed. OpenGLuses right-handed coordinates; DirectX uses left-handedcoordinates. Thisis also explained in detail elsewhere, so I won't go into it. Ifyou'renot using OpenGL or DirectX, either figure out what your API uses, orif you'rewriting your own or something, pick one and stick with it. Therewill beno turning back.

LeftHanded | RightHanded |

X Rotation * | 1 | 0 | 0 | 0 | 0 | cos (phi) | -sin (phi) | 0 | 0 | sin (phi) | cos (phi) | 0 | 0 | 0 | 0 | 1 | | Y Rotation * | cos (theta) | 0 | sin (theta) | 0 | 0 | 1 | 0 | 0 | -sin (theta) | 0 | cos (theta) | 0 | 0 | 0 | 0 | 1 | | Z Rotation * | cos (psi) | -sin (psi) | 0 | 0 | sin (psi) | cos (psi) | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | | | X Rotation * | 1 | 0 | 0 | 0 | 0 | cos (phi) | sin (phi) | 0 | 0 | -sin (phi) | cos (phi) | 0 | 0 | 0 | 0 | 1 | | Y Rotation * | cos (theta) | 0 | -sin (theta) | 0 | 0 | 1 | 0 | 0 | sin (theta) | 0 | cos (theta) | 0 | 0 | 0 | 0 | 1 | | Z Rotation * | cos (psi) | sin (psi) | 0 | 0 | -sin (psi) | cos (psi) | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | | |

*Where (phi) represents the rotation about the X axis, (theta)represents therotation about the Y axis, and (psi) represents the rotation about theZ axis

Those really aren't as complicated as theylook. Andfor those of you wondering why I didn't store all of those in 3*3matrices,just hold on ;) That's coming later. For the purposes ofthistutorial, I'm going to try to avoid picking a coordinate system, sothat itwill be equally useful for both OpenGL and DirectX programmers. We'llcall the rotation matrix for the X axis *matRotationX*, therotationmatrix for the Y axis *matRotationY,* and the rotation matrix forthe Zaxis *matRotationZ*.

By multiplying the vector representing a point by one of these matrices(withthe values properly filled in), you can rotate the point around anyaxis. However, you'll probably want to allow rotation about all threeaxes. Youcould multiply the vector by one matrix, then multiply it by the nextmatrix,then multiply it by the next matrix... but that would produce some veryslowcode, because you would be performing far too many operations for eachpoint. Matrices can be combined, which will save you some veryvaluabletime in your code. We'll call the matrix which represents allyourrotations *matRotationTotal*, and here's the way to generate it:

*matRotationTotal*=matRotationX * matRotationY * matRotationZ

After that, you can simply transform each point with *matRotationTotal*,and the point will be rotated about all three axes. When you needtochange the amount of rotation, rebuild *matRotationX, matRotationY, *and*matRotationZ*,and then multiply them together to get the new *matRotationTotal*. Pretty easy, and it gets points rotating around in threedimensions. (Note: If you don't know how to multiply matrices, or if you don't knowhow tomultiply a vector by a matrix, consult a basic tutorial and matrixmath. To give you a hint, a vector can be represented by a 1*4 matrix...)

That wraps up this tutorial. Go implement this if you thinkyou'reready. Alternatively, read the next tutorial first. Yourchoice.