From e9de4252fb98f15aee4dc68f28c555036642013a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 17 Sep 2018 01:25:10 +0200 Subject: [PATCH] Fixed #166 (internal error when writing GDS file) This fix consists of computing the intersection points in the split procedure with higher resolution to avoid topology changes due to snapping on the cut line. --- src/db/db/dbPolygonTools.cc | 8 ++++---- src/db/unit_tests/dbPolygonTools.cc | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/db/db/dbPolygonTools.cc b/src/db/db/dbPolygonTools.cc index 77f7c9dcd..e44ecfa8b 100644 --- a/src/db/db/dbPolygonTools.cc +++ b/src/db/db/dbPolygonTools.cc @@ -112,7 +112,7 @@ struct cut_polygon_edge { typedef typename PointType::coord_type coord_type; typedef typename db::edge edge_type; - typedef typename db::coord_traits::area_type projection_type; + typedef double projection_type; cut_polygon_edge () : contour (-1), index (0), projected (0), point (), last_point () @@ -179,7 +179,7 @@ public: bool operator< (const loose_end_struct &other) const { - if (proj () != other.proj ()) { + if (! db::coord_traits::equal (proj (), other.proj ())) { return proj () < other.proj (); } else { return db::vprod_sign (edge (), other.edge ()) > 0; @@ -196,13 +196,13 @@ static bool _cut_polygon_internal (const PolygonType &input, const Edge &line, C typedef db::edge edge_type; typedef cut_polygon_edge cut_polygon_edge_type; typedef cut_polygon_segment cutting_segment_type; - typedef typename db::coord_traits::area_type projection_type; bool do_hole_assignment = (input.holes () > 0); std::vector hull_polygons; std::vector hole_polygons; std::vector cutting_segments; + double line_length = line.double_length (); for (unsigned int nc = 0; nc < input.holes () + 1; ++nc) { @@ -229,7 +229,7 @@ static bool _cut_polygon_internal (const PolygonType &input, const Edge &line, C int s1 = line.side_of (e.p1 ()); int s2 = line.side_of (e.p2 ()); - projection_type p = db::sprod (ip.second - line.p1 (), line.p2 () - line.p1 ()); + double p = line_length * double (db::vprod (e.p1 () - line.p1 (), e.d ())) / double (db::vprod (line.d (), e.d ())); if (s1 < 0 && s2 >= 0) { // right -> left or on edge diff --git a/src/db/unit_tests/dbPolygonTools.cc b/src/db/unit_tests/dbPolygonTools.cc index 06224c533..6229f89f4 100644 --- a/src/db/unit_tests/dbPolygonTools.cc +++ b/src/db/unit_tests/dbPolygonTools.cc @@ -2241,3 +2241,20 @@ TEST(403) EXPECT_EQ (right_of.size (), size_t (0)); } } + +// issue 166 +TEST(404) +{ + db::Polygon poly; + std::string s ("(390,0;438,936;176,874;0,832;438,937;541,961;821,102)"); + tl::Extractor ex (s.c_str ()); + ex.read (poly); + + std::vector sp; + db::split_polygon (poly, sp); + EXPECT_EQ (sp.size (), size_t (2)); + if (sp.size () >= 2) { + EXPECT_EQ (sp[0].to_string (), "(390,0;438,936;390,925;438,937;541,961;821,102)"); + EXPECT_EQ (sp[1].to_string (), "(0,832;176,874;390,925)"); + } +}