I recently needed to find the average of two angles. I was programmatically creating a irregular polygon. I wanted to draw a small square at the points of the polygon, and I wanted the squares to be rotated to the average of the two lines that met at that point.

The issue is that if you have two bearings, one at 20° and one at 350°, or one at 15° and one at 315°. If you just average the two numbers, you get 185°, but the more appropriate number is 5°. This is called by some a “Wraparound issue” and if you search the web you will see lots of ways to solve this problem. Unfortunately they mostly try to solve it using a mathematical equation. Now for people that have read this blog for awhile know that I am not allergic to math, but if we can solve this problem simply with an algorithm, we should … that’s what computers are for, right?

So, here is my algorithm and the thought behind it.

(Assumptions: 0 >= bearings < 360)

First if you look at the difference between the two bearings, you will see that there are two possibilities, the actual difference is greater than 180° or less than 180°. Since we are only concerned about “fixing” the issue when the difference is greater than 180°, that is the first thing we will check.

We will call the smaller value bearing **bearingA** and the larger value bearing **bearingB**.

Since we know that bearingB has a larger value and that the difference is greater than 180, so bearingB > 180.

So, if we subtract 360 – bearingB, then just add bearingA + bearingB and divide the total in half, we are 90% there.

One last check. If the result is less than 0, we need to add 360 back in.

So, example #1 20° & 350° | So, example #2 15° & 315° |

And here is the code:

- private static double GetAverageBearing(double bearingA, double bearingB)
- {
- if (bearingA > bearingB)
- {
- var temp = bearingA;
- bearingA = bearingB;
- bearingB = temp;
- }
- if (bearingB - bearingA > 180) bearingB -= 360;
- var finalBearing = (bearingB + bearingA)/2;
- if (finalBearing < 0) finalBearing += 360;
- return finalBearing;
- }

## 1 comment:

Thanks! I believe there is a typo above in the example: 354 degrees should be 345 degrees.

I used this example to translate a VB equivalent. Here it is if anyone else is interested:

Public Function AverageBearing(ByVal BearingA As Double, ByVal BearingB As Double) As Double

Dim TempBearing As Double

Dim FinalBearing As Double

If BearingA > BearingB Then

TempBearing = BearingA

BearingA = BearingB

BearingB = TempBearing

End If

If (BearingB - BearingA) > 180 Then BearingB = BearingB - 360

FinalBearing = (BearingB + BearingA) / 2

If FinalBearing < 0 Then FinalBearing = FinalBearing + 360

AverageBearing = FinalBearing

End Function

Post a Comment