de9im.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-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_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
  7. #define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
  8. #include <boost/geometry/strategies/intersection_result.hpp>
  9. #include <boost/geometry/util/math.hpp>
  10. #include <boost/geometry/util/select_coordinate_type.hpp>
  11. namespace boost { namespace geometry
  12. {
  13. namespace policies { namespace relate
  14. {
  15. template <typename S1, typename S2>
  16. struct segments_de9im
  17. {
  18. typedef de9im_segment return_type;
  19. typedef S1 segment_type1;
  20. typedef S2 segment_type2;
  21. typedef typename select_coordinate_type<S1, S2>::type coordinate_type;
  22. static inline return_type rays_intersect(bool on_segment,
  23. double ra, double rb,
  24. coordinate_type const& dx1, coordinate_type const& dy1,
  25. coordinate_type const& dx2, coordinate_type const& dy2,
  26. coordinate_type const& wx, coordinate_type const& wy,
  27. S1 const& s1, S2 const& s2)
  28. {
  29. if(on_segment)
  30. {
  31. // 0 <= ra <= 1 and 0 <= rb <= 1
  32. // Now check if one of them is 0 or 1, these are "touch" cases
  33. bool a = math::equals(ra, 0.0) || math::equals(ra, 1.0);
  34. bool b = math::equals(rb, 0.0) || math::equals(rb, 1.0);
  35. if (a && b)
  36. {
  37. // Touch boundary/boundary: i-i == -1, i-b == -1, b-b == 0
  38. // Opposite: if both are equal they touch in opposite direction
  39. return de9im_segment(ra,rb,
  40. -1, -1, 1,
  41. -1, 0, 0,
  42. 1, 0, 2, false, math::equals(ra,rb));
  43. }
  44. else if (a || b)
  45. {
  46. // Touch boundary/interior: i-i == -1, i-b == -1 or 0, b-b == -1
  47. int A = a ? 0 : -1;
  48. int B = b ? 0 : -1;
  49. return de9im_segment(ra,rb,
  50. -1, B, 1,
  51. A, -1, 0,
  52. 1, 0, 2);
  53. }
  54. // Intersects: i-i == 0, i-b == -1, i-e == 1
  55. return de9im_segment(ra,rb,
  56. 0, -1, 1,
  57. -1, -1, 0,
  58. 1, 0, 2);
  59. }
  60. // Not on segment, disjoint
  61. return de9im_segment(ra,rb,
  62. -1, -1, 1,
  63. -1, -1, 0,
  64. 1, 0, 2);
  65. }
  66. static inline return_type collinear_touch(coordinate_type const& x,
  67. coordinate_type const& y, bool opposite, char)
  68. {
  69. return de9im_segment(0,0,
  70. -1, -1, 1,
  71. -1, 0, 0,
  72. 1, 0, 2,
  73. true, opposite);
  74. }
  75. template <typename S>
  76. static inline return_type collinear_interior_boundary_intersect(S const& s,
  77. bool a_within_b, bool opposite)
  78. {
  79. return a_within_b
  80. ? de9im_segment(0,0,
  81. 1, -1, -1,
  82. 0, 0, -1,
  83. 1, 0, 2,
  84. true, opposite)
  85. : de9im_segment(0,0,
  86. 1, 0, 1,
  87. -1, 0, 0,
  88. -1, -1, 2,
  89. true, opposite);
  90. }
  91. static inline return_type collinear_a_in_b(S1 const& s, bool opposite)
  92. {
  93. return de9im_segment(0,0,
  94. 1, -1, -1,
  95. 0, -1, -1,
  96. 1, 0, 2,
  97. true, opposite);
  98. }
  99. static inline return_type collinear_b_in_a(S2 const& s, bool opposite)
  100. {
  101. return de9im_segment(0,0,
  102. 1, 0, 1,
  103. -1, -1, 0,
  104. -1, -1, 2,
  105. true, opposite);
  106. }
  107. static inline return_type collinear_overlaps(
  108. coordinate_type const& x1, coordinate_type const& y1,
  109. coordinate_type const& x2, coordinate_type const& y2, bool opposite)
  110. {
  111. return de9im_segment(0,0,
  112. 1, 0, 1,
  113. 0, -1, 0,
  114. 1, 0, 2,
  115. true, opposite);
  116. }
  117. static inline return_type segment_equal(S1 const& s, bool opposite)
  118. {
  119. return de9im_segment(0,0,
  120. 1, -1, -1,
  121. -1, 0, -1,
  122. -1, -1, 2,
  123. true, opposite);
  124. }
  125. static inline return_type degenerate(S1 const& segment, bool a_degenerate)
  126. {
  127. return a_degenerate
  128. ? de9im_segment(0,0,
  129. 0, -1, -1,
  130. -1, -1, -1,
  131. 1, 0, 2,
  132. false, false, false, true)
  133. : de9im_segment(0,0,
  134. 0, -1, 1,
  135. -1, -1, 0,
  136. -1, -1, 2,
  137. false, false, false, true);
  138. }
  139. static inline return_type collinear_disjoint()
  140. {
  141. return de9im_segment(0,0,
  142. -1, -1, 1,
  143. -1, -1, 0,
  144. 1, 0, 2,
  145. true);
  146. }
  147. };
  148. }} // namespace policies::relate
  149. }} // namespace boost::geometry
  150. #endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP