Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:19

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 = typename tag<Geometry1>::type,
0050     typename Tag2 = typename tag<Geometry2>::type
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         typedef typename decltype(strategy.azimuth())::template result_type
0062             <
0063                 typename coordinate_type<Point1>::type,
0064                 typename coordinate_type<Point2>::type
0065             >::type calc_t;
0066 
0067         calc_t result = 0;
0068         calc_t const x1 = geometry::get_as_radian<0>(p1);
0069         calc_t const y1 = geometry::get_as_radian<1>(p1);
0070         calc_t const x2 = geometry::get_as_radian<0>(p2);
0071         calc_t const y2 = geometry::get_as_radian<1>(p2);
0072 
0073         strategy.azimuth().apply(x1, y1, x2, y2, result);
0074 
0075         // NOTE: It is not clear which units we should use for the result.
0076         //   For now radians are always returned but a user could expect
0077         //   e.g. something like this:
0078         /*
0079         bool const both_degree = std::is_same
0080                 <
0081                     typename detail::cs_angular_units<Point1>::type,
0082                     geometry::degree
0083                 >::value
0084             && std::is_same
0085                 <
0086                     typename detail::cs_angular_units<Point2>::type,
0087                     geometry::degree
0088                 >::value;
0089         if (both_degree)
0090         {
0091             result *= math::r2d<calc_t>();
0092         }
0093         */
0094 
0095         return result;
0096     }
0097 };
0098 
0099 } // namespace dispatch
0100 #endif // DOXYGEN_NO_DISPATCH
0101 
0102 
0103 namespace resolve_strategy
0104 {
0105 
0106 template
0107 <
0108     typename Strategy,
0109     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0110 >
0111 struct azimuth
0112 {
0113     template <typename P1, typename P2>
0114     static auto apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
0115     {
0116         return dispatch::azimuth<P1, P2>::apply(p1, p2, strategy);
0117     }
0118 };
0119 
0120 template <typename Strategy>
0121 struct azimuth<Strategy, false>
0122 {
0123     template <typename P1, typename P2>
0124     static auto apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
0125     {
0126         using strategies::azimuth::services::strategy_converter;
0127         return dispatch::azimuth
0128             <
0129                 P1, P2
0130             >::apply(p1, p2, strategy_converter<Strategy>::get(strategy));
0131     }
0132 };
0133 
0134 template <>
0135 struct azimuth<default_strategy, false>
0136 {
0137     template <typename P1, typename P2>
0138     static auto apply(P1 const& p1, P2 const& p2, default_strategy)
0139     {
0140         typedef typename strategies::azimuth::services::default_strategy
0141             <
0142                 P1, P2
0143             >::type strategy_type;
0144 
0145         return dispatch::azimuth<P1, P2>::apply(p1, p2, strategy_type());
0146     }
0147 };
0148 
0149 
0150 } // namespace resolve_strategy
0151 
0152 
0153 namespace resolve_variant
0154 {
0155 } // namespace resolve_variant
0156 
0157 
0158 /*!
0159 \brief Calculate azimuth of a segment defined by a pair of points.
0160 \ingroup azimuth
0161 \tparam Point1 Type of the first point of a segment.
0162 \tparam Point2 Type of the second point of a segment.
0163 \param point1 First point of a segment.
0164 \param point2 Second point of a segment.
0165 \return Azimuth in radians.
0166 
0167 \qbk{[include reference/algorithms/azimuth.qbk]}
0168 
0169 \qbk{
0170 [heading Example]
0171 [azimuth]
0172 [azimuth_output]
0173 }
0174 */
0175 template <typename Point1, typename Point2>
0176 inline auto azimuth(Point1 const& point1, Point2 const& point2)
0177 {
0178     concepts::check<Point1 const>();
0179     concepts::check<Point2 const>();
0180 
0181     return resolve_strategy::azimuth
0182             <
0183                 default_strategy
0184             >::apply(point1, point2, default_strategy());
0185 }
0186 
0187 
0188 /*!
0189 \brief Calculate azimuth of a segment defined by a pair of points.
0190 \ingroup azimuth
0191 \tparam Point1 Type of the first point of a segment.
0192 \tparam Point2 Type of the second point of a segment.
0193 \tparam Strategy Type of an umbrella strategy defining azimuth strategy.
0194 \param point1 First point of a segment.
0195 \param point2 Second point of a segment.
0196 \param strategy Umbrella strategy defining azimuth strategy.
0197 \return Azimuth in radians.
0198 
0199 \qbk{distinguish,with strategy}
0200 \qbk{[include reference/algorithms/azimuth.qbk]}
0201 
0202 \qbk{
0203 [heading Example]
0204 [azimuth_strategy]
0205 [azimuth_strategy_output]
0206 }
0207 */
0208 template <typename Point1, typename Point2, typename Strategy>
0209 inline auto azimuth(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
0210 {
0211     concepts::check<Point1 const>();
0212     concepts::check<Point2 const>();
0213 
0214     return resolve_strategy::azimuth<Strategy>::apply(point1, point2, strategy);
0215 }
0216 
0217 
0218 }} // namespace boost::geometry
0219 
0220 
0221 #endif // BOOST_GEOMETRY_ALGORITHMS_AZIMUTH_HPP