From 7aa2bb366e4fadb0ef2a78a73435ba4b73bd2cd6 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Thu, 7 May 2026 20:35:54 +0200 Subject: [PATCH] arrange polies, fuse boxes only when obb also overlaps --- src/svgfill/src/arrange_polygons.cpp | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/svgfill/src/arrange_polygons.cpp b/src/svgfill/src/arrange_polygons.cpp index a7b591fdb1..cfb51321f8 100644 --- a/src/svgfill/src/arrange_polygons.cpp +++ b/src/svgfill/src/arrange_polygons.cpp @@ -1085,6 +1085,45 @@ bool aabb_overlap(const DBox& a, const DBox& b, double eps = 1.e-9) { a[1].y() + eps >= b[0].y(); } +std::pair projected_interval_on_axis(const std::array& points, const DDir& axis_u) { + auto u = unit(axis_u); + auto t0 = (points.front() - CGAL::ORIGIN) * u; + auto interval = std::make_pair(t0, t0); + for (auto& p : points) { + auto t = (p - CGAL::ORIGIN) * u; + interval.first = std::min(interval.first, t); + interval.second = std::max(interval.second, t); + } + return interval; +} + +bool intervals_overlap(const std::pair& a, const std::pair& b, double eps = 1.e-9) { + return a.first <= b.second + eps && b.first <= a.second + eps; +} + +bool obb_overlap(const std::array& a, const std::array& b, double eps = 1.e-9) { + auto has_separating_axis = [&](const std::array& points) { + for (size_t i = 0; i < points.size(); ++i) { + auto edge = points[(i + 1) % points.size()] - points[i]; + auto axis = unit(perpendicular(edge)); + if (axis.squared_length() < 1.e-18) { + continue; + } + if (!intervals_overlap(projected_interval_on_axis(a, axis), projected_interval_on_axis(b, axis), eps)) { + return true; + } + } + return false; + }; + + return !has_separating_axis(a) && !has_separating_axis(b); +} + +template +bool obb_overlap(const T& a, const U& b, double eps = 1.e-9) { + return obb_overlap(a.corners, b.corners, eps); +} + CenterLineGraphData make_center_line_graph_data( const std::map>& line_graph, const std::map& midpoint_to_edge_length) @@ -1378,6 +1417,9 @@ bool clusters_can_merge(const BoxCluster& a, const BoxCluster& b, double angle_t if (!aabb_overlap(a.box.bbox, b.box.bbox)) { return false; } + if (!obb_overlap(a.box, b.box)) { + return false; + } if (angle_between_dirs_deg(a.box.direction, b.box.direction) > angle_tol_deg) { return false; }