segment_intersection.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  5. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  6. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  7. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  8. // Use, modification and distribution is subject to the Boost Software License,
  9. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. #if defined(_MSC_VER)
  12. // We deliberately mix float/double's here so turn off warning
  13. #pragma warning( disable : 4244 )
  14. #endif // defined(_MSC_VER)
  15. #include <geometry_test_common.hpp>
  16. #include <boost/geometry/algorithms/assign.hpp>
  17. #include <boost/geometry/strategies/cartesian/intersection.hpp>
  18. #include <boost/geometry/strategies/intersection_result.hpp>
  19. #include <boost/geometry/policies/relate/intersection_points.hpp>
  20. #include <boost/geometry/policies/relate/direction.hpp>
  21. #include <boost/geometry/policies/relate/tupled.hpp>
  22. #include <boost/geometry/algorithms/intersection.hpp>
  23. #include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
  24. #include <boost/geometry/geometries/point.hpp>
  25. #include <boost/geometry/geometries/segment.hpp>
  26. #include <boost/geometry/geometries/adapted/boost_tuple.hpp>
  27. BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian);
  28. template <typename P>
  29. static void test_segment_intersection(int caseid,
  30. int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4,
  31. char expected_how,
  32. int expected_x1 = -99, int expected_y1 = -99,
  33. int expected_x2 = -99, int expected_y2 = -99)
  34. {
  35. using namespace boost::geometry;
  36. typedef typename bg::coordinate_type<P>::type coordinate_type;
  37. typedef bg::model::referring_segment<const P> segment_type;
  38. P p1, p2, p3, p4;
  39. bg::assign_values(p1, x1, y1);
  40. bg::assign_values(p2, x2, y2);
  41. bg::assign_values(p3, x3, y3);
  42. bg::assign_values(p4, x4, y4);
  43. segment_type s12(p1,p2);
  44. segment_type s34(p3,p4);
  45. bg::detail::segment_as_subrange<segment_type> sr12(s12);
  46. bg::detail::segment_as_subrange<segment_type> sr34(s34);
  47. std::size_t expected_count = 0;
  48. if (expected_x1 != -99 && expected_y1 != -99)
  49. {
  50. expected_count++;
  51. }
  52. if (expected_x2 != -99 && expected_y2 != -99)
  53. {
  54. expected_count++;
  55. }
  56. // Using intersection_insert
  57. std::vector<P> out;
  58. bg::detail::intersection::intersection_insert<P>(s12, s34,
  59. std::back_inserter(out));
  60. // Using strategy
  61. typedef bg::segment_intersection_points<P> result_type;
  62. typedef bg::policies::relate::segments_intersection_points
  63. <
  64. result_type
  65. > points_policy_type;
  66. result_type is
  67. = bg::strategy::intersection::cartesian_segments<>
  68. ::apply(sr12, sr34, points_policy_type());
  69. bg::policies::relate::direction_type dir
  70. = bg::strategy::intersection::cartesian_segments<>
  71. ::apply(sr12, sr34, bg::policies::relate::segments_direction());
  72. //BOOST_CHECK_EQUAL(boost::size(out), expected_count);
  73. BOOST_CHECK_EQUAL(is.count, expected_count);
  74. BOOST_CHECK_MESSAGE(dir.how == expected_how,
  75. caseid
  76. << " how: detected: " << dir.how
  77. << " expected: " << expected_how);
  78. if (expected_count == 2
  79. && is.count == 2
  80. && boost::size(out) == 2)
  81. {
  82. // Two intersection points, reverse expectation if necessary
  83. bool const first_matches
  84. = std::fabs(bg::get<0>(out[0]) - expected_x1) < 1.0e-6
  85. && std::fabs(bg::get<1>(out[0]) - expected_y1) < 1.0e-6;
  86. if (! first_matches)
  87. {
  88. std::swap(expected_x1, expected_x2);
  89. std::swap(expected_y1, expected_y2);
  90. }
  91. }
  92. if (expected_x1 != -99 && expected_y1 != -99
  93. && boost::size(out) >= 1)
  94. {
  95. BOOST_CHECK_CLOSE(bg::get<0>(out[0]), coordinate_type(expected_x1), 0.001);
  96. BOOST_CHECK_CLOSE(bg::get<1>(out[0]), coordinate_type(expected_y1), 0.001);
  97. BOOST_CHECK_CLOSE(bg::get<0>(is.intersections[0]), expected_x1, 0.001);
  98. BOOST_CHECK_CLOSE(bg::get<1>(is.intersections[0]), expected_y1, 0.001);
  99. }
  100. if (expected_x2 != -99 && expected_y2 != -99
  101. && boost::size(out) >= 2)
  102. {
  103. BOOST_CHECK_CLOSE(bg::get<0>(out[1]), coordinate_type(expected_x2), 0.001);
  104. BOOST_CHECK_CLOSE(bg::get<1>(out[1]), coordinate_type(expected_y2), 0.001);
  105. BOOST_CHECK_CLOSE(bg::get<0>(is.intersections[1]), expected_x2, 0.001);
  106. BOOST_CHECK_CLOSE(bg::get<1>(is.intersections[1]), expected_y2, 0.001);
  107. }
  108. }
  109. template <typename P>
  110. void test_all()
  111. {
  112. test_segment_intersection<P>( 1, 0,2, 2,0, 0,0, 2,2, 'i', 1, 1);
  113. test_segment_intersection<P>( 2, 2,2, 3,1, 0,0, 2,2, 'a', 2, 2);
  114. test_segment_intersection<P>( 3, 3,1, 2,2, 0,0, 2,2, 't', 2, 2);
  115. test_segment_intersection<P>( 4, 0,2, 1,1, 0,0, 2,2, 'm', 1, 1);
  116. test_segment_intersection<P>( 5, 1,1, 0,2, 0,0, 2,2, 's', 1, 1);
  117. test_segment_intersection<P>( 6, 0,2, 2,0, 0,0, 1,1, 'm', 1, 1);
  118. test_segment_intersection<P>( 7, 2,0, 0,2, 0,0, 1,1, 'm', 1, 1);
  119. test_segment_intersection<P>( 8, 2,3, 3,2, 0,0, 2,2, 'd');
  120. test_segment_intersection<P>( 9, 0,0, 2,2, 0,0, 2,2, 'e', 0, 0, 2, 2);
  121. test_segment_intersection<P>(10, 2,2, 0,0, 0,0, 2,2, 'e', 2, 2, 0, 0);
  122. test_segment_intersection<P>(11, 1,1, 3,3, 0,0, 2,2, 'c', 1, 1, 2, 2);
  123. test_segment_intersection<P>(12, 3,3, 1,1, 0,0, 2,2, 'c', 1, 1, 2, 2);
  124. test_segment_intersection<P>(13, 0,2, 2,2, 2,1, 2,3, 'm', 2, 2);
  125. test_segment_intersection<P>(14, 2,2, 2,4, 2,0, 2,2, 'a', 2, 2);
  126. test_segment_intersection<P>(15, 2,2, 2,4, 2,0, 2,1, 'd');
  127. test_segment_intersection<P>(16, 2,4, 2,2, 2,0, 2,1, 'd');
  128. test_segment_intersection<P>(17, 2,1, 2,3, 2,2, 2,4, 'c', 2, 2, 2, 3);
  129. test_segment_intersection<P>(18, 2,3, 2,1, 2,2, 2,4, 'c', 2, 3, 2, 2);
  130. test_segment_intersection<P>(19, 0,2, 2,2, 4,2, 2,2, 't', 2, 2);
  131. test_segment_intersection<P>(20, 0,2, 2,2, 2,2, 4,2, 'a', 2, 2);
  132. test_segment_intersection<P>(21, 1,2, 3,2, 2,1, 2,3, 'i', 2, 2);
  133. test_segment_intersection<P>(22, 2,4, 2,1, 2,1, 2,3, 'c', 2, 1, 2, 3);
  134. test_segment_intersection<P>(23, 2,4, 2,1, 2,3, 2,1, 'c', 2, 3, 2, 1);
  135. test_segment_intersection<P>(24, 1,1, 3,3, 0,0, 3,3, 'c', 1, 1, 3, 3);
  136. test_segment_intersection<P>(25, 2,0, 2,4, 2,1, 2,3, 'c', 2, 1, 2, 3);
  137. test_segment_intersection<P>(26, 2,0, 2,4, 2,3, 2,1, 'c', 2, 3, 2, 1);
  138. test_segment_intersection<P>(27, 0,0, 4,4, 1,1, 3,3, 'c', 1, 1, 3, 3);
  139. test_segment_intersection<P>(28, 0,0, 4,4, 3,3, 1,1, 'c', 3, 3, 1, 1);
  140. test_segment_intersection<P>(29, 1,1, 3,3, 0,0, 4,4, 'c', 1, 1, 3, 3);
  141. test_segment_intersection<P>(30, 0,0, 2,2, 2,2, 3,1, 'a', 2, 2);
  142. test_segment_intersection<P>(31, 0,0, 2,2, 2,2, 1,3, 'a', 2, 2);
  143. test_segment_intersection<P>(32, 0,0, 2,2, 1,1, 2,0, 's', 1, 1);
  144. test_segment_intersection<P>(33, 0,0, 2,2, 1,1, 0,2, 's', 1, 1);
  145. test_segment_intersection<P>(34, 2,2, 1,3, 0,0, 2,2, 'a', 2, 2);
  146. test_segment_intersection<P>(35, 2,2, 3,1, 0,0, 2,2, 'a', 2, 2);
  147. test_segment_intersection<P>(36, 0,0, 2,2, 0,2, 1,1, 'm', 1, 1);
  148. test_segment_intersection<P>(37, 0,0, 2,2, 2,0, 1,1, 'm', 1, 1);
  149. test_segment_intersection<P>(38, 1,1, 0,2, 0,0, 2,2, 's', 1, 1);
  150. test_segment_intersection<P>(39, 1,1, 2,0, 0,0, 2,2, 's', 1, 1);
  151. test_segment_intersection<P>(40, 2,0, 1,1, 0,0, 2,2, 'm', 1, 1);
  152. test_segment_intersection<P>(41, 1,2, 0,2, 2,2, 0,2, 'c', 1, 2, 0, 2);
  153. test_segment_intersection<P>(42, 2,1, 1,1, 2,2, 0,2, 'd');
  154. test_segment_intersection<P>(43, 4,1, 3,1, 2,2, 0,2, 'd');
  155. test_segment_intersection<P>(44, 4,2, 3,2, 2,2, 0,2, 'd');
  156. test_segment_intersection<P>(45, 2,0, 0,2, 0,0, 2,2, 'i', 1, 1);
  157. // In figure: times 2
  158. test_segment_intersection<P>(46, 8,2, 4,6, 0,0, 8, 8, 'i', 5, 5);
  159. }
  160. int test_main(int, char* [])
  161. {
  162. #if !defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
  163. test_all<boost::tuple<double, double> >();
  164. test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
  165. #endif
  166. test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
  167. return 0;
  168. }