| 2669 | } |
| 2670 | |
| 2671 | void clean_noisy_bounds(DebugWriter& debug_output, Arrangement_2& arr, SegmentLookup& segment_lookup, double threshold) { |
| 2672 | using SK = CGAL::Simple_cartesian<double>; |
| 2673 | CGAL::Cartesian_converter<K, SK> C{}; |
| 2674 | |
| 2675 | auto other = [](const Segment_2& e, const Point_2& v) { |
| 2676 | return (e.source() == v) ? e.target() : e.source(); |
| 2677 | }; |
| 2678 | |
| 2679 | auto edge_badness = [&](const Segment_2& e) -> double { |
| 2680 | auto closest = segment_lookup.n_closest_input_segments(e, 2); |
| 2681 | if (closest.size() != 2) { |
| 2682 | throw std::runtime_error("Unable to locate two nearby edges"); |
| 2683 | } |
| 2684 | |
| 2685 | auto get_dir = [&](const Segment_2& s) { |
| 2686 | auto a = C(s.source()); |
| 2687 | auto b = C(s.target()); |
| 2688 | SK::Vector_2 v = b - a; |
| 2689 | double l = std::sqrt(v.squared_length()); |
| 2690 | if (l <= 1e-12) { |
| 2691 | return std::make_pair(SK::Vector_2(0, 0), 0.); |
| 2692 | } |
| 2693 | return std::make_pair(v / l, l); |
| 2694 | }; |
| 2695 | |
| 2696 | auto [own_dir, own_length] = get_dir(e); |
| 2697 | |
| 2698 | auto angle = [&](const SK::Vector_2& ov) { |
| 2699 | double d = std::abs(own_dir * ov); |
| 2700 | if (d > 1.0) { |
| 2701 | d = 1.0; |
| 2702 | } |
| 2703 | return std::acos(d); |
| 2704 | }; |
| 2705 | |
| 2706 | double best = std::numeric_limits<double>::infinity(); |
| 2707 | for (auto& s : closest) { |
| 2708 | auto [dv, dl] = get_dir(s); |
| 2709 | best = std::min(best, angle(dv)); |
| 2710 | } |
| 2711 | return (best + 0.01) / own_length; |
| 2712 | }; |
| 2713 | |
| 2714 | size_t facet_index = 0; |
| 2715 | for (auto it = arr.faces_begin(); it != arr.faces_end(); ++it, ++facet_index) { |
| 2716 | if (!it->is_unbounded()) { |
| 2717 | std::set<std::pair<Point_2, Point_2>> to_remove; |
| 2718 | std::vector<std::pair<Point_2, Point_2>> to_insert; |
| 2719 | |
| 2720 | std::vector<Segment_2> segs; |
| 2721 | std::vector<Arrangement_2::Vertex_const_handle> vertices; |
| 2722 | std::vector<Arrangement_2::Halfedge_handle> halfedges; |
| 2723 | |
| 2724 | auto circ = it->outer_ccb(); |
| 2725 | do { |
| 2726 | auto a = circ->source()->point(); |
| 2727 | auto b = circ->target()->point(); |
| 2728 | segs.emplace_back(a, b); |
no test coverage detected