In my 2D animation program I have a sprite which transformation is described by a 2D affine transformation matrix (SVGMatrix):
$$ \begin{bmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \\ \end{bmatrix} $$
I'm trying to figure out how to set this sprite position to given screen coordinates:
$$ \begin{bmatrix} x \\ y \\ 1 \\ \end{bmatrix} $$
The sprite position is the position of sprite's pivot point, which is defined by sprite's transformation matrix.
For example, if a sprite of 64 x 64 pixels in size has this transformation matrix:
$$ \begin{bmatrix} 2 & 0 & 32 \\ 0 & 2 & 32 \\ 0 & 0 & 1 \\ \end{bmatrix} $$
...The sprite's pivot point is in its center, and the sprite is scaled x2.
The operation I look for, set_position(x, y), should change sprite's transformation matrix in such way, so that the center (pivot point) of this sprite will be at $(x, y)$.
(Unfortunately, I'm quite rusty on the topic and googling does not yield anything satisfactory. However, I feel that this is an embarassingly basic question...)
Say, I want the sprite to appear at $(300, 200)$:
set_position(300, 200)
For a sprite with identity transformation matrix —not scaled, rotated, inverted or skewed, pivot at $(0, 0)$:
$$ \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{bmatrix} $$
...The result would be:
$$ \begin{bmatrix} 1 & 0 & 300 \\ 0 & 1 & 200 \\ 0 & 0 & 1 \\ \end{bmatrix} $$
If the sprite was scaled:
$$ \begin{bmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \\ \end{bmatrix} $$
...The result should take that in account:
$$ \begin{bmatrix} 2 & 0 & 150 \\ 0 & 2 & 100 \\ 0 & 0 & 1 \\ \end{bmatrix} $$
Same thing for rotation, inversion and skew/shear.
That is, for a sprite of 64 x 64 pixels in size, this operation (in pseudocode) would move the sprite's pivot to its center and will rotate around the pivot by 90 degrees:
translate(32, 32)
rotate(π/2)
The corresponding matrix for the sprite:
$$ \begin{bmatrix} 0 & 1 & 32 \\ -1 & 0 & 32 \\ 0 & 0 & 1 \\ \end{bmatrix} $$
Now, my set_position(300, 200) operation should change the sprite's transformation matrix so that the sprite's center (i.e. the pivot) would be at specified coordinates, $(300, 200)$.
Calculating expected set_position() result in this case will require some trigonometry, I guess, since sprite's coordinate system was rotated beforehand.
Looks like I'm missing something. Any clues on how to approach this?
Looks like this really is an embarrassingly simple question.
Effectively, I need the translation to the given screen coordinates to happen before sprite's own transformation.
So, I need to multiply translation matrix for the coordinates that I need the by sprite's translation matrix, not vice-versa.
$$ \begin{bmatrix} 0 & 0 & x \\ 0 & 0 & y \\ 0 & 0 & 1 \\ \end{bmatrix} \times \begin{bmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \\ \end{bmatrix} $$
Doh.