Scanline polygon generator: avoid spikes

The implementation of the scanline polygon generator
will avoid spikes as hole cutlines. Helps
fixing #116.
This commit is contained in:
Matthias Koefferlein
2018-04-23 22:22:32 +02:00
parent e710b28a6d
commit ca9a6db8a5
24 changed files with 57 additions and 1 deletions
+6 -1
View File
@@ -731,8 +731,13 @@ PolygonGenerator::join_contours (db::Coord x)
db::Coord xprev = db::coord_traits<db::Coord>::rounded (edge_xaty (eprev, m_y));
db::Point pprev (xprev, m_y);
tl_assert (c1.size () >= 2);
// remove collinear edges along the cut line
cprev.back () = pprev;
while (cprev.size () > 1 && cprev.end ()[-2].y () == m_y && cprev.end ()[-1].y () == m_y) {
cprev.pop_back ();
}
tl_assert (c1.size () >= 2);
if ((c1.begin () + 1)->y () == m_y) {
cprev.insert (cprev.end (), c1.begin () + 1, c1.end ());
} else {
+51
View File
@@ -2295,3 +2295,54 @@ TEST(101)
EXPECT_EQ (out.size (), size_t (1));
EXPECT_EQ (out[0].to_string (), "(0,0;0,9;1,10;10,10;10,0)");
}
TEST(102)
{
db::EdgeProcessor ep;
{
db::Point pts[] = {
db::Point (0, 0),
db::Point (0, 1000),
db::Point (1000, 1000),
db::Point (1000, 0)
};
db::Polygon p;
p.assign_hull (&pts[0], &pts[sizeof(pts) / sizeof(pts[0])]);
ep.insert (p, 0);
}
{
db::Point pts[] = {
db::Point (100, 100),
db::Point (100, 200),
db::Point (200, 200),
db::Point (200, 100)
};
db::Polygon p;
p.assign_hull (&pts[0], &pts[sizeof(pts) / sizeof(pts[0])]);
ep.insert (p, 1);
}
{
db::Point pts[] = {
db::Point (500, 100),
db::Point (500, 200),
db::Point (600, 200),
db::Point (600, 100)
};
db::Polygon p;
p.assign_hull (&pts[0], &pts[sizeof(pts) / sizeof(pts[0])]);
ep.insert (p, 1);
}
std::vector<db::Polygon> out;
db::PolygonContainer pc (out);
db::PolygonGenerator pg (pc, true, true);
db::BooleanOp op (db::BooleanOp::ANotB);
ep.process (pg, op);
EXPECT_EQ (out.size (), size_t (1));
EXPECT_EQ (out[0].to_string (), "(0,0;0,200;100,200;100,100;200,100;200,200;500,200;500,100;600,100;600,200;0,200;0,1000;1000,1000;1000,0)");
}