Is there a known algorithm for finding if there exists an intersection between two ranges of degrees? It must be circular.
Ex. does 330 - 40 intersect with 20-50? (yes)
I know that, in general for a set of ranges, if the max of the mins is less than the min of the maxes, than they intersect, but the circular nature of degrees makes this a bit more complicated.
I currently have the following code. It seems to do exactly what I want it to, but it's very ugly. Anyone know of a better way to do this? Other than moving repetitive code into functions to make this look nicer? Ignore floating point comparison I'm just being lazy for this example
Note: I don't fmod 360 or -360 because it will result in 0 and screwing up the comparison. Ex. (5 - 360) inside of (350-20) --> would result in trying to figure out if (5 - 0) is inside of (350-20), now what? It seems to keep it more simple.
// Example program
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
bool bearingRangesIntersect(float p_fBearingMinDeg0, float p_fBearingMaxDeg0, float p_fBearingMinDeg1, float p_fBearingMaxDeg1){
// Normalize
if(p_fBearingMinDeg0 != -360.0f && p_fBearingMinDeg0 != 360.0f && (p_fBearingMinDeg0 < 0.0f || p_fBearingMinDeg0 > 360.0f)){
p_fBearingMinDeg0 = fmod(p_fBearingMinDeg0, 360.0f);
if(p_fBearingMinDeg0 < 0.0f){
p_fBearingMinDeg0 += 360.0;
}
}
if(p_fBearingMinDeg1 != -360.0f && p_fBearingMinDeg1 != 360.0f && (p_fBearingMinDeg1 < 0.0f || p_fBearingMinDeg1 > 360.0f)){
p_fBearingMinDeg1= fmod(p_fBearingMinDeg1, 360.0f);
if(p_fBearingMinDeg1< 0.0f){
p_fBearingMinDeg1+= 360.0;
}
}
if(p_fBearingMaxDeg0 != -360.0f && p_fBearingMaxDeg0 != 360.0f && (p_fBearingMaxDeg0 < 0.0f || p_fBearingMaxDeg0 > 360.0f)){
p_fBearingMaxDeg0= fmod(p_fBearingMaxDeg0, 360.0f);
if(p_fBearingMaxDeg0< 0.0f){
p_fBearingMaxDeg0+= 360.0;
}
}
if(p_fBearingMaxDeg1 != -360.0f && p_fBearingMaxDeg1 != 360.0f && (p_fBearingMaxDeg1 < 0.0f || p_fBearingMaxDeg1 > 360.0f)){
p_fBearingMaxDeg1 = fmod(p_fBearingMaxDeg1, 360.0f);
if(p_fBearingMaxDeg1 < 0.0f){
p_fBearingMaxDeg1 += 360.0;
}
}
// Make the min < max to respect comparison
if(p_fBearingMinDeg0 > p_fBearingMaxDeg0){
p_fBearingMinDeg0 -= 360.0f;
if(p_fBearingMinDeg0 < -360.0f){
p_fBearingMinDeg0 = fmod(p_fBearingMinDeg0, 360.0f);
}
}
if(p_fBearingMinDeg1 > p_fBearingMaxDeg1){
p_fBearingMinDeg1 -= 360.0f;
if(p_fBearingMinDeg1 < -360.0f){
p_fBearingMinDeg1 = fmod(p_fBearingMinDeg0, 360.0f);
}
}
float fMaxOfMins = std::max(p_fBearingMinDeg0, p_fBearingMinDeg1);
float fMinOfMaxs = std::min(p_fBearingMaxDeg0, p_fBearingMaxDeg1);
return fMaxOfMins < fMinOfMaxs;
}
int main()
{
// should be true
bool result0 = bearingRangesIntersect(320,50,20,50);
bool result1 = bearingRangesIntersect(-40,50, 20,50);
bool result2 = bearingRangesIntersect(320,50,320,90);
bool result3 = bearingRangesIntersect(-40,-90,-50,-80);
// should be false
bool result5 = bearingRangesIntersect(-40,50, 80,150);
bool result6 = bearingRangesIntersect(181,270,-50,180);
bool result7 = bearingRangesIntersect(300,50, 200, 270);
bool result8 = bearingRangesIntersect(-120,-90, -40,-20);
std::cout << "result0 = " << result0 << std::endl;
std::cout << "result1 = " << result1 << std::endl;
std::cout << "result2 = " << result2 << std::endl;
std::cout << "result3 = " << result3 << std::endl;
std::cout << "result5 = " << result5 << std::endl;
std::cout << "result6 = " << result6 << std::endl;
std::cout << "result7 = " << result7 << std::endl;
std::cout << "result8 = " << result8 << std::endl;
return 0;
}