nicematt nicematt - 2 months ago 7
Javascript Question

Rotating point by its form axe makes itself move to the left-top

Firstly, I need to rotate a single line about its own axe to be rendered in HTML5 canvas.
I'm not actually rotating a line, but I'm rotating its points coordinates before I render it.

I've specific bounds which refers to the total size of what will be drawn in a path (e.g, the line), they're used to construct a point B, which is the center point of the path.

form.bx = x + (w / 2);
form.by = y + (h / 2);


Note:
form
is actually a path generated by my interface, it contains the rotation angle, etc.

Both of these functions rotates coordinates of a point and return them. Parameters:


  • x – the x coor. of the A point.

  • y – the y coor. of the A point.

  • c – the angle cosine (
    Math.cos(angle)
    ).

  • s – the angle sine (
    Math.sin(angle)
    ).

  • Bx – the x coor. of the point on which point A will be rotated about.

  • By – the y coor. of the point on which point A will be rotated about.






function rotatePointX(x, y, c, s, Bx, By) {
return Math.round(((Bx - x) * c) - ((By - y) * s));
}

function rotatePointY(x, y, c, s, Bx, By) {
return Math.round(((Bx - x) * s) + ((By - y) * c));
}





The problem: the rotation makes my line move to the left-top of the canvas.

Fiddle

My line should be in its specific position. What am I doing wrong? Thanks

Answer

Rotation always occurs relative to the origin, if you want to rotate relative to some other point you have to

  1. move all your space so that the new origin is the point the rotation will occur about
  2. perform the rotation
  3. move all your space back to its original position

1)

x' = x - Bx
y' = y - By

2)

x'' = x' * cos(angle) - y' * sin(angle)
y'' = x' * sin(angle) + y' * cos(angle)

3)

x''' = x'' + Bx
y''' = y'' + By

To find the value of x''', y''' you have to replace 1 and 2 in 3

1 in 2:

x'' = (x - Bx) * cos(angle) - (y - By) * sin(angle)
y'' = (x - Bx) * sin(angle) + (y - By) * cos(angle)

2 in 3:

x''' = (x - Bx) * cos(angle) - (y - By) * sin(angle) + Bx
y''' = (x - Bx) * sin(angle) + (y - By) * cos(angle) + By

You can avoid all this mess by performing the transform doing matrix multiplication like so

[x'''] = [1 0 Bx] [cos(angle) -sin(angle) 0] [1 0 -Bx] [x]
[y''']   [0 1 By] [sin(angle)  cos(angle) 0] [0 1 -By] [y]
[1   ]   [0 0  1] [         0           0 1] [0 0   1] [1]

The additional dimension is used to be able to perform translation since translation is a shearing mapping

https://jsfiddle.net/hnv0dcs6/2/

Comments