Calculating the translation of an affine matrix so that it centres during scaling

1.4k Views Asked by At

I have this example of what I want to achieve. The second set of rects is where I want to get to.

There are two sets of rects in the link above. The first set is where I currently am, I want to scale svg elements in and out. The centre rect is the start position and the first rect is what happens if the user zooms out and the last rect is what happens when the user zooms in.

I want my rects to remain centred as the scaling happens as is displayed in the second set of rects.

If my starting affine matrix looks like this:

$$\begin{bmatrix}1 & 0 & 0\\0 & 1 & 0\\0 & 0 & 1\end{bmatrix}$$

If I change the scale to:

$$\begin{bmatrix}0.5 & 0 & 0\\0 & 0.5 & 0\\0 & 0 & 1\end{bmatrix}$$

What are my calculations to maintain the centre translation for the $Δx$ and $Δy$ parts of the affine matrix to ensure the elements do not get shifted up to the top left when zooming or scaling out.

The result would be something like this:

$$\begin{bmatrix}0.5 & 0 & -22.5\\0 & 0.5 & -22.5\\0 & 0 & 1\end{bmatrix}$$

The rects have a width of $50$ and a starting point of $(20, 20)$ before each transformation is applied.

2

There are 2 best solutions below

6
On BEST ANSWER

$\def\vec{\boldsymbol}$For a general setting, suppose the fixed point of this affine transformation is $(x_0, y_0)$, which is the center in your case. Since the scaling matrix is $A = \begin{pmatrix}a&0\\0&b\end{pmatrix}$, then$$ A \begin{pmatrix}x_0\\y_0\end{pmatrix} + \vec{b} = \begin{pmatrix}x_0\\y_0\end{pmatrix} \Longrightarrow \vec{b} = (I - A) \begin{pmatrix}x_0\\y_0\end{pmatrix} = \begin{pmatrix}(1 - a)x_0\\(1 - b)y_0\end{pmatrix}. $$ Therefore, the affine transformation matrix is$$ M = \begin{pmatrix}A & \vec{b}\\\vec{0} & 1\end{pmatrix} = \begin{pmatrix}a & 0 & (1 - a)x_0\\0 & b & (1 - b)y_0\\0 & 0 & 1\end{pmatrix}. $$

0
On

Here is a helpful link that illustrates how different css matrix transforms transform the corners of your rectangle.

Here's my handwritten explanation on how to scale rectangles and center them for any scaling length and rectangle size. (I'm happy to host it on stack exchange, it's just that it doesn't appear as though this website supports .pdf files..)

P.S. if you want to keep your rectangles having a starting point at (20, 20), first draw them with a center of (0, 0), and then after you've scaled and centered them, then translate all of them (using the translate operator) to (20, 20)