ssf.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2016, 2018, 2019.
  4. // Modifications copyright (c) 2016-2019, Oracle and/or its affiliates.
  5. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  6. // Use, modification and distribution is subject to the Boost Software License,
  7. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP
  10. #define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP
  11. #include <boost/geometry/core/cs.hpp>
  12. #include <boost/geometry/core/access.hpp>
  13. #include <boost/geometry/core/radian_access.hpp>
  14. #include <boost/geometry/util/math.hpp>
  15. #include <boost/geometry/util/promote_floating_point.hpp>
  16. #include <boost/geometry/util/select_calculation_type.hpp>
  17. #include <boost/geometry/strategies/side.hpp>
  18. #include <boost/geometry/strategies/spherical/disjoint_segment_box.hpp>
  19. #include <boost/geometry/strategies/spherical/envelope.hpp>
  20. //#include <boost/geometry/strategies/concepts/side_concept.hpp>
  21. #include <boost/geometry/strategies/spherical/point_in_point.hpp>
  22. namespace boost { namespace geometry
  23. {
  24. namespace strategy { namespace side
  25. {
  26. #ifndef DOXYGEN_NO_DETAIL
  27. namespace detail
  28. {
  29. template <typename T>
  30. int spherical_side_formula(T const& lambda1, T const& delta1,
  31. T const& lambda2, T const& delta2,
  32. T const& lambda, T const& delta)
  33. {
  34. // Create temporary points (vectors) on unit a sphere
  35. T const cos_delta1 = cos(delta1);
  36. T const c1x = cos_delta1 * cos(lambda1);
  37. T const c1y = cos_delta1 * sin(lambda1);
  38. T const c1z = sin(delta1);
  39. T const cos_delta2 = cos(delta2);
  40. T const c2x = cos_delta2 * cos(lambda2);
  41. T const c2y = cos_delta2 * sin(lambda2);
  42. T const c2z = sin(delta2);
  43. // (Third point is converted directly)
  44. T const cos_delta = cos(delta);
  45. // Apply the "Spherical Side Formula" as presented on my blog
  46. T const dist
  47. = (c1y * c2z - c1z * c2y) * cos_delta * cos(lambda)
  48. + (c1z * c2x - c1x * c2z) * cos_delta * sin(lambda)
  49. + (c1x * c2y - c1y * c2x) * sin(delta);
  50. T zero = T();
  51. return math::equals(dist, zero) ? 0
  52. : dist > zero ? 1
  53. : -1; // dist < zero
  54. }
  55. }
  56. #endif // DOXYGEN_NO_DETAIL
  57. /*!
  58. \brief Check at which side of a Great Circle segment a point lies
  59. left of segment (> 0), right of segment (< 0), on segment (0)
  60. \ingroup strategies
  61. \tparam CalculationType \tparam_calculation
  62. */
  63. template <typename CalculationType = void>
  64. class spherical_side_formula
  65. {
  66. public :
  67. typedef spherical_tag cs_tag;
  68. typedef strategy::envelope::spherical<CalculationType> envelope_strategy_type;
  69. static inline envelope_strategy_type get_envelope_strategy()
  70. {
  71. return envelope_strategy_type();
  72. }
  73. typedef strategy::disjoint::segment_box_spherical disjoint_strategy_type;
  74. static inline disjoint_strategy_type get_disjoint_strategy()
  75. {
  76. return disjoint_strategy_type();
  77. }
  78. typedef strategy::within::spherical_point_point equals_point_point_strategy_type;
  79. static inline equals_point_point_strategy_type get_equals_point_point_strategy()
  80. {
  81. return equals_point_point_strategy_type();
  82. }
  83. template <typename P1, typename P2, typename P>
  84. static inline int apply(P1 const& p1, P2 const& p2, P const& p)
  85. {
  86. typedef typename promote_floating_point
  87. <
  88. typename select_calculation_type_alt
  89. <
  90. CalculationType,
  91. P1, P2, P
  92. >::type
  93. >::type calculation_type;
  94. calculation_type const lambda1 = get_as_radian<0>(p1);
  95. calculation_type const delta1 = get_as_radian<1>(p1);
  96. calculation_type const lambda2 = get_as_radian<0>(p2);
  97. calculation_type const delta2 = get_as_radian<1>(p2);
  98. calculation_type const lambda = get_as_radian<0>(p);
  99. calculation_type const delta = get_as_radian<1>(p);
  100. return detail::spherical_side_formula(lambda1, delta1,
  101. lambda2, delta2,
  102. lambda, delta);
  103. }
  104. };
  105. #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
  106. namespace services
  107. {
  108. /*template <typename CalculationType>
  109. struct default_strategy<spherical_polar_tag, CalculationType>
  110. {
  111. typedef spherical_side_formula<CalculationType> type;
  112. };*/
  113. template <typename CalculationType>
  114. struct default_strategy<spherical_equatorial_tag, CalculationType>
  115. {
  116. typedef spherical_side_formula<CalculationType> type;
  117. };
  118. template <typename CalculationType>
  119. struct default_strategy<geographic_tag, CalculationType>
  120. {
  121. typedef spherical_side_formula<CalculationType> type;
  122. };
  123. }
  124. #endif
  125. }} // namespace strategy::side
  126. }} // namespace boost::geometry
  127. #endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP