 # The Transformation Matrix for 2D Games

This tutorial will introduce the Transformation Matrix, one of the standard technique to translate, rotate and scale 2D graphics. The first part of this series, A Gentle Primer on 2D Rotations, explaines some of the Maths that is be used here.

#### Introduction

In the previous post we have seen how a 2D point can be represented in the plane, and how trigonometry links its Polar and Cartesian representations: In a nutshell:  The second important result is that any given point an be rotated by an angle around the origin as follow:  These are the only two notions you need to understand this tutorial.

#### Matrix notation

When it comes to 3D graphics, there’s an alternative representation that is often encountered. A rotation can, in fact, be expressed as a matrix multiplication. To do this, let’s express as the column vector . The problem is now finding a matrix so that: Remembering matrix multiplication: Please, note that the result is a vector with one column. This makes sense, because the result is another point in the 2D plane. The matrix can be defined as: Every rotation of radians in the 2D plane can be obtained by multiplying a column vector by .

There are other operations which, unfortunately, cannot be achieved with this matrix. Translations is one of them. What we want is a new matrix such that: This is not possible with the current setting. In order to obtain this result, we need to modify the way is represented. The point is now represented by the three dimensional column vector . This is necessary in order to make the matrix multiplication works, since the new now has three rows and columns.

This technique is currently being used in most 2D graphics framework. The matrix is often called the Transformation matrix and can be used to perform the following operations: #### Composition

Using matrices to perform transformation has an incredible advantage: they can be multiplied together to perform multiple transformation. A single matrix can hold as many transformation as you like. In a nutshell: This is true because matrix multiplication is an associative operator. It is important to remember, however, that these transformations are not commutative. This means that is not the same as . Intuitively, this is obvious: rotating and translating is different from translating and then rotation.

#### Inversion

Transformations can be undone. For every transformation matrix which does rotates or translates, there is a matrix which performs the “opposite” operation. This means that if we apply , followed by , we obtain the original point: By using the associative property, we can get a glimpse of what this matrix is:   If you have a basic knowledge of matrix algebra, you should recognise this: is the inverse matrix of . Inverting a matrix is a non trivial task, and goes beyond the scope of this tutorial. However, you don’t really need to know how to invert a matrix to undo a transformation. Because of the way the transformation matrix has been constructed, it is always true that:  The meaning of these two equations should be intuitive to grasp: if you rotate a point of angles, followed by a rotation of , you get the original point. The same applies for translations.  From this, it follows that if you have a series of elementary rotations and translations, the inverse of their composition is the composition of their inverses, in reversed order: From a more general point of view, it is not true that all transformations can be undone. For instance the following transformations cannot be undone: Multiplying the component by zero destroys its information, which cannot be restored with another multiplication. Such transformation, however, is neither a rotation nor a translation. In this particular case, the matrix cannot be inverted. When this occurs, it is also referred as singular or degenerate. A matrix is singular is and only if its determinant is zero.

#### Rotation around a point

As seen in the previous part of this tutorial (A Gentle Primer on 2D Rotations), to rotate around an arbitrary point, we need to first make that our new origin of the Cartesian plane. Then we rotate the point, and finally we restore the origin of the plane. This can be expressed a composition of three transformations: It’s important to remember that, despite the order in which they are written, the first transformation is the one on right.

#### Conclusion

This post has introduced the transformation matrix, which is one of the standard ways in which transformations are stored and performed in computer graphics. We have explored the following transformations:

• Translation by : • Rotation by around the origin: • Rotation by around the point : The main advantage of the matrix notation is that transformations can be composed by multiplying their respective transformation matrices. This also allows to “undo” transformation by calculating the inverse of its matrix.

The next post in this series will focus on the geometrical consequences of the equations we have derived. This will help to demystify one of the most misunderstood concept of Maths: complex numbers. Their understanding is essential for quaternions.

#### Other resources

• Part 1. A Gentle Primer on 2D Rotations
• Part 2. The Transformation Matrix
• Part 3. Rotations in the Complex Plane
• Part 4. Understanding Rotations in 3D
• Part 5. Understanding Quaternions

A new tutorial is released every week.

##### 💖 Support this blog

This websites exists thanks to the contribution of patrons on Patreon. If you think these posts have either helped or inspired you, please consider supporting this blog.  1. Bryan

Hi Alan,
I’m trying to understand what a mentor has described to me and am looking for some additional help.

I am attempting to cancel out velocity of movement of a player when I’ve detected a collision, given the normal of the collision geometry, so that I have a smooth result that does not overlap the geometry of the collision.

Vector3 CancelCollision(Vector3 dVel, Vector3 normal)
{
Vector3 originalVector = dVel;
dVel = Vector3.Project(dVel, normal);

dVel = originalVector – dVel;

dVel = dVel.normalized * originalVector.magnitude;

return dVel;
}

This mostly works, but there is a small amount of error, which has been attributed by my mentor as being a discrepancy of the magnitude as a result of using the ‘shadow’ of the projection.

I’ve been told that I need to rotate the original velocity to a cardinal direction, do the calculation, then rotate the result back. I’ve been told that the only way to get the correct result is with matrix math, which I somewhat understand but do not understand within the context of the current application.

I have enjoyed reading through your article here. Thanks for the help.

### Webmentions

• Render 3D Projection with Rotation Matrix - CSE IULI October 3, 2018

Hi Alan,
I’m trying to understand what a mentor has described to me and am looking for some additional help.

I am attempting to cancel out velocity of movement of a player when I’ve detected a collision, given the normal of the collision geometry, so that I have a smooth result that does not overlap the geometry of the collision.

Vector3 CancelCollision(Vector3 dVel, Vector3 normal)
{
Vector3 originalVector = dVel;
dVel = Vector3.Project(dVel, normal);

dVel = originalVector – dVel;

dVel = dVel.normalized * originalVector.magnitude;

return dVel;
}

This mostly works, but there is a small amount of error, which has been attributed by my mentor as being a discrepancy of the magnitude as a result of using the ‘shadow’ of the projection.

I’ve been told that I need to rotate the original velocity to a cardinal direction, do the calculation, then rotate the result back. I’ve been told that the only way to get the correct result is with matrix math, which I somewhat understand but do not understand within the context of the current application.

I have enjoyed reading through your article here. Thanks for the help.

• Matriz de Transformação para jogos 2D | October 3, 2018

Hi Alan,
I’m trying to understand what a mentor has described to me and am looking for some additional help.

I am attempting to cancel out velocity of movement of a player when I’ve detected a collision, given the normal of the collision geometry, so that I have a smooth result that does not overlap the geometry of the collision.

Vector3 CancelCollision(Vector3 dVel, Vector3 normal)
{
Vector3 originalVector = dVel;
dVel = Vector3.Project(dVel, normal);

dVel = originalVector – dVel;

dVel = dVel.normalized * originalVector.magnitude;

return dVel;
}

This mostly works, but there is a small amount of error, which has been attributed by my mentor as being a discrepancy of the magnitude as a result of using the ‘shadow’ of the projection.

I’ve been told that I need to rotate the original velocity to a cardinal direction, do the calculation, then rotate the result back. I’ve been told that the only way to get the correct result is with matrix math, which I somewhat understand but do not understand within the context of the current application.

I have enjoyed reading through your article here. Thanks for the help.