Tuesday, 1 October 2013

3D Transformations

Similar to 2D transformations, which used 3x3 matrices, 3D transformations use 4X4 matrices (X, Y, Z, W)
3D Translation: point (X,Y,Z) is to be translated by amount Dx, Dy and Dz to location (X',Y',Z')
X' = Dx + X
Y' = Dy + Y
Z' = Dz + Z

or P' = T * P where
_   _
P' = |  X' |
|  Y' |
|  Z' |
|  1  |
-   -
_          _
T  = |  1 0 0 Dx  | = T(Dx,Dy,Dz)
|  0 1 0 Dy  |
|  0 0 1 Dz  |
|  0 0 0  1  |
-          -
_   _
P  = |  X  |
|  Y  |
|  Z  |
|  1  |
-   -

3D Scaling:

_   _
P' = |  X' |
|  Y' |
|  Z' |
|  1  |
-   -
_            _
S  = |  Sx 0  0  0  | = S(Sx,Sy,Sz)
|  0  Sy 0  0  |
|  0  0  Sz 0  |
|  0  0  0  1  |
-            -
_   _
P  = |  X  |
|  Y  |
|  Z  |
|  1  |
-   -

3D Rotation:

For 3D rotation we need to pick an axis to rotate about. The most common choices are the X-axis, the Y-axis, and the Z-axis
_   _
P' = |  X' |
|  Y' |
|  Z' |
|  1  |
-   -
_                           _
Rz = |  cos(theta) -sin(theta) 0 0 | = Rz(theta)
|  sin(theta)  cos(theta) 0 0 |
|       0           0     1 0 |
|       0           0     0 1 |
-                           -
_                           _
Rx = |  1     0           0      0 | = Rx(theta)
|  0 cos(theta) -sin(theta) 0 |
|  0 sin(theta)  cos(theta) 0 |
|  0     0           0      1 |
-                           -
_                           _
Ry = | cos(theta)  0 sin(theta)  0 | = Ry(theta)
|     0       1      0      0 |
| -sin(theta) 0 cos(theta)  0 |
|     0       0      0      1 |
-                           -
_   _
P  = |  X  |
|  Y  |
|  Z  |
|  1  |
-   -

Complex / Compound Rotations

Now what if rotations are to occur other than around one of the cartesian axes? There are two ways of looking at this:
1. A series of rotations about cartesian axes, which can be combined by multiplying the appropriate matrices together. Again, the righmost matrix is the operation that occurs first. Note that with this approach there may be more than one combination of rotations that yield the same end result.
2. An alternate axis of rotation can be chosen, other than the cartesian axes, and the point rotated a given amount about this axis. For any given orientation change there exists a single unique axis and rotation angle ( 0 <= theta <= 180 degrees ) that will yield the desired rotation. This alternative approach is the basis for "quaternions", which will not likely be discussed further in this course. ( Quaternions are used heavily in the WorldToolKit package, which is no longer produced, and can be useful for interpolating rotations between two oblique angles. )
Composition is handled in a similar way to the 2D case, multiplying the transformation matrices from right to left.

OpenGL Transform Operations

In OpenGL translation, rotation, and scaling are performed using commands such as:
glTranslate{fd}(X,Y,Z) - glTranslatef(1.0, 2.5, 3.0)
glRotate{df}(Angle, X, Y, Z) - glRotatef(60.0, 0.0, 0.0, 1.0)
glScale{df}(X, Y, Z) - glScalef(1.0, 1.5, 2.0)
What these commands do in practice is to generate the corresponding transformation matrix for the operation that was requested, multiply it by whatever matrix is currently on top of the currently active matrix stack, and replace the matrix on the top of the stack with the result. If you want to calculate and save the result of a complex series of transformations, one approach is to push an identity matrix onto the stack, perform each of the operations in turn, and then save a copy of the result from the top of the stack into a global or static variable, ( possibly popping it off the stack if it won't be needed there immediately. )