azimuth.hpp 5.9 KB

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