17

I am trying to rotate a vector around a certain point on the vector(in C++):

1 2 3
4 5 6
7 8 9

rotated around the point (1,1) (which is the "5") 90 degrees would result in:

7 4 1
8 5 2
9 6 3

Right now I am using:

x = (x * cos(90)) - (y * sin(90))
y = (y * cos(90)) + (x * sin(90))

But I don't want it rotated around (0,0)

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Erik Ahlswede
  • 2,077
  • 2
  • 25
  • 36

5 Answers5

36

The answer depends on your coordinate system.

Computer graphics coordinate system, with (0,0) at Top left

If you are using a computer graphics vector implementation where (0,0) is the top left corner and you are rotating around the point (dx, dy), then the rotation calculation, including the translation back into the original coordinate system, would be:

x_rotated =      ((x - dx) * cos(angle)) - ((dy - y) * sin(angle)) + dx
y_rotated = dy - ((dy - y) * cos(angle)) + ((x - dx) * sin(angle))

Physics/Maths coordinate system, with (0,0) at Bottom left

If you are using a more traditional real world coordinate system, where (0,0) is the bottom left corner, then the rotation calculation, around the point (dx, dy) including the translation back into the original coordinate system, would be:

x_rotated = ((x - dx) * cos(angle)) - ((y - dy) * sin(angle)) + dx
y_rotated = ((x - dx) * sin(angle)) + ((y - dy) * cos(angle)) + dy

Thanks to mmx for their comment on Pesto's post, and to SkeletorFromEterenia for highlighting an error in my implementation.

Mark Booth
  • 7,605
  • 2
  • 68
  • 92
  • Maybe silly question, but may top left system works with definition for bottom left? Maybe silly mental example, let say that I want rotate 9, 9 around 10, 10 by 45 degree. Now set expectations, 9,9 vs 10,10 have -45 degree. +45 rotation gave 0 between center and rotated vector, so I expect x= 10 y=10-length of vector. And "standard equations gave me this" with one thing, default rotation is counterclokwise, but here I work like it was clockwise. And finally question, can standard equations work for top left coordinate system with default rotation as clockwise? – viceriel Mar 21 '22 at 13:50
  • You can write your software in such a way to handle multiple coordinate systems at the same time, but I would recommend against it @viceriel as it's far too easy to end up getting confused, and it expands your test data set enormously. – Mark Booth Mar 21 '22 at 15:04
11

The solution is to translate the vector to a coordinate system in which the center of rotation is (0,0). Apply the rotation matrix and translate the vector back to the original coordinate system.

dx = x of rotation center  
dy = y of rotation center

V2 = V - [dx, dy, 0]  
V3 = V2 * rotation matrix  
Result = V3 + [dx, dy, 0]
0x90
  • 39,472
  • 36
  • 165
  • 245
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
4

Assuming you're using a standard vector implementation where (0,0) would be the top left corner and you're rotating around the point (x_origin, y_origin), this should do it:

x = ((x - x_origin) * cos(angle)) - ((y_origin - y) * sin(angle))
y = ((y_origin - y) * cos(angle)) - ((x - x_origin) * sin(angle))

Note that the y's are y_origin - y because the y value increases as you go down.

Pesto
  • 23,810
  • 2
  • 71
  • 76
2

I found the answer from Mark Booth to be wrong (rotate (0,1,0) by 0 degrees and you get (0,-1,0) with his formula), and I ended up with:

double cs = cos_deg(new_degrees);
double sn = sin_deg(new_degrees);

double translated_x = x - x_origin;
double translated_y = y - y_origin;
    
double result_x = translated_x * cs - translated_y * sn;
double result_y = translated_x * sn + translated_y * cs;
    
result_x += x_origin;
result_y += y_origin;

This can be further shortened of course, but I want to make it as simple as possible.

Mark Booth
  • 7,605
  • 2
  • 68
  • 92
  • Thanks for pointing out the error, I've now updated [my answer](https://stackoverflow.com/a/620769/42473) with a fix, and detailed how the coordinate system you are using means that you need a different solution to the one [Pesto](https://stackoverflow.com/a/620769/42473) proposed. – Mark Booth Mar 02 '21 at 11:43
1

You will need to use a translation matrix to move rotate about a different point.

Ben S
  • 68,394
  • 30
  • 171
  • 212