This is part of the Rendering Tutorial

Rotating objects to acquire a better viewing angle

If we always would look to the objects from the bottom, it would alsways render us with a pretty dumb sight (just look at how dumb the house looks when viewed from the bottom). We want something better than that. But we don't want to touch our assumption of putting the camera along the Z axis, as this would make our projection from 3D to 2D a lot harder. We have one other option in order to view the objects from a different angle. We can rotate the objects around the origin of our 3D space, and we would automatically be looking at the object from a different place. Put the math of this section together with the projection code of the previous section, and you would be able to rotate the camera around the object, but I won't go into that.

I'll first explain how you can rotate your objects around each of the X, Y and Z axes for a given angle. After that I'll explain how you can do all these rotations at once. It'll get a tiny bit mathematical now, but it shouldn't be hard to understand.

Rotating around the Z axis

I'll first start with rotation around the Z axis as this is similar to the rotation of X, Y coordinates in a 2 dimensional plane, which can be easily understood. At your right you can see the result of rotating our house object over an angle of 45 degrees (pi/4 in radians) around the Z axis. Rotating around the Z axis is easy to understand as the Z values of our 3D coordinates remain the same where the X and Y values of the coordinates change. We can thus approach this mathematically from a 2 dimensional point of view.

If we have a point sitting at coordinate (x, y) and we want to turn it round the origin with an angle alpha, then the new coordinate of the point will become (x', y') with

x' = cos( alpha ) * x + sin( alpha ) * y and y' = -sin( alpha ) * x + cos( alpha ) * y

I have depicted this, for an angle of about 35 degrees, in the picture at your right. I have used the coordinate system of a computer screen in this picture, so the rotation is going clockwise, where it would go the other way round if you would be using high school coordinate systems (as everything is mirrored over the X axis, rotation goes the other way round).

In mathematics, the rotation operator for 3 dimensional coordinates over the Z axis can be represented by a 3x3 matrix that can operate on vectors with 3 elements denoting the X, Y and Z values with

(x') (cos( alpha )sin( alpha )0) (x)
(y')=(-sin( alpha )cos( alpha )0).(y)
(z') (001) (z)

Rotating around the X axis

Similarly, we can see the rotation around the X axis as an operator that only acts on the Y and Z coordinates, with the following matrix that can be applied to the 3D coordinates in order to obtain new coordinates after the rotation by an angle of alpha:

(x') (100) (x)
(y')=(0cos( alpha )sin( alpha )).(y)
(z') (0-sin( alpha )cos( alpha )) (z)

The picture on the right shows a rotation of our house around the X axis for an angle of 45 degrees, and its result on our camera's viewpoint. Things start to get interesting, as the house starts to come out a bit clearer, but we need to rotate it a bit more.

Rotating around the Y axis

Lastly, we can do the similar thing with rotations around the Y axis with

(x') (cos( alpha )0sin( alpha )) (x)
(z') (-sin( alpha )0cos( alpha )) (z)

In the picture on the right, the house is rotated over an angle of 45 degrees around the Y axis.

Rotating around multiple axes at once

In order to get a good viewing point of our 3D objects, we could use the rotation operators to turn around the objects in the 3 dimensional space such that we can, for example, view our house from a bird's eye view point. in the picture on the right, we have rotated the house around the X axis and Z axis, both with an angle of -2 * PI / 3.

There are a number of ways to obtain this position of the object. We could first rotate the house around the X axis and then rotate it around the Z axis. We could also have changed the order of these rotations. You could now wonder about the result of these two orders, and whether there would be a difference among both. The good news is that there isn't (I'm not going to explain why, this is pretty basic math, but beyond the scope of this tutorial). You could choose either orders and the result will be the same. So to make things easier, you could do the rotation around both the X, Y and Z axis at once if you multiply the rotation matrices. Indeed, if we combine the above matrices, then a rotation around the X axis by alpha, around the Y axis with beta and around the Z axis with gamma in one combined rotation matrix can be written as

(x') (cos( alpha ) * cos( beta );sin( gamma ) * cos( beta );-sin( beta );) (x)
(y')=(( sin( alpha ) * sin( beta ) * cos( gamma ) ) - ( cos( alpha ) * sin( gamma );( sin( alpha ) * sin( beta ) * sin( gamma ) ) + ( cos( alpha ) * cos( gamma ) );sin( alpha ) * cos( beta );).(y)
(z') (( cos( alpha ) * sin( beta ) * cos( gamma ) ) + ( sin( alpha ) * sin( gamma ) );( cos( alpha ) * sin( beta ) * sin( gamma ) ) - ( sin( alpha ) * cos( gamma ) );cos( alpha ) * cos( beta );) (z)

(This is a simplified version of the matrix, thanks to Walle for doing the math, I have used ";" characters so you can easily discriminate the elements of the matrix)

In the following sections, we'll be viewing the world from this latest viewing angle.

Speeding up computations

In order to rotate the objects in your 3D world according to our rotation matrix, you have to apply the above matrices to each of the coordinates in your world. So at first, this sounds like a computationally expensive task. However, note that the rotation matrices are independent of the X, Y and Z values of the coordinate that needs to be rotated around the origin. So, if you want things to go fast, you don't need to compute the transformation matrix for each of the coordinates, but you can compute it only once and apply it to all coordinates.

Rotating around an arbitrary axis

For now, we have only considered rotations around axes that go through the origin of our 3D space. But it's perfectly possible you somehow need to rotate around another arbitrary axis that doesn' go through the origin of your 3D world. this can be solved easily. Translate the coordinates of your world such that the rotation axis now contains the origin of your 3 dimensional space, apply the rotation matrix, and translate the coordinates back to reverse the first translation. Your objects have now rotated around your arbitrary axis.

The math is up to you. You can find an introduction on translations in the section on more transformations.


Sorting faces and using Z buffers

comments powered by Disqus