mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-22 22:24:01 -06:00
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
|
// 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);
|
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)); });
|
||||||
// sort input points
|
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());
|
||||||
std::sort(points.begin(), points.end(), sort_points);
|
|
||||||
|
|
||||||
int n = points.size(), k = 0;
|
|
||||||
Polygon hull;
|
Polygon hull;
|
||||||
|
int n = (int)pts.size();
|
||||||
if (n >= 3) {
|
if (n >= 3) {
|
||||||
|
int k = 0;
|
||||||
hull.points.resize(2 * n);
|
hull.points.resize(2 * n);
|
||||||
|
|
||||||
// Build lower hull
|
// Build lower hull
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; ++ i) {
|
||||||
while (k >= 2 && points[i].ccw(hull[k-2], hull[k-1]) <= 0) k--;
|
while (k >= 2 && pts[i].ccw(hull[k-2], hull[k-1]) <= 0)
|
||||||
hull[k++] = points[i];
|
-- k;
|
||||||
|
hull[k ++] = pts[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build upper hull
|
// Build upper hull
|
||||||
for (int i = n-2, t = k+1; i >= 0; i--) {
|
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--;
|
while (k >= t && pts[i].ccw(hull[k-2], hull[k-1]) <= 0)
|
||||||
hull[k++] = points[i];
|
-- k;
|
||||||
|
hull[k ++] = pts[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
hull.points.resize(k);
|
hull.points.resize(k);
|
||||||
|
|
||||||
assert(hull.points.front() == hull.points.back());
|
assert(hull.points.front() == hull.points.back());
|
||||||
hull.points.pop_back();
|
hull.points.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
return hull;
|
return hull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -937,31 +937,7 @@ Polygon ModelObject::convex_hull_2d(const Transform3d &trafo_instance) const
|
||||||
}
|
}
|
||||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
#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)); });
|
return Geometry::convex_hull(std::move(pts));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelObject::center_around_origin(bool include_modifiers)
|
void ModelObject::center_around_origin(bool include_modifiers)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue