intersection_segment.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #include <algorithm>
  11. #include <ostream>
  12. #include <sstream>
  13. #include <string>
  14. #include <vector>
  15. #include <boost/config.hpp>
  16. #include <geometry_test_common.hpp>
  17. #include <boost/geometry/algorithms/correct.hpp>
  18. #include <boost/geometry/algorithms/within.hpp>
  19. #include <boost/geometry/algorithms/intersection_segment.hpp>
  20. #include <boost/geometry/io/wkt/aswkt.hpp>
  21. static std::ostream & operator<<(std::ostream &s, const bg::intersection_result& r)
  22. {
  23. switch(r)
  24. {
  25. case bg::is_intersect_no : s << "is_intersect_no"; break;
  26. case bg::is_intersect : s << "is_intersect"; break;
  27. case bg::is_parallel : s << "is_parallel"; break;
  28. case bg::is_collinear_no : s << "is_collinear_no"; break;
  29. case bg::is_collinear_one : s << "is_collinear_one"; break;
  30. case bg::is_collinear_connect : s << "is_collinear_connect"; break;
  31. case bg::is_collinear_overlap : s << "is_collinear_overlap"; break;
  32. case bg::is_collinear_overlap_opposite : s << "is_collinear_overlap_opposite"; break;
  33. case bg::is_collinear_connect_opposite : s << "is_collinear_connect_opposite"; break;
  34. // detailed connection results:
  35. case bg::is_intersect_connect_s1p1 : s << "is_intersect_connect_s1p1"; break;
  36. case bg::is_intersect_connect_s1p2 : s << "is_intersect_connect_s1p2"; break;
  37. case bg::is_intersect_connect_s2p1 : s << "is_intersect_connect_s2p1"; break;
  38. case bg::is_intersect_connect_s2p2 : s << "is_intersect_connect_s2p2"; break;
  39. }
  40. return s;
  41. }
  42. static std::string as_string(const bg::intersection_result& r)
  43. {
  44. std::stringstream out;
  45. out << r;
  46. return out.str();
  47. }
  48. typedef bg::model::point<double> P;
  49. typedef bg::const_segment<P> S;
  50. static void test_intersection(double s1x1, double s1y1, double s1x2, double s1y2,
  51. double s2x1, double s2y1, double s2x2, double s2y2,
  52. // Expected results
  53. bg::intersection_result expected_result,
  54. int exptected_count, const P& exp_p1, const P& exp_p2)
  55. {
  56. S s1(P(s1x1, s1y1), P(s1x2, s1y2));
  57. S s2(P(s2x1, s2y1), P(s2x2, s2y2));
  58. std::vector<P> ip;
  59. double ra, rb;
  60. bg::intersection_result r = bg::intersection_s(s1, s2, ra, rb, ip);
  61. r = bg::intersection_connect_result(r, ra, rb);
  62. BOOST_CHECK_EQUAL(ip.size(), exptected_count);
  63. BOOST_CHECK_EQUAL(as_string(expected_result), as_string(r));
  64. if (ip.size() == 2 && ip[0] != exp_p1)
  65. {
  66. // Swap results, second point is not as expected, swap results, order is not prescribed,
  67. // it might be OK.
  68. std::reverse(ip.begin(), ip.end());
  69. }
  70. if (ip.size() >= 1)
  71. {
  72. BOOST_CHECK_EQUAL(ip[0], exp_p1);
  73. }
  74. if (ip.size() >= 2)
  75. {
  76. BOOST_CHECK_EQUAL(ip[1], exp_p2);
  77. }
  78. /*
  79. std::cout << exptected_count << " " << r;
  80. if (exptected_count >= 1) std::cout << " " << ip[0];
  81. if (exptected_count >= 2) std::cout << " " << ip[1];
  82. std::cout << std::endl;
  83. */
  84. }
  85. //BOOST_AUTO_TEST_CASE( test1 )
  86. int test_main( int , char* [] )
  87. {
  88. // Identical cases
  89. test_intersection(0,0, 1,1, 0,0, 1,1, bg::is_collinear_overlap, 2, P(0,0), P(1,1));
  90. test_intersection(1,1, 0,0, 0,0, 1,1, bg::is_collinear_overlap_opposite, 2, P(1,1), P(0,0));
  91. test_intersection(0,1, 0,2, 0,1, 0,2, bg::is_collinear_overlap, 2, P(0,1), P(0,2)); // Vertical
  92. test_intersection(0,2, 0,1, 0,1, 0,2, bg::is_collinear_overlap_opposite, 2, P(0,2), P(0,1)); // Vertical
  93. // Overlap cases
  94. test_intersection(0,0, 1,1, -0.5,-0.5, 2,2, bg::is_collinear_overlap, 2, P(0,0), P(1,1));
  95. test_intersection(0,0, 1,1, 0.5,0.5, 1.5,1.5, bg::is_collinear_overlap, 2, P(0.5,0.5), P(1,1));
  96. test_intersection(0,0, 0,1, 0,-10, 0,10, bg::is_collinear_overlap, 2, P(0,0), P(0,1)); // Vertical
  97. test_intersection(0,0, 0,1, 0,10, 0,-10, bg::is_collinear_overlap_opposite, 2, P(0,0), P(0,1)); // Vertical
  98. test_intersection(0,0, 1,1, 1,1, 2,2, bg::is_collinear_connect, 1, P(1,1), P(0,0)); // Single point
  99. // Colinear, non overlap cases
  100. test_intersection(0,0, 1,1, 1.5,1.5, 2.5,2.5, bg::is_collinear_no, 0, P(0,0), P(0,0));
  101. test_intersection(0,0, 0,1, 0,5, 0,6, bg::is_collinear_no, 0, P(0,0), P(0,0)); // Vertical
  102. // Parallel cases
  103. test_intersection(0,0, 1,1, 1,0, 2,1, bg::is_parallel, 0, P(0,0), P(0,1));
  104. // Intersect cases
  105. test_intersection(0,2, 4,2, 3,0, 3,4, bg::is_intersect, 1, P(3,2), P(0,0));
  106. // Non intersect cases
  107. // Single point cases
  108. test_intersection(0,0, 0,0, 1,1, 2,2, bg::is_collinear_no, 0, P(1,1), P(0,0)); // Colinear/no
  109. test_intersection(2,2, 2,2, 1,1, 3,3, bg::is_collinear_one, 1, P(2,2.01), P(0,0)); // On segment
  110. test_intersection(1,1, 3,3, 2,2, 2,2, bg::is_collinear_one, 1, P(2,2), P(0,0)); // On segment
  111. test_intersection(1,1, 3,3, 1,1, 1,1, bg::is_collinear_one, 1, P(1,1), P(0,0)); // On segment, start
  112. test_intersection(1,1, 3,3, 3,3, 3,3, bg::is_collinear_one, 1, P(3,3), P(0,0)); // On segment, end
  113. return 0;
  114. }