Messing with the Matrix: CGAffineTransform (Swift, iOS, Xcode)


I've been writing quite a few posts recently about CGAffineTransform and CATransform3D functions. They are something that I never really took the time to grasp until recently and wanted to share some findings, mainly because reading around it appears I'm not the only one who has failed to immediately understand the logic of these transformations.

Apologies for any repetition or cross-over with earlier posts, but there is quite a bit of new information in this collection of notes.

Direct manipulation of the matrix

The following transformation makes no changes to a UIView that it transforms:
CGAffineTransformMake(1, 0, 0, 1, 0, 0)
It simply multiplies x by 1 and y by 1 and repositions each point using this formula. The result of which is that x and y points remain static. It does not change the default, or "identity transform", and so simply repeats the values of each matrix position that you would find should you work through the transform value of any (untransformed) UIView.

But if we were to do this:
CGAffineTransformMake(1, 0, 2, 1, 0, 0)
The transformation would result in x = 1 * x + 2 * y and y = 0 * x + 1 * y and therefore stretch the view, pushing all x points except where x = 0 over to the right.

Correspondence between properties and the matrix

The read/write properties belonging to a CGAffineTransform are listed as a, b, c, d, tx and ty and as Apple explains these correspond to the matrix in the following way:
a = The value at position [1,1] in the matrix.
b = The value at position [1,2] in the matrix.
c = The value at position [2,1] in the matrix.
d = The value at position [2,2] in the matrix.
tx = The value at position [3,1] in the matrix.
ty = The value at position [3,2] in the matrix.

where the matrix is arranged in this way:


Correspondence between CGAffineTransform functions and the matrix

If we wrote the following:
CGAffineTransformMake(2, 0, 0, 2, 0, 0)
We would be setting a (or position 1,1) to 2 and d (or position 2,2) to 2. Resulting in:

x' = 2 * x + 0 * y + 0
y' = 0 * x + 2* y + 0

This is exactly the same result as scaling the view to double its size by writing:
CGAffineTransformMakeScale(2, 2)
Note: It is important to point out here that transformation happens about the centre point of a view (whichever function is used), so scaling by 2x a view of size 200x200 with origin 0,0 would result in a new origin of -100,-100, since the view will have expanded by 100 in each direction (up, down, left and right).

The untouchables

In a CGAffineTransform you can change all values except (1, 3),  (2, 3) and (3, 3), which determine the factor by which the coordinates have been scaled (see homogenous coordinates). All other properties can be manipulated to create all manner of bespoke transforms should you wish to do so.

Endorse on Coderwall

Comments