ssf.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Use, modification and distribution is subject to the Boost Software License,
  4. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP
  7. #define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP
  8. #include <boost/mpl/if.hpp>
  9. #include <boost/type_traits.hpp>
  10. #include <boost/geometry/core/cs.hpp>
  11. #include <boost/geometry/core/access.hpp>
  12. #include <boost/geometry/core/radian_access.hpp>
  13. #include <boost/geometry/util/select_coordinate_type.hpp>
  14. #include <boost/geometry/util/math.hpp>
  15. #include <boost/geometry/strategies/side.hpp>
  16. //#include <boost/geometry/strategies/concepts/side_concept.hpp>
  17. namespace boost { namespace geometry
  18. {
  19. namespace strategy { namespace side
  20. {
  21. /*!
  22. \brief Check at which side of a Great Circle segment a point lies
  23. left of segment (> 0), right of segment (< 0), on segment (0)
  24. \ingroup strategies
  25. \tparam CalculationType \tparam_calculation
  26. */
  27. template <typename CalculationType = void>
  28. class spherical_side_formula
  29. {
  30. public :
  31. template <typename P1, typename P2, typename P>
  32. static inline int apply(P1 const& p1, P2 const& p2, P const& p)
  33. {
  34. typedef typename boost::mpl::if_c
  35. <
  36. boost::is_void<CalculationType>::type::value,
  37. // Select at least a double...
  38. typename select_most_precise
  39. <
  40. typename select_most_precise
  41. <
  42. typename select_most_precise
  43. <
  44. typename coordinate_type<P1>::type,
  45. typename coordinate_type<P2>::type
  46. >::type,
  47. typename coordinate_type<P>::type
  48. >::type,
  49. double
  50. >::type,
  51. CalculationType
  52. >::type coordinate_type;
  53. // Convenient shortcuts
  54. typedef coordinate_type ct;
  55. ct const lambda1 = get_as_radian<0>(p1);
  56. ct const delta1 = get_as_radian<1>(p1);
  57. ct const lambda2 = get_as_radian<0>(p2);
  58. ct const delta2 = get_as_radian<1>(p2);
  59. ct const lambda = get_as_radian<0>(p);
  60. ct const delta = get_as_radian<1>(p);
  61. // Create temporary points (vectors) on unit a sphere
  62. ct const cos_delta1 = cos(delta1);
  63. ct const c1x = cos_delta1 * cos(lambda1);
  64. ct const c1y = cos_delta1 * sin(lambda1);
  65. ct const c1z = sin(delta1);
  66. ct const cos_delta2 = cos(delta2);
  67. ct const c2x = cos_delta2 * cos(lambda2);
  68. ct const c2y = cos_delta2 * sin(lambda2);
  69. ct const c2z = sin(delta2);
  70. // (Third point is converted directly)
  71. ct const cos_delta = cos(delta);
  72. // Apply the "Spherical Side Formula" as presented on my blog
  73. ct const dist
  74. = (c1y * c2z - c1z * c2y) * cos_delta * cos(lambda)
  75. + (c1z * c2x - c1x * c2z) * cos_delta * sin(lambda)
  76. + (c1x * c2y - c1y * c2x) * sin(delta);
  77. ct zero = ct();
  78. return dist > zero ? 1
  79. : dist < zero ? -1
  80. : 0;
  81. }
  82. };
  83. #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
  84. namespace services
  85. {
  86. /*template <typename CalculationType>
  87. struct default_strategy<spherical_polar_tag, CalculationType>
  88. {
  89. typedef spherical_side_formula<CalculationType> type;
  90. };*/
  91. template <typename CalculationType>
  92. struct default_strategy<spherical_equatorial_tag, CalculationType>
  93. {
  94. typedef spherical_side_formula<CalculationType> type;
  95. };
  96. template <typename CalculationType>
  97. struct default_strategy<geographic_tag, CalculationType>
  98. {
  99. typedef spherical_side_formula<CalculationType> type;
  100. };
  101. }
  102. #endif
  103. }} // namespace strategy::side
  104. }} // namespace boost::geometry
  105. #endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP