Я пытаюсь определить угол между двумя точками через центральную точку, используя c ++. Я использую std :: atan2 (y, x), чтобы получить угол. Для краткости я конвертирую радианы в градусы. Это работает нормально.
Однако мои проблемы связаны с изменением знака при изменении положения двух точек. Заданный угол составляет либо -200, либо 160. Конечно, это тот же самый угол, всего 360 градусов. Я предпочел бы просто иметь то же значение, чтобы сделать проверки сравнения в здравом уме. Как я могу это сделать?
Функция, которую я использую для вычисления угла и преобразования в градусы:
static double computeAngleFromCenter(cv::Point center, cv::Point p, bool asDegrees = false)
{
double angle = std::atan2(p.y - center.y, p.x - center.x);
if (asDegrees)
angle *= 180 / 3.1415926;
return angle;
}
Очевидный ответ — просто добавить 360, если угол < 0, а это лучший способ?
Согласно документации для atan2
возврат всегда в диапазоне [-pi, pi]
так что я не думаю, что вы когда-нибудь увидите -200 deg
как вы предлагали. Это сказал делает по-прежнему возвращать результаты в 3-м и 4-м квадрантах как отрицательные значения. Поскольку функция явно вызывает это поведение, наиболее простым решением является добавление 2pi
радианы к отрицательному результату возврата.
В соответствии с документация:
Возвращаемое значение:
Главный арктангенс y / x, в интервале [-pi, + pi] радиан. Один радиан эквивалентен 180 / PI градусов.
Если вы предпочитаете, чтобы он возвращал значение на интервале [0, +2pi]
тогда да, вам нужно будет применить небольшую поправку.
Вы можете использовать fmod перед условным преобразованием в градусы:
angle = fmod( angle + PI * 2, PI * 2 );
В зависимости от компилятора и математической библиотеки, он может быть быстрее или медленнее, чем более простой код, который легче читать:
if (angle < 0)
angle += PI * 2;
Если этот код используется только сотни раз в секунду на настольном компьютере, я сомневаюсь, что вы даже заметите разницу. Для телефона / планшета, возможно, я бы установил этот предел в десятки раз в секунду.
редактировать: нужен отрицательный угол PI * 2
добавил, не только PI
,
Более прямо возможно:
static double computeAngleFromCenter(cv::Point center, cv::Point p, bool asDegrees = false)
{
double angle = std::atan2(p.y - center.y, p.x - center.x);
if (asDegrees)
angle *= 180 / 3.1415926;
return angle + 360; // [180, 540] Always positive.
}
static double computeAngleFromCenter(cv::Point center, cv::Point p, bool asDegrees = false)
{
double angle = std::atan2(p.y - center.y, p.x - center.x);
if (asDegrees)
angle *= 180 / 3.1415926;
if(angle<0)angle+=360;
return angle;
}