#include "minkowski.h" #include #include #include #include #include #include #include #undef min #undef max 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; using namespace std;; 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(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])))); } } } double inputscale; using namespace boost::polygon; vector Avec; vector Bvec; vector> chlds; vector> retpnts; vector> retholes; void getResults(double* data, double* holesData) { int index=0; for(int i=0;i()); for(int j=0;j polys; std::vector pts; // get maximum bounds for scaling factor unsigned int len = Avec.size()/2; double Amaxx = 0; double Aminx = 0; double Amaxy = 0; double Aminy = 0; for (unsigned int i = 0; i < len; i++) { double x1=Avec[i*2]; double y1=Avec[i*2+1]; Amaxx = (std::max)(Amaxx, (double)x1); Aminx = (std::min)(Aminx, (double)x1); Amaxy = (std::max)(Amaxy, (double)y1); Aminy = (std::min)(Aminy, (double)y1); } len = Bvec.size()/2; double Bmaxx = 0; double Bminx = 0; double Bmaxy = 0; double Bminy = 0; for (unsigned int i = 0; i < len*2; i+=2) { double x1=Bvec[i]; double y1=Bvec[i+1]; Bmaxx = (std::max)(Bmaxx, (double)x1); Bminx = (std::min)(Bminx, (double)x1); Bmaxy = (std::max)(Bmaxy, (double)y1); Bminy = (std::min)(Bminy, (double)y1); } double Cmaxx = Amaxx + Bmaxx; double Cminx = Aminx + Bminx; double Cmaxy = Amaxy + Bmaxy; double Cminy = Aminy + Bminy; double maxxAbs = (std::max)(Cmaxx, std::fabs(Cminx)); double maxyAbs = (std::max)(Cmaxy, std::fabs(Cminy)); double maxda = (std::max)(maxxAbs, maxyAbs); int maxi = std::numeric_limits::max(); if(maxda < 1){ maxda = 1; } // why 0.1? dunno. it doesn't screw up with 0.1 inputscale = (0.1f * (double)(maxi)) / maxda; //double scale = 1000; len = Avec.size()/2; for (unsigned int i = 0; i < len; i++) { double x1=Avec[i*2]; double y1=Avec[i*2+1]; int x = (int)(inputscale * (double)x1); int y = (int)(inputscale * (double)y1); pts.push_back(point(x, y)); } polygon poly; boost::polygon::set_points(poly, pts.begin(), pts.end()); a+=poly; // subtract holes from a here... len = chlds.size(); for(unsigned int i=0; i hole=chlds[i]; pts.clear(); unsigned int hlen = hole.size()/2; for(unsigned int j=0; j pointlist = vector(); int j = 0; for(polygon_traits::iterator_type itr = polys[i].begin(); itr != polys[i].end(); ++itr) { // std::cout << (double)(*itr).get(boost::polygon::HORIZONTAL) / inputscale << std::endl; double x1=((double)(*itr).get(boost::polygon::HORIZONTAL)) / inputscale + xshift; double y1=((double)(*itr).get(boost::polygon::VERTICAL)) / inputscale + yshift; pointlist.push_back(x1); pointlist.push_back(y1); j++; } retpnts.push_back(pointlist); // holes int k = 0; for(polygon_with_holes_traits::iterator_holes_type itrh = begin_holes(polys[i]); itrh != end_holes(polys[i]); ++itrh){ vector child=vector(); int z = 0; for(polygon_traits::iterator_type itr2 = (*itrh).begin(); itr2 != (*itrh).end(); ++itr2) { double x1=((double)(*itr2).get(boost::polygon::HORIZONTAL)) / inputscale + xshift; double y1=((double)(*itr2).get(boost::polygon::VERTICAL)) / inputscale + yshift; child.push_back(x1); child.push_back(y1); z++; } retholes.push_back(child); k++; } } }