Limit the object movement to the vincinity of the print bed.

This commit is contained in:
bubnikv 2017-06-08 11:02:29 +02:00
parent dabcff1c07
commit 8b5f7f0fb2
8 changed files with 142 additions and 25 deletions

View file

@ -15,7 +15,7 @@ typedef std::vector<ThickLine> ThickLines;
class Line
{
public:
public:
Point a;
Point b;
Line() {};

View file

@ -140,6 +140,29 @@ MultiPoint::intersection(const Line& line, Point* intersection) const
return false;
}
bool MultiPoint::first_intersection(const Line& line, Point* intersection) const
{
bool found = false;
double dmin = 0.;
for (const Line &l : this->lines()) {
Point ip;
if (l.intersection(line, &ip)) {
if (! found) {
found = true;
dmin = ip.distance_to(line.a);
*intersection = ip;
} else {
double d = ip.distance_to(line.a);
if (d < dmin) {
dmin = d;
*intersection = ip;
}
}
}
}
return found;
}
std::string
MultiPoint::dump_perl() const
{

View file

@ -13,7 +13,7 @@ class BoundingBox;
class MultiPoint
{
public:
public:
Points points;
operator Points() const;
@ -35,8 +35,24 @@ class MultiPoint
double length() const;
bool is_valid() const { return this->points.size() >= 2; }
int find_point(const Point &point) const;
int find_point(const Point &point) const;
bool has_boundary_point(const Point &point) const;
int closest_point_index(const Point &point) const {
int idx = -1;
if (! this->points.empty()) {
idx = 0;
double dist_min = this->points.front().distance_to(point);
for (int i = 1; i < int(this->points.size()); ++ i) {
double d = this->points[i].distance_to(point);
if (d < dist_min) {
dist_min = d;
idx = i;
}
}
}
return idx;
}
const Point* closest_point(const Point &point) const { return this->points.empty() ? nullptr : &this->points[this->closest_point_index(point)]; }
BoundingBox bounding_box() const;
// Return true if there are exact duplicates.
bool has_duplicate_points() const;
@ -56,6 +72,7 @@ class MultiPoint
}
bool intersection(const Line& line, Point* intersection) const;
bool first_intersection(const Line& line, Point* intersection) const;
std::string dump_perl() const;
static Points _douglas_peucker(const Points &points, const double tolerance);

View file

@ -293,6 +293,44 @@ Polygon::convex_points(double angle) const
return points;
}
// Projection of a point onto the polygon.
Point Polygon::point_projection(const Point &point) const
{
Point proj = point;
double dmin = std::numeric_limits<double>::max();
if (! this->points.empty()) {
for (size_t i = 0; i < this->points.size(); ++ i) {
const Point &pt0 = this->points[i];
const Point &pt1 = this->points[(i + 1 == this->points.size()) ? 0 : i + 1];
double d = pt0.distance_to(point);
if (d < dmin) {
dmin = d;
proj = pt0;
}
d = pt1.distance_to(point);
if (d < dmin) {
dmin = d;
proj = pt1;
}
Pointf v1(coordf_t(pt1.x - pt0.x), coordf_t(pt1.y - pt0.y));
coordf_t div = dot(v1);
if (div > 0.) {
Pointf v2(coordf_t(point.x - pt0.x), coordf_t(point.y - pt0.y));
coordf_t t = dot(v1, v2) / div;
if (t > 0. && t < 1.) {
Point foot(coord_t(floor(coordf_t(pt0.x) + t * v1.x + 0.5)), coord_t(floor(coordf_t(pt0.y) + t * v1.y + 0.5)));
d = foot.distance_to(point);
if (d < dmin) {
dmin = d;
proj = foot;
}
}
}
}
}
return proj;
}
BoundingBox get_extents(const Polygon &poly)
{
return poly.bounding_box();

View file

@ -51,6 +51,8 @@ public:
std::string wkt() const;
Points concave_points(double angle = PI) const;
Points convex_points(double angle = PI) const;
// Projection of a point onto the polygon.
Point point_projection(const Point &point) const;
};
extern BoundingBox get_extents(const Polygon &poly);