minkowski.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. Copyright 2010 Intel Corporation
  3. Use, modification and distribution are 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. */
  7. #include <iostream>
  8. #include <boost/polygon/polygon.hpp>
  9. typedef boost::polygon::point_data<int> point;
  10. typedef boost::polygon::polygon_set_data<int> polygon_set;
  11. typedef boost::polygon::polygon_with_holes_data<int> polygon;
  12. typedef std::pair<point, point> edge;
  13. using namespace boost::polygon::operators;
  14. void convolve_two_segments(std::vector<point>& figure, const edge& a, const edge& b) {
  15. using namespace boost::polygon;
  16. figure.clear();
  17. figure.push_back(point(a.first));
  18. figure.push_back(point(a.first));
  19. figure.push_back(point(a.second));
  20. figure.push_back(point(a.second));
  21. convolve(figure[0], b.second);
  22. convolve(figure[1], b.first);
  23. convolve(figure[2], b.first);
  24. convolve(figure[3], b.second);
  25. }
  26. template <typename itrT1, typename itrT2>
  27. void convolve_two_point_sequences(polygon_set& result, itrT1 ab, itrT1 ae, itrT2 bb, itrT2 be) {
  28. using namespace boost::polygon;
  29. if(ab == ae || bb == be)
  30. return;
  31. point first_a = *ab;
  32. point prev_a = *ab;
  33. std::vector<point> vec;
  34. polygon poly;
  35. ++ab;
  36. for( ; ab != ae; ++ab) {
  37. point first_b = *bb;
  38. point prev_b = *bb;
  39. itrT2 tmpb = bb;
  40. ++tmpb;
  41. for( ; tmpb != be; ++tmpb) {
  42. convolve_two_segments(vec, std::make_pair(prev_b, *tmpb), std::make_pair(prev_a, *ab));
  43. set_points(poly, vec.begin(), vec.end());
  44. result.insert(poly);
  45. prev_b = *tmpb;
  46. }
  47. prev_a = *ab;
  48. }
  49. }
  50. template <typename itrT>
  51. void convolve_point_sequence_with_polygons(polygon_set& result, itrT b, itrT e, const std::vector<polygon>& polygons) {
  52. using namespace boost::polygon;
  53. for(std::size_t i = 0; i < polygons.size(); ++i) {
  54. convolve_two_point_sequences(result, b, e, begin_points(polygons[i]), end_points(polygons[i]));
  55. for(polygon_with_holes_traits<polygon>::iterator_holes_type itrh = begin_holes(polygons[i]);
  56. itrh != end_holes(polygons[i]); ++itrh) {
  57. convolve_two_point_sequences(result, b, e, begin_points(*itrh), end_points(*itrh));
  58. }
  59. }
  60. }
  61. void convolve_two_polygon_sets(polygon_set& result, const polygon_set& a, const polygon_set& b) {
  62. using namespace boost::polygon;
  63. result.clear();
  64. std::vector<polygon> a_polygons;
  65. std::vector<polygon> b_polygons;
  66. a.get(a_polygons);
  67. b.get(b_polygons);
  68. for(std::size_t ai = 0; ai < a_polygons.size(); ++ai) {
  69. convolve_point_sequence_with_polygons(result, begin_points(a_polygons[ai]),
  70. end_points(a_polygons[ai]), b_polygons);
  71. for(polygon_with_holes_traits<polygon>::iterator_holes_type itrh = begin_holes(a_polygons[ai]);
  72. itrh != end_holes(a_polygons[ai]); ++itrh) {
  73. convolve_point_sequence_with_polygons(result, begin_points(*itrh),
  74. end_points(*itrh), b_polygons);
  75. }
  76. for(std::size_t bi = 0; bi < b_polygons.size(); ++bi) {
  77. polygon tmp_poly = a_polygons[ai];
  78. result.insert(convolve(tmp_poly, *(begin_points(b_polygons[bi]))));
  79. tmp_poly = b_polygons[bi];
  80. result.insert(convolve(tmp_poly, *(begin_points(a_polygons[ai]))));
  81. }
  82. }
  83. }
  84. namespace boost { namespace polygon{
  85. template <typename T>
  86. std::ostream& operator<<(std::ostream& o, const polygon_data<T>& poly) {
  87. o << "Polygon { ";
  88. for(typename polygon_data<T>::iterator_type itr = poly.begin();
  89. itr != poly.end(); ++itr) {
  90. if(itr != poly.begin()) o << ", ";
  91. o << (*itr).get(HORIZONTAL) << " " << (*itr).get(VERTICAL);
  92. }
  93. o << " } ";
  94. return o;
  95. }
  96. template <typename T>
  97. std::ostream& operator<<(std::ostream& o, const polygon_with_holes_data<T>& poly) {
  98. o << "Polygon With Holes { ";
  99. for(typename polygon_with_holes_data<T>::iterator_type itr = poly.begin();
  100. itr != poly.end(); ++itr) {
  101. if(itr != poly.begin()) o << ", ";
  102. o << (*itr).get(HORIZONTAL) << " " << (*itr).get(VERTICAL);
  103. } o << " { ";
  104. for(typename polygon_with_holes_data<T>::iterator_holes_type itr = poly.begin_holes();
  105. itr != poly.end_holes(); ++itr) {
  106. o << (*itr);
  107. }
  108. o << " } } ";
  109. return o;
  110. }
  111. }}
  112. int main(int argc, char **argv) {
  113. polygon_set a, b, c;
  114. a += boost::polygon::rectangle_data<int>(0, 0, 1000, 1000);
  115. a -= boost::polygon::rectangle_data<int>(100, 100, 900, 900);
  116. a += boost::polygon::rectangle_data<int>(1000, -1000, 1010, -990);
  117. std::vector<polygon> polys;
  118. std::vector<point> pts;
  119. pts.push_back(point(-40, 0));
  120. pts.push_back(point(-10, 10));
  121. pts.push_back(point(0, 40));
  122. pts.push_back(point(10, 10));
  123. pts.push_back(point(40, 0));
  124. pts.push_back(point(10, -10));
  125. pts.push_back(point(0, -40));
  126. pts.push_back(point(-10, -10));
  127. pts.push_back(point(-40, 0));
  128. polygon poly;
  129. boost::polygon::set_points(poly, pts.begin(), pts.end());
  130. b+=poly;
  131. pts.clear();
  132. pts.push_back(point(1040, 1040));
  133. pts.push_back(point(1050, 1045));
  134. pts.push_back(point(1045, 1050));
  135. boost::polygon::set_points(poly, pts.begin(), pts.end());
  136. b+=poly;
  137. polys.clear();
  138. convolve_two_polygon_sets(c, a, b);
  139. c.get(polys);
  140. for(int i = 0; i < polys.size(); ++i ){
  141. std::cout << polys[i] << std::endl;
  142. }
  143. return 0;
  144. }