Search code examples
c#compass-geolocation360-degrees

Getting the difference between two headings


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

Solution

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