获取两个标题之间的差异

发布于 2024-10-17 12:56:17 字数 1181 浏览 6 评论 0原文

我有这个方法来计算 2 个 0-360 罗盘方向之间的差异。

尽管这可以计算出我的绝对偏差(例如,始终为正输出)有多远,但我无法弄清楚需要做什么才能将符号引入输出中。

理想情况下,如果从初始航向到最终航向的最短距离是顺时针旋转,如果航向之间的最短距离涉及逆时针旋转,我希望错误具有正号-明智的是,我希望 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;
    }

I have this method for figuring out the difference between 2 0-360 compass headings.

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.

A few examples of desired inputs/outputs

initial -- final -- error

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

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

360 .................... 1 .......... 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;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

⒈起吃苦の倖褔 2024-10-24 12:56:18

如果我正确理解了这个问题,我认为下面的代码应该有效:

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 之间。

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. 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.

生寂 2024-10-24 12:56:18

我认为您的期望结果表不正确。这是我笨拙的方法:

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

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;
}
心奴独伤 2024-10-24 12:56:18
Degree_Diff = (MIN(ABS(ENDCOMPASS-STARTCOMPASS),ABS(360-ENDCOMPASS+STARTCOMPASS),ABS(360-STARTCOMPASS+ENDCOMPASS))) 
Degree_Diff = (MIN(ABS(ENDCOMPASS-STARTCOMPASS),ABS(360-ENDCOMPASS+STARTCOMPASS),ABS(360-STARTCOMPASS+ENDCOMPASS))) 
亢潮 2024-10-24 12:56:17

编辑:添加了差异恰好为 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;
            }
        }

Edit: added check for when the difference is exactly 180 degrees. previously this was returning either 180 or -180 depending on whether final was greater or lower than initial. I've modified it so that it returns positive 180 in both cases.


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;
            }
        }
放手` 2024-10-24 12:56:17

这是一个简单的解决方案,尽管在 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;

Here's a straightforward solution, albeit named a bit differently and in 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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文