## 2D Affine Transformations

Consider the figure of a heart draw above with the following points:

A: (-0.2, 0.1)
C: (-0.2, 0.2)
J: (-0.1, 0.3)
E: (0.0, 0.2)
G: (0.1, 0.3)
H: (0.2, 0.2)
I: (0.2, 0.1)
F: (0.1, 0.0)
D: (0.0, -0.1)
B: (-0.1, 0.0)


We would like to perform operations that manipulate this figure in space.

Vertex processing involves multiply matrices successively on one another. In the context of 2D, these are 3x3 matrices on homogenous coordinates.

There are 3 common affine transformations we can perform on a model:

1. Translation
2. Scale
3. Rotation

Given our 10 points above, we built a polygon shaped like a heart. Each homogenous point can be represented as a column matrix.

A 3x3 matrix of the form can be used to perform the necessary translation, scale, and rotation necessary on the point:

The above shows a simple matrix which will scale a polygon by $a$ width, and $b$ height.

We can then find $A^\prime$, the transformed point by performing the matrix multiplication:

### Translation

A 3x3 matrix can be set up to translate a model. This matrix in the form:

For example, to translate a model $0.2$ units to the left, and $0.2$ units down, we would construct the matrix:

Computing this for the point $A$ represented by a column matrix:

If we do this for all points in the figure, we will obtain this result:

### Scaling

We can perform scaling using the same approach as translation with an adjustment. Instead, our matrix can multiply against each component like so:

This will scale the figure by $n$ times.

We can also perform a non-uniform scaling by having different factors against each component:

This is the same matrix I had mentioned earlier, where it will scale a figure by $a$ times the width, and $b$ times the height.

To convince ourselves that these matrices do scale a point, we can work out $A^\prime$, by scaling $A$ with this matrix:

Applying this on point $A = \begin{bmatrix} -0.2 \\ 0.1 \\ 1 \end{bmatrix}$ , we get $A^\prime = \begin{bmatrix} -0.4 \\ 0.2 \\ 0.1 \end{bmatrix}$.

Computing this for all points leads to an object twice the size.

### Rotation

Rotating an object is not too hard. To rotate a point about the origin at an angle $\theta$, the rotation matrix can be expressed as

Note that the positive rotation is counter-clockwise.

For example, if we choose to rotate an object by $45^\circ$, the rotation is:

Rotating $A$ by this matrix will give us the evaluated result, $A^\prime = \begin{bmatrix} -0.1 \\ -0.2 \\ 1\end{bmatrix}$.

### Composite Transformations

We can also apply multiple transformation matrices on top of another. $M = M_0M_1M_2M_3$. These can all be multiplied together to obtain the single transformation matrix.

Since matrix multiplication is anti-commutative, we must take care in considering the order of operations.

A good way to think about applying multiple transformations on $A$, is to start from the latest transformation against $A$, and move bottom-up.

Think of it like a stack. The last transformation matrix specified is applied first.

Thus a transformation $M = RT$ is a translation followed by a rotation when evaluated. This is evaluated from right-to-left.

Evaluating from left to right would yield a completely different result. So be careful here.

### Demo

I have built a little program which can be played around with below to help understand how some of this 2D affine transformation works. 😄

• Enter a transformation matrix.
• Click on Add Transformation to queue up the transformation.
• When ready to transform the figure, click on Apply Transformation to see the effect.
• The textarea also includes a log file to indicate the order of the transformations being applied.

Note that for trigonometric expressions such as $sin 45^\circ$, you must evaluate the expression and enter it into the matrix. For example, $0.7071$ will be entered in.

The source code can be found in this Github repository: https://github.com/urbanspr1nter/cg-tools/tree/master/2d-affine-transformations