mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 17:27:52 -06:00
Templated convex_hull function in Geometry.cpp
This commit is contained in:
parent
3f72ca2a15
commit
48b9793d3d
4 changed files with 43 additions and 19 deletions
|
@ -195,47 +195,62 @@ using namespace boost::polygon; // provides also high() and low()
|
||||||
|
|
||||||
namespace Slic3r { namespace Geometry {
|
namespace Slic3r { namespace Geometry {
|
||||||
|
|
||||||
static bool
|
struct SortPoints {
|
||||||
sort_points (Point a, Point b)
|
template <class T>
|
||||||
{
|
bool operator()(const T& a, const T& b) const {
|
||||||
return (a.x < b.x) || (a.x == b.x && a.y < b.y);
|
return (b.x > a.x) || (a.x == b.x && b.y > a.y);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* 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
|
template<class T>
|
||||||
convex_hull(Points points)
|
static T raw_convex_hull(T& points)
|
||||||
{
|
{
|
||||||
assert(points.size() >= 3);
|
assert(points.size() >= 3);
|
||||||
// sort input points
|
// sort input points
|
||||||
std::sort(points.begin(), points.end(), sort_points);
|
std::sort(points.begin(), points.end(), SortPoints());
|
||||||
|
|
||||||
int n = points.size(), k = 0;
|
int n = points.size(), k = 0;
|
||||||
Polygon hull;
|
T hull;
|
||||||
|
|
||||||
if (n >= 3) {
|
if (n >= 3) {
|
||||||
hull.points.resize(2*n);
|
hull.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.points[k-2], hull.points[k-1]) <= 0) k--;
|
while (k >= 2 && points[i].ccw(hull[k-2], hull[k-1]) <= 0) k--;
|
||||||
hull.points[k++] = points[i];
|
hull[k++] = points[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.points[k-2], hull.points[k-1]) <= 0) k--;
|
while (k >= t && points[i].ccw(hull[k-2], hull[k-1]) <= 0) k--;
|
||||||
hull.points[k++] = points[i];
|
hull[k++] = points[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
hull.points.resize(k);
|
hull.resize(k);
|
||||||
|
|
||||||
assert( hull.points.front().coincides_with(hull.points.back()) );
|
assert( hull.front().coincides_with(hull.back()) );
|
||||||
hull.points.pop_back();
|
hull.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
return hull;
|
return hull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pointf3s
|
||||||
|
convex_hull(Pointf3s points)
|
||||||
|
{
|
||||||
|
return raw_convex_hull(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
Polygon
|
||||||
|
convex_hull(Points points)
|
||||||
|
{
|
||||||
|
Polygon hull;
|
||||||
|
hull.points = raw_convex_hull(points);
|
||||||
|
return hull;
|
||||||
|
}
|
||||||
|
|
||||||
Polygon
|
Polygon
|
||||||
convex_hull(const Polygons &polygons)
|
convex_hull(const Polygons &polygons)
|
||||||
{
|
{
|
||||||
|
@ -243,7 +258,7 @@ convex_hull(const Polygons &polygons)
|
||||||
for (Polygons::const_iterator p = polygons.begin(); p != polygons.end(); ++p) {
|
for (Polygons::const_iterator p = polygons.begin(); p != polygons.end(); ++p) {
|
||||||
pp.insert(pp.end(), p->points.begin(), p->points.end());
|
pp.insert(pp.end(), p->points.begin(), p->points.end());
|
||||||
}
|
}
|
||||||
return convex_hull(pp);
|
return convex_hull(std::move(pp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* accepts an arrayref of points and returns a list of indices
|
/* accepts an arrayref of points and returns a list of indices
|
||||||
|
|
|
@ -108,8 +108,10 @@ inline bool segment_segment_intersection(const Pointf &p1, const Vectorf &v1, co
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pointf3s convex_hull(Pointf3s points);
|
||||||
Polygon convex_hull(Points points);
|
Polygon convex_hull(Points points);
|
||||||
Polygon convex_hull(const Polygons &polygons);
|
Polygon convex_hull(const Polygons &polygons);
|
||||||
|
|
||||||
void chained_path(const Points &points, std::vector<Points::size_type> &retval, Point start_near);
|
void chained_path(const Points &points, std::vector<Points::size_type> &retval, Point start_near);
|
||||||
void chained_path(const Points &points, std::vector<Points::size_type> &retval);
|
void chained_path(const Points &points, std::vector<Points::size_type> &retval);
|
||||||
template<class T> void chained_path_items(Points &points, T &items, T &retval);
|
template<class T> void chained_path_items(Points &points, T &items, T &retval);
|
||||||
|
|
|
@ -263,6 +263,12 @@ operator<<(std::ostream &stm, const Pointf &pointf)
|
||||||
return stm << pointf.x << "," << pointf.y;
|
return stm << pointf.x << "," << pointf.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
Pointf::ccw(const Pointf &p1, const Pointf &p2) const
|
||||||
|
{
|
||||||
|
return (double)(p2.x - p1.x)*(double)(this->y - p1.y) - (double)(p2.y - p1.y)*(double)(this->x - p1.x);
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
Pointf::wkt() const
|
Pointf::wkt() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -221,6 +221,7 @@ public:
|
||||||
static Pointf new_unscale(const Point &p) {
|
static Pointf new_unscale(const Point &p) {
|
||||||
return Pointf(unscale(p.x), unscale(p.y));
|
return Pointf(unscale(p.x), unscale(p.y));
|
||||||
};
|
};
|
||||||
|
double ccw(const Pointf &p1, const Pointf &p2) const;
|
||||||
std::string wkt() const;
|
std::string wkt() const;
|
||||||
std::string dump_perl() const;
|
std::string dump_perl() const;
|
||||||
void scale(double factor);
|
void scale(double factor);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue