mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-13 18:21:51 +08:00
Fixing Polyline::split_at() to handle correctly splitting
at the first / last point.
This commit is contained in:
parent
0c99a14b63
commit
d01f6099c3
@ -132,37 +132,33 @@ template void Polyline::simplify_by_visibility<ExPolygonCollection>(const ExPoly
|
|||||||
|
|
||||||
void Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
|
void Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
|
||||||
{
|
{
|
||||||
if (this->points.empty()) return;
|
if (this->size() < 2 || this->points.front() == point) {
|
||||||
|
*p1 = *this;
|
||||||
// find the line to split at
|
p2->clear();
|
||||||
size_t line_idx = 0;
|
return;
|
||||||
Point p = this->first_point();
|
|
||||||
double min = (p - point).cast<double>().norm();
|
|
||||||
Lines lines = this->lines();
|
|
||||||
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
|
||||||
Point p_tmp = point.projection_onto(*line);
|
|
||||||
if ((p_tmp - point).cast<double>().norm() < min) {
|
|
||||||
p = p_tmp;
|
|
||||||
min = (p - point).cast<double>().norm();
|
|
||||||
line_idx = line - lines.begin();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create first half
|
auto min_dist2 = std::numeric_limits<double>::max();
|
||||||
p1->points.clear();
|
auto min_point_it = this->points.cbegin();
|
||||||
for (Lines::const_iterator line = lines.begin(); line != lines.begin() + line_idx + 1; ++line)
|
Point prev = this->points.front();
|
||||||
if (line->a != p)
|
for (auto it = this->points.cbegin() + 1; it != this->points.cend(); ++ it) {
|
||||||
p1->points.push_back(line->a);
|
Point proj = point.projection_onto(Line(prev, *it));
|
||||||
// we add point instead of p because they might differ because of numerical issues
|
auto d2 = (proj - point).cast<double>().squaredNorm();
|
||||||
// and caller might want to rely on point belonging to result polylines
|
if (d2 < min_dist2) {
|
||||||
p1->points.push_back(point);
|
min_dist2 = d2;
|
||||||
|
min_point_it = it;
|
||||||
// create second half
|
|
||||||
p2->points.clear();
|
|
||||||
p2->points.push_back(point);
|
|
||||||
for (Lines::const_iterator line = lines.begin() + line_idx; line != lines.end(); ++line) {
|
|
||||||
p2->points.push_back(line->b);
|
|
||||||
}
|
}
|
||||||
|
prev = *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
p1->points.assign(this->points.cbegin(), min_point_it);
|
||||||
|
if (p1->points.back() != point)
|
||||||
|
p1->points.emplace_back(point);
|
||||||
|
|
||||||
|
p2->points = { point };
|
||||||
|
if (*min_point_it == point)
|
||||||
|
++ min_point_it;
|
||||||
|
p2->points.insert(p2->points.end(), min_point_it, this->points.cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Polyline::is_straight() const
|
bool Polyline::is_straight() const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user