2D Affine Transformations
March 15, 2020
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:
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 width, and height.
We can then find , the transformed point by performing the matrix multiplication:
A 3x3 matrix can be set up to translate a model. This matrix in the form:
For example, to translate a model units to the left, and units down, we would construct the matrix:
Computing this for the point represented by a column matrix:
If we do this for all points in the figure, we will obtain this result:
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 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 times the width, and times the height.
To convince ourselves that these matrices do scale a point, we can work out , by scaling with this matrix:
Applying this on point , we get .
Computing this for all points leads to an object twice the size.
Rotating an object is not too hard. To rotate a point about the origin at an angle , 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 , the rotation is:
Rotating by this matrix will give us the evaluated result, .
We can also apply multiple transformation matrices on top of another. . 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 , is to start from the latest transformation against , and move bottom-up.
Think of it like a stack. The last transformation matrix specified is applied first.
Thus a transformation 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.
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.
textareaalso includes a log file to indicate the order of the transformations being applied.
Note that for trigonometric expressions such as , you must evaluate the expression and enter it into the matrix. For example, 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