ssf.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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-2021.
  4. // Modifications copyright (c) 2016-2021, 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/coordinate_promotion.hpp>
  14. #include <boost/geometry/core/radian_access.hpp>
  15. #include <boost/geometry/util/math.hpp>
  16. #include <boost/geometry/util/select_calculation_type.hpp>
  17. #include <boost/geometry/strategy/spherical/envelope.hpp>
  18. #include <boost/geometry/strategies/side.hpp>
  19. #include <boost/geometry/strategies/spherical/disjoint_segment_box.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. template <typename P1, typename P2, typename P>
  69. static inline int apply(P1 const& p1, P2 const& p2, P const& p)
  70. {
  71. typedef typename promote_floating_point
  72. <
  73. typename select_calculation_type_alt
  74. <
  75. CalculationType,
  76. P1, P2, P
  77. >::type
  78. >::type calculation_type;
  79. calculation_type const lambda1 = get_as_radian<0>(p1);
  80. calculation_type const delta1 = get_as_radian<1>(p1);
  81. calculation_type const lambda2 = get_as_radian<0>(p2);
  82. calculation_type const delta2 = get_as_radian<1>(p2);
  83. calculation_type const lambda = get_as_radian<0>(p);
  84. calculation_type const delta = get_as_radian<1>(p);
  85. return detail::spherical_side_formula(lambda1, delta1,
  86. lambda2, delta2,
  87. lambda, delta);
  88. }
  89. };
  90. #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
  91. namespace services
  92. {
  93. /*template <typename CalculationType>
  94. struct default_strategy<spherical_polar_tag, CalculationType>
  95. {
  96. typedef spherical_side_formula<CalculationType> type;
  97. };*/
  98. template <typename CalculationType>
  99. struct default_strategy<spherical_equatorial_tag, CalculationType>
  100. {
  101. typedef spherical_side_formula<CalculationType> type;
  102. };
  103. template <typename CalculationType>
  104. struct default_strategy<geographic_tag, CalculationType>
  105. {
  106. typedef spherical_side_formula<CalculationType> type;
  107. };
  108. }
  109. #endif
  110. }} // namespace strategy::side
  111. }} // namespace boost::geometry
  112. #endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP