diff --git a/src/svgfill/src/arrange_polygons.cpp b/src/svgfill/src/arrange_polygons.cpp index b106c94f07..47882238ae 100644 --- a/src/svgfill/src/arrange_polygons.cpp +++ b/src/svgfill/src/arrange_polygons.cpp @@ -1469,6 +1469,7 @@ std::vector merge_intersecting_parallel_boxes_iterative(const s std::vector members = clusters[i].members; members.insert(members.end(), clusters[j].members.begin(), clusters[j].members.end()); auto merged = BoxCluster{members, merge_cluster_to_box(members, records)}; + std::cout << "Result width: " << merged.box.avg_width << " fromt " << clusters[i].box.avg_width << " & " << clusters[j].box.avg_width << std::endl; std::vector next_clusters; next_clusters.reserve(clusters.size() - 1); @@ -2170,92 +2171,115 @@ extend_end_vertices_based_on_input_simple( const K::FT& max_projection_distance) { auto max_intersection_distance = max_projection_distance / 4; - std::list> constructed_segments; - for (auto it = G.vertices_begin(); it != G.vertices_end(); ++it) { - if (it->second.size() == 1) { - auto& M = it->first; + const auto& process_point = [&](const Point_2& M, const Point_2& incoming) { + for (auto& bnd : outer_perimiter) { + // if point M is contained in bnd interior: + // if (!bnd.has_on_unbounded_side(M)) { + if (bnd.has_on_bounded_side(M)) { + // create ray incoming -> M + CGAL::Ray_2 ray(incoming, M - incoming); - for (auto& bnd : outer_perimiter) { - // if point M is contained in bnd interior: - // if (!bnd.has_on_unbounded_side(M)) { - if (bnd.has_on_bounded_side(M)) { - auto& incoming = *it->second.begin(); - // create ray incoming -> M - CGAL::Ray_2 ray(incoming, M - incoming); + // intersect ray with boundary + boost::optional> closest_segment; + boost::optional> closest_intersection_point; + K::FT sq_distance_along_ray = std::numeric_limits::infinity(); + for (auto jt = bnd.edges_begin(); jt != bnd.edges_end(); ++jt) { + const auto& seg = *jt; + auto x = CGAL::intersection(ray, seg); + if (x) { + if (auto* xp = variant_get>(&*x)) { + auto dist = ((*xp) - M).squared_length(); + if (dist < sq_distance_along_ray) { + if (dist < (max_intersection_distance * max_intersection_distance)) { + closest_segment = seg; + closest_intersection_point = *xp; + sq_distance_along_ray = dist; + } else { + } + } + } + } + } - // intersect ray with boundary - boost::optional> closest_segment; - boost::optional> closest_intersection_point; - K::FT sq_distance_along_ray = std::numeric_limits::infinity(); - for (auto jt = bnd.edges_begin(); jt != bnd.edges_end(); ++jt) { - const auto& seg = *jt; - auto x = CGAL::intersection(ray, seg); - if (x) { - if (auto* xp = variant_get>(&*x)) { - auto dist = ((*xp) - M).squared_length(); - if (dist < sq_distance_along_ray) { - if (dist < (max_intersection_distance * max_intersection_distance)) { - closest_segment = seg; - closest_intersection_point = *xp; - sq_distance_along_ray = dist; - } else { + if (closest_intersection_point) { + return closest_intersection_point; + // constructed_segments.push_front({M, *closest_intersection_point}); + } else { + + // Loop over boundary segments, and project point onto it, take the closest + K::FT closest_distance = std::numeric_limits::infinity(); + boost::optional> closest_point; + for (auto& poly : outer_perimiter) { + for (auto jt = poly.edges_begin(); jt != poly.edges_end(); ++jt) { + auto seg = *jt; + auto Pp = seg.supporting_line().projection(M); + if (seg.has_on(Pp)) { + auto d = CGAL::squared_distance(Pp, M); + if (d < (max_projection_distance * max_projection_distance)) { + if (d < closest_distance) { + closest_distance = d; + closest_point = Pp; } } } } } - if (closest_intersection_point) { - constructed_segments.push_front({M, *closest_intersection_point}); + if (closest_point) { + return closest_point; + // constructed_segments.push_front({M, *closest_point}); } else { - // Loop over boundary segments, and project point onto it, take the closest - K::FT closest_distance = std::numeric_limits::infinity(); - boost::optional> closest_point; for (auto& poly : outer_perimiter) { - for (auto jt = poly.edges_begin(); jt != poly.edges_end(); ++jt) { - auto seg = *jt; - auto Pp = seg.supporting_line().projection(M); - if (seg.has_on(Pp)) { - auto d = CGAL::squared_distance(Pp, M); - if (d < (max_projection_distance * max_projection_distance)) { - if (d < closest_distance) { - closest_distance = d; - closest_point = Pp; - } + for (auto it = poly.begin(); it != poly.end(); ++it) { + auto Pp = *it; + auto d = CGAL::squared_distance(Pp, M); + if (d < (max_projection_distance * max_projection_distance)) { + if (d < closest_distance) { + closest_distance = d; + closest_point = Pp; } } } } if (closest_point) { - constructed_segments.push_front({M, *closest_point}); + return closest_point; + // constructed_segments.push_front({M, *closest_point}); } else { - - for (auto& poly : outer_perimiter) { - for (auto it = poly.begin(); it != poly.end(); ++it) { - auto Pp = *it; - auto d = CGAL::squared_distance(Pp, M); - if (d < (max_projection_distance * max_projection_distance)) { - if (d < closest_distance) { - closest_distance = d; - closest_point = Pp; - } - } - } - } - - if (closest_point) { - constructed_segments.push_front({M, *closest_point}); - } else { - std::cout << "Unable to find projection or intersection point for interior boundary (" << M.x() << " " << M.y() << ")" << std::endl; - } } } } } } + return boost::optional{}; + }; + + using solution_length_point_incoming = std::tuple; + std::vector solutions; + + for (auto it = G.vertices_begin(); it != G.vertices_end(); ++it) { + if (it->second.size() == 1) { + auto& M = it->first; + if (auto result = process_point(M, *it->second.begin())) { + auto d = (M - *result).squared_length(); + solutions.emplace_back(d, *result, *it->second.begin()); + } else { + std::cout << "Unable to find projection or intersection point for interior boundary (" << M.x() << " " << M.y() << ")" << std::endl; + } + } + } + + std::sort(solutions.begin(), solutions.end()); + std::list> constructed_segments; + + for (auto& [d, point, incoming] : solutions) { + if (auto result = process_point(point, incoming)) { + constructed_segments.push_front({point, *result}); + } else { + std::cout << "Unable to find projection or intersection point for interior boundary (" << M.x() << " " << M.y() << ")" << std::endl; + } } return constructed_segments;