2
votes

This seems like it should be really simple but I'm having trouble with it. Basically, I have three points that keep changing (lets call them p1, p2, and p3). Also, let's define p2 as the vertex point.

Essentially, what I need to do is calculate the angle between the three points. A good example would be if the three angles form a 179 degree angle, then the points change to form a 181 degree angle. So what I really need is a good method for determining if an angle is greater than 180 degrees. I tried using the law of cosines, but it did not give me a good answer because when the points form a 181 degree angle, it simply interprets it as a 179 degree angle in a different direction. Also, I am doing this in Python, if that helps. Thanks!

2
Do you have a consistent angle measurement scheme? Like are all angles measured ccw?Henry Prickett-Morgan
In this case you must know that the angle is on the clockwise or counterclockwise side of the first segment, correct? Otherwise interpreting 181 as 179 is absolutely correct.Mark Ransom
All angles are measured consistently. It doesn't really matter whether its counterclockwise or clockwise, all that matters is when the angle crosses the 180 degree boundary.user3047641

2 Answers

6
votes

What you are trying to decide is whether (p3-p2) is a left or right turn comparing to (p2-p1). This is actually a core part of Graham Scan which is used for computing convex hulls (https://en.wikipedia.org/wiki/Graham_scan). Quoting Wikipedia with slight edits:

...determining whether three points constitute a "left turn" or a "right turn" does not require computing the actual angle between the two line segments, and can actually be achieved with simple arithmetic only. For three points P1=(x1, y1), P2=(x2, y2), and P3=(x3, y3), simply compute the z-coordinate of the cross product of the two vectors (p2-p1) and (p3-p1), which is given by the expression (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1). If the result is 0, the points are collinear; if it is positive, the three points constitute a "left turn" or counter-clockwise orientation, otherwise a "right turn" or clockwise orientation (for counter-clockwise numbered points).

0
votes

To get signed angle in the full range, use atan2 function with dot and cross product of vectors p2p1 and p2p3

Angle(in radians) = atan2(cross(p2p1,p2p3), dot(p2p1,p2p3))