ssf.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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.
  4. // Modifications copyright (c) 2016-2018, 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 strategy::envelope::spherical<CalculationType> envelope_strategy_type;
  68. static inline envelope_strategy_type get_envelope_strategy()
  69. {
  70. return envelope_strategy_type();
  71. }
  72. typedef strategy::disjoint::segment_box_spherical disjoint_strategy_type;
  73. static inline disjoint_strategy_type get_disjoint_strategy()
  74. {
  75. return disjoint_strategy_type();
  76. }
  77. typedef strategy::within::spherical_point_point equals_point_point_strategy_type;
  78. static inline equals_point_point_strategy_type get_equals_point_point_strategy()
  79. {
  80. return equals_point_point_strategy_type();
  81. }
  82. template <typename P1, typename P2, typename P>
  83. static inline int apply(P1 const& p1, P2 const& p2, P const& p)
  84. {
  85. typedef typename promote_floating_point
  86. <
  87. typename select_calculation_type_alt
  88. <
  89. CalculationType,
  90. P1, P2, P
  91. >::type
  92. >::type calculation_type;
  93. calculation_type const lambda1 = get_as_radian<0>(p1);
  94. calculation_type const delta1 = get_as_radian<1>(p1);
  95. calculation_type const lambda2 = get_as_radian<0>(p2);
  96. calculation_type const delta2 = get_as_radian<1>(p2);
  97. calculation_type const lambda = get_as_radian<0>(p);
  98. calculation_type const delta = get_as_radian<1>(p);
  99. return detail::spherical_side_formula(lambda1, delta1,
  100. lambda2, delta2,
  101. lambda, delta);
  102. }
  103. };
  104. #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
  105. namespace services
  106. {
  107. /*template <typename CalculationType>
  108. struct default_strategy<spherical_polar_tag, CalculationType>
  109. {
  110. typedef spherical_side_formula<CalculationType> type;
  111. };*/
  112. template <typename CalculationType>
  113. struct default_strategy<spherical_equatorial_tag, CalculationType>
  114. {
  115. typedef spherical_side_formula<CalculationType> type;
  116. };
  117. template <typename CalculationType>
  118. struct default_strategy<geographic_tag, CalculationType>
  119. {
  120. typedef spherical_side_formula<CalculationType> type;
  121. };
  122. }
  123. #endif
  124. }} // namespace strategy::side
  125. }} // namespace boost::geometry
  126. #endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP