Determine if angle lies between 2 other angles

后端 未结 12 1565
予麋鹿
予麋鹿 2020-12-15 05:47

I am trying to figure out whether a angle lies between 2 other angles. I have been trying to create a simple function to perform this but none of my techniques will work for

12条回答
  •  暖寄归人
    2020-12-15 06:30

    Is angle T between angles A and B, there are always two answers: true and false.

    We need specify what we mean, and in this case we're looking for the normalized small sweep angles and whether our angle is between those values. Given any two angles, there is a reflex angle between them, is the normalized value of T within that reflex angle?

    If we rotate A and B and T such that T = 0 and normalize A and B to within +-hemicircumference (180° or 2PI). Then our answer is whether A and B have different signs, and are within a hemicircumference of each other.

    If we subtract the angle from test, then add 180° (so A is relative to T+180). Then we mod by 360 giving us a range between [-360°,360°] we add 360° and mod again (note, you could also just check if it's negative and add 360 if it is), giving us a value that is certain to be [0°,360°]. We subtract 180° giving us a value between [-180°,180°] relative to T+180°-180° aka, T. So T is now angle zero and all angles fall within the normalized range. Now we check to make sure the angles have a sign change and that they are not more than 180° apart, we have our answer.

    Because the question asks in C++:

    bool isAngleBetweenNormalizedSmallSweepRange(int test, int a, int b) {
        int a_adjust = ((((a - test + 180)) % 360) + 360) % 360 - 180;
        int b_adjust = ((((b - test + 180)) % 360) + 360) % 360 - 180;
        return ((a_adjust ^ b_adjust) < 0) && ((a_adjust - b_adjust) < 180) && ((a_adjust - b_adjust) > -180);
    }
    

    We can also do some tricks to simplify out the code and avoid any unneeded modulo ops (see comments below). Normalize will move angle a into the range [-180°,180°] relative to angle t.

    int normalized(int a, int test) {
        int n = a - test + 180;
        if ((n > 360) || (n < -360)) n %= 360;
        return (n > 0)? n - 180: n + 180;
    }
    
    bool isAngleBetweenNormalizedSmallSweepRange(int test, int a, int b) {
        int a_adjust = normalized(a,test);
        int b_adjust = normalized(b,test);
        return ((a_adjust ^ b_adjust) < 0) &&
                ((a_adjust > b_adjust)? a_adjust-b_adjust: b_adjust-a_adjust) < 180;
    }
    

    Also if we can be sure the range is [0,360], we can make do with a simpler if statement

    bool isAngleBetweenNormalizedSmallSweepRange(int test, int a, int b) {
        int dA = a - test + 180;
        if (dA > 360) {
            dA -= 360;
        }
        int a_adjust = (dA > 0) ? dA - 180 : dA + 180;
        int dB = b - test + 180;
        if (dB > 360) {
            dB -= 360;
        }
        int b_adjust = (dB > 0) ? dB - 180 : dB + 180;
        return ((a_adjust ^ b_adjust) < 0)
                && ((a_adjust > b_adjust) ? a_adjust - b_adjust : b_adjust - a_adjust) < 180;
    }
    

    JS Fiddle test of the code

提交回复
热议问题