Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 08:34:23

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2014-2023.
0006 // Modifications copyright (c) 2014-2023, Oracle and/or its affiliates.
0007 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0008 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0009 
0010 // Use, modification and distribution is subject to the Boost Software License,
0011 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0012 // http://www.boost.org/LICENSE_1_0.txt)
0013 
0014 #ifndef BOOST_GEOMETRY_ALGORITHMS_AZIMUTH_HPP
0015 #define BOOST_GEOMETRY_ALGORITHMS_AZIMUTH_HPP
0016 
0017 
0018 #include <boost/geometry/algorithms/not_implemented.hpp>
0019 
0020 #include <boost/geometry/core/radian_access.hpp>
0021 #include <boost/geometry/core/tag.hpp>
0022 
0023 #include <boost/geometry/geometries/concepts/check.hpp>
0024 
0025 #include <boost/geometry/strategies/default_strategy.hpp>
0026 #include <boost/geometry/strategies/azimuth/cartesian.hpp>
0027 #include <boost/geometry/strategies/azimuth/geographic.hpp>
0028 #include <boost/geometry/strategies/azimuth/spherical.hpp>
0029 
0030 namespace boost { namespace geometry
0031 {
0032 
0033 
0034 #ifndef DOXYGEN_NO_DETAIL
0035 namespace detail
0036 {
0037 
0038 } // namespace detail
0039 #endif // DOXYGEN_NO_DETAIL
0040 
0041 
0042 #ifndef DOXYGEN_NO_DISPATCH
0043 namespace dispatch
0044 {
0045 
0046 template
0047 <
0048     typename Geometry1, typename Geometry2,
0049     typename Tag1 = tag_t<Geometry1>,
0050     typename Tag2 = tag_t<Geometry2>
0051 >
0052 struct azimuth : not_implemented<Tag1, Tag2>
0053 {};
0054 
0055 template <typename Point1, typename Point2>
0056 struct azimuth<Point1, Point2, point_tag, point_tag>
0057 {
0058     template <typename Strategy>
0059     static auto apply(Point1 const& p1, Point2 const& p2, Strategy const& strategy)
0060     {
0061         auto azimuth_strategy = strategy.azimuth();
0062         using calc_t = typename decltype(azimuth_strategy)::template result_type
0063             <
0064                 coordinate_type_t<Point1>,
0065                 coordinate_type_t<Point2>
0066             >::type;
0067 
0068         calc_t result = 0;
0069         calc_t const x1 = geometry::get_as_radian<0>(p1);
0070         calc_t const y1 = geometry::get_as_radian<1>(p1);
0071         calc_t const x2 = geometry::get_as_radian<0>(p2);
0072         calc_t const y2 = geometry::get_as_radian<1>(p2);
0073 
0074         azimuth_strategy.apply(x1, y1, x2, y2, result);
0075 
0076         // NOTE: It is not clear which units we should use for the result.
0077         //   For now radians are always returned but a user could expect
0078         //   e.g. something like this:
0079         /*
0080         bool const both_degree = std::is_same
0081                 <
0082                     typename detail::cs_angular_units<Point1>::type,
0083                     geometry::degree
0084                 >::value
0085             && std::is_same
0086                 <
0087                     typename detail::cs_angular_units<Point2>::type,
0088                     geometry::degree
0089                 >::value;
0090         if (both_degree)
0091         {
0092             result *= math::r2d<calc_t>();
0093         }
0094         */
0095 
0096         return result;
0097     }
0098 };
0099 
0100 } // namespace dispatch
0101 #endif // DOXYGEN_NO_DISPATCH
0102 
0103 
0104 namespace resolve_strategy
0105 {
0106 
0107 template
0108 <
0109     typename Strategy,
0110     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0111 >
0112 struct azimuth
0113 {
0114     template <typename P1, typename P2>
0115     static auto apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
0116     {
0117         return dispatch::azimuth<P1, P2>::apply(p1, p2, strategy);
0118     }
0119 };
0120 
0121 template <typename Strategy>
0122 struct azimuth<Strategy, false>
0123 {
0124     template <typename P1, typename P2>
0125     static auto apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
0126     {
0127         using strategies::azimuth::services::strategy_converter;
0128         return dispatch::azimuth
0129             <
0130                 P1, P2
0131             >::apply(p1, p2, strategy_converter<Strategy>::get(strategy));
0132     }
0133 };
0134 
0135 template <>
0136 struct azimuth<default_strategy, false>
0137 {
0138     template <typename P1, typename P2>
0139     static auto apply(P1 const& p1, P2 const& p2, default_strategy)
0140     {
0141         typedef typename strategies::azimuth::services::default_strategy
0142             <
0143                 P1, P2
0144             >::type strategy_type;
0145 
0146         return dispatch::azimuth<P1, P2>::apply(p1, p2, strategy_type());
0147     }
0148 };
0149 
0150 
0151 } // namespace resolve_strategy
0152 
0153 
0154 namespace resolve_variant
0155 {
0156 } // namespace resolve_variant
0157 
0158 
0159 /*!
0160 \brief Calculate azimuth of a segment defined by a pair of points.
0161 \ingroup azimuth
0162 \tparam Point1 Type of the first point of a segment.
0163 \tparam Point2 Type of the second point of a segment.
0164 \param point1 First point of a segment.
0165 \param point2 Second point of a segment.
0166 \return Azimuth in radians.
0167 
0168 \qbk{[include reference/algorithms/azimuth.qbk]}
0169 
0170 \qbk{
0171 [heading Example]
0172 [azimuth]
0173 [azimuth_output]
0174 }
0175 */
0176 template <typename Point1, typename Point2>
0177 inline auto azimuth(Point1 const& point1, Point2 const& point2)
0178 {
0179     concepts::check<Point1 const>();
0180     concepts::check<Point2 const>();
0181 
0182     return resolve_strategy::azimuth
0183             <
0184                 default_strategy
0185             >::apply(point1, point2, default_strategy());
0186 }
0187 
0188 
0189 /*!
0190 \brief Calculate azimuth of a segment defined by a pair of points.
0191 \ingroup azimuth
0192 \tparam Point1 Type of the first point of a segment.
0193 \tparam Point2 Type of the second point of a segment.
0194 \tparam Strategy Type of an umbrella strategy defining azimuth strategy.
0195 \param point1 First point of a segment.
0196 \param point2 Second point of a segment.
0197 \param strategy Umbrella strategy defining azimuth strategy.
0198 \return Azimuth in radians.
0199 
0200 \qbk{distinguish,with strategy}
0201 \qbk{[include reference/algorithms/azimuth.qbk]}
0202 
0203 \qbk{
0204 [heading Example]
0205 [azimuth_strategy]
0206 [azimuth_strategy_output]
0207 }
0208 */
0209 template <typename Point1, typename Point2, typename Strategy>
0210 inline auto azimuth(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
0211 {
0212     concepts::check<Point1 const>();
0213     concepts::check<Point2 const>();
0214 
0215     return resolve_strategy::azimuth<Strategy>::apply(point1, point2, strategy);
0216 }
0217 
0218 
0219 }} // namespace boost::geometry
0220 
0221 
0222 #endif // BOOST_GEOMETRY_ALGORITHMS_AZIMUTH_HPP