|
@@ -25,42 +25,45 @@ sort_points (Point a, Point b)
|
|
|
}
|
|
|
|
|
|
/* This implementation is based on Andrew's monotone chain 2D convex hull algorithm */
|
|
|
-void
|
|
|
-convex_hull(Points points, Polygon* hull)
|
|
|
+Polygon
|
|
|
+convex_hull(Points points)
|
|
|
{
|
|
|
assert(points.size() >= 3);
|
|
|
// sort input points
|
|
|
std::sort(points.begin(), points.end(), sort_points);
|
|
|
|
|
|
int n = points.size(), k = 0;
|
|
|
- hull->points.resize(2*n);
|
|
|
+ Polygon hull;
|
|
|
+ hull.points.resize(2*n);
|
|
|
|
|
|
// Build lower hull
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
- while (k >= 2 && points[i].ccw(hull->points[k-2], hull->points[k-1]) <= 0) k--;
|
|
|
- hull->points[k++] = points[i];
|
|
|
+ while (k >= 2 && points[i].ccw(hull.points[k-2], hull.points[k-1]) <= 0) k--;
|
|
|
+ hull.points[k++] = points[i];
|
|
|
}
|
|
|
|
|
|
// Build upper hull
|
|
|
for (int i = n-2, t = k+1; i >= 0; i--) {
|
|
|
- while (k >= t && points[i].ccw(hull->points[k-2], hull->points[k-1]) <= 0) k--;
|
|
|
- hull->points[k++] = points[i];
|
|
|
+ while (k >= t && points[i].ccw(hull.points[k-2], hull.points[k-1]) <= 0) k--;
|
|
|
+ hull.points[k++] = points[i];
|
|
|
}
|
|
|
|
|
|
- hull->points.resize(k);
|
|
|
+ hull.points.resize(k);
|
|
|
+
|
|
|
+ assert( hull.points.front().coincides_with(hull.points.back()) );
|
|
|
+ hull.points.pop_back();
|
|
|
|
|
|
- assert( hull->points.front().coincides_with(hull->points.back()) );
|
|
|
- hull->points.pop_back();
|
|
|
+ return hull;
|
|
|
}
|
|
|
|
|
|
-void
|
|
|
-convex_hull(const Polygons &polygons, Polygon* hull)
|
|
|
+Polygon
|
|
|
+convex_hull(const Polygons &polygons)
|
|
|
{
|
|
|
Points pp;
|
|
|
for (Polygons::const_iterator p = polygons.begin(); p != polygons.end(); ++p) {
|
|
|
pp.insert(pp.end(), p->points.begin(), p->points.end());
|
|
|
}
|
|
|
- convex_hull(pp, hull);
|
|
|
+ return convex_hull(pp);
|
|
|
}
|
|
|
|
|
|
/* accepts an arrayref of points and returns a list of indices
|