diff --git a/src/db/db/dbPLC.cc b/src/db/db/dbPLC.cc index 8d85580ba..28f70b706 100644 --- a/src/db/db/dbPLC.cc +++ b/src/db/db/dbPLC.cc @@ -903,10 +903,10 @@ Graph::bbox () const } db::Layout * -Graph::to_layout (bool decompose_by_id) const +Graph::to_layout (bool decompose_by_id, double dbu) const { db::Layout *layout = new db::Layout (); - layout->dbu (0.001); + layout->dbu (dbu); auto dbu_trans = db::CplxTrans (layout->dbu ()).inverted (); @@ -950,9 +950,9 @@ Graph::to_layout (bool decompose_by_id) const } void -Graph::dump (const std::string &path, bool decompose_by_id) const +Graph::dump (const std::string &path, bool decompose_by_id, double dbu) const { - std::unique_ptr ly (to_layout (decompose_by_id)); + std::unique_ptr ly (to_layout (decompose_by_id, dbu)); tl::OutputStream stream (path); diff --git a/src/db/db/dbPLC.h b/src/db/db/dbPLC.h index 6e098e81c..b1b479517 100644 --- a/src/db/db/dbPLC.h +++ b/src/db/db/dbPLC.h @@ -879,13 +879,13 @@ class DB_PUBLIC Graph * according to bit 0, 1 and 2 of the ID (useful with the 'mark_polygons' * flat in TriangulateParameters). */ - void dump (const std::string &path, bool decompose_by_id = false) const; + void dump (const std::string &path, bool decompose_by_id = false, double dbu = 0.001) const; /** * @brief Creates a new layout object representing the polygon graph * This method is for testing purposes mainly. */ - db::Layout *to_layout (bool decompose_by_id = false) const; + db::Layout *to_layout (bool decompose_by_id = false, double dbu = 0.001) const; protected: Vertex *create_vertex (double x, double y); diff --git a/src/db/db/dbPLCTriangulation.cc b/src/db/db/dbPLCTriangulation.cc index f59ec1a68..28084ae89 100644 --- a/src/db/db/dbPLCTriangulation.cc +++ b/src/db/db/dbPLCTriangulation.cc @@ -42,11 +42,8 @@ static inline bool is_equal (const db::DPoint &a, const db::DPoint &b) std::abs (a.y () - b.y ()) < std::max (1.0, (std::abs (a.y ()) + std::abs (b.y ()))) * db::epsilon; } -// distance of point to vertex to be considered "on edge vertex" relative to edge length involved -const double snap_to_edge_vertex = 1e-5; - // distance of point to edge center to be considered "on edge center" relative to edge length involved -double snap_to_edge_center = 1e-3; +const double snap_to_edge_center = 1e-3; Triangulation::Triangulation (Graph *graph) @@ -238,70 +235,67 @@ Triangulation::insert_point (db::DCoord x, db::DCoord y, std::list > *new_triangles) { - std::vector tris = find_triangle_for_point (*vertex); + Polygon *in_triangle = 0; + Edge *on_edge = 0; + + if (! find_triangle_for_point (*vertex, in_triangle, on_edge)) { - // the new vertex is outside the domain - if (tris.empty ()) { + // the new vertex is outside the domain tl_assert (! m_is_constrained); insert_new_vertex (vertex, new_triangles); return vertex; - } - - // check, if the new vertex is on an edge (may be edge between triangles or edge on outside) - Edge *on_edge = 0; - std::vector on_vertex; - for (int i = 0; i < 3; ++i) { - - Edge *e = tris.front ()->edge (i); - - double snap_range = snap_to_edge_vertex * e->length (); - - if (std::abs (e->edge ().distance (*vertex)) < snap_range - db::epsilon) { - if (vertex->distance (*e->v1 ()) < snap_range + db::epsilon || vertex->distance (*e->v2 ()) < snap_range + db::epsilon) { - on_vertex.push_back (e); - } else if (! on_edge) { - on_edge = e; - } - } } if (on_edge) { - split_triangles_on_edge (vertex, on_edge, new_triangles); - return vertex; + if (is_equal (*vertex, *on_edge->v1 ())) { + return on_edge->v1 (); + } else if (is_equal (*vertex, *on_edge->v2 ())) { + return on_edge->v2 (); + } else { + split_triangles_on_edge (vertex, on_edge, new_triangles); + return vertex; + } - } else if (! on_vertex.empty ()) { + } else if (in_triangle) { - tl_assert (on_vertex.size () == size_t (2)); - return on_vertex.front ()->common_vertex (on_vertex [1]); + split_triangle (in_triangle, vertex, new_triangles); + return vertex; - } else if (tris.size () == size_t (1)) { + } else { - // the new vertex is inside one triangle - split_triangle (tris.front (), vertex, new_triangles); - return vertex; + tl_assert (false); + return 0; } - - tl_assert (false); } -std::vector -Triangulation::find_triangle_for_point (const db::DPoint &point) +bool Triangulation::find_triangle_for_point (const db::DPoint &point, Polygon *&in_triangle, Edge *&on_edge) { Edge *edge = find_closest_edge (point); - std::vector res; if (edge) { - for (auto t = edge->begin_polygons (); t != edge->end_polygons (); ++t) { - if (t->contains (point) >= 0) { - res.push_back (t.operator-> ()); + + if (edge->side_of (point) == 0) { + + on_edge = edge; + return true; + + } else { + + for (auto t = edge->begin_polygons (); t != edge->end_polygons (); ++t) { + if (t->contains (point) >= 0) { + in_triangle = t.operator-> (); + return true; + } } + } + } - return res; + return false; } Edge * @@ -1140,17 +1134,23 @@ static bool is_touching (const db::DEdge &a, const db::DEdge &b) std::vector Triangulation::ensure_edge_inner (Vertex *from, Vertex *to) { - auto crossed_edges = search_edges_crossing (from, to); std::vector result; + // check if there is an edge already + Edge *already_there = find_edge_for_points (*from, *to); + if (already_there) { + result.push_back (already_there); + return result; + } + + auto crossed_edges = search_edges_crossing (from, to); + db::DEdge dedge (*from , *to); if (crossed_edges.empty ()) { // no crossing edge - there should be a edge already - Edge *res = find_edge_for_points (*from, *to); - tl_assert (res != 0); - result.push_back (res); + tl_assert (false); } else if (crossed_edges.size () == 1 && ! is_touching (dedge, crossed_edges.front ()->edge ())) { @@ -1171,7 +1171,7 @@ Triangulation::ensure_edge_inner (Vertex *from, Vertex *to) db::DPoint p = (*e)->intersection_point (dedge); double dp = fabs ((p - *from).sq_length () - l_half); if (d < 0.0 || dp < d) { - dp = d; + d = dp; split_point = p; split_edge = *e; } @@ -1396,6 +1396,9 @@ template DB_PUBLIC void Triangulation::make_contours (const db::DPolygon &, cons void Triangulation::create_constrained_delaunay (const db::Region ®ion, const CplxTrans &trans) { + std::vector > box_contours; + make_contours (db::Polygon (region.bbox ()), trans, box_contours); + std::vector > edge_contours; for (auto p = region.begin_merged (); ! p.at_end (); ++p) { @@ -1408,6 +1411,9 @@ Triangulation::create_constrained_delaunay (const db::Region ®ion, const Cplx void Triangulation::create_constrained_delaunay (const db::Polygon &p, const CplxTrans &trans) { + std::vector > box_contours; + make_contours (db::Polygon (p.box ()), trans, box_contours); + std::vector > edge_contours; make_contours (p, trans, edge_contours); @@ -1417,6 +1423,9 @@ Triangulation::create_constrained_delaunay (const db::Polygon &p, const CplxTran void Triangulation::create_constrained_delaunay (const db::DPolygon &p, const DCplxTrans &trans) { + std::vector > box_contours; + make_contours (db::DPolygon (p.box ()), trans, box_contours); + std::vector > edge_contours; make_contours (p, trans, edge_contours); @@ -1485,6 +1494,9 @@ Triangulation::triangulate (const db::Region ®ion, const std::vector > box_contours; + make_contours (db::Polygon (region.bbox ()), trans, box_contours); + std::vector > edge_contours; for (auto p = region.begin_merged (); ! p.at_end (); ++p) { make_contours (*p, trans, edge_contours); @@ -1514,6 +1526,9 @@ Triangulation::triangulate (const db::Polygon &poly, const std::vector > box_contours; + make_contours (db::Polygon (poly.box ()), trans, box_contours); + std::vector > edge_contours; make_contours (poly, trans, edge_contours); @@ -1539,6 +1554,9 @@ Triangulation::triangulate (const db::Polygon &poly, const std::vector > box_contours; + make_contours (db::Polygon (poly.box ()), trans, box_contours); + std::vector > edge_contours; make_contours (poly, trans, edge_contours); @@ -1564,6 +1582,9 @@ Triangulation::triangulate (const db::DPolygon &poly, const std::vector > box_contours; + make_contours (db::DPolygon (poly.box ()), trans, box_contours); + std::vector > edge_contours; make_contours (poly, trans, edge_contours); diff --git a/src/db/db/dbPLCTriangulation.h b/src/db/db/dbPLCTriangulation.h index 8bcb790af..8c352514c 100644 --- a/src/db/db/dbPLCTriangulation.h +++ b/src/db/db/dbPLCTriangulation.h @@ -335,7 +335,7 @@ class DB_PUBLIC Triangulation void remove_inside_vertex (Vertex *vertex, std::list > *new_triangles_out = 0); std::vector fill_concave_corners (const std::vector &edges); void fix_triangles (const std::vector &tris, const std::vector &fixed_edges, std::list > *new_triangles); - std::vector find_triangle_for_point (const db::DPoint &point); + bool find_triangle_for_point (const db::DPoint &point, Polygon *&in_triangle, Edge *&on_edge); Edge *find_closest_edge (const db::DPoint &p, Vertex *vstart = 0, bool inside_only = false) const; Vertex *insert (Vertex *vertex, std::list > *new_triangles = 0); void split_triangle (Polygon *t, Vertex *vertex, std::list > *new_triangles_out); diff --git a/src/db/unit_tests/dbPLCTriangulationTests.cc b/src/db/unit_tests/dbPLCTriangulationTests.cc index 44b90ff97..5a81b5ca1 100644 --- a/src/db/unit_tests/dbPLCTriangulationTests.cc +++ b/src/db/unit_tests/dbPLCTriangulationTests.cc @@ -896,8 +896,8 @@ TEST(triangulate_geo) } EXPECT_LT (n_skinny, size_t (20)); - EXPECT_GT (plc.num_polygons (), size_t (29000)); - EXPECT_LT (plc.num_polygons (), size_t (30000)); + EXPECT_GT (plc.num_polygons (), size_t (30000)); + EXPECT_LT (plc.num_polygons (), size_t (30200)); } TEST(triangulate_analytic) @@ -951,8 +951,8 @@ TEST(triangulate_analytic) EXPECT_GE (t->b (), param.min_b); } - EXPECT_GT (plc.num_polygons (), size_t (1250)); - EXPECT_LT (plc.num_polygons (), size_t (1300)); + EXPECT_GT (plc.num_polygons (), size_t (1300)); + EXPECT_LT (plc.num_polygons (), size_t (1340)); } TEST(triangulate_problematic) @@ -1078,7 +1078,7 @@ TEST(triangulate_issue1996) EXPECT_LT (plc.num_polygons (), size_t (132000)); } -TEST(triangulate_discussion_2883) +TEST(triangulate_issue_2429) { db::DPoint contour[] = { db::DPoint (-13025.428, -33338.541), @@ -1114,27 +1114,76 @@ TEST(triangulate_discussion_2883) db::DPolygon poly; poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0])); - double dbu = 0.001; + double dbu = 1.0; - db::plc::TriangulationParameters param; - param.min_b = 0.3; + { + db::plc::TriangulationParameters param; + param.min_b = 0.3; + param.max_area = 0.0; - db::plc::Graph plc; - TestableTriangulation tri (&plc); - db::DCplxTrans trans = db::DCplxTrans (dbu) * db::DCplxTrans (db::DTrans (db::DPoint () - poly.box ().center ())); - tri.triangulate (trans * poly, param); + db::plc::Graph plc; + TestableTriangulation tri (&plc); + db::DCplxTrans trans = db::DCplxTrans (dbu) * db::DCplxTrans (db::DTrans (db::DPoint () - poly.box ().center ())); + tri.triangulate (trans * poly, param); - EXPECT_EQ (tri.check (false), true); + EXPECT_EQ (tri.check (false), true); - // for debugging: - // tri.dump ("debug.gds"); + // for debugging: + // tri.dump ("debug.gds"); - for (auto t = plc.begin (); t != plc.end (); ++t) { - EXPECT_GE (t->b (), param.min_b); + for (auto t = plc.begin (); t != plc.end (); ++t) { + EXPECT_GE (t->b (), param.min_b); + } + + EXPECT_GE (plc.num_polygons (), size_t (65)); + EXPECT_LE (plc.num_polygons (), size_t (67)); } - EXPECT_GE (plc.num_polygons (), size_t (70)); - EXPECT_LE (plc.num_polygons (), size_t (72)); + { + db::plc::TriangulationParameters param; + param.min_b = 0.3; + param.max_area = 500.0; + + db::plc::Graph plc; + TestableTriangulation tri (&plc); + db::DCplxTrans trans = db::DCplxTrans (dbu) * db::DCplxTrans (db::DTrans (db::DPoint () - poly.box ().center ())); + tri.triangulate (trans * poly, param); + + EXPECT_EQ (tri.check (false), true); + + // for debugging: + // tri.dump ("debug.gds"); + + for (auto t = plc.begin (); t != plc.end (); ++t) { + EXPECT_GE (t->b (), param.min_b); + } + + EXPECT_GE (plc.num_polygons (), size_t (94)); + EXPECT_LE (plc.num_polygons (), size_t (96)); + } + + { + db::plc::TriangulationParameters param; + param.min_b = 0.9; + param.max_area = 50.0; + + db::plc::Graph plc; + TestableTriangulation tri (&plc); + db::DCplxTrans trans = db::DCplxTrans (dbu) * db::DCplxTrans (db::DTrans (db::DPoint () - poly.box ().center ())); + tri.triangulate (trans * poly, param); + + EXPECT_EQ (tri.check (false), true); + + // for debugging: + // tri.dump ("debug.gds"); + + for (auto t = plc.begin (); t != plc.end (); ++t) { + EXPECT_GE (t->b (), param.min_b); + } + + EXPECT_GE (plc.num_polygons (), size_t (670)); + EXPECT_LE (plc.num_polygons (), size_t (676)); + } } TEST(triangulate_with_vertexes) diff --git a/src/pex/pex/pexRNetExtractor.cc b/src/pex/pex/pexRNetExtractor.cc index aa724090a..b17a7b32d 100644 --- a/src/pex/pex/pexRNetExtractor.cc +++ b/src/pex/pex/pexRNetExtractor.cc @@ -339,6 +339,8 @@ class ExtractingReceiver case RExtractorTechConductor::Tesselation: { pex::TriangulationRExtractor rex (m_dbu); + rex.triangulation_parameters ().max_area = mp_cond->triangulation_max_area; + rex.triangulation_parameters ().min_b = mp_cond->triangulation_min_b; rex.extract (poly, local_vertex_ports, local_polygon_ports, local_network); } break; diff --git a/src/pex/unit_tests/pexTriangulationRExtractorTests.cc b/src/pex/unit_tests/pexTriangulationRExtractorTests.cc index d441c0ee1..9d1689deb 100644 --- a/src/pex/unit_tests/pexTriangulationRExtractorTests.cc +++ b/src/pex/unit_tests/pexTriangulationRExtractorTests.cc @@ -357,7 +357,7 @@ TEST(extraction_meander) rex.extract (poly, vertex_ports, polygon_ports, rn); EXPECT_EQ (rn.to_string (), - "R V0 V1 8.61417" // what is the "real" value? + "R V0 V1 8.60459" // what is the "real" value? ) } diff --git a/testdata/algo/hm_decomposition_au1.gds b/testdata/algo/hm_decomposition_au1.gds index dd04b81d9..06bfe96bc 100644 Binary files a/testdata/algo/hm_decomposition_au1.gds and b/testdata/algo/hm_decomposition_au1.gds differ diff --git a/testdata/algo/hm_decomposition_au2.gds b/testdata/algo/hm_decomposition_au2.gds index 279d6e3c4..3c7853d9d 100644 Binary files a/testdata/algo/hm_decomposition_au2.gds and b/testdata/algo/hm_decomposition_au2.gds differ diff --git a/testdata/algo/hm_decomposition_au3.gds b/testdata/algo/hm_decomposition_au3.gds index 197dedc16..e93a7497a 100644 Binary files a/testdata/algo/hm_decomposition_au3.gds and b/testdata/algo/hm_decomposition_au3.gds differ diff --git a/testdata/algo/hm_decomposition_au4.gds b/testdata/algo/hm_decomposition_au4.gds index 3331beee2..08df5da40 100644 Binary files a/testdata/algo/hm_decomposition_au4.gds and b/testdata/algo/hm_decomposition_au4.gds differ diff --git a/testdata/algo/hm_decomposition_au5.gds b/testdata/algo/hm_decomposition_au5.gds index 3ce6e3a45..609033a24 100644 Binary files a/testdata/algo/hm_decomposition_au5.gds and b/testdata/algo/hm_decomposition_au5.gds differ diff --git a/testdata/algo/hm_decomposition_au6.gds b/testdata/algo/hm_decomposition_au6.gds index 1c81106dc..88a0fac65 100644 Binary files a/testdata/algo/hm_decomposition_au6.gds and b/testdata/algo/hm_decomposition_au6.gds differ diff --git a/testdata/algo/hm_decomposition_au7.gds b/testdata/algo/hm_decomposition_au7.gds index cae3d5cb1..84854aa30 100644 Binary files a/testdata/algo/hm_decomposition_au7.gds and b/testdata/algo/hm_decomposition_au7.gds differ diff --git a/testdata/ruby/dbPolygonTest.rb b/testdata/ruby/dbPolygonTest.rb index 14e6f1983..b5df2cdef 100644 --- a/testdata/ruby/dbPolygonTest.rb +++ b/testdata/ruby/dbPolygonTest.rb @@ -1062,15 +1062,15 @@ def test_hm_decomposition assert_equal(sorted_polygons(p.hm_decomposition(false, false)), "(0,0;0,100;1000,100);(0,0;1000,100;1100,100);(0,0;1100,100;2200,100;2200,0);(1000,100;1000,1000;1100,1000;1100,100)") assert_equal(sorted_polygons(p.hm_decomposition(true, false)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1100,100;1100,0);(1000,100;1000,1000;1100,1000;1100,100);(1100,0;1100,100;2200,100;2200,0)") assert_equal(sorted_polygons(p.hm_decomposition(false, true)), "(0,0;0,100;1000,100;1100,100;2200,100;2200,0);(1000,100;1000,1000;1100,1000;1100,100)") - assert_equal(sorted_polygons(p.hm_decomposition(true, true)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1000,1000;1100,1000;1100,100;1100,0);(1100,0;1100,100;2200,100;2200,0)") - assert_equal(sorted_polygons(p.hm_decomposition(false, false, 0.0, 0.5)), "(0,0;0,100;500,100;1000,100;1100,0;825,0;550,0;275,0);(1000,100;1000,550;1000,775;1000,1000;1100,1000;1100,550;1100,325;1100,100);(1100,0;1000,100;1100,100);(1100,0;1100,100;1650,100;1925,100;2200,100;2200,0;1650,0;1375,0)") + assert_equal(sorted_polygons(p.hm_decomposition(true, true)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1100,100;2200,100;2200,0;1100,0);(1000,100;1000,1000;1100,1000;1100,100)") + assert_equal(sorted_polygons(p.hm_decomposition(false, false, 0.0, 0.5)), "(0,0;0,100;250,100;500,100;1000,100;1100,0;825,0;550,0);(1000,100;1000,325;1000,550;1000,775;1000,1000;1100,1000;1100,550;1100,100);(1100,0;1000,100;1100,100);(1100,0;1100,100;1650,100;1925,100;2200,100;2200,0;1650,0;1375,0)") p = RBA::DPolygon::new([ [0, 0], [0, 100], [1000, 100], [1000, 1000], [1100, 1000], [1100, 100], [2200, 100], [2200, 0] ]) assert_equal(sorted_dpolygons(p.hm_decomposition(false, false)), "(0,0;0,100;1000,100);(0,0;1000,100;1100,100);(0,0;1100,100;2200,100;2200,0);(1000,100;1000,1000;1100,1000;1100,100)") assert_equal(sorted_dpolygons(p.hm_decomposition(true, false)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1100,100;1100,0);(1000,100;1000,1000;1100,1000;1100,100);(1100,0;1100,100;2200,100;2200,0)") assert_equal(sorted_dpolygons(p.hm_decomposition(false, true)), "(0,0;0,100;1000,100;1100,100;2200,100;2200,0);(1000,100;1000,1000;1100,1000;1100,100)") - assert_equal(sorted_dpolygons(p.hm_decomposition(true, true)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1000,1000;1100,1000;1100,100;1100,0);(1100,0;1100,100;2200,100;2200,0)") - assert_equal(sorted_dpolygons(p.hm_decomposition(false, false, 0.0, 0.5)), "(0,0;0,100;500,100;1000,100;1100,0;825,0;550,0;275,0);(1000,100;1000,550;1000,775;1000,1000;1100,1000;1100,550;1100,325;1100,100);(1100,0;1000,100;1100,100);(1100,0;1100,100;1650,100;1925,100;2200,100;2200,0;1650,0;1375,0)") + assert_equal(sorted_dpolygons(p.hm_decomposition(true, true)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1100,100;2200,100;2200,0;1100,0);(1000,100;1000,1000;1100,1000;1100,100)") + assert_equal(sorted_dpolygons(p.hm_decomposition(false, false, 0.0, 0.5)), "(0,0;0,100;250,100;500,100;1000,100;1100,0;825,0;550,0);(1000,100;1000,325;1000,550;1000,775;1000,1000;1100,1000;1100,550;1100,100);(1100,0;1000,100;1100,100);(1100,0;1100,100;1650,100;1925,100;2200,100;2200,0;1650,0;1375,0)") end diff --git a/testdata/ruby/dbSimplePolygonTest.rb b/testdata/ruby/dbSimplePolygonTest.rb index eb1efd246..82441d769 100644 --- a/testdata/ruby/dbSimplePolygonTest.rb +++ b/testdata/ruby/dbSimplePolygonTest.rb @@ -452,15 +452,15 @@ def test_hm_decomposition assert_equal(sorted_polygons(p.hm_decomposition(false, false)), "(0,0;0,100;1000,100);(0,0;1000,100;1100,100);(0,0;1100,100;2200,100;2200,0);(1000,100;1000,1000;1100,1000;1100,100)") assert_equal(sorted_polygons(p.hm_decomposition(true, false)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1100,100;1100,0);(1000,100;1000,1000;1100,1000;1100,100);(1100,0;1100,100;2200,100;2200,0)") assert_equal(sorted_polygons(p.hm_decomposition(false, true)), "(0,0;0,100;1000,100;1100,100;2200,100;2200,0);(1000,100;1000,1000;1100,1000;1100,100)") - assert_equal(sorted_polygons(p.hm_decomposition(true, true)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1000,1000;1100,1000;1100,100;1100,0);(1100,0;1100,100;2200,100;2200,0)") - assert_equal(sorted_polygons(p.hm_decomposition(false, false, 0.0, 0.5)), "(0,0;0,100;500,100;1000,100;1100,0;825,0;550,0;275,0);(1000,100;1000,550;1000,775;1000,1000;1100,1000;1100,550;1100,325;1100,100);(1100,0;1000,100;1100,100);(1100,0;1100,100;1650,100;1925,100;2200,100;2200,0;1650,0;1375,0)") + assert_equal(sorted_polygons(p.hm_decomposition(true, true)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1100,100;2200,100;2200,0;1100,0);(1000,100;1000,1000;1100,1000;1100,100)") + assert_equal(sorted_polygons(p.hm_decomposition(false, false, 0.0, 0.5)), "(0,0;0,100;250,100;500,100;1000,100;1100,0;825,0;550,0);(1000,100;1000,325;1000,550;1000,775;1000,1000;1100,1000;1100,550;1100,100);(1100,0;1000,100;1100,100);(1100,0;1100,100;1650,100;1925,100;2200,100;2200,0;1650,0;1375,0)") p = RBA::DSimplePolygon::new([ [0, 0], [0, 100], [1000, 100], [1000, 1000], [1100, 1000], [1100, 100], [2200, 100], [2200, 0] ]) assert_equal(sorted_dpolygons(p.hm_decomposition(false, false)), "(0,0;0,100;1000,100);(0,0;1000,100;1100,100);(0,0;1100,100;2200,100;2200,0);(1000,100;1000,1000;1100,1000;1100,100)") assert_equal(sorted_dpolygons(p.hm_decomposition(true, false)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1100,100;1100,0);(1000,100;1000,1000;1100,1000;1100,100);(1100,0;1100,100;2200,100;2200,0)") assert_equal(sorted_dpolygons(p.hm_decomposition(false, true)), "(0,0;0,100;1000,100;1100,100;2200,100;2200,0);(1000,100;1000,1000;1100,1000;1100,100)") - assert_equal(sorted_dpolygons(p.hm_decomposition(true, true)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1000,1000;1100,1000;1100,100;1100,0);(1100,0;1100,100;2200,100;2200,0)") - assert_equal(sorted_dpolygons(p.hm_decomposition(false, false, 0.0, 0.5)), "(0,0;0,100;500,100;1000,100;1100,0;825,0;550,0;275,0);(1000,100;1000,550;1000,775;1000,1000;1100,1000;1100,550;1100,325;1100,100);(1100,0;1000,100;1100,100);(1100,0;1100,100;1650,100;1925,100;2200,100;2200,0;1650,0;1375,0)") + assert_equal(sorted_dpolygons(p.hm_decomposition(true, true)), "(0,0;0,100;1000,100;1000,0);(1000,0;1000,100;1100,100;2200,100;2200,0;1100,0);(1000,100;1000,1000;1100,1000;1100,100)") + assert_equal(sorted_dpolygons(p.hm_decomposition(false, false, 0.0, 0.5)), "(0,0;0,100;250,100;500,100;1000,100;1100,0;825,0;550,0);(1000,100;1000,325;1000,550;1000,775;1000,1000;1100,1000;1100,550;1100,100);(1100,0;1000,100;1100,100);(1100,0;1100,100;1650,100;1925,100;2200,100;2200,0;1650,0;1375,0)") end end