algorithmmathgeometrydegrees

Diff of two wind directions


I want to plot graph showing difference of two wind directions (measured by two different sensors not at the same place) during the time period.

I have both values presented as azimuth, i.e. north = 0, east = 90, south = 180, west = 270. I am thinking about the following requirements:

  1. absolute value of difference should be +0 .. +180 such that the smaller angle between both value is used
  2. the sign of the difference should be defined by defining positive value for situation where angle between valueB and valueA is smaller in the clock direction (e.g. valueB=50, valueA=10 or valueB=50, valueA=350) while negative value is used if angle is smaller in counter-clock direction (e.g the opposite)

I think that this requirements can also be understand so that I want to rotate reference system to make valueA get azimuth = 0 and then return the azimuth of value B on the scale -180 .. +180.

I have something like this:

diff = abs(valueB - valueA)
if (diff >= 180) diff = 360 - diff

if (valueA < 180) offsetA = valueA else offsetA = valueA - 360
offsetB = valueB - offsetA
if (offsetB < 0) offsetB = offsetB + 360
if (offsetB >= 360) offsetB = offsetB - 360
if (offsetB > 180) diff = (-1) * diff

Question 1: Is shorter code possible?

Question 2: Is there a better presentation of difference between two wind directions? I do not see how Wind Rose (which is nice for presentation of speed + direction) could be used to present the difference between two directions during the time period.

Question 3: I will use Python or R. Are there already such function implemented in some library?

If another SE forum is more appropriate, please suggest.


Solution

  • In a CodeProject article I wrote way back in 2011 "Circular Values Math and Statistics with C++11" I addressed the same problem. I called it the directed distance between two circular values.

    If the inputs are in the range [0..360) you can use the following:

    // the length of the directed walk from c1 to c2, with the lowest absolute-value length
    // return value is in [-180, 180)
    double Sdist(double c1, double c2)
    {
        double d = c2 - c1;
        if (d <  -180.) return d + 180.;
        if (d >=  180.) return d - 180.;
                        return d       ;
    }
    

    I also defined another distance type for circular values: the increasing distance (clockwise).

    // the length of the increasing walk from c1 to c2 with the lowest length
    // return value is in [0, 360)
    double Pdist(double c1, double c2)
    {
        return c2 >= c1 ? c2 - c1 : 360. - c1 + c2;
    }
    

    See sections 8 and 9 in the article. The article and source code with some fixes are also available on GitHub.