diff options
Diffstat (limited to 'boost/geometry/formulas/spherical.hpp')
-rw-r--r-- | boost/geometry/formulas/spherical.hpp | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/boost/geometry/formulas/spherical.hpp b/boost/geometry/formulas/spherical.hpp index ff24c51a88..5599cd6e81 100644 --- a/boost/geometry/formulas/spherical.hpp +++ b/boost/geometry/formulas/spherical.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016, Oracle and/or its affiliates. +// Copyright (c) 2016-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -15,6 +15,7 @@ #include <boost/geometry/core/coordinate_type.hpp> #include <boost/geometry/core/access.hpp> #include <boost/geometry/core/radian_access.hpp> +#include <boost/geometry/core/radius.hpp> //#include <boost/geometry/arithmetic/arithmetic.hpp> #include <boost/geometry/arithmetic/cross_product.hpp> @@ -24,6 +25,8 @@ #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> #include <boost/geometry/util/select_coordinate_type.hpp> +#include <boost/geometry/formulas/result_direct.hpp> + namespace boost { namespace geometry { namespace formula { @@ -217,6 +220,62 @@ inline int azimuth_side_value(T const& azi_a1_p, T const& azi_a1_a2) : 1; // left } +template +< + bool Coordinates, + bool ReverseAzimuth, + typename CT, + typename Sphere +> +inline result_direct<CT> spherical_direct(CT const& lon1, + CT const& lat1, + CT const& sig12, + CT const& alp1, + Sphere const& sphere) +{ + result_direct<CT> result; + + CT const sin_alp1 = sin(alp1); + CT const sin_lat1 = sin(lat1); + CT const cos_alp1 = cos(alp1); + CT const cos_lat1 = cos(lat1); + + CT const norm = math::sqrt(cos_alp1 * cos_alp1 + sin_alp1 * sin_alp1 + * sin_lat1 * sin_lat1); + CT const alp0 = atan2(sin_alp1 * cos_lat1, norm); + CT const sig1 = atan2(sin_lat1, cos_alp1 * cos_lat1); + CT const sig2 = sig1 + sig12 / get_radius<0>(sphere); + + CT const cos_sig2 = cos(sig2); + CT const sin_alp0 = sin(alp0); + CT const cos_alp0 = cos(alp0); + + if (Coordinates) + { + CT const sin_sig2 = sin(sig2); + CT const sin_sig1 = sin(sig1); + CT const cos_sig1 = cos(sig1); + + CT const norm2 = math::sqrt(cos_alp0 * cos_alp0 * cos_sig2 * cos_sig2 + + sin_alp0 * sin_alp0); + CT const lat2 = atan2(cos_alp0 * sin_sig2, norm2); + + CT const omg1 = atan2(sin_alp0 * sin_sig1, cos_sig1); + CT const lon2 = atan2(sin_alp0 * sin_sig2, cos_sig2); + + result.lon2 = lon1 + lon2 - omg1; + result.lat2 = lat2; + } + + if (ReverseAzimuth) + { + CT const alp2 = atan2(sin_alp0, cos_alp0 * cos_sig2); + result.reverse_azimuth = alp2; + } + + return result; +} + } // namespace formula }} // namespace boost::geometry |