ssf.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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.
  4. // Modifications copyright (c) 2016, 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_segment.hpp>
  20. //#include <boost/geometry/strategies/concepts/side_concept.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. namespace strategy { namespace side
  24. {
  25. #ifndef DOXYGEN_NO_DETAIL
  26. namespace detail
  27. {
  28. template <typename T>
  29. int spherical_side_formula(T const& lambda1, T const& delta1,
  30. T const& lambda2, T const& delta2,
  31. T const& lambda, T const& delta)
  32. {
  33. // Create temporary points (vectors) on unit a sphere
  34. T const cos_delta1 = cos(delta1);
  35. T const c1x = cos_delta1 * cos(lambda1);
  36. T const c1y = cos_delta1 * sin(lambda1);
  37. T const c1z = sin(delta1);
  38. T const cos_delta2 = cos(delta2);
  39. T const c2x = cos_delta2 * cos(lambda2);
  40. T const c2y = cos_delta2 * sin(lambda2);
  41. T const c2z = sin(delta2);
  42. // (Third point is converted directly)
  43. T const cos_delta = cos(delta);
  44. // Apply the "Spherical Side Formula" as presented on my blog
  45. T const dist
  46. = (c1y * c2z - c1z * c2y) * cos_delta * cos(lambda)
  47. + (c1z * c2x - c1x * c2z) * cos_delta * sin(lambda)
  48. + (c1x * c2y - c1y * c2x) * sin(delta);
  49. T zero = T();
  50. return math::equals(dist, zero) ? 0
  51. : dist > zero ? 1
  52. : -1; // dist < zero
  53. }
  54. }
  55. #endif // DOXYGEN_NO_DETAIL
  56. /*!
  57. \brief Check at which side of a Great Circle segment a point lies
  58. left of segment (> 0), right of segment (< 0), on segment (0)
  59. \ingroup strategies
  60. \tparam CalculationType \tparam_calculation
  61. */
  62. template <typename CalculationType = void>
  63. class spherical_side_formula
  64. {
  65. public :
  66. typedef strategy::envelope::spherical_segment<CalculationType> envelope_strategy_type;
  67. static inline envelope_strategy_type get_envelope_strategy()
  68. {
  69. return envelope_strategy_type();
  70. }
  71. typedef strategy::disjoint::segment_box_spherical disjoint_strategy_type;
  72. static inline disjoint_strategy_type get_disjoint_strategy()
  73. {
  74. return disjoint_strategy_type();
  75. }
  76. template <typename P1, typename P2, typename P>
  77. static inline int apply(P1 const& p1, P2 const& p2, P const& p)
  78. {
  79. typedef typename promote_floating_point
  80. <
  81. typename select_calculation_type_alt
  82. <
  83. CalculationType,
  84. P1, P2, P
  85. >::type
  86. >::type calculation_type;
  87. calculation_type const lambda1 = get_as_radian<0>(p1);
  88. calculation_type const delta1 = get_as_radian<1>(p1);
  89. calculation_type const lambda2 = get_as_radian<0>(p2);
  90. calculation_type const delta2 = get_as_radian<1>(p2);
  91. calculation_type const lambda = get_as_radian<0>(p);
  92. calculation_type const delta = get_as_radian<1>(p);
  93. return detail::spherical_side_formula(lambda1, delta1,
  94. lambda2, delta2,
  95. lambda, delta);
  96. }
  97. };
  98. #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
  99. namespace services
  100. {
  101. /*template <typename CalculationType>
  102. struct default_strategy<spherical_polar_tag, CalculationType>
  103. {
  104. typedef spherical_side_formula<CalculationType> type;
  105. };*/
  106. template <typename CalculationType>
  107. struct default_strategy<spherical_equatorial_tag, CalculationType>
  108. {
  109. typedef spherical_side_formula<CalculationType> type;
  110. };
  111. template <typename CalculationType>
  112. struct default_strategy<geographic_tag, CalculationType>
  113. {
  114. typedef spherical_side_formula<CalculationType> type;
  115. };
  116. }
  117. #endif
  118. }} // namespace strategy::side
  119. }} // namespace boost::geometry
  120. #endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP