Home About Me Notes Galleries Files Links
Cover Programming Maths Odd Bits
Cover Vectors
Cover Primitives Operations Matrix Operations Homogeneous Matrices

Matrix Operations

Addition, Negation, Subtraction and Scaling

Nothing much needs to be said about these operations. The procedures for adding, negating, subtracting and scaling matrices are the same as those for simple vectors. Actually, the need to do any of these operation on matrices is fairly uncommon.


Matrix Multiplication

In general, the result of multiplying one matrix with another is formed from dot products of the left matrix's rows and the right matrix's columns. For this reason the width of the left matrix and the height of the right matrix must be equal. The ‘free’ dimensions, the height of the left matrix and the width of the right matrix define the height and width of the result.

Matrices are commonly used to transform the positions of vertices in 3D graphics. Possible transformations include scaling, shearing and rotation in any combination. The transformation is achieved by multiplying each vertex's position vector (itself a kind of matrix) with the transformation matrix to form a new set of vertices.

To multiply a matrix and a vector, assemble a new vector from the dot products of successive rows of the matrix and the original vector. Strictly speaking, you're supposed to transpose the rows you extract from the matrix so they become column vectors. The dot product function needs two column vectors to work with. That's just prissy talk, really, when you can run your left finger across rows of the matrix and your right finger down the column of the vector as you perform the dot product operation.

P′    =    TP
=    
T₁₁  T₁₂  T₁₃
T₂₁T₂₂T₂₃
T₃₁T₃₂T₃₃
Px
Py
Pz
=   
·
T₁₁ Px
T₁₂ Py
T₁₃ Pz
·
T₂₁ Px
T₂₂ Py
T₂₃ Pz
·
T₃₁ Px
T₃₂ Py
T₃₃ Pz
=   
T₁₁Px+T₁₂Py+T₁₃Pz
T₂₁Px+T₂₂Py+T₂₃Pz
T₃₁Px+T₃₂Py+T₃₃Pz

Matrix multiplication is associative, even when the terms are a mixture of matrices and vectors. A transformation T, followed by another transformation T, then by T, all to be performed on a vector P may be written like this:

P‴  =  TTTP  =  T(T(TP))  =  (TTT)P

The last one is interesting because it shows that successive transformations can be combined into one matrix. This is handy when you have to perform compound transformations on thousands of vertices in a 3D program, say. You just have to know how to multiply one matrix by another.

The product of two matrices is calculated like this: Each entry in the product is positioned at some row i and some column j. Take row i from the left-hand matrix and transpose it. Now find the dot product of that and a column j taken from the right-hand matrix. That is the value of the entry at row i, column j. Repeat for the remaining entries.

A₁₁  A₁₂  A₁₃
A₂₁A₂₂A₂₃
A₃₁A₃₂A₃₃
B₁₁  B₁₂  B₁₃
B₂₁B₂₂B₂₃
B₃₁B₃₂B₃₃
  =  
Arow1T·Bcol1    Arow1T·Bcol2    Arow1T·Bcol3
Arow2T·Bcol1Arow2T·Bcol2Arow2T·Bcol3
Arow3T·Bcol1Arow3T·Bcol2Arow3T·Bcol3

OpenGL transformations

The graphics API OpenGL actually performs its transformations in reverse order to the sequence of tranformation commands in the program. This might seem a horribly backward way of doing things but actually leads to a simple interpretation of the transformations.

In OpenGL, each successive transformation command moves the coordinate system around relative to the previous one. The camera transform changes the coordinate system from the default Right, Up, Back to East, North, Up in metres, say. A translation to an aircraft's position in the world and a suitable rotation transform changes the current coordinate system to Starboard, Forward, Up, say. The plane may be drawn using its natural coordindates. Translate and rotate to the position and orientation of a laptop carried abord the plane and apply a suitable scale transform to change the cuurent coordinate system to the virtual laptop's screen, so that (0, 0, 0) is at the top left of the laptop's screen and (640, 480, 0) is at the bottom right. Assuming your camera is set up to see the laptop's screen, perhaps though the aircraft's window, further drawing commands will behave as if it's the virtuallaptop you're drawing to, not your real computer display.

The combined transformation matrix is a product of the camera matrix, some translations, rotations and a scale for the laptop's screen's resolution:

Mcombined = CTaircraftRaircraftTlaptopRlaptopSlaptop

That looks great and even reads left-to-right in the same order as the transformation cammands given in OpenGL code. Hang on! looking at the expression "T(T(TP))" as described in the previous section, aren't the OpenGL vertices first transformed by Slaptop and last transformed by C, the camera's tranformation matrix?

Yes, they are. When you look at the transformation matrices in right-to-left order, each transformation is applied to the vertices about a fixed coordinate system aligned to the (real) computer display. When you look the same matrices in left-to-right order, each transformation shifts the coordinate system around relative in position, orientation and scale to the previous one.

When a transformation command given to OpenGL, the transform's matrix is cunningly postmultiplied to the current ‘modelview’ matrix. The combined transformation then used to transform the OpenGL vertices by the usual way, by matrix premultiplication of the vertices. This is how OpenGL handles the moving reference frame method of specifying transformations.

Hopefully, you now understand the order of transformations in a product of transformation matrices, whether you regard transformations as something that happens to vertices about a fixed, global reference frame, or as a way of specifying successively local coordinate systems on which new vertices can be specified.


Transposing a Matrix

Tranposing a matrix is almost as trivial as tranposing a vector, Take the first row of the original matrix, transpose it and use it for the first column of the the tranposed matrix. Repeat for the other rows. ATcol(n) = Arow(n)T.

T
spam   eggs   biscuits
sausagebeansbrain
   =   
spam   sausage
eggsbeans
biscuitsbrain

It happens that AB = (BA)T. Matrix multiplication is not commutative.

The inverse of a rotation matrix can be found simply by transposing the matrix. This is handy to know, since finding the inverse of any old matrix is often laborious.


2D Matrix Transformations

The 2D identity matrix and the general form of the three basic transformation matrices are listed below.

The blue grids and axes indicate the transformed positions of the vertices taken from the green grids. A point (2,1), say, on the green xy grid, represented as a vector [2  1]T is transformed to the point (2, 1) om the blue x′y′ grid.

In OpenGL, the blue grids and axes show the new coordinate system relative to the previous one, after the transformation command is issued.

The inverse of each matrix is also given. An inverse transformation matrix can be used to undo the original transformation, though in OpenGL it's usually faster and easier to simply use the matrix push and pop commands.

Transformation Description  Matrix   Inverse 
Identity
(Nothing happens)
1  0
01
1  0
01
Scaling
(scale = 0.5)
x-scale  0
0y-scale
x-scale⁻¹  0
0y-scale⁻¹
Shearing along x
(x-shear = 0.6)
1  x-shear
01
1  x-shear
01
Rotation
(θ = 30°)
cosθ  ⁻sinθ
sinθcosθ
cosθ  sinθ
⁻sinθcosθ

Finding the inverse of an arbitrary matrix can be a bit of a hassle, and if you can understand statements like the inverse of a matrix A is the matrix formed from A's cofactors, transposed and scaled by the inverse of the determinant of A and the determinant of the matrix A can be found by cofactor expansion along any row or column of A, you probably know more about linear algebra than what these web pages have to offer. At least the inverse of any rotation matrix is trivial to find. The inverse of a rotation matrix is its transpose.


What about Translation?

It would seem that displacing all the vertices equally or moving the origin to a new location would be easy. Translation via matrix multiplication is actually impossible. Never mind that OpenGL can perform translation with a matix. It's still impossible. Notice how the origin in each of the diagrams above are unaffected by the transformations. That's because it's full of zeros and can't be multiplied by anything to form a product that isn't also full of zeros. Translation can only be performed by adding a displacement vector to the position vector of each vertex you come across.

The impossibility of a translation matrix would seem to limit the usefulness of matrix multiplication since commonly required transformations involve translations upon rotations upon more translations and yet more rotations with a bit of scaling thrown in somewhere. A single matrix that combines these transformations cannot exist, and performing multiple matrix operations and vector additions is computationally exorbitant.

The page on Homogeneous Matrices describes how translation with a matrix can be done. Prepare to breakfast at Milliways or at least lose a few sanity points.


3D Matrix Transformations

The 3D matrices for scaling and shearing, apart from being 3×3 in size, are trivially different from the ones used for 2D transformations. The 3D identity matrix is just a fatter version of the 2D one:

I
1  0  0
010
001

The only 3D transformation matrices that require a bit of thought are the ones used for rotation.


Rotation about a principal axis

Rotation about a principal axis in 3D is really a rotation in a plane formed by two other axes. It's not hard to see that the matrices below are copies of the 2D rotation matrix padded out with extra ones and zeros.

Matrix   Description
1  0  0
0cosθ⁻sinθ
0sinθcosθ
Rotation by θ about x
cosθ  0  ⁻sinθ
010
sinθ0cosθ
Rotation by θ about y
cosθ  ⁻sinθ  0
sinθcosθ0
001
Rotation by θ about z

By multiplying all three of these matrices, with appropriate values of θ for each, it's possible to come up with a matrix that can be used to transform a set of vertices to any new orientation, given those three euler angles.

Describing orientation with euler angles is useful for jointed objects such as gun turrets, cameras on dollies and other gimbled bits of machinery. Most such machinery have pitch upon yaw or roll upon pitch upon yaw.


Rotation about an arbitrary axis through the origin

This is best done with quaternion rotation, whatever quaternions are, exactly. Although the maths looks daunting, it's not really all that computationally expensive.

Let A be a unit vector that lies in the axis of rotation.
Let θ be the rotation angle.
This rotation can be described as a quaternion, Q where
Qx =  Axsin(
θ
2
),   
Qy =  Aysin(
θ
2
),     
Qz =  Azsin(
θ
2
),     
Qw =  cos(
θ
2
)  
This rotation quaternion can be converted into an equivalent matrix, T.
sx = 2Qx,   sy = 2Qy,   sz = 2Qz
wx = sxQw,   wy = syQw,   wz = szQw
xx = sxQx,   yy = syQy,   zz = szQz
xy = syQx,   yz = szQy,   zx = sxQz
T   =  
1 − (yy + zz)  xy + wz  zx − wy
xy − wz1 − (xx + zz)yz + wx
zx + wyyz − wx1 − (xx + yy)

Rotation about an arbitrary axis anywhere

Consider a point P that lies on the axis of rotation. For each vector to be transformed, subtract P so that P becomes the new origin, rorate about the origin as usual, then add P to the rotated vector to restore the original origin.

In OpenGL, simply translate by P, do the rotation, then translate by ⁻P.


Homogeneous Matrices

Read all about them on the next page.