finding angle between 3 points
Moderator: Board moderators
-
- Experienced poster
- Posts: 114
- Joined: Wed Jul 30, 2003 10:30 pm
- Location: Newfoundland, Canada (St. John's)
finding angle between 3 points
I want to find the angle (in degrees) of three points.
I am trying to use the java Math.atan2(p1, p2) method, but am not getting what I want.
Take for example the points
(2, 2)(1, 1)(3, 1) the angle can be found by doing this:
angle1 = atan2( (1-1), (1-3) )
angle2 = atan2( (2-1), (2-1) )
angle = angle2 - angle1
This gives (after conversion to degrees) 45.0 which is correct.
But, if I change the points to (2, 2)(3, 3)(1, 3) I get back -315. I should be getting 45.0 again. This is because of the way polar coordinates work. For example, an angle of 181 degrees would actually be -179.
I dunno if any of this makes sense, but could someone help me figure out a good way to find the angle between these three points???
I am trying to use the java Math.atan2(p1, p2) method, but am not getting what I want.
Take for example the points
(2, 2)(1, 1)(3, 1) the angle can be found by doing this:
angle1 = atan2( (1-1), (1-3) )
angle2 = atan2( (2-1), (2-1) )
angle = angle2 - angle1
This gives (after conversion to degrees) 45.0 which is correct.
But, if I change the points to (2, 2)(3, 3)(1, 3) I get back -315. I should be getting 45.0 again. This is because of the way polar coordinates work. For example, an angle of 181 degrees would actually be -179.
I dunno if any of this makes sense, but could someone help me figure out a good way to find the angle between these three points???
-
- Experienced poster
- Posts: 131
- Joined: Thu Apr 17, 2003 8:39 am
- Location: Baku, Azerbaijan
k1=(2-1)/(2-1)
k2=(1-1)/(1-3)
k1=tg(alfa) where alfa angle 0<alfa<=2*pi
k2=tg(betta) "----------------------------------"
let gamma be angle between this three points then
tg(gamma)=tg(betta-alfa)=(tg(betta)-tg(alfa))/(1+tg(alfa)*tg(betta))=(k2-k1)/(1+k1*k2)
gamma = arctan((k2-k1)/(1+k1*k2))
It is a common way to find angles between two lines. I hope it will help.
k2=(1-1)/(1-3)
k1=tg(alfa) where alfa angle 0<alfa<=2*pi
k2=tg(betta) "----------------------------------"
let gamma be angle between this three points then
tg(gamma)=tg(betta-alfa)=(tg(betta)-tg(alfa))/(1+tg(alfa)*tg(betta))=(k2-k1)/(1+k1*k2)
gamma = arctan((k2-k1)/(1+k1*k2))
It is a common way to find angles between two lines. I hope it will help.
_____________
NO sigNature
NO sigNature
-
- Experienced poster
- Posts: 136
- Joined: Tue Apr 01, 2003 6:59 am
- Location: Jakarta, Indonesia
Can you specify more which angle you want to find??
Check this out:
*A
*B *C
From these three points, there are three angles can be formed:
1. ABC
2. ACB
3. BAC
So which angle do you want to calculate?
Check this out:
*A
*B *C
From these three points, there are three angles can be formed:
1. ABC
2. ACB
3. BAC
So which angle do you want to calculate?
There are 3 things one need to be successful : motivation, ability and chance. And if you're a believer, make it four : God's will.
-
- Experienced poster
- Posts: 169
- Joined: Wed Oct 31, 2001 2:00 am
- Location: Singapore
Well I'm not too sure, but would using cosine rule cause a loss in precision? Using pythagoras's theorem for the lengths, then cosine rule for the angle: angle = acos[(a^2+b^2-c^2)/(2ab)]. The loss in precision could then come in through the acos(), and the sqrt() needed for the 2ab. For a^2, b^2, c^2 no sqrt is needed.
-
- Experienced poster
- Posts: 114
- Joined: Wed Jul 30, 2003 10:30 pm
- Location: Newfoundland, Canada (St. John's)
Sorry about the last post, I was rushing so I didn't get to give a good reply.
Basically, I want a function that can take three points, A,B,C and return the angle formed by ABC. So I am looking for angle B.
My current way is this:
[java]
public static double getAngle(Point p1, Point p2) {
return Math.toDegrees(Math.atan2(p2.y-p1.y, p2.x-p1.x));
}
[...]
double baseAngle = getAngle(point2, point3);
double angle = getAngle(point1, point2) - baseAngle;
[/java]
For the following points it returns the following angles:
The angle should be 45.0 for all of them. But for the third one it gives me a -315. Can anyone help me fix my broken code??
Does anyone know of a good way to get these angles? I've searched the net but can't find anything that helps. Thanks!!
Basically, I want a function that can take three points, A,B,C and return the angle formed by ABC. So I am looking for angle B.
My current way is this:
[java]
public static double getAngle(Point p1, Point p2) {
return Math.toDegrees(Math.atan2(p2.y-p1.y, p2.x-p1.x));
}
[...]
double baseAngle = getAngle(point2, point3);
double angle = getAngle(point1, point2) - baseAngle;
[/java]
For the following points it returns the following angles:
Code: Select all
(2,2)(1,1)(3,1) :: 45.0
(2,2)(3,1)(3,3) :: 45.0
(2,2)(3,3)(1,3) :: -315.0
(2,2)(1,3)(1,1) :: 45.0
Does anyone know of a good way to get these angles? I've searched the net but can't find anything that helps. Thanks!!
-
- Experienced poster
- Posts: 136
- Joined: Tue Apr 01, 2003 6:59 am
- Location: Jakarta, Indonesia
Well xbeanx, if your problem is only to rid of the negative angle (I assume that your algo to calculate angle is correct), you just need to add conditional statement:
I think those two conditional statement should be enough to fix your problem.

Code: Select all
if ( angle > 360 || angle < -360 ) angle = floor ( angle / 360 )
if ( angle < 0 ) angle = 360 + angle



There are 3 things one need to be successful : motivation, ability and chance. And if you're a believer, make it four : God's will.
-
- Experienced poster
- Posts: 114
- Joined: Wed Jul 30, 2003 10:30 pm
- Location: Newfoundland, Canada (St. John's)
Joseph, thanks for trying to help.
Unfortunately, my problem is not just with negative angles... It is more with consistency.
If I get the angle (2,2)(1,1)(3,1) it should be 45.0
If I get the angle (2,2)(3,1)(1,1) it should be -45.0
(one turns right, the other left)
The 4 angles I gave as examples earlier:
(2,2)(1,1)(3,1) :: 45.0
(2,2)(3,1)(3,3) :: 45.0
(2,2)(3,3)(1,3) :: -315.0
(2,2)(1,3)(1,1) :: 45.0
Should all be 45.0. I know why the -315 is in there, but I don't know how to effectively get rid of it without affecting the other 3 angles.
Unfortunately, my problem is not just with negative angles... It is more with consistency.
If I get the angle (2,2)(1,1)(3,1) it should be 45.0
If I get the angle (2,2)(3,1)(1,1) it should be -45.0
(one turns right, the other left)
The 4 angles I gave as examples earlier:
(2,2)(1,1)(3,1) :: 45.0
(2,2)(3,1)(3,3) :: 45.0
(2,2)(3,3)(1,3) :: -315.0
(2,2)(1,3)(1,1) :: 45.0
Should all be 45.0. I know why the -315 is in there, but I don't know how to effectively get rid of it without affecting the other 3 angles.
-
- New poster
- Posts: 19
- Joined: Fri Oct 04, 2002 7:50 pm
- Location: Warsaw, Poland
-
- New poster
- Posts: 19
- Joined: Fri Oct 04, 2002 7:50 pm
- Location: Warsaw, Poland
i think you should subtract p2 from both p1 and p3.
this should work when p1 p2 p3 counter-clockwise oriented.
this should work when p1 p2 p3 counter-clockwise oriented.
Code: Select all
x1 -= x2;
y1 -= y2;
x3 -= x2;
y3 -= y2;
double angle1 = atan2(y1, x1);
double angle2 = atan2(y3, x3);
if( angle1 < 0.0 ) angle1 += 2*M_PI;
if( angle2 < 0.0 ) angle2 += 2*M_PI;
return 180.0*(angle1 - angle2)/M_PI;
-
- Experienced poster
- Posts: 114
- Joined: Wed Jul 30, 2003 10:30 pm
- Location: Newfoundland, Canada (St. John's)
I fixed it with
if(Math.abs(end1Angle) > 180) end1Angle += (end1Angle < 0) ? 360 : -360;
if(Math.abs(end2Angle) > 180) end2Angle += (end2Angle < 0) ? 360 : -360;
It took me a while to figure it out, but it works fine now.
As for the reference to P109... I solved that one no problem with the same code I was using here. I guess it didn't make much of a difference in that problem.
if(Math.abs(end1Angle) > 180) end1Angle += (end1Angle < 0) ? 360 : -360;
if(Math.abs(end2Angle) > 180) end2Angle += (end2Angle < 0) ? 360 : -360;
It took me a while to figure it out, but it works fine now.
As for the reference to P109... I solved that one no problem with the same code I was using here. I guess it didn't make much of a difference in that problem.
-
- New poster
- Posts: 19
- Joined: Fri Oct 04, 2002 7:50 pm
- Location: Warsaw, Poland
-
- Experienced poster
- Posts: 114
- Joined: Wed Jul 30, 2003 10:30 pm
- Location: Newfoundland, Canada (St. John's)
This was actually a problem with 132 for me.
What I was trying to do is draw a line from the centre of mass to each end, then check that the angles of these lines are <= 90 degrees. That way I can check if the point lies between the endpoints.
Anyway, it worked and I got accepted. Does anyone know an easy way to check if the centre of mass is between the endpoints for this problem?
What I was trying to do is draw a line from the centre of mass to each end, then check that the angles of these lines are <= 90 degrees. That way I can check if the point lies between the endpoints.
Anyway, it worked and I got accepted. Does anyone know an easy way to check if the centre of mass is between the endpoints for this problem?
-
- Experienced poster
- Posts: 131
- Joined: Thu Apr 17, 2003 8:39 am
- Location: Baku, Azerbaijan
tg() is tangent in math or sin()/cos() in pascal or k for line. What I wrote is just formula to find angle between two lines, the common situation of three points.
2xbeanx
To solve this problem just make convex and check if mass center is above
sides of this convex. But if you have problems with angle you can check if all points are on one side of a line. You don't even make convex for it. You know formula y=k*x+b. First get k1 and b1 for two points. Then I b of other points with initial k1. If all this points are greater or less than b1, then all is OK.
Algo:
The main part is of course check. Convex method is faster than this method. But if you have problems with angles this is a best method (I think so).
2xbeanx
To solve this problem just make convex and check if mass center is above
sides of this convex. But if you have problems with angle you can check if all points are on one side of a line. You don't even make convex for it. You know formula y=k*x+b. First get k1 and b1 for two points. Then I b of other points with initial k1. If all this points are greater or less than b1, then all is OK.
Algo:
Code: Select all
for i:=1 to n do
for j:=i+1 to n do
begin
check(i,j,t);
if t<>-1 then
begin
if t<min then min:=t;
end;
end;
_____________
NO sigNature
NO sigNature