Steve Howell wrote:
I just saw the thread for medians, and it reminded me of a problem
that I need to solve.  We are writing some Python software for
sailing, and we need to detect when we've departed from the median
heading on the leg.  Calculating arithmetic medians is
straightforward, but compass bearings add a twist.

The numerical median of 1, 2, 3, 4, 5, 6, 359 is 4.  But for
navigational purposes you would actually order the numbers 359, 1, 2,
3, 4, 5, 6, so the desired median heading of the boat is actually 3.

Of course, you could express 359 better as -1 degrees to north, then
the sequence would be -1, 1, 2, 3, 4, 5, and 6.  And you'd be good.

But that trick does not generalize if you go south instead, as you
have similar issues with -179, 174, 175, 176, 177, 178, and 179.

Has anybody solved this in Python, either for compass bearings or a
different domain?  I can think of kind of a brute force solution where
you keep rotating the sequence until the endpoints are closest
together mod 360, but I wonder if there is something more elegant.

When you read the headings clockwise the values normally increase and
you pick the middle one. However, when you cross north the values
decrease. You can spot whether the set of headings crosses north by
checking whether the difference between the minimum and maximum is
greater than 180. If it is then make the westerly headings negative,
sort the values, and pick the middle one, adding 180 if it's negative.

def compass_median(points):
    points = sorted(points)
    if points[-1] - points[0] > 180:
        points = [(p - 360 if p > 180 else p) for p in points]
        points.sort()
    median = points[len(points) // 2]
    return median + 360 if median < 0 else median
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to