Наименьшая разница между двумя углами? - PullRequest
8 голосов
/ 17 июля 2011

Я пытаюсь вычислить наименьшую разницу между двумя углами.

Это мой текущий код (небольшое изменение того, что я нашел в сети):

float a1 = MathHelper.ToDegrees(Rot);
float a2 = MathHelper.ToDegrees(m_fTargetRot);

float dif = (float)(Math.Abs(a1 - a2);

if (dif > 180)
  dif = 360 - dif;

dif = MathHelper.ToRadians(dif);

Работает нормально, за исключением случаев на краю круга. Например, если текущий угол равен 355, а целевой угол равен 5, он рассчитывает разницу -350, а не 10, поскольку 365 градусов равно 5 градусам.

Есть идеи, что я могу сделать, чтобы сделать эту работу?

Ответы [ 4 ]

8 голосов
/ 17 июля 2011

У вас в основном было это.Просто возьмите модуль diff 360 перед проверкой, чтобы увидеть, превышает ли оно 180:

float a1 = MathHelper.ToDegrees(Rot);
float a2 = MathHelper.ToDegrees(m_fTargetRot);

float dif = (float)Math.Abs(a1 - a2) % 360;

if (dif > 180)
    dif = 360 - dif;

dif = MathHelper.ToRadians(dif);

Редактировать: @ Эндрю Рассел сделал замечание в комментариях к вашему вопросу, и нижеприведенное решение использует преимуществометода MathHelper.WrapAngle, как он предложил:

diff = Math.Abs(MathHelper.WrapAngle(a2 - a1));
3 голосов
/ 17 июля 2011

Вы бы расширили проверку для углов вне:

if (dif < 0) dif = dif + 360;
if (dif > 180) dif = 360 - dif;
2 голосов
/ 13 декабря 2012

Мне никогда не нравилось обрабатывать обтекание с помощью операторов case.Вместо этого я использую определение точечного произведения для вычисления угла (без знака) между двумя углами:

vec(a) . vec(b) = ||a|| ||b|| cos(theta)

Мы просто собираемся создать единичные векторы a и b,||a|| == ||b|| == 1.

Начиная с vec(x) = [cos(x),sin(x)], мы получаем:

unsigned_angle_theta(a,b) = acos(cos(a)cos(b) + sin(a)sin(b))

(nb все углы в радианах)

1 голос
/ 17 июля 2011

Результат можно нормализовать до 0 <= theta <360: </p>

while(theta < 0) { theta += 360; }

Если вы хотите сохранить ответ в радианах (рекомендуется):

const Double TwoPi = 2 * Math.Pi;
while(theta < 0) { theta += TwoPi; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...