azimuth.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // Boost.Geometry
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2014-2021.
  4. // Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
  5. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  6. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_GEOMETRY_ALGORITHMS_AZIMUTH_HPP
  11. #define BOOST_GEOMETRY_ALGORITHMS_AZIMUTH_HPP
  12. #include <boost/geometry/algorithms/not_implemented.hpp>
  13. #include <boost/geometry/core/cs.hpp>
  14. #include <boost/geometry/core/access.hpp>
  15. #include <boost/geometry/core/radian_access.hpp>
  16. #include <boost/geometry/core/tag.hpp>
  17. #include <boost/geometry/core/tags.hpp>
  18. #include <boost/geometry/strategies/azimuth.hpp>
  19. #include <boost/geometry/strategies/default_strategy.hpp>
  20. #include <boost/geometry/strategies/azimuth/cartesian.hpp>
  21. #include <boost/geometry/strategies/azimuth/geographic.hpp>
  22. #include <boost/geometry/strategies/azimuth/spherical.hpp>
  23. #include <boost/geometry/util/math.hpp>
  24. namespace boost { namespace geometry
  25. {
  26. #ifndef DOXYGEN_NO_DETAIL
  27. namespace detail
  28. {
  29. } // namespace detail
  30. #endif // DOXYGEN_NO_DETAIL
  31. #ifndef DOXYGEN_NO_DISPATCH
  32. namespace dispatch
  33. {
  34. template
  35. <
  36. typename Geometry1, typename Geometry2,
  37. typename Tag1 = typename tag<Geometry1>::type,
  38. typename Tag2 = typename tag<Geometry2>::type
  39. >
  40. struct azimuth : not_implemented<Tag1, Tag2>
  41. {};
  42. template <typename Point1, typename Point2>
  43. struct azimuth<Point1, Point2, point_tag, point_tag>
  44. {
  45. template <typename Strategy>
  46. static auto apply(Point1 const& p1, Point2 const& p2, Strategy const& strategy)
  47. {
  48. typedef typename decltype(strategy.azimuth())::template result_type
  49. <
  50. typename coordinate_type<Point1>::type,
  51. typename coordinate_type<Point2>::type
  52. >::type calc_t;
  53. calc_t result = 0;
  54. calc_t const x1 = geometry::get_as_radian<0>(p1);
  55. calc_t const y1 = geometry::get_as_radian<1>(p1);
  56. calc_t const x2 = geometry::get_as_radian<0>(p2);
  57. calc_t const y2 = geometry::get_as_radian<1>(p2);
  58. strategy.azimuth().apply(x1, y1, x2, y2, result);
  59. // NOTE: It is not clear which units we should use for the result.
  60. // For now radians are always returned but a user could expect
  61. // e.g. something like this:
  62. /*
  63. bool const both_degree = std::is_same
  64. <
  65. typename detail::cs_angular_units<Point1>::type,
  66. geometry::degree
  67. >::value
  68. && std::is_same
  69. <
  70. typename detail::cs_angular_units<Point2>::type,
  71. geometry::degree
  72. >::value;
  73. if (both_degree)
  74. {
  75. result *= math::r2d<calc_t>();
  76. }
  77. */
  78. return result;
  79. }
  80. };
  81. } // namespace dispatch
  82. #endif // DOXYGEN_NO_DISPATCH
  83. namespace resolve_strategy
  84. {
  85. template
  86. <
  87. typename Strategy,
  88. bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
  89. >
  90. struct azimuth
  91. {
  92. template <typename P1, typename P2>
  93. static auto apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
  94. {
  95. return dispatch::azimuth<P1, P2>::apply(p1, p2, strategy);
  96. }
  97. };
  98. template <typename Strategy>
  99. struct azimuth<Strategy, false>
  100. {
  101. template <typename P1, typename P2>
  102. static auto apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
  103. {
  104. using strategies::azimuth::services::strategy_converter;
  105. return dispatch::azimuth
  106. <
  107. P1, P2
  108. >::apply(p1, p2, strategy_converter<Strategy>::get(strategy));
  109. }
  110. };
  111. template <>
  112. struct azimuth<default_strategy, false>
  113. {
  114. template <typename P1, typename P2>
  115. static auto apply(P1 const& p1, P2 const& p2, default_strategy)
  116. {
  117. typedef typename strategies::azimuth::services::default_strategy
  118. <
  119. P1, P2
  120. >::type strategy_type;
  121. return dispatch::azimuth<P1, P2>::apply(p1, p2, strategy_type());
  122. }
  123. };
  124. } // namespace resolve_strategy
  125. namespace resolve_variant
  126. {
  127. } // namespace resolve_variant
  128. /*!
  129. \brief Calculate azimuth of a segment defined by a pair of points.
  130. \ingroup azimuth
  131. \tparam Point1 Type of the first point of a segment.
  132. \tparam Point2 Type of the second point of a segment.
  133. \param point1 First point of a segment.
  134. \param point2 Second point of a segment.
  135. \return Azimuth in radians.
  136. \qbk{[include reference/algorithms/azimuth.qbk]}
  137. \qbk{
  138. [heading Example]
  139. [azimuth]
  140. [azimuth_output]
  141. }
  142. */
  143. template <typename Point1, typename Point2>
  144. inline auto azimuth(Point1 const& point1, Point2 const& point2)
  145. {
  146. concepts::check<Point1 const>();
  147. concepts::check<Point2 const>();
  148. return resolve_strategy::azimuth
  149. <
  150. default_strategy
  151. >::apply(point1, point2, default_strategy());
  152. }
  153. /*!
  154. \brief Calculate azimuth of a segment defined by a pair of points.
  155. \ingroup azimuth
  156. \tparam Point1 Type of the first point of a segment.
  157. \tparam Point2 Type of the second point of a segment.
  158. \tparam Strategy Type of an umbrella strategy defining azimuth strategy.
  159. \param point1 First point of a segment.
  160. \param point2 Second point of a segment.
  161. \param strategy Umbrella strategy defining azimuth strategy.
  162. \return Azimuth in radians.
  163. \qbk{distinguish,with strategy}
  164. \qbk{[include reference/algorithms/azimuth.qbk]}
  165. \qbk{
  166. [heading Example]
  167. [azimuth_strategy]
  168. [azimuth_strategy_output]
  169. }
  170. */
  171. template <typename Point1, typename Point2, typename Strategy>
  172. inline auto azimuth(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
  173. {
  174. concepts::check<Point1 const>();
  175. concepts::check<Point2 const>();
  176. return resolve_strategy::azimuth<Strategy>::apply(point1, point2, strategy);
  177. }
  178. }} // namespace boost::geometry
  179. #endif // BOOST_GEOMETRY_ALGORITHMS_AZIMUTH_HPP