简体   繁体   English

获得两个标题之间的区别

[英]Getting the difference between two headings

I have this method for figuring out the difference between 2 0-360 compass headings. 我有这种方法来计算2 0-360指南针标题之间的区别。

Although this works for figuring out how far absolutely (as in, always positive output) off I am, I am having trouble figuring out what needs to be done to introduce the sign into the output. 虽然这可以用来确定我的绝对距离(例如,总是正输出),但我无法弄清楚要将标志引入输出需要做些什么。

Ideally, if the shortest distance from the initial heading to the final heading is by going around clockwise, I'd like the error to have a positive sign, if the shortest distance between the headings involves going around counterclock-wise, I'd like the error to have a negative sign. 理想情况下,如果从初始航向到最终航向的最短距离是顺时针方向,我希望error有一个正号,如果标题之间的最短距离涉及逆时针方向,我会喜欢有error号的error

A few examples of desired inputs/outputs 一些期望的输入/输出的例子

initial -- final -- error initial - final - error

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

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

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

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

Code: 码:

    /// <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;
    }

Edit: added check for when the difference is exactly 180 degrees. 编辑:添加检查差异恰好是180度。 previously this was returning either 180 or -180 depending on whether final was greater or lower than initial. 以前这是返回180或-180,取决于最终是否大于或低于初始。 I've modified it so that it returns positive 180 in both cases. 我已修改它,以便在两种情况下都返回正数180。


So here's my attempt... 所以这是我的尝试......

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;
            }
        }

If I understand the question correctly, I think the following code should work: 如果我正确理解了这个问题,我认为以下代码应该有效:

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;
}

Basically I'm treating 360 degrees the same as 0, which I believe is ok. 基本上我对待360度与0相同,我认为没问题。 This code will produce the same results as listed in the table above. 此代码将生成与上表中列出的结果相同的结果。 Code does not do bounds checking, it is expecting values between 0 and 360. 代码不进行边界检查,期望值介于0到360之间。

I think your table of desired results is incorrect. 我认为你想要的结果表是不正确的。 Here's my klunky way: 这是我笨重的方式:

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;
}

Here's a straightforward solution, albeit named a bit differently and in Dart. 这是一个简单的解决方案,尽管在Dart中有点不同。 Based on this avionics answer . 基于这个航空电子学的答案

/// 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;
}

Edit: There's an even more concise answer here , but I haven't tried it myself: 编辑:有一个更简洁的答案在这里 ,但我还没有尝试过自己:

double headingDiff(double h1, double h2) => (h2 - h1 + 540) % 360 - 180;
Degree_Diff = (MIN(ABS(ENDCOMPASS-STARTCOMPASS),ABS(360-ENDCOMPASS+STARTCOMPASS),ABS(360-STARTCOMPASS+ENDCOMPASS))) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM