All affine transformations in 2D can be expressed as a matrix of the form:
[ ac dx ] T = [ bd dy ] [ 0 0 1 ]
This can be expressed by the context.transform(a, b, c, d, dx, dy); method context.transform(a, b, c, d, dx, dy); .
When applying to some coordinate (x,y) , you first need to add the third coordinate, which is always 1 : <x, y, 1> . Then you can multiply the transformation matrix to get the result:
[ a*x + c*y + dx ] [ b*x + d*y + dy ] [ 1 ]
If in the last coordinate you get anything other than "1", you need to divide the vector into it.
To go the other way, you have to invert the matrix:
[ d/M -c/M (c*dy - d*dx)/M ] [ b/M a/M (b*dx - a*dy)/M ] [ 0 0 1 ]
where M (a*d - b*c) .
Several transformations can be applied sequentially by multiplying their matrices. The order of the multiplications is important.
context.translate(dx,dy) <==> context.transform( 1, 0, 0, 1, dx, dy) context.rotate(θ) <==> context.transform( c, s, -s, c, 0, 0) context.scale(sx,sy) <==> context.transform(sx, 0, 0, sy, 0, 0)
where c = Math.cos(θ) and s = Math.sin(θ)
If you have a coordinate (x,y) in the space of objects, and you want to know where it will appear on the screen, you will apply a transformation to it.
If there is some coordinate (x,y) on the screen, and you want to find out which point on the object, then you multiply by the inverse of the transformation.