Matrices

 

Matrices are a fundemental concept in computer graphics/games these days. A matrix can represent many different things, rotation, transformation, scaling, shearing e.t.c. - the word matrix just means "container". I should mention that I use row major in this website which maybe different from how you are used to - a side effect of lots of PS2 programming.

 

The simplest matrix is the identity matrix which I have mentioned in the rotation section. The rows of our matrix represent the basis vectors I talked about in the last section, since I am assuming you have read that section I'm going to move onto talking about rotation matrices directly.

 

Multiplying two matrices A and B

Multiplying two matrices together results in another matrix, the general rule for multiplying matrices is "multiply row into coloumn and sum":

 

AB = C

 

[a0,a1]   [b0,b1]     [a0b0 + a1b2,   a0b1 + a1b3]

|   |    |    |  =  |                        |

[a2,a3]   [b2,b3]     [a2b0 + a3b2,   a2b1 + a3b3]

 

 Here A is transformed by B to yeild C.

 

Rotating a matrix from world space into object space

Here we are going to rotate the first matrix A into the space of the second, B.

 

A BT = C

 

A has basis vectors U and V and B has S and T.

 

[U_x,U_y]   [S_x,T_x]     [U_x*S_x + U_y*S_y, U_x*T_x + U_y*T_y]

|       |   |       |  =  |                                    |

[V_x,V_y]   [S_y,T_y]     [V_x*S_x + V_y*S_y, V_x*T_x + V_y*T_y]

 

You will notice that B (consisting of S_x S_y, T_x T_y) has been transposed so that the rows and columns are swapped - this is because we want to arrange the maths so that we are performing the same projection operation as was discussed in the last section (i.e. projection onto the axis) because we must multiply row into coloumn.

The same operation expressed in terms of vectors looks like this:

 

[U] . [S]   =   [U.S   U.T]

[V]   [T]       [V.S   V.T]

 

You can see that the result is the same, we are still projecting the axis of A (i.e. U and V) onto the axis of B (S and T) to yield a new matrix which is A in terms of B. I.e. we now have a set of weights which describe a linear combination of the basis vectors of B (S and T).

 

Rotating a matrix from object space into world space

Now, just as when we were dealing with vectors we can use our set of weights (which is our matrix in the space of another matrix) to form a linear combination and resolve back into world space:

CB = A

C is our matrix of weights, B is as before and it yields the result A which we started out with in the last example. There is no need for the transpose function this time because we already have our weights and we just want to recombine them with our basis matrix B.

As an illustration of basis vectors and what I mean by linear combination of basis, here is an example of how to draw a rotated semi circle without knowing the rotation angle:

You will be used to using the sine and cosine functions in order to draw circles/semi circles in 2d;

x = cos(a)

y = sin(a)

-PI < a < PI

But what about when we are given a vector V and we want to have our semi circle perpendicular to this vector?

First we need to find our basis. We already have our up vector which is simply U = V / ||V|| and get can get our right vector using the perp operator R = perp(U). Now we have our basis, sin and cos become our weights and we can find the rotated semi circle thus:

P = cos(a)*R + sin(a)*U

 

<awaiting applet>

Transformation matrices

 

So far we have been talking about rotation matrices but more often than not we actually end up dealing with transformation matrices when programming, since our objects have positions as well as rotations. A transformation matrix is one which contains this positional component "tacked" onto the end of the matrix after the rotational part as an additonal row. When we deal with transformation matrices we must also deal with points instead of vectors since a vector doesn't have a position, it only has a direction and magnitude. In 2d a trasformation matrix looks like this:

 

[R_x, R_y]

[U_x, U_y]

[T_x, T_y]

 

Points

A point is simply a position in space. It is represented, again, as a linear combination of the local basis (in 3d):

P = aX, bY, cZ, 1

We store the a,b,c part and ignore the X Y Z because its implicit and refers to the local basis vectors X Y Z. Although a point and a vector look very similar, they are not the same and should be treated differently.

You will have noticed that the point has a 1 as it's last component; this is called the homogenus component and it ensures that the matrix multiply works with our transformation matrix which has another row tacked onto the bottom of it (in 2d):

 

P*M = P'

expanded out:

[P_x, P_y, 1] * [R_x, R_y]

                [U_x, U_y]   =  [P_x*R_x + P_y*U_x + T_x,

                [T_x, T_y]       P_x*R_y + P_y*U_y + T_y]

 

You may choose not to store this homogenus component and simply assume it when you actually come to implement the maths.

Points cannot be rotated into the space of a matrix like vectors could, they must instead be transformed and we cannot use the transpose of a matrix to do this (like we could for a vector), we must instead use the inverse. However, we can use a trick to do the job for us; if we first convert our point into a vector we can then rotate by the transpose of the matrix to get the same result:

P = point to transform

T = origin of transformation matrix M

R = rotational part of transformation matrix M

P' = R*(P-T)

which is the same as saying

P' = (P-T)*RT

We have converted our point into a vector pointing from origin of the matrix M to our point and then rotated this vector into the space of the matrix R to yield the new point P'.

This is the same operation as if we were to compute the inverse of the matrix M and transform P by it (assuming orthonormality).

 

If we want to do the oposite and take a point in object space and transform it into world space we can use the same thinking and keep the rotational part of the matrix separate from the translational part, but it turns out exactly the same in this case, due to the internals of the transformation matrix: (you can see how in the section on multiplying two matrices above)

P' = (P*R) + T

=

P' = P*M

 

Inverse of a matrix

All the matrices we have talked about have been orthonormalised which means that computing the inverse is fairly simple. You just transpose the rotational part of the matrix and then rotate the translational part into the space of it and negate:

 

Matrix M with rotational component R and tranlastional component T:

R-1 = RT

T-1 = -T*RT

To form M simply tack the translational part onto the rotational as before. Then when you come to transform your points by this matrix, the resulting maths is the same as the trick I showed above for transforming vectors by the inverse of a matrix implictly(which is reassuring):

 

The inverse of a transformation matrix is much more useful when it comes to operating on other transformation matrices; for example in a game what you actually pass to the hardware when you want to draw a model is a matrix which transforms from object space into view space, which involves inverting the camera matrix and multiplying the object's matrix by it (and also the perspective matrix depending on platform). Skeletal animation and skinning is also something which makes use of the inverse - often you would like to transform things into and out of "bone" space in order to deform the vertices of a mesh correctly.