Check if angle is between two other angles

Monkey Forums/Monkey Code/Check if angle is between two other angles

Yahfree(Posted 2012) [#1]
This function takes an angle n, and checks if it is between two other angles a and b. It works in degrees, and normalizes the angles before calculations, so it won't matter if they are negative or positive or higher than 360.

Function betweenAngle:Bool(_n:Float,_a:Float,_b:Float)
        Local n:Float = (360 + (_n Mod 360)) Mod 360;
        Local a:Float = (3600000 + _a) Mod 360;
        Local b:Float = (3600000 + _b) Mod 360;

        If (a < b) Return (a <= n And n <= b);
        Return (a <= n Or n <= b);
End Function



Paul - Taiphoz(Posted 2012) [#2]
thanks , gona add this to my vector class..


Floyd(Posted 2012) [#3]
That 3600000 should set off an alarm in your head. It can't be good.

The other obvious warning sign is the lack of symmetry. The geometric problem is clearly unchanged if the values of a and b are swapped. The code should have the same property.

The first step is to enforce the symmetry. Notice that the problem is essentially the same if n,a,b are all changed by the same amount. They could for example be replaced by n+75,a+75,b+75 or n-200,a-200,b-200. Let's use n-n,a-n,b-n.

We must now decide if zero ( n-n ) is between two angles. If we draw a picture then angle zero is the positive x axis. This is between the two angles if we have

1. One angle above the x axis and the other below. In code this is Sgn( a ) <> Sgn( b )

2. The angle bounded by a and b is at most 180 degrees. Code is Abs( a ) + Abs( b ) <= 180

I thought this was the complete test but then realized I had made the common mistake of forgetting about boundary cases. What if one or both angles are exactly on the x axis? The final a = 0 Or b = 0 deals with that.

Notice that swapping a and b in this code changes nothing, just as in the underlying geometry.

[monkeycode]Function betweenAngle:Bool(n:Float, a:Float, b:Float)

a = Angle180( a - n )
b = Angle180( b - n )
Return ( Sgn( a ) <> Sgn( b ) ) And ( Abs( a ) + Abs( b ) <= 180 ) Or a = 0 Or b = 0

End Function

Function Angle180:Float( a:Float )

a Mod= 360
If a > 180 Then Return a-360
If a <= -180 Then Return a+360
Return a

End Function[/monkeycode]
Final comment: The Angle180 function transforms an angle into the nicely symmetric -180 to +180 range and mimics ATan2. Much of the convoluted code that you see around the Blitz/Monkey forums comes from insisting that angles be in the range 0 to 360. It is often much simpler to use -180 to +180.


Paul - Taiphoz(Posted 2012) [#4]
thanks for the update, something to consider when it comes to the angles, for some of us its simply easier to picture them when its 0-360 and a lot harder for us when its -180 180, some people just don't do as well with angles as others.


Yahfree(Posted 2012) [#5]
Floyd, good catch! I never thought about that. I found this code in one of my old bmax projects.