/Src/Dependencies/Boost/libs/geometry/test/strategies/segment_intersection.cpp

http://hadesmem.googlecode.com/ · C++ · 374 lines · 241 code · 57 blank · 76 comment · 27 complexity · 87450bb4773244b906fd3f880e9521b1 MD5 · raw file

  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
  5. // Copyright (c) 2009-2011 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. #define HAVE_MATRIX_AS_STRING
  16. #include <geometry_test_common.hpp>
  17. #include <boost/geometry/algorithms/assign.hpp>
  18. #include <boost/geometry/strategies/cartesian/cart_intersect.hpp>
  19. #include <boost/geometry/strategies/intersection_result.hpp>
  20. #include <boost/geometry/policies/relate/intersection_points.hpp>
  21. #include <boost/geometry/policies/relate/direction.hpp>
  22. //#include <boost/geometry/policies/relate/de9im.hpp>
  23. #include <boost/geometry/policies/relate/tupled.hpp>
  24. #include <boost/geometry/algorithms/intersection.hpp>
  25. #include <boost/geometry/geometries/point.hpp>
  26. #include <boost/geometry/geometries/segment.hpp>
  27. #include <boost/geometry/geometries/adapted/boost_tuple.hpp>
  28. BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian);
  29. template <typename R>
  30. void print_is(R const& is)
  31. {
  32. #ifdef REPORT
  33. for (int i = 0; i < is.count; i++)
  34. {
  35. std::cout
  36. << " (" << bg::get<0>(is.intersections[i])
  37. << "," << bg::get<1>(is.intersections[i])
  38. << ")";
  39. }
  40. #endif
  41. }
  42. /*
  43. void print_im(bg::de9im const& im)
  44. {
  45. #ifdef REPORT
  46. if (im.equals()) std::cout << " EQUALS";
  47. if (im.disjoint()) std::cout << " DISJOINT";
  48. if (im.intersects()) std::cout << " INTERSECTS";
  49. if (im.touches()) std::cout << " TOUCHES";
  50. if (im.crosses()) std::cout << " CROSSES";
  51. if (im.overlaps()) std::cout << " OVERLAPS";
  52. if (im.within()) std::cout << " WITHIN";
  53. if (im.contains()) std::cout << " CONTAINS";
  54. //std::cout << " ra=" << im.ra << " rb=" << im.rb;
  55. #endif
  56. }
  57. */
  58. template <typename P>
  59. static void test_segment_intersection(int caseno,
  60. int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4,
  61. std::string const& expected_matrix,
  62. std::string const& expected_characteristic,
  63. std::string const& expected_direction_a = "",
  64. std::string const& expected_direction_b = "",
  65. int expected_x1 = -99, int expected_y1 = -99,
  66. int expected_x2 = -99, int expected_y2 = -99)
  67. {
  68. using namespace boost::geometry;
  69. #ifdef REPORT
  70. std::cout << "CASE " << caseno << std::endl;
  71. #endif
  72. typedef typename bg::coordinate_type<P>::type coordinate_type;
  73. typedef bg::model::referring_segment<const P> segment_type;
  74. P p1, p2, p3, p4;
  75. bg::assign_values(p1, x1, y1);
  76. bg::assign_values(p2, x2, y2);
  77. bg::assign_values(p3, x3, y3);
  78. bg::assign_values(p4, x4, y4);
  79. segment_type s12(p1,p2);
  80. segment_type s34(p3,p4);
  81. // Get the intersection point (or two points)
  82. segment_intersection_points<P> is
  83. = strategy::intersection::relate_cartesian_segments
  84. <
  85. policies::relate::segments_intersection_points
  86. <
  87. segment_type,
  88. segment_type,
  89. segment_intersection_points<P>
  90. >
  91. >::apply(s12, s34);
  92. // Get the Dimension Extended 9 Intersection Matrix (de9im) for Segments
  93. // (this one is extended by GGL having opposite)
  94. /***
  95. TODO TO BE UPDATED (if necessary) OR DELETED
  96. de9im_segment matrix = strategy::intersection::relate_cartesian_segments
  97. <
  98. policies::relate::segments_de9im<segment_type, segment_type>
  99. >::apply(s12, s34);
  100. ***/
  101. // Get just a character for Left/Right/intersects/etc, purpose is more for debugging
  102. policies::relate::direction_type dir = strategy::intersection::relate_cartesian_segments
  103. <
  104. policies::relate::segments_direction<segment_type, segment_type>
  105. >::apply(s12, s34);
  106. int expected_count = 0;
  107. if (expected_x1 != -99 && expected_y1 != -99)
  108. {
  109. expected_count++;
  110. BOOST_CHECK(is.count >= 1);
  111. BOOST_CHECK_CLOSE(bg::get<0>(is.intersections[0]),
  112. coordinate_type(expected_x1), 0.001);
  113. BOOST_CHECK_CLOSE(bg::get<1>(is.intersections[0]),
  114. coordinate_type(expected_y1), 0.001);
  115. }
  116. if (expected_x2 != -99 && expected_y2 != -99)
  117. {
  118. expected_count++;
  119. BOOST_CHECK(is.count >= 2);
  120. BOOST_CHECK_CLOSE(bg::get<0>(is.intersections[1]),
  121. coordinate_type(expected_x2), 0.001);
  122. BOOST_CHECK_CLOSE(bg::get<1>(is.intersections[1]),
  123. coordinate_type(expected_y2), 0.001);
  124. }
  125. BOOST_CHECK_EQUAL(is.count, expected_count);
  126. //BOOST_CHECK_EQUAL(expected_matrix, matrix.matrix_as_string());
  127. std::string characteristic;
  128. characteristic += dir.how;
  129. BOOST_CHECK_EQUAL(characteristic, expected_characteristic);
  130. if (!expected_direction_a.empty())
  131. {
  132. BOOST_CHECK_EQUAL(dir.dir_a == 1 ? "L"
  133. : dir.dir_a == -1 ? "R"
  134. : "-", expected_direction_a);
  135. }
  136. if (!expected_direction_b.empty())
  137. {
  138. BOOST_CHECK_EQUAL(dir.dir_b == 1 ? "L"
  139. : dir.dir_b == -1 ? "R"
  140. : "-", expected_direction_b);
  141. }
  142. // Things can also be used together
  143. // -> intersection is only once calculated, two results
  144. /***
  145. typedef boost::tuple
  146. <
  147. de9im_segment,
  148. policies::relate::direction_type
  149. > tup;
  150. tup t = strategy::intersection::relate_cartesian_segments
  151. <
  152. policies::relate::segments_tupled
  153. <
  154. policies::relate::segments_de9im<segment_type, segment_type>,
  155. policies::relate::segments_direction<segment_type, segment_type>
  156. >
  157. >::apply(segment_type(p1,p2), segment_type(p3,p4));
  158. //BOOST_CHECK_EQUAL(t.get<0>().matrix_as_string(), matrix.matrix_as_string());
  159. BOOST_CHECK_EQUAL(t.get<1>().how, dir.how);
  160. */
  161. #ifdef REPORT
  162. //std::cout << std::endl << "\t" << matrix.as_string() << " ";
  163. std::cout << "METHOD=" << c << " ";
  164. print_is(is);
  165. //print_im(matrix);
  166. std::cout << std::endl;
  167. #endif
  168. /*
  169. To check with a spatial database: issue this statement
  170. std::cout << "select relate("
  171. << "GeomFromText(LINESTRING('" << x1 << " " << y1 << "," << x2 << " " << y2 << ")')"
  172. << ", "
  173. << "GeomFromText(LINESTRING('" << x3 << " " << y3 << "," << x4 << " " << y4 << ")')"
  174. << ");"
  175. << std::endl;
  176. */
  177. // Now use generic intersection.
  178. std::vector<P> out;
  179. bg::detail::intersection::intersection_insert<P>(s12, s34, std::back_inserter(out));
  180. BOOST_CHECK_EQUAL(boost::size(out), expected_count);
  181. if (expected_x1 != -99 && expected_y1 != -99
  182. && is.count >= 1
  183. && boost::size(out) >= 1)
  184. {
  185. BOOST_CHECK_CLOSE(bg::get<0>(out[0]),
  186. coordinate_type(expected_x1), 0.001);
  187. BOOST_CHECK_CLOSE(bg::get<1>(out[0]),
  188. coordinate_type(expected_y1), 0.001);
  189. }
  190. if (expected_x2 != -99 && expected_y2 != -99
  191. && is.count >= 2
  192. && boost::size(out) >= 2)
  193. {
  194. BOOST_CHECK_CLOSE(bg::get<0>(out[1]),
  195. coordinate_type(expected_x2), 0.001);
  196. BOOST_CHECK_CLOSE(bg::get<1>(out[1]),
  197. coordinate_type(expected_y2), 0.001);
  198. }
  199. }
  200. template <typename P>
  201. void test_all()
  202. {
  203. test_segment_intersection<P>( 1, 0,2, 2,0, 0,0, 2,2, "0-1--0102",
  204. "i", "R", "L", 1, 1);
  205. test_segment_intersection<P>( 2, 2,2, 3,1, 0,0, 2,2, "--1-00102",
  206. "a", "R", "R", 2, 2);
  207. test_segment_intersection<P>( 3, 3,1, 2,2, 0,0, 2,2, "--1-00102",
  208. "t", "R", "L", 2, 2);
  209. test_segment_intersection<P>( 4, 0,2, 1,1, 0,0, 2,2, "--10-0102",
  210. "m", "L", "L", 1, 1);
  211. #ifdef REPORT
  212. std::cout << std::endl;
  213. #endif
  214. test_segment_intersection<P>( 5, 1,1, 0,2, 0,0, 2,2, "--10-0102",
  215. "s", "L", "R", 1, 1);
  216. test_segment_intersection<P>( 6, 0,2, 2,0, 0,0, 1,1, "-01--0102",
  217. "m", "R", "R", 1, 1);
  218. test_segment_intersection<P>( 7, 2,0, 0,2, 0,0, 1,1, "-01--0102",
  219. "m", "L", "L", 1, 1);
  220. test_segment_intersection<P>( 8, 2,3, 3,2, 0,0, 2,2, "--1--0102",
  221. "d");
  222. #ifdef REPORT
  223. std::cout << std::endl;
  224. #endif
  225. test_segment_intersection<P>( 9, 0,0, 2,2, 0,0, 2,2, "1---0---2",
  226. "e", "-", "-", 0, 0, 2, 2);
  227. test_segment_intersection<P>(10, 2,2, 0,0, 0,0, 2,2, "1---0---2",
  228. "e", "-", "-", 2, 2, 0, 0);
  229. test_segment_intersection<P>(11, 1,1, 3,3, 0,0, 2,2, "1010-0102",
  230. "c", "-", "-", 1, 1, 2, 2);
  231. test_segment_intersection<P>(12, 3,3, 1,1, 0,0, 2,2, "1010-0102",
  232. "c", "-", "-", 1, 1, 2, 2);
  233. #ifdef REPORT
  234. std::cout << std::endl;
  235. #endif
  236. test_segment_intersection<P>(13, 0,2, 2,2, 2,1, 2,3, "--10-0102",
  237. "m", "L", "L", 2, 2);
  238. test_segment_intersection<P>(14, 2,2, 2,4, 2,0, 2,2, "--1-00102",
  239. "C", "-", "-", 2, 2);
  240. test_segment_intersection<P>(15, 2,2, 2,4, 2,0, 2,1, "--1--0102",
  241. "d");
  242. test_segment_intersection<P>(16, 2,4, 2,2, 2,0, 2,1, "--1--0102",
  243. "d");
  244. test_segment_intersection<P>(17, 2,1, 2,3, 2,2, 2,4, "1010-0102",
  245. "c", "-", "-", 2, 3, 2, 2);
  246. test_segment_intersection<P>(18, 2,3, 2,1, 2,2, 2,4, "1010-0102",
  247. "c", "-", "-", 2, 3, 2, 2);
  248. test_segment_intersection<P>(19, 0,2, 2,2, 4,2, 2,2, "--1-00102",
  249. "C", "-", "-", 2, 2);
  250. test_segment_intersection<P>(20, 0,2, 2,2, 2,2, 4,2, "--1-00102",
  251. "C", "-", "-", 2, 2);
  252. test_segment_intersection<P>(21, 1,2, 3,2, 2,1, 2,3, "0-1--0102",
  253. "i", "R", "L", 2, 2);
  254. test_segment_intersection<P>(22, 2,4, 2,1, 2,1, 2,3, "101-00--2",
  255. "c", "-", "-", 2, 1, 2, 3);
  256. test_segment_intersection<P>(23, 2,4, 2,1, 2,3, 2,1, "101-00--2",
  257. "c", "-", "-", 2, 3, 2, 1);
  258. test_segment_intersection<P>(24, 1,1, 3,3, 0,0, 3,3, "1--00-102",
  259. "c", "-", "-", 1, 1, 3, 3);
  260. test_segment_intersection<P>(25, 2,0, 2,4, 2,1, 2,3, "101--0--2",
  261. "c", "-", "-", 2, 1, 2, 3);
  262. test_segment_intersection<P>(26, 2,0, 2,4, 2,3, 2,1, "101--0--2",
  263. "c", "-", "-", 2, 3, 2, 1);
  264. test_segment_intersection<P>(27, 0,0, 4,4, 1,1, 3,3, "101--0--2",
  265. "c", "-", "-", 1, 1, 3, 3);
  266. test_segment_intersection<P>(28, 0,0, 4,4, 3,3, 1,1, "101--0--2",
  267. "c", "-", "-", 3, 3, 1, 1);
  268. test_segment_intersection<P>(29, 1,1, 3,3, 0,0, 4,4, "1--0--102",
  269. "c", "-", "-", 1, 1, 3, 3);
  270. test_segment_intersection<P>(30, 0,0, 2,2, 2,2, 3,1, "--1-00102",
  271. "a", "R", "R", 2, 2);
  272. test_segment_intersection<P>(31, 0,0, 2,2, 2,2, 1,3, "--1-00102",
  273. "a", "L", "L", 2, 2);
  274. test_segment_intersection<P>(32, 0,0, 2,2, 1,1, 2,0, "-01--0102",
  275. "s", "L", "R", 1, 1);
  276. test_segment_intersection<P>(33, 0,0, 2,2, 1,1, 0,2, "-01--0102",
  277. "s", "R", "L", 1, 1);
  278. test_segment_intersection<P>(34, 2,2, 1,3, 0,0, 2,2, "--1-00102",
  279. "a", "L", "L", 2, 2);
  280. test_segment_intersection<P>(35, 2,2, 3,1, 0,0, 2,2, "--1-00102",
  281. "a", "R", "R", 2, 2);
  282. test_segment_intersection<P>(36, 0,0, 2,2, 0,2, 1,1, "-01--0102",
  283. "m", "L", "L", 1, 1);
  284. test_segment_intersection<P>(37, 0,0, 2,2, 2,0, 1,1, "-01--0102",
  285. "m", "R", "R", 1, 1);
  286. test_segment_intersection<P>(38, 1,1, 0,2, 0,0, 2,2, "--10-0102",
  287. "s", "L", "R", 1, 1);
  288. test_segment_intersection<P>(39, 1,1, 2,0, 0,0, 2,2, "--10-0102",
  289. "s", "R", "L", 1, 1);
  290. test_segment_intersection<P>(40, 2,0, 1,1, 0,0, 2,2, "--10-0102",
  291. "m", "R", "R", 1, 1);
  292. test_segment_intersection<P>(41, 1,2, 0,2, 2,2, 0,2, "1--00-102",
  293. "c", "-", "-", 1, 2, 0, 2);
  294. test_segment_intersection<P>(42, 2,1, 1,1, 2,2, 0,2, "--1--0102",
  295. "p");
  296. test_segment_intersection<P>(43, 4,1, 3,1, 2,2, 0,2, "--1--0102",
  297. "p");
  298. test_segment_intersection<P>(44, 4,2, 3,2, 2,2, 0,2, "--1--0102",
  299. "d");
  300. test_segment_intersection<P>(45, 2,0, 0,2, 0,0, 2,2, "0-1--0102",
  301. "i", "L", "R", 1, 1);
  302. // In figure: times 2
  303. test_segment_intersection<P>(46, 8,2, 4,6, 0,0, 8, 8, "0-1--0102",
  304. "i", "L", "R", 5, 5);
  305. }
  306. int test_main(int, char* [])
  307. {
  308. std::cout << "Note this test is out-of-date and either obsolete or should be updated" << std::endl;
  309. test_all<boost::tuple<double, double> >();
  310. test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
  311. test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
  312. return 0;
  313. }