Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scaling around a specific point in 2d coordinate system

Below is an image my coordinate system: enter image description here

What I am trying to do is that I want to start scaling around a specific point in the canvas, the scaling works fine but my problem is that I don't know how to calculate how much to move the canvas while scaling, note that I am not using canvas.scale.

I am simply increasing the distance between each 2 units in the system while scaling and it's working just fine.

So is there any equation that can help me find out how much to offset the canvas while scaling at specific point?

Suppose I want to scale around point(0,4) how to know how much to move the canvas while scaling?

like image 788
has19 Avatar asked Jul 18 '16 22:07

has19


2 Answers

Equations in this case are less useful than knowing the right principle. The answer is only one sentence, but I'll need to explain the principle first.

When you say "scale around a point", what you're looking for is to temporarily treat that other point as the origin. Scaling around the origin is trivial; it's simply scalar multiplication. Scaling around another point is three operations:

  • Translate the designated point to the origin
  • Scale at the (temporary, new) origin.
  • Translate back so that the origin goes back to the designated point.

In mathematical notation, call the scaling operator S. Call the translation operator that take the designated point to the origin T. The operator that takes the origin to the designated point is the inverse of T, denoted T-1. Then the operator that does "scaling at a point" is T-1ST. (Apply operators from right to left.)

The operator T-1ST is called the conjugation of S by T. In linear algebra, it's also call a similarity transform. If S and T can be represented by matrices (as is true in this setting), the combined operator is the product of the matrices.

So here's the one sentence answer: Conjugate your scaling operation by a translation to the origin.

I should add, although it's not part of the question, that conjugation is also how you rotate around a point.

like image 80
eh9 Avatar answered Sep 21 '22 13:09

eh9


So lets say we want to apply a scaling which leaves a specific point (x0,y0) fixed. Lets say we are using uniform scaling by a factor s followed by a translation by (u,v). This means our full transformation is

(x',y') = s (x,y) + (u,v)

Now (x0,y0) is fixed so

(x0,y0) = s * (x0,y0) + (u,v)

A bit of rearrangement gives

(u,v) = (1 - s) (x0, y0)

In psudocode it might be like

double s= scale_factor;
double x0 = center_point_x;
double y0 = center_point_y;
canvas.scale(s);
double u = (1-s) * x0;
double v = (1-s) * y0;
canvas.translate(u,v);
like image 31
Salix alba Avatar answered Sep 21 '22 13:09

Salix alba