C++ Пересечение диапазона градусов
Существует ли известный алгоритм для нахождения пересечения двух диапазонов градусов? Это должно быть круглым.
Ex. 330 - 40 пересекается с 20-50? (да)
Я знаю, что, в общем случае для набора диапазонов, если максимум мин меньше, чем минимум максимумов, чем они пересекаются, но круговая природа степеней делает это немного сложнее.
В настоящее время у меня есть следующий код. Кажется, он делает именно то, что я хочу, но это очень уродливо. Кто-нибудь знает лучший способ сделать это? Кроме перемещения повторяющегося кода в функции, чтобы это выглядело лучше? Проигнорируйте сравнение с плавающей запятой, я просто ленив для этого примера
Примечание: я не fmod 360 или -360, потому что это приведет к 0 и испортит сравнение. Ex. (5 - 360) внутри (350-20) -> приведет к попытке выяснить, находится ли (5 - 0) внутри (350-20), что теперь? Кажется, чтобы было проще.
// 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;
}