diff options
Diffstat (limited to 'boost/geometry/formulas/elliptic_arc_length.hpp')
-rw-r--r-- | boost/geometry/formulas/elliptic_arc_length.hpp | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/boost/geometry/formulas/elliptic_arc_length.hpp b/boost/geometry/formulas/elliptic_arc_length.hpp index 75881f3d0d..65c8f60226 100644 --- a/boost/geometry/formulas/elliptic_arc_length.hpp +++ b/boost/geometry/formulas/elliptic_arc_length.hpp @@ -14,7 +14,6 @@ #include <boost/math/constants/constants.hpp> #include <boost/geometry/core/radius.hpp> -#include <boost/geometry/core/srs.hpp> #include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/math.hpp> @@ -46,14 +45,45 @@ public : bool meridian; }; + template <typename T> + static bool meridian_not_crossing_pole(T lat1, T lat2, CT diff) + { + CT half_pi = math::pi<CT>()/CT(2); + return math::equals(diff, CT(0)) || + (math::equals(lat2, half_pi) && math::equals(lat1, -half_pi)); + } + + static bool meridian_crossing_pole(CT diff) + { + return math::equals(math::abs(diff), math::pi<CT>()); + } + + + template <typename T, typename Spheroid> + static CT meridian_not_crossing_pole_dist(T lat1, T lat2, Spheroid const& spheroid) + { + return math::abs(apply(lat2, spheroid) - apply(lat1, spheroid)); + } + + template <typename T, typename Spheroid> + static CT meridian_crossing_pole_dist(T lat1, T lat2, Spheroid const& spheroid) + { + CT c0 = 0; + CT half_pi = math::pi<CT>()/CT(2); + CT lat_sign = 1; + if (lat1+lat2 < c0) + { + lat_sign = CT(-1); + } + return math::abs(lat_sign * CT(2) * apply(half_pi, spheroid) + - apply(lat1, spheroid) - apply(lat2, spheroid)); + } + template <typename T, typename Spheroid> static result apply(T lon1, T lat1, T lon2, T lat2, Spheroid const& spheroid) { result res; - CT c0 = 0; - CT pi = math::pi<CT>(); - CT half_pi = pi/CT(2); CT diff = geometry::math::longitude_distance_signed<geometry::radian>(lon1, lon2); if (lat1 > lat2) @@ -61,24 +91,14 @@ public : std::swap(lat1, lat2); } - if ( math::equals(diff, c0) || - (math::equals(lat2, half_pi) && math::equals(lat1, -half_pi)) ) + if ( meridian_not_crossing_pole(lat1, lat2, diff) ) { - // single meridian not crossing pole - res.distance = apply(lat2, spheroid) - apply(lat1, spheroid); + res.distance = meridian_not_crossing_pole_dist(lat1, lat2, spheroid); res.meridian = true; } - - if (math::equals(math::abs(diff), pi)) + else if ( meridian_crossing_pole(diff) ) { - // meridian crosses pole - CT lat_sign = 1; - if (lat1+lat2 < c0) - { - lat_sign = CT(-1); - } - res.distance = math::abs(lat_sign * CT(2) * apply(half_pi, spheroid) - - apply(lat1, spheroid) - apply(lat2, spheroid)); + res.distance = meridian_crossing_pole_dist(lat1, lat2, spheroid); res.meridian = true; } return res; |