Наименьшая разница между 2 углами
учитывая 2 угла в диапазоне-PI - > PI вокруг координаты, каково значение наименьшего из 2 углов между ними?
принимая во внимание, что разница между Пи и-пи не 2 Пи, а ноль.
пример:
представьте себе круг, с 2 линиями, выходящими из центра, между этими линиями есть 2 угла, угол, который они делают внутри aka чем меньше угол, и угол они делают на снаружи, ака больший угол. Оба угла при сложении образуют полный круг. Учитывая, что каждый угол может поместиться в определенном диапазоне,каково значение меньших углов, учитывая опрокидывание
8 ответов:
это дает знаковый угол для любых углов:
a = targetA - sourceA a = (a + 180) % 360 - 180
остерегайтесь, во многих языках
modulo
операция возвращает значение с тем же знаком, что и дивиденд (например, C, C++, C#, JavaScript,полный список здесь). Для этого требуется пользовательский
x-целевой угол. y-исходный или начальный угол:
atan2(sin(x-y), cos(x-y))
возвращает подписанный Дельта-угол. Обратите внимание, что в зависимости от вашего API порядок параметров для функции atan2() может отличаться.
если ваши два угла-x и y, то один из углов между ними - abs(x-y). Другой угол (2 * PI) - abs(x-y). Таким образом, значение наименьшего из 2 углов:
min((2 * PI) - abs(x - y), abs(x - y))
это дает вам абсолютное значение угла, и он предполагает, что входы нормализованы (т. е.: в пределах диапазона
[0, 2π)
).если вы хотите сохранить знак (т. е. направление) угол, а также принять углов вне диапазона
[0, 2π)
вы можете обобщить вышесказанное. Вот код Python для обобщенной версии:PI = math.pi TAU = 2*PI def smallestSignedAngleBetween(x, y): a = (x - y) % TAU b = (y - x) % TAU return -a if a < b else b
отметим, что
%
оператор не ведет себя одинаково на всех языках, особенно когда используются отрицательные значения, поэтому при переносе могут потребоваться некоторые корректировки знака.
Я поднимаюсь на вызов предоставления подписанного ответа:
def f(x,y): import math return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)
для пользователей UnityEngine, простой способ-это просто использовать Mathf.DeltaAngle.
нет необходимости вычислять тригонометрические функции. Простой код на языке C:
#include <math.h> #define PIV2 M_PI+M_PI #define C360 360.0000000000000000000 double difangrad(double x, double y) { double arg; arg = fmod(y-x, PIV2); if (arg < 0 ) arg = arg + PIV2; if (arg > M_PI) arg = arg - PIV2; return (-arg); } double difangdeg(double x, double y) { double arg; arg = fmod(y-x, C360); if (arg < 0 ) arg = arg + C360; if (arg > 180) arg = arg - C360; return (-arg); }
пусть dif = a-b , в радианах
dif = difangrad(a,b);
пусть dif = a-b , в градусах
dif = difangdeg(a,b); difangdeg(180.000000 , -180.000000) = 0.000000 difangdeg(-180.000000 , 180.000000) = -0.000000 difangdeg(359.000000 , 1.000000) = -2.000000 difangdeg(1.000000 , 359.000000) = 2.000000
нет греха, нет cos, нет загара,.... только геометрия!!!!