Factored out convex hull calculation from ModelObject::convex_hull_2d()
to Geometry::convex_hull(). Update Geometry::convex_hull() to handle duplicate points.
This commit is contained in:
parent
8db2d96c75
commit
5644b98d3b
2 changed files with 13 additions and 41 deletions
|
@ -212,36 +212,32 @@ static bool sort_pointfs(const Vec3d& a, const Vec3d& b)
|
|||
}
|
||||
|
||||
// This implementation is based on Andrew's monotone chain 2D convex hull algorithm
|
||||
Polygon convex_hull(Points points)
|
||||
Polygon convex_hull(Points pts)
|
||||
{
|
||||
assert(points.size() >= 3);
|
||||
// sort input points
|
||||
std::sort(points.begin(), points.end(), sort_points);
|
||||
std::sort(pts.begin(), pts.end(), [](const Point& a, const Point& b) { return a(0) < b(0) || (a(0) == b(0) && a(1) < b(1)); });
|
||||
pts.erase(std::unique(pts.begin(), pts.end(), [](const Point& a, const Point& b) { return a(0) == b(0) && a(1) == b(1); }), pts.end());
|
||||
|
||||
int n = points.size(), k = 0;
|
||||
Polygon hull;
|
||||
|
||||
int n = (int)pts.size();
|
||||
if (n >= 3) {
|
||||
int k = 0;
|
||||
hull.points.resize(2 * n);
|
||||
|
||||
// Build lower hull
|
||||
for (int i = 0; i < n; i++) {
|
||||
while (k >= 2 && points[i].ccw(hull[k-2], hull[k-1]) <= 0) k--;
|
||||
hull[k++] = points[i];
|
||||
for (int i = 0; i < n; ++ i) {
|
||||
while (k >= 2 && pts[i].ccw(hull[k-2], hull[k-1]) <= 0)
|
||||
-- k;
|
||||
hull[k ++] = pts[i];
|
||||
}
|
||||
|
||||
// Build upper hull
|
||||
for (int i = n-2, t = k+1; i >= 0; i--) {
|
||||
while (k >= t && points[i].ccw(hull[k-2], hull[k-1]) <= 0) k--;
|
||||
hull[k++] = points[i];
|
||||
while (k >= t && pts[i].ccw(hull[k-2], hull[k-1]) <= 0)
|
||||
-- k;
|
||||
hull[k ++] = pts[i];
|
||||
}
|
||||
|
||||
hull.points.resize(k);
|
||||
|
||||
assert(hull.points.front() == hull.points.back());
|
||||
hull.points.pop_back();
|
||||
}
|
||||
|
||||
return hull;
|
||||
}
|
||||
|
||||
|
|
|
@ -937,31 +937,7 @@ Polygon ModelObject::convex_hull_2d(const Transform3d &trafo_instance) const
|
|||
}
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
}
|
||||
std::sort(pts.begin(), pts.end(), [](const Point& a, const Point& b) { return a(0) < b(0) || (a(0) == b(0) && a(1) < b(1)); });
|
||||
pts.erase(std::unique(pts.begin(), pts.end(), [](const Point& a, const Point& b) { return a(0) == b(0) && a(1) == b(1); }), pts.end());
|
||||
|
||||
Polygon hull;
|
||||
int n = (int)pts.size();
|
||||
if (n >= 3) {
|
||||
int k = 0;
|
||||
hull.points.resize(2 * n);
|
||||
// Build lower hull
|
||||
for (int i = 0; i < n; ++ i) {
|
||||
while (k >= 2 && pts[i].ccw(hull[k-2], hull[k-1]) <= 0)
|
||||
-- k;
|
||||
hull[k ++] = pts[i];
|
||||
}
|
||||
// Build upper hull
|
||||
for (int i = n-2, t = k+1; i >= 0; i--) {
|
||||
while (k >= t && pts[i].ccw(hull[k-2], hull[k-1]) <= 0)
|
||||
-- k;
|
||||
hull[k ++] = pts[i];
|
||||
}
|
||||
hull.points.resize(k);
|
||||
assert(hull.points.front() == hull.points.back());
|
||||
hull.points.pop_back();
|
||||
}
|
||||
return hull;
|
||||
return Geometry::convex_hull(std::move(pts));
|
||||
}
|
||||
|
||||
void ModelObject::center_around_origin(bool include_modifiers)
|
||||
|
|
Loading…
Reference in a new issue