Fixed ExPolygon::overlaps(), which was not commutative.

Wrote unit tests for Clipper polyline clipping operations.
Rewrote ExPolygon unit tests from Perl to C++.
This commit is contained in:
Vojtech Bubnik 2022-11-15 15:32:16 +01:00
parent f1c0c61895
commit db3f696888
7 changed files with 187 additions and 90 deletions

View file

@ -154,14 +154,18 @@ bool ExPolygon::overlaps(const ExPolygon &other) const
svg.draw_outline(*this);
svg.draw_outline(other, "blue");
#endif
Polylines pl_out = intersection_pl(to_polylines(other), *this);
#if 0
svg.draw(pl_out, "red");
#endif
if (! pl_out.empty())
return true;
//FIXME ExPolygon::overlaps() shall be commutative, it is not!
return this->contains(other.contour.points.front());
// See unit test SCENARIO("Clipper diff with polyline", "[Clipper]")
// for in which case the intersection_pl produces any intersection.
return ! pl_out.empty() ||
// If *this is completely inside other, then pl_out is empty, but the expolygons overlap. Test for that situation.
other.contains(this->contour.points.front());
}
void ExPolygon::simplify_p(double tolerance, Polygons* polygons) const

View file

@ -60,6 +60,10 @@ public:
// Does this expolygon overlap another expolygon?
// Either the ExPolygons intersect, or one is fully inside the other,
// and it is not inside a hole of the other expolygon.
// The test may not be commutative if the two expolygons touch by a boundary only,
// see unit test SCENARIO("Clipper diff with polyline", "[Clipper]").
// Namely expolygons touching at a vertical boundary are considered overlapping, while expolygons touching
// at a horizontal boundary are NOT considered overlapping.
bool overlaps(const ExPolygon &other) const;
void simplify_p(double tolerance, Polygons* polygons) const;

View file

@ -84,8 +84,7 @@ public:
float overhangs_area = 0.f;
bool overlaps(const Structure &rhs) const {
//FIXME ExPolygon::overlaps() shall be commutative, it is not!
return this->bbox.overlap(rhs.bbox) && (this->polygon->overlaps(*rhs.polygon) || rhs.polygon->overlaps(*this->polygon));
return this->bbox.overlap(rhs.bbox) && this->polygon->overlaps(*rhs.polygon);
}
float overlap_area(const Structure &rhs) const {
double out = 0.;