Opened 7 years ago

Last modified 7 years ago

#11929 new Bugs

haversine method is inaccurate

Reported by: Charles Karney <charles@…> Owned by: Barend Gehrels
Milestone: To Be Determined Component: geometry
Version: Boost 1.58.0 Severity: Problem
Keywords: distance Cc: charles.karney@…

Description

The following code illustrates a problem with the "haversine" strategy for computing great circle distances. It computes the distance between two nearly antipodal points. The relative error in the result is 5e-9, much bigger than you should get with doubles.

#include <iostream>
#include <cmath>
#include <boost/geometry.hpp>

namespace bg = boost::geometry;
typedef bg::model::point<double, 2,
                         bg::cs::spherical_equatorial<bg::degree> > pt;

int main() {
  double pi = std::atan2(0, -1);
  bg::model::segment<pt> seg;
  bg::read_wkt("SEGMENT(0.000001 0, 180 0)", seg);
  double
    // arc length (converted to degrees
    dist = bg::distance(seg.first, seg.second) * (180/pi),
    // the correct distance (in degrees)
    dist0 = 180 - 0.000001,
    err = (dist - dist0) / dist0;
  std::cout << "relative error " << err << "\n";
}

Running this code gives

relative error 5.55556e-09

Discussion:

  • Surely it's a bad idea to embed the algorithm name "haversine" into the API. Computing great circle distances is really straightforward. Users shouldn't need to worry about the underlying method. Maybe "great_circle" is a better name.
  • The use of haversines made sense when the log haversine function was tabulated and you needed trigonometric identities involving products to facilitate computations with log tables. Nowadays there are better formulas.
  • As this example illustrates, it's subject to a loss of accuracy with antipodal points (it takes the arcsine of a number close to 1.)
  • A good formula to use is given in the Wikipedia article on great-circle navigation (this is the formula used by Vincenty in the spherical limit -- but it surely doesn't originate with him).

Change History (1)

comment:1 by Charles Karney <charles@…>, 7 years ago

Summary: haversine method is accuratehaversine method is inaccurate
Note: See TracTickets for help on using tickets.