| 1789 | } |
| 1790 | |
| 1791 | void edge_slide(Graph2D<K>& G) { |
| 1792 | std::list<CGAL::Segment_2<K>> edges_to_remove, edges_to_insert; |
| 1793 | |
| 1794 | for (auto vit = G.vertices_begin(); vit != G.vertices_end(); ++vit) { |
| 1795 | auto& selected = vit->first; |
| 1796 | |
| 1797 | if (vit->second.size() >= 3) { |
| 1798 | for (auto vjt = vit->second.begin(); vjt != vit->second.end(); ++vjt) { |
| 1799 | auto& neighbour = *vjt; |
| 1800 | bool processed_neighbour = false; |
| 1801 | |
| 1802 | if (G.find(neighbour)->second.size() == 2 && !is_parallel_2degree_node(G.find(neighbour))) { |
| 1803 | auto vkt = G.find(neighbour)->second.begin(); |
| 1804 | if (selected == *vkt) { |
| 1805 | vkt++; |
| 1806 | } |
| 1807 | auto& other = *vkt; |
| 1808 | |
| 1809 | if ((other - neighbour).squared_length() < (neighbour - selected).squared_length()) { |
| 1810 | continue; |
| 1811 | } |
| 1812 | |
| 1813 | auto incoming = CGAL::Ray_2<K>(other, neighbour - other); |
| 1814 | boost::optional<CGAL::Segment_2<K>> closest_neighbouring_segment; |
| 1815 | boost::optional<CGAL::Point_2<K>> closest_intersection_point; |
| 1816 | K::FT sq_distance_along_ray = std::numeric_limits<double>::infinity(); |
| 1817 | |
| 1818 | for (auto vlt = vit->second.begin(); vlt != vit->second.end(); ++vlt) { |
| 1819 | auto& other_neighbour = *vlt; |
| 1820 | if (vlt != vjt) { |
| 1821 | CGAL::Segment_2<K> neighbouring_segment(selected, other_neighbour); |
| 1822 | auto x = CGAL::intersection(incoming, neighbouring_segment); |
| 1823 | if (x) { |
| 1824 | if (auto* xp = variant_get<CGAL::Point_2<K>>(&*x)) { |
| 1825 | auto dist = ((*xp) - other).squared_length(); |
| 1826 | if (dist < sq_distance_along_ray) { |
| 1827 | closest_neighbouring_segment = neighbouring_segment; |
| 1828 | closest_intersection_point = *xp; |
| 1829 | sq_distance_along_ray = dist; |
| 1830 | } |
| 1831 | } |
| 1832 | } |
| 1833 | } |
| 1834 | } |
| 1835 | |
| 1836 | if (closest_intersection_point && closest_neighbouring_segment) { |
| 1837 | edges_to_remove.push_back(*closest_neighbouring_segment); |
| 1838 | edges_to_remove.push_back({neighbour, selected}); |
| 1839 | edges_to_insert.push_back({closest_neighbouring_segment->source(), *closest_intersection_point}); |
| 1840 | edges_to_insert.push_back({closest_neighbouring_segment->target(), *closest_intersection_point}); |
| 1841 | edges_to_insert.push_back({neighbour, *closest_intersection_point}); |
| 1842 | |
| 1843 | processed_neighbour = true; |
| 1844 | } |
| 1845 | } |
| 1846 | if (processed_neighbour) { |
| 1847 | // Only one neigbour is processed because otherwise we obtain intersections |
| 1848 | break; |
no test coverage detected