Получение разницы между двумя заголовками - PullRequest
9 голосов
/ 17 февраля 2011

У меня есть этот метод для определения разницы между 2 0-360 заголовками компаса.

Хотя это работает для определения того, насколько далеко (как и всегда, положительный вывод) от меня, у меня возникают проблемы с выяснением того, что нужно сделать, чтобы ввести знак в вывод.

В идеале, если кратчайшее расстояние от начального до конечного курса идет по часовой стрелке, я бы хотел, чтобы error имел положительный знак, если кратчайшее расстояние между заголовками предполагает обход против часовой стрелки. Я бы хотел, чтобы у error был отрицательный знак.

Несколько примеров желаемых входов / выходов

initial - final - error

0 .................... 30 .......... 30

30 .................... 0 .......... -30

360 .................... 1 .......... 1

1 .................... 360 .......... -1

Код:

    /// <summary>
    /// Calculate the error from a given initial heading to a final heading
    /// </summary>
    /// <param name="inital"></param>
    /// <param name="final"></param>
    /// <returns></returns>
    private double GetHeadingError(double initial, double final)
    {
        double directionA = final - initial;
        double directionB = 360 - (final + initial);
        double error = 0;

        if (Math.Abs(directionA) < Math.Abs(directionB))
        {
            error = directionA;
        }
        else
        {
            error = directionB;
        }

        return error;
    }

Ответы [ 5 ]

15 голосов
/ 17 февраля 2011

Редактировать: добавлена ​​проверка, когда разница точно равна 180 градусам. ранее это возвращало или 180 или -180 в зависимости от того, был ли финал больше или ниже, чем начальный. Я изменил его так, чтобы он возвращал положительное значение 180 в обоих случаях.


Итак, вот моя попытка ...

private static double GetHeadingError(double initial, double final)
        {
            if (initial > 360 || initial < 0 || final > 360 || final < 0)
            {
                //throw some error
            }

            var diff = final - initial;
            var absDiff = Math.Abs(diff);

            if (absDiff <= 180)
            {
                //Edit 1:27pm
                return absDiff == 180 ? absDiff : diff;
            }

            else if (final > initial)
            {
                return absDiff - 360;
            }

            else
            {
                return 360 - absDiff;
            }
        }
2 голосов
/ 17 февраля 2011

Если я правильно понимаю вопрос, я думаю, что следующий код должен работать:

private double GetHeadingError(double initial, double final)
{
            if(initial == 360) initial = 0;
            if(final == 360) final = 0;
            double clockWise = (final - initial);
            double counterClockWise = (360 - final + initial);
            return (Math.Abs(clockWise) <= Math.Abs(counterClockWise)) ? clockWise : -counterClockWise;
}

В основном я лечу 360 градусов так же, как 0, что, я считаю, нормальноЭтот код даст те же результаты, что перечислены в таблице выше.Код не выполняет проверку границ, он ожидает значения от 0 до 360.

1 голос
/ 28 февраля 2012
Degree_Diff = (MIN(ABS(ENDCOMPASS-STARTCOMPASS),ABS(360-ENDCOMPASS+STARTCOMPASS),ABS(360-STARTCOMPASS+ENDCOMPASS))) 
1 голос
/ 17 февраля 2011

Я думаю, что ваша таблица желаемых результатов неверна.Вот мой грубый путь:

private double MyGetHeadingError(double initial, double final)
{
    initial += 1000;
    final += 1000;

    bool flipped = false;
    if (initial > final)
    {
        double temp;
        temp = final;
        final = initial;
        initial = temp;
        flipped = true;
    }
    double error;
    if (final - initial > 180)
        final = final - 360;

    error = final - initial;

    if (flipped == true)
        error = -error;
    return error;
}
0 голосов
/ 22 февраля 2019

Вот простое решение, хотя и названное немного по-другому и в Dart.На основании этого ответа авионики .

/// The difference of two headings in degrees such that it is always in the range
/// (-180, 180]. A negative number indicates [h2] is to the left of [h1].
double headingDiff(double h1, double h2) {
  double left = h1 - h2;
  double right = h2 - h1;
  if (left < 0) left += 360;
  if (right < 0) right += 360;
  return left < right ? -left : right;
}

Редактировать: Здесь есть еще более краткий ответ здесь , но я сам не пробовал:

double headingDiff(double h1, double h2) => (h2 - h1 + 540) % 360 - 180;
...