2015-01-20 2 views
2

Я пытаюсь найти способ найти кратчайшее расстояние между двумя углами. Углы находятся в интервале -360 < 360 и указаны в градусах.Найти кратчайшее расстояние между двумя углами

Короче говоря, мне нужен простой способ (чем проще, тем лучше) найти кратчайшее расстояние между двумя углами, назовем их angle1 и angle2. Angle1 - это угол, который я хочу получить, угол 2 - это угол, на котором я нахожусь. После этого я хочу использовать функцию if, чтобы определить направление вращения объекта.

псевдокод:

CloseDistance = (Find shortest distance between angle1 (where i want to go) and angle2 (where i am)) 

if (CloseDistance > Something) 
    {Rotate to the right} else {Rotate to the left} 
+0

По расстоянию вы имеете в виду наименьший угол поворота, чтобы перейти от одного заголовка к другому, правильно? –

+6

Я не совсем понимаю, что означает «кратчайшее расстояние между двумя углами». Углы - это скаляры, поэтому кратчайшее «расстояние» между ними является их разницей. Если вы говорите о какой-либо другой форме геометрического расстояния, было бы полезно, если бы вы сделали приблизительную диаграмму. –

+0

Получил исправление в виде ответа от Kyle, спасибо за помощь! – Captain

ответ

7
public static double AngleDifference(double angle1, double angle2) 
{ 
    double diff = (angle2 - angle1 + 180) % 360 - 180; 
    return diff < -180 ? diff + 360 : diff; 
} 

Это работает, заметив, что мы хотим взять разницу между двумя углами, angle1 и angle2 и завернуть, что результат в диапазоне [-180, 179). Оператор mod позволяет нам обернуть что-то в диапазон [0, n). То есть x % n «обертывания» (с оговоркой для x < 0) x до диапазона [0, n).

Наш диапазон начинается с -180, а не 0, поэтому мы переносим его, добавляя 180. Затем мы завершаем до 360, а затем переходим обратно. Вот что делает первая строка метода.

Вторая линия заботится об этой маленькой морщине с отрицательными цифрами. Если angle2 - angle1 + 180 оказалось меньше 0, то diff будет меньше 180. В этом случае мы просто переносим его обратно в диапазон, добавляя к нему 360. В противном случае мы ничего не делаем.

В качестве дополнительного бонуса входные углы полностью не ограничены. Они не должны быть между -360 и 360. Они могут быть любыми.

+0

Реализована в моем коде, работает безупречно и делает именно то, что мне нужно. Огромное спасибо! – Captain

+0

@Captain Нет проблем! Пожалуйста, подумайте над выбором этого ответа, поскольку он вам помог. – Kyle

0

кажется вам нужно привести угол в интервале -180 .. + 179. Отрицательные знаки означают правое вращение, положительные - влево (или наоборот).

Ergo, вам нужен modular arithmetic с по модулю 360.

В C# remaidner operator делает то, что вам нужно:

var distance = (destinationAngle - sourceAngle) % 360; 

К сожалению, это дает результат в интервале -359 .. + 359. Чтобы исправить это, вы можете преобразовать слишком большие значения интервальных -180 .. + 179:

var distance = (destinationAngle - sourceAngle) % 360; 
if (distance < -180) 
    distance += 360; 
else if (distance > 179) 
    distance -= 360; 

Асимметричные концы интервала (-180 и +179) появились потому, -180 и +180 оба тот же угол, поэтому вы должны выбрать один из них, чтобы избежать двусмысленности.

F.e.

Destination | Source | Result 
      45 |  30 |  15 
      30 |  45 | -15 
      -45 | -30 | -15 
      -30 | -45 |  15 
360 + 45 = 405 |  30 |  15 
      -405 | -30 | -15 

Как я могу видеть, что вам нужно. Если ваши углы удваиваются, используйте метод Math.IEEERemainder.

0

Максимальное расстояние между 2 углами 180 градусов, просто выбрать угол, который находится в диапазоне от 0 до 360

int angle1 = n; 
int angle2 = n2; 

if(angle1 < 0) 
    angle1 += 360; 

if(angle2 < 0) 
    angle2 += 360; 

if (angle2 > angle1 && angle2 - angle1 <= 180) 
    //go clockwise 
else if (angle2 > angle1 && angle2 - angle1 > 180) 
    //go counter clockwise 
else if (angle1 > angle2 && angle1 - angle2 <= 180) 
    //go counter clockwise 
else if (angle1 > angle2 && angle1 - angle2 > 180) 
    //go clockwise 
0

Простейший способом я нашел

double closedistance = (destangle - startangle) % 360 

abs(closedistance) дает требуемое расстояние ,

знак closedistance (= closedistance/abs(closedistance)) задает направление вращения (+ против часовой стрелки, - по часовой стрелке) или просто проверить его, как этот

if (closedistance > 0) {} // anticlockwise 
else {} // clockwise 

Это работает для любого значения углов.

Смежные вопросы