TimChang
TimChang

Reputation: 2417

How to check angle in range?

For example: angle 10 is cross 270 ~ 390 , because 270 to 390 is inclue 270 ~ 360 and 0 ~ 30.

InRange(0, 180, 90);//true;
InRange(180, 270, 90);//false;
InRange(270, 390, 10);//false; <== but this is in range , How to fix?

And my method:

public bool InRange(int start, int end, int angle)
{
    if (angle >= start && angle <= end)
    {
        return true;
    }

    return false;
}

Upvotes: 0

Views: 446

Answers (4)

user1196549
user1196549

Reputation:

Let me assume that 0° ≤ start < 360° and 0° < end - start ≤ 360°.

There are two cases:

  • end < 360°: the condition is start ≤ angle mod 360° ≤ end.

  • end ≥ 360°: the condition is not (end - 360° ≤ angle mod 360° ≤ start).

CAUTION: the usual % operator does not perform a true modulo operation for the negative argument.

Upvotes: 1

Display Name
Display Name

Reputation: 15111

When normalizing, use % (or my own Mod for the sake of reinventing the wheel) and if because they are cheaper than looping with while.

class Program
{
    static int Mod(int x, int n)
    {
        if (x < 0)
            return -Mod(-x, n);
        if (n < 0)
            return Mod(x, -n);

        int m = x / n;
        return x - m * n;
    }

    // Normalize x to be between left inclusive and right exclusive.
    static int Normalize(int left, int right, int x)
    {
        int period = right - left;
        // int temp = x % period;
        int temp = Mod(x, period); // reinvent the wheel!
        if (temp < left)
            return temp + period;
        if (temp >= right)
            return temp - period;
        return temp;
    }

    // Test whether x between start and end inclusive
    static bool InRange(int start, int end, int x)
    {
        start = Normalize(0, 360, start);
        end = Normalize(0, 360, end);
        x = Normalize(0, 360, x);

        if (start <= end)
            return start <= x && x <= end;

        else
            return !(end < x && x < start);
    }

    static void Main()
    {
        System.Console.WriteLine(InRange(0, 180, 90)); // must be true
        System.Console.WriteLine(InRange(180, 270, 90)); //  must be false
        System.Console.WriteLine(InRange(270, 390, 10)); // must be true
        System.Console.WriteLine(InRange(270, 180, 90)); // must be true        
        System.Console.WriteLine(InRange(270, 270, -90)); // must be true        
    }
}

Upvotes: 1

Caius Jard
Caius Jard

Reputation: 74660

Move all the angles to within a consistent circle:

static bool InR(int f, int t, int w){
  f%=360;
  t%=360;
  w%=360;

  while(f<0) f += 360;
  while(t<f) t += 360;
  while(w<f) w += 360;
  
    
  return f <= w && w <= t;
}

Upvotes: 1

MBo
MBo

Reputation: 80287

Be sure that range is normalized (390>270)

Find middle angle m = (270+390)/2 and half-angle h = (390-270)/2

Compare cosine of difference of needed angle a and middle one m with cosine of half-angle h (convert degrees to radians if needed in your language). This approach helps to avoid problems with periodicity etc

if cos(a - m) >= cos(h)  
    {a inside the range}

enter image description here

Upvotes: 1

Related Questions