Найдите, находится ли угол в пределах X градусов от другого

StackOverflow https://stackoverflow.com/questions/1581267

Вопрос

Мне нужен алгоритм, чтобы выяснить, находится ли один угол в пределах определенного количества градусов от другого угла.

Моей первой мыслью было (a-x < b) && (a+x > b), но он терпит неудачу, когда ему приходится работать с углами, которые изменяются от -179 до 180.

На диаграмме выше область (зеленая), между которой должен находиться угол, находится между отрицательной и положительной сторонами.Как я могу определить, попадает ли угол (красная линия) внутрь этой области?

Это было полезно?

Решение

попробуйте эту формулу:

360-(|a-b|)%360<x || (|a-b|)%360<x

Или, в PHP:

<?php

$b = 10;
$angle1 = -179;
$angle2 = 180;

$diff = $angle1 - $angle2;
if(abs($diff % 360) <= $b || (360-abs($diff % 360))<=$b) {
  echo "yes";
} else {
  echo "no";
}

?>

Другие советы

Как справедливо отмечает Марсель, деление по модулю на отрицательные числа потенциально проблематично.Кроме того, в чем разница между 355 и 5 градусами?Возможно, предполагается, что температура составит 350 градусов, но 10 градусов - это, вероятно, то, чего ожидают люди.Мы делаем следующие предположения:

  1. нам нужен наименьший положительный угол между двумя другими углами, чтобы 0 <= diff <= 180;
  2. мы работаем в градусах.Если в радианах, замените 360 на 2*PI;
  3. углы могут быть положительными или отрицательными, могут находиться за пределами диапазона -360 < x < 360 где x - входной угол и
  4. порядок входных углов или направление разницы не имеет значения.

Входные данные:углы a и b.Таким образом, алгоритм прост:

  1. Нормализуйте a и b, чтобы 0 <= x < 360;
  2. Вычислите кратчайший угол между двумя нормальными углами.

Для первого шага, чтобы преобразовать угол в желаемый диапазон, есть две возможности:

  • x >= 0:норма = x % 360
  • x < 0:нормальный = (-x / 360 + 1) * 360 + x

Второй предназначен для устранения любой двусмысленности в отношении различий в интерпретации операций с отрицательным модулем.Итак, чтобы привести работающий пример для x = -400:

  -x / 360 + 1
= -(-400) / 360 + 1
= 400 / 360 + 1
= 1 + 1
= 2

тогда

normal = 2 * 360 + (-400)
       = 320

таким образом, для входов 10 и -400 нормальные углы равны 10 и 320.

Теперь мы вычисляем кратчайший угол между ними.Для проверки работоспособности сумма этих двух углов должна быть равна 360.В данном случае возможны значения 50 и 310 (нарисуйте их, и вы увидите это).Чтобы разобраться с этим:

normal1 = min(normal(a), normal(b))
normal2 = max(normal(a), normal(b))
angle1 = normal2 - normal1
angle2 = 360 + normal1 - normal2

Итак, для нашего примера:

normal1 = min(320, 10) = 10
normal2 = max(320, 10) = 320
angle1 = normal2 - normal1 = 320 - 10 = 310
angle2 = 360 + normal1 - normal2 = 360 + 10 - 320 = 50

Вы заметите normal1 + normal2 = 360 (и вы даже можете доказать, что это будет так, если хотите).

Наконец:

diff = min(normal1, normal2)

или 50 в нашем случае.

При радиусе 1 расстояние между конечными точками линии равно 2sin((a-b/2).Поэтому отбросьте 2, поскольку вас интересует только сравнение, и сравните sin (x / 2) с sin((a-b)/ 2).Тригонометрические функции заботятся обо всей упаковке.

Вы также можете использовать точечный продукт:

cos(a)*cos(b) + sin(a)*sin(b) >= cos(x)

реализация на c++:

float diff = fabsf(angle1 - angle2);
bool isInRange = fmodf(diff, 360.0f) <= ANGLE_RANGE ||
                 360.0f - fmodf(diff, 360.0f) <= ANGLE_RANGE;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top