/* Copyright 2010 Intel Corporation Use, modification and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). */ #include #include typedef boost::polygon::point_data point; typedef boost::polygon::polygon_set_data polygon_set; typedef boost::polygon::polygon_with_holes_data polygon; typedef std::pair edge; using namespace boost::polygon::operators; void convolve_two_segments(std::vector& figure, const edge& a, const edge& b) { using namespace boost::polygon; figure.clear(); figure.push_back(point(a.first)); figure.push_back(point(a.first)); figure.push_back(point(a.second)); figure.push_back(point(a.second)); convolve(figure[0], b.second); convolve(figure[1], b.first); convolve(figure[2], b.first); convolve(figure[3], b.second); } template void convolve_two_point_sequences(polygon_set& result, itrT1 ab, itrT1 ae, itrT2 bb, itrT2 be) { using namespace boost::polygon; if(ab == ae || bb == be) return; point first_a = *ab; point prev_a = *ab; std::vector vec; polygon poly; ++ab; for( ; ab != ae; ++ab) { point first_b = *bb; point prev_b = *bb; itrT2 tmpb = bb; ++tmpb; for( ; tmpb != be; ++tmpb) { convolve_two_segments(vec, std::make_pair(prev_b, *tmpb), std::make_pair(prev_a, *ab)); set_points(poly, vec.begin(), vec.end()); result.insert(poly); prev_b = *tmpb; } prev_a = *ab; } } template void convolve_point_sequence_with_polygons(polygon_set& result, itrT b, itrT e, const std::vector& polygons) { using namespace boost::polygon; for( ; b != e; ++b) { for(std::size_t i = 0; i < polygons.size(); ++i) { convolve_two_point_sequences(result, b, e, begin_points(polygons[i]), end_points(polygons[i])); for(polygon_with_holes_traits::iterator_holes_type itrh = begin_holes(polygons[i]); itrh != end_holes(polygons[i]); ++itrh) { convolve_two_point_sequences(result, b, e, begin_points(*itrh), end_points(*itrh)); } } } } void convolve_two_polygon_sets(polygon_set& result, const polygon_set& a, const polygon_set& b) { using namespace boost::polygon; result.clear(); std::vector a_polygons; std::vector b_polygons; a.get(a_polygons); b.get(b_polygons); for(std::size_t ai = 0; ai < a_polygons.size(); ++ai) { convolve_point_sequence_with_polygons(result, begin_points(a_polygons[ai]), end_points(a_polygons[ai]), b_polygons); for(polygon_with_holes_traits::iterator_holes_type itrh = begin_holes(a_polygons[ai]); itrh != end_holes(a_polygons[ai]); ++itrh) { convolve_point_sequence_with_polygons(result, begin_points(*itrh), end_points(*itrh), b_polygons); } for(std::size_t bi = 0; bi < b_polygons.size(); ++bi) { polygon tmp_poly = a_polygons[ai]; result.insert(convolve(tmp_poly, *(begin_points(b_polygons[bi])))); tmp_poly = b_polygons[bi]; result.insert(convolve(tmp_poly, *(begin_points(a_polygons[ai])))); } } } namespace boost { namespace polygon{ template std::ostream& operator<<(std::ostream& o, const polygon_data& poly) { o << "Polygon { "; for(typename polygon_data::iterator_type itr = poly.begin(); itr != poly.end(); ++itr) { if(itr != poly.begin()) o << ", "; o << (*itr).get(HORIZONTAL) << " " << (*itr).get(VERTICAL); } o << " } "; return o; } template std::ostream& operator<<(std::ostream& o, const polygon_with_holes_data& poly) { o << "Polygon With Holes { "; for(typename polygon_with_holes_data::iterator_type itr = poly.begin(); itr != poly.end(); ++itr) { if(itr != poly.begin()) o << ", "; o << (*itr).get(HORIZONTAL) << " " << (*itr).get(VERTICAL); } o << " { "; for(typename polygon_with_holes_data::iterator_holes_type itr = poly.begin_holes(); itr != poly.end_holes(); ++itr) { o << (*itr); } o << " } } "; return o; } }} int main(int argc, char **argv) { polygon_set a, b, c; a += boost::polygon::rectangle_data(0, 0, 1000, 1000); a -= boost::polygon::rectangle_data(100, 100, 900, 900); std::vector polys; std::vector pts; pts.push_back(point(-40, 0)); pts.push_back(point(-10, 10)); pts.push_back(point(0, 40)); pts.push_back(point(10, 10)); pts.push_back(point(40, 0)); pts.push_back(point(10, -10)); pts.push_back(point(0, -40)); pts.push_back(point(-10, -10)); pts.push_back(point(-40, 0)); polygon poly; boost::polygon::set_points(poly, pts.begin(), pts.end()); b+=poly; polys.clear(); convolve_two_polygon_sets(c, a, b); c.get(polys); for(int i = 0; i < polys.size(); ++i ){ std::cout << polys[i] << std::endl; } return 0; }