From 90ed8a2390e282711a1a2a96f86c31c4943c58be Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 5 Sep 2025 23:48:49 +0200 Subject: [PATCH] Excluding degenerated edges from polygons so we don't consider them corners, addressing duplicate corners with zero distance. --- src/db/db/dbEdgePairRelations.cc | 13 +++++++++++-- src/db/db/dbRegionCheckUtils.cc | 8 +++++--- src/db/unit_tests/dbEdgePairRelationsTests.cc | 10 ++++++---- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/db/db/dbEdgePairRelations.cc b/src/db/db/dbEdgePairRelations.cc index de4f46078..e5da82d64 100644 --- a/src/db/db/dbEdgePairRelations.cc +++ b/src/db/db/dbEdgePairRelations.cc @@ -353,6 +353,8 @@ static bool var_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits< } + bool allow_zero_projection = false; + if (db::sprod_sign (e, g) == 0) { if (! g.is_degenerate ()) { @@ -367,6 +369,8 @@ static bool var_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits< l1 = l - dl; l2 = l + dl; + allow_zero_projection = true; + } } else { @@ -388,7 +392,7 @@ static bool var_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits< l1 = std::max (0.0, l1); l2 = std::min (1.0, l2); - if (l1 > l2 + db::epsilon) { + if (allow_zero_projection ? l1 > l2 + db::epsilon : l1 > l2 - db::epsilon) { return false; } else { if (output) { @@ -469,7 +473,12 @@ EdgeRelationFilter::check (const db::Edge &a, const db::Edge &b, db::EdgePair *o // Check whether the edges have an angle less than the ignore_angle parameter if (a.is_degenerate () || b.is_degenerate ()) { - // accept dots as "always good" + // accept dots as "always good", expect if they are identical and the zero distance mode does not include this case + if (a == b && (m_zero_distance_mode == NeverIncludeZeroDistance || + m_zero_distance_mode == IncludeZeroDistanceWhenCollinearAndTouching || + m_zero_distance_mode == IncludeZeroDistanceWhenOverlapping)) { + return false; + } } else if (m_ignore_angle == 90.0) { if (db::sprod_sign (aa, b) >= 0) { return false; diff --git a/src/db/db/dbRegionCheckUtils.cc b/src/db/db/dbRegionCheckUtils.cc index f57ef287e..7f71edb4c 100644 --- a/src/db/db/dbRegionCheckUtils.cc +++ b/src/db/db/dbRegionCheckUtils.cc @@ -463,8 +463,10 @@ void poly2poly_check::enter (const PolygonType &o, size_t p) { for (typename PolygonType::polygon_edge_iterator e = o.begin_edge (); ! e.at_end (); ++e) { - m_edge_heap.push_back (*e); - m_scanner.insert (& m_edge_heap.back (), p); + if (! (*e).is_degenerate ()) { + m_edge_heap.push_back (*e); + m_scanner.insert (& m_edge_heap.back (), p); + } } } @@ -497,7 +499,7 @@ poly2poly_check::enter (const PolygonType &o, size_t p, const poly2 } for (typename PolygonType::polygon_edge_iterator e = o.begin_edge (); ! e.at_end (); ++e) { - if (interact (box, *e)) { + if (! (*e).is_degenerate () && interact (box, *e)) { m_edge_heap.push_back (*e); m_scanner.insert (& m_edge_heap.back (), p); } diff --git a/src/db/unit_tests/dbEdgePairRelationsTests.cc b/src/db/unit_tests/dbEdgePairRelationsTests.cc index 42bc669d3..c0809bbda 100644 --- a/src/db/unit_tests/dbEdgePairRelationsTests.cc +++ b/src/db/unit_tests/dbEdgePairRelationsTests.cc @@ -135,7 +135,8 @@ TEST(3) EXPECT_EQ (output.to_string (), "(80,0;-60,-100)"); EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), true); EXPECT_EQ (output.to_string (), "(-100,0;-100,-100)"); - EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), true); + EXPECT_EQ (output.to_string (), "(-100,100;-100,-100)"); // dot vs. line (issue #2141) EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 50), db::Point (100, 50)), &output), false); EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (100, -50)), &output), true); EXPECT_EQ (output.to_string (), "(100,-50;100,-50)"); @@ -170,14 +171,15 @@ TEST(4) EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (200, -200)), &output), false); EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (120, 200), db::Point (120, -200)), &output), false); EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 200), db::Point (100, -200)), &output), true); - EXPECT_EQ (output.to_string (), "(100,0;100,-100)"); + EXPECT_EQ (output.to_string (), "(100,0;100,0)"); EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 200), db::Point (80, -200)), &output), true); - EXPECT_EQ (output.to_string (), "(80,0;80,-100)"); + EXPECT_EQ (output.to_string (), "(80,0;80,0)"); EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-80, 200), db::Point (-80, -200)), &output), false); EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 0), db::Point (-200, -200)), &output), true); EXPECT_EQ (output.to_string (), "(80,0;0,-57)"); EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), true); + EXPECT_EQ (output.to_string (), "(-100,0;-100,0)"); // dot vs. line (issue #2141) EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 50), db::Point (100, 50)), &output), false); EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (100, -50)), &output), true); EXPECT_EQ (output.to_string (), "(100,-50;100,-50)");