Rotations in Three Dimensions: 3D Rotation Matrices


By confuted
Okay, so I assume going into this tutorial that you know how to perform matrix multiplication. I don't care 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 go for this tutorial.

The way presented for doing rotations in the last tutorial wasn't really a good one. It works just fine in two dimensions, but as soon as you want to rotate around the X or Y-axes, it becomes more difficult. Sure, it's easy to make equations that will represent a rotation on any one of those axes, but just go ahead and try to make equations that will represent changes on three axes at once. If you manage to pull that off, make sure to let us know. Meanwhile, I'll present a way to do the rotations with matrices.



Matrices might seem scary, especially to someone who has never used them before. However, they really aren't too difficult to use. They're also very powerful. The first thing to note is that it is possible to use a vector to specify a point in 3d space. Basically, every point is a displacement from the origin by a certain amount, which is described by the vector. Vectors are useful for lots of other things as well, and perhaps someday I'll write about some of those. Meanwhile, we'll just use them for storing points.

A vector can be multiplied by a matrix, and after the multiplication, you'll get a new vector. This may seem useless, but when you multiply the vector by the right matrix, you'll get a point that has been transformed by the matrix. This can mean rotated on any axis (including arbitrary ones! that will come later), translated, or both. You see, the thing with matrices is this: If you have one matrix representing rotation on the X axis, and another matrix representing rotation on the Y axis, you can multiply them together to get a new matrix which represents the rotation on both axes. However, in case you didn't catch this in any tutorials you read about matrices, please note that if A and B are matrices, A*B != B*A. This will cause us some problems later, but for now, just keep it in the back of your mind.

I'm not going to derive these matrices that I'm about to give you here. One reason is that it's been done other places. Another reason is that it would involve me explaining a lot of things that have also been explained better elsewhere. The most important reason is because I can't. However, that doesn't matter. You don't need to be able to derive these matrices; you just need to know how to use them. You'll also need to know which coordinate system you're using: left-handed or right-handed. OpenGL uses right-handed coordinates; DirectX uses left-handed coordinates. This is also explained in detail elsewhere, so I won't go into it. If you're not using OpenGL or DirectX, either figure out what your API uses, or if you're writing your own or something, pick one and stick with it. There will be no turning back.

Right Handed

Left Handed

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 the rotation about the Y axis, and (psi) represents the rotation about the Z axis

Those really aren't as complicated as they look. And for those of you wondering why I didn't store all of those in 3*3 matrices, just hold on ;) That's coming later. For the purposes of this tutorial, I'm going to try to avoid picking a coordinate system, so that it will be equally useful for both OpenGL and DirectX programmers. We'll call the rotation matrix for the X axis matRotationX, the rotation matrix for the Y axis matRotationY, and the rotation matrix for the Z axis matRotationZ.

By multiplying the vector representing a point by one of these matrices (with the values properly filled in), you can rotate the point around any axis. However, you'll probably want to allow rotation about all three axes. You could multiply the vector by one matrix, then multiply it by the next matrix, then multiply it by the next matrix... but that would produce some very slow code, because you would be performing far too many operations for each point. Matrices can be combined, which will save you some very valuable time in your code. We'll call the matrix which represents all your rotations 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 need to change 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 three dimensions. (Note: If you don't know how to multiply matrices, or if you don't know how to multiply a vector by a matrix, consult a basic tutorial and matrix math. 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 think you're ready. Alternatively, read the next tutorial first.


Previous: The basics of 3D Rotations
Next: Rotation About An Arbitrary Axis
Back to Graphics tutorials index