如何检查范围内的角度?

How to check angle in range?

例如:角度10是cross 270 ~ 390,因为270到390包括270 ~ 360和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?

还有我的方法:

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

    return false;
}

确保范围标准化 (390>270)

求中角m = (270+390)/2和half-angleh = (390-270)/2

将所需角度 a 和中间角度 m 的余弦与 half-angle h 的余弦进行比较(如果需要,请将度数转换为弧度)。这种方法有助于避免周期性等问题

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

让我假设 0° ≤ start < 360°0° < end - start ≤ 360°

有两种情况:

  • end < 360°:条件为start ≤ angle mod 360° ≤ end.

  • end ≥ 360°:条件为not (end - 360° ≤ angle mod 360° ≤ start).

注意:通常的 % 运算符不会对负参数执行真正的模运算。

将所有角度移动到一致的圆内:

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;
}

规范化时,使用 %(或者我自己的 Mod,为了重新发明轮子)和 if,因为它们比使用 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        
    }
}