[Instruction] How to rotate points
Posted: Tue May 24, 2016 7:58 pm
I thought this might be interesting, since it is useful for a lot of applications. If you know how to rotate points, you won't learn anything here.
The process is relatively simple, but you need to understand it once. Therefore I go through the process in detail. That makes it look complex or difficult, but only when reading for the first time. Promised!
(read left to right, top to bottom)
So you have a line and want to rotate it. A line has two points, so you need to rotate the two points, then connect them again by a line.
The first step is to define the anchor point, which is the point around that you want to rotate the points. Here I decided to take the middle of the line, so that both points rotate evenly. We can calculate that anchor point easily by halving the distance on the x-axis and the halving the distance on the y-axis (see image 2)
Now we need the distance between the anchor point and the points P1 and P2. Here comes Pythagoras to the rescue: A right-angled triangle with two sides known. The hypotenuse is then the squareroot of a² + b². If we build such a rectangle in a way that the distance we're looking for equals the hypotenuse, we are already done.
In this example, a is the distance on the x-axis and b the distance on the y-axis, between AP and P1, or:
Best of all: we get d2 for free, since both points are axactly the same distance away from AP: d2 = d1
The unit circle is a thought circle around AP with a radius of 1. Read about the unit circle in math publications. For us it especially means that we can a) get an angle and b) scale the result easily later on.
What we need as well is the angle at which the points P1 and P2 are offsetted to AP. Therefore we can use the arcustangent. All programming languages know atan2, which is a variation of atan, that takes into account the sign of the two components. This is important because we would just get -(pi/2) to pi/2 from atan, but a full circle ranges from -pi to pi. The signs are used in atan2 to get the correct quadrant.
CAUTION: The standard convention is to pass y before x!
Since atan2 works for the unit circle by following a vector starting at 0,0, we need to make AP that [0,0] point. Just subtract it from the points' coordinates as shown in image 4 and 5.
We now have an angle alpha, and just need to add the rotation n we want to it:
With the new angle beta, we can calculate the new position of the point P2. We already know the position of the point that is on the unit circle at angle beta. We just need to use sin and cos. But cos(beta) and sin(beta) will only be in the range of the unit circle, which has a radius of 1. That range is [-1, 1]. But luckily we already calculated the original distance between AP and P2: d2. So let's multiply the results with d2. But we also temporarily moved AP to [0, 0], so we have to add AP as well. And now we have the new position of P2:
The last step is to get the coordinates of P1 as well. Very easy, just use the opposite angle of beta. If you're working with radians, just reverse the sign. If you're working with degrees, just add beta to 180. Then just repeat the last calculation, but for P1'.
Shortlist:
(1) Define anchor point.
(2) Get distance between points
(3) atan2(y, x) to get angle
(4) Rotate angle
(5) Do offset + [cos or sin] * distance
And that's it!
The process is relatively simple, but you need to understand it once. Therefore I go through the process in detail. That makes it look complex or difficult, but only when reading for the first time. Promised!
(read left to right, top to bottom)
So you have a line and want to rotate it. A line has two points, so you need to rotate the two points, then connect them again by a line.
The first step is to define the anchor point, which is the point around that you want to rotate the points. Here I decided to take the middle of the line, so that both points rotate evenly. We can calculate that anchor point easily by halving the distance on the x-axis and the halving the distance on the y-axis (see image 2)
Now we need the distance between the anchor point and the points P1 and P2. Here comes Pythagoras to the rescue: A right-angled triangle with two sides known. The hypotenuse is then the squareroot of a² + b². If we build such a rectangle in a way that the distance we're looking for equals the hypotenuse, we are already done.
In this example, a is the distance on the x-axis and b the distance on the y-axis, between AP and P1, or:
- Code: Select all
a = APx - P1x
b = APy - P1y
d1 = ((APx - P1x)^^2 + (APy - P1y)^^2)^^0.5
Best of all: we get d2 for free, since both points are axactly the same distance away from AP: d2 = d1
The unit circle is a thought circle around AP with a radius of 1. Read about the unit circle in math publications. For us it especially means that we can a) get an angle and b) scale the result easily later on.
What we need as well is the angle at which the points P1 and P2 are offsetted to AP. Therefore we can use the arcustangent. All programming languages know atan2, which is a variation of atan, that takes into account the sign of the two components. This is important because we would just get -(pi/2) to pi/2 from atan, but a full circle ranges from -pi to pi. The signs are used in atan2 to get the correct quadrant.
CAUTION: The standard convention is to pass y before x!
Since atan2 works for the unit circle by following a vector starting at 0,0, we need to make AP that [0,0] point. Just subtract it from the points' coordinates as shown in image 4 and 5.
We now have an angle alpha, and just need to add the rotation n we want to it:
- Code: Select all
beta = alpha + n
With the new angle beta, we can calculate the new position of the point P2. We already know the position of the point that is on the unit circle at angle beta. We just need to use sin and cos. But cos(beta) and sin(beta) will only be in the range of the unit circle, which has a radius of 1. That range is [-1, 1]. But luckily we already calculated the original distance between AP and P2: d2. So let's multiply the results with d2. But we also temporarily moved AP to [0, 0], so we have to add AP as well. And now we have the new position of P2:
- Code: Select all
P2'x = APx + cos(beta) * d2
P2'y = APy + sin(beta) * d2
The last step is to get the coordinates of P1 as well. Very easy, just use the opposite angle of beta. If you're working with radians, just reverse the sign. If you're working with degrees, just add beta to 180. Then just repeat the last calculation, but for P1'.
Shortlist:
(1) Define anchor point.
(2) Get distance between points
(3) atan2(y, x) to get angle
(4) Rotate angle
(5) Do offset + [cos or sin] * distance
And that's it!