diff --git a/src/Lib/Geometry/poly_support.cxx b/src/Lib/Geometry/poly_support.cxx index 3003b286..9583d07d 100644 --- a/src/Lib/Geometry/poly_support.cxx +++ b/src/Lib/Geometry/poly_support.cxx @@ -356,6 +356,24 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p ) { return result; } +/* + * Helper class for sorting points along a given axis. + */ +class Point3DOrdering { +public: + Point3DOrdering(int axis):axis(axis) {} + bool operator()(const Point3D& a, const Point3D& b) { + return a[axis] &xcuts ) { int contour_num = node->get_contour_num(); const point_list& pts=p.get_contour(contour_num); @@ -383,26 +401,17 @@ static void intersect_yline_with_contour( double yline, TGContourNode *node, TGP } if (ymax-yminget_contour_num(); + const point_list& contourpts=p.get_contour(contour_num); + + pts.insert(pts.end(),contourpts.begin(),contourpts.end()); +} + // recurse the contour tree and build up the point inside list for // each contour/hole static void calc_point_inside( TGContourNode *node, TGPolygon &p ) { @@ -435,21 +454,52 @@ static void calc_point_inside( TGContourNode *node, TGPolygon &p ) { * partition the line in IN/OUT parts. Find the longest segment and take * its midpoint as point inside the contour. */ - const point_list& pts=p.get_contour(contour_num); - double ymin,ymax; - ymin=ymax=pts[0].y(); + /* + * Try to find a line on which none of the contour points lie. For that, + * sort all contour points (also those of our direct children) by + * y-coordinate, find the two with the largest distance and take their + * center y-coordinate. + */ + point_list allpoints; - for (int i = 0; i < pts.size() ; ++i ) { - if (pts[i].y()get_num_kids(); ++i ) { + if ( node->get_kid( i ) != NULL ) { + collect_contour_points( node->get_kid( i ), p, allpoints ); + } + } + + if ( allpoints.size() < 2 ) { + throw sg_exception("Polygon must have at least 2 contour points"); + } + + sort(allpoints.begin(), allpoints.end(), Point3DOrdering(PY)); + + point_list::iterator point_it; + + point_it=allpoints.begin(); + Point3D lastpt=*point_it; + + double maxdiff=0.0; + double yline; // the y-location of the intersection line + + while ((++point_it) != allpoints.end()) { + double diff=point_it->y()-lastpt.y(); + if (diff>maxdiff) { + maxdiff=diff; + yline=(point_it->y()+lastpt.y())/2.0; + } + lastpt=*point_it; + } + + if (maxdiff(cout, " ")); - cout << endl; + // copy(xcuts.begin(), xcuts.end(), ostream_iterator(cout, " ")); + // cout << endl; if ( xcuts.size() < 2 || (xcuts.size() % 2) != 0 ) { throw sg_exception("Geometric inconsistency in calc_point_inside()");