Transformations

Transformations are functions that take a position and return a new position

    newpos = ApplyRotation(pos)

All GL transformations (translate, rotate, scale) are simple operations on the (X, Y, Z) values of points






Translation

Translation is addition of an offset. e.g. to translate by (-1, 0, 3):

    newx = x + -1
    newy = y + 0
    newz = z + 3
or
    [ newx newy newz ] = [ x y z ] + [ -1 0 3 ]





Scaling

Scaling multiplies each coordinate by a value:

    newx = x * sx
    newy = y * sy
    newz = z * sz





Rotation

Rotation about the Z axis:

    newx = x * cos(a) - y * sin(a)
    newy = x * sin(a) + y * cos(a)
    newz = z 

Rotation about X or Y is similar, with just the x, y, & z variables shuffled around.

Rotation about an arbitrary axis is more complex, but based on the same idea






General Transformations

In general, the math for any transformation, or combination of transformations, looks like:

    newx = Ax + By + Cz + D
    newy = Ex + Fy + Gz + H
    newz = Ix + Jy + Kz + L

This can be simplified by treating positions as 4-coordinate vectors, where the last coordinate (w) is usually 1.

The transformation is then a 4x4 matrix which the vectors are multiplied by.

                              | A E I M |
 [ X Y Z W ] =  [ x y z w ] * | B F J N |
                              | C G K O |
                              | D H L P |





Columns vs Rows

In some cases, the matrix transformation is written flipped around:

    | x |     | A B C D |     | x |
    | y |  =  | E F G H |  *  | y |
    | z |     | I J K L |     | z |
    | w |     | M N O P |     | w |

The two are mathematically the same.






Identity Matrix

The identity matrix, generated by glLoadIdentity(), leaves vertex data unchanged:

    |  1   0   0   0  |
    |  0   1   0   0  | 
    |  0   0   1   0  | 
    |  0   0   0   1  | 





Translation Matrix

A translation matrix looks like:

    |  1   0   0   0  |
    |  0   1   0   0  | 
    |  0   0   1   0  | 
    | tx  ty  tz   1  | 

e.g. translating by (-1, 0, 3) is

                |  1  0  0  0  |
  [ x y z 1 ] * |  0  1  0  0  |
                |  0  0  1  0  |
                | -1  0  3  1  |

The matrices for translation, rotation, scaling, and projections are all described in Appendix F of the OpenGL book.






Combining Transformations

Two transformations are combined by multiplying their matrices.

    glTranslatef(-1,0,3)
    glRotatef(45, 0, 0, 1)
yields:
| .707 -.707 0 0 |   |  1  0  0  0  |   | .707 -.707  0  0 |
| .707  .707 0 0 | * |  0  1  0  0  | = | .707  .707  0  0 |
|   0     0  1 0 |   |  0  0  1  0  |   |   0     0   1  0 |
|   0     0  0 1 |   | -1  0  3  1  |   |  -1     0   3  1 |





Inverse Transformations

The inverse of a transformation T (one that "undoes" T) has as its matrix the inverse of T's matrix.

i.e. T * T-1 = Identity






OpenGL Matrices

Fixed-function OpenGL stores a ModelView matrix and a Projection matrix, which can be manipulated by glTranslate, glRotate, etc, as well as the following:

glMultMatrix(m)
Multiply current transformation by a matrix

glLoadMatrix(m)
Replace current transformation by a matrix

glGetFloatv(GL_MODELVIEW_MATRIX)
Returns current transformation matrix



Shader-based OpenGL supports matrices as a basic data type in shaders, but does not include glTranslate, etc.

They must be replaced by a separate library, with the matrices passed as shader attributes.






PushMatrix / PopMatrix

Fixed-function OpenGL maintains a stack of saved transformation matrices.

glPushMatrix() & glPopMatrix() save and restore transformation state.



Make sure you always have the same number of pushes & pops.

The number of transformations you can save is finite; it is at least 32.

Example: pushpop.py






Hierarchical Transformations

Hierarchical transformations can be thought of as transformations that are "attached to" other transformations.

They are used to transform objects relative to other objects.

A common use is in articulated bodies.






Hierarchical Transformations

We can draw this "car" by transforming the two wheels relative to the body of the car.

We'd like each wheel to be affected by the car body's transformation, but not by any other wheel's transformation.






Hierarchical Transformations

This can be accomplished by saving & restoring transformation state.

apply body transformation
draw body
save state
apply front wheel transformation
draw wheel
restore saved state
apply rear wheel transformation
draw wheel

Examples:






Transformation Hierarchy

Hierarchical transformations are often represented as a tree of transformations.

This is the basis of scene graph systems.



Creative Commons License
This document is by Dave Pape, and is released under a Creative Commons License.