From 5e36d564aa4e5f3ffc96f23b795181d03274386e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Sat, 16 Oct 2021 14:11:22 +0200 Subject: [PATCH] Added workaround for antipode routes Fixes #155 --- src/common/greatcircle.cpp | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/common/greatcircle.cpp b/src/common/greatcircle.cpp index 7192bf0c..7d422b86 100644 --- a/src/common/greatcircle.cpp +++ b/src/common/greatcircle.cpp @@ -1,11 +1,41 @@ #include "greatcircle.h" +#define DELTA 1e-5 + +static bool antipodes(const Coordinates &c1, const Coordinates &c2) +{ + return ((qAbs(c1.lat() + c2.lat()) < DELTA) + && (qAbs(180.0 - qAbs(c1.lon() - c2.lon())) < DELTA)); +} + GreatCircle::GreatCircle(const Coordinates &c1, const Coordinates &c2) { - double lat1 = deg2rad(c1.lat()); - double lon1 = deg2rad(c1.lon()); - double lat2 = deg2rad(c2.lat()); - double lon2 = deg2rad(c2.lon()); + double lat1, lon1, lat2, lon2; + + if (antipodes(c1, c2)) { + /* In case of antipodes (which would lead to garbage output without + this hack), move the points DELTA degrees closer to each other in + a way that the route never crosses the antimeridian. */ + if (c1.lon() < c2.lon()) { + lon1 = deg2rad(c1.lon() + DELTA); + lon2 = deg2rad(c2.lon() - DELTA); + } else { + lon1 = deg2rad(c1.lon() - DELTA); + lon2 = deg2rad(c2.lon() + DELTA); + } + if (c1.lat() < c2.lat()) { + lat1 = deg2rad(c1.lat() + DELTA); + lat2 = deg2rad(c2.lat() - DELTA); + } else { + lat1 = deg2rad(c1.lat() - DELTA); + lat2 = deg2rad(c2.lat() + DELTA); + } + } else { + lat1 = deg2rad(c1.lat()); + lon1 = deg2rad(c1.lon()); + lat2 = deg2rad(c2.lat()); + lon2 = deg2rad(c2.lon()); + } double cosLat1 = cos(lat1); double cosLat2 = cos(lat2);