From bea59957563d102853ec3f32c29971c088a7f8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Mar 2021 14:27:16 +0200 Subject: [PATCH] Handle "right" folds The following configurations of collinear points: x-2 x x-1 AND x+2 x x+1 cannot be handled with the typical left swap because the interval has range n-1. Instead, just manually swap like it is done when the fold is on the left (which can and is immediately detected at the beginning of the insertion event) --- .../include/CGAL/Random_polygon_2_sweep.h | 46 +++++++++++++++++++ .../CGAL/Polygon_2/Polygon_2_simplicity.h | 2 + 2 files changed, 48 insertions(+) diff --git a/Generator/include/CGAL/Random_polygon_2_sweep.h b/Generator/include/CGAL/Random_polygon_2_sweep.h index 6a059662ba6..b60b8bfdf4e 100644 --- a/Generator/include/CGAL/Random_polygon_2_sweep.h +++ b/Generator/include/CGAL/Random_polygon_2_sweep.h @@ -179,6 +179,52 @@ less_than_in_tree(Vertex_index new_edge, Vertex_index tree_edge) const m_vertex_data->point(mid), m_vertex_data->point(right))); m_vertex_data->is_simple_result = false; + + // need to handle the specific combinations: + // as the standard x;x+k swap (see below) will not work + if (m_vertex_data->edges[tree_edge.as_int()].is_left_to_right) + { + // x+1 x x+2 + // This is actually already handled in the insertion event, when the orientation returns "COPLANAR" + // but leaving the code below for completion. + if (m_vertex_data->next(mid) == left || m_vertex_data->next(mid) == right) + { + // swap mid & left + m_vertex_data->conflict1 = m_vertex_data->prev(mid); + m_vertex_data->conflict2 = left; + return true; + } + // x-2 x x-1 + else if (m_vertex_data->prev(mid) == left || m_vertex_data->prev(mid) == right) + { + // swap mid & right + m_vertex_data->conflict1 = left; + m_vertex_data->conflict2 = mid; + return true; + } + } + else // right to left + { + // x+2 x x+1 + if (m_vertex_data->next(mid) == left || m_vertex_data->next(mid) == right) + { + // swap mid & right + m_vertex_data->conflict1 = m_vertex_data->prev(mid); + m_vertex_data->conflict2 = right; + return true; + } + // x-1 x x-2 + // This is actually already handled in the insertion event, when the orientation returns "COPLANAR" + // but leaving the code below for completion. + else if (m_vertex_data->prev(mid) == left || m_vertex_data->prev(mid) == right) + { + // swap mid & left + m_vertex_data->conflict1 = right; + m_vertex_data->conflict2 = mid; + return true; + } + } + Vertex_index mid_succ = m_vertex_data->next(mid); if (mid_succ.as_int() <= (std::min)(left.as_int(), right.as_int())) { diff --git a/Polygon/include/CGAL/Polygon_2/Polygon_2_simplicity.h b/Polygon/include/CGAL/Polygon_2/Polygon_2_simplicity.h index 03a6856f162..b222b02cd08 100644 --- a/Polygon/include/CGAL/Polygon_2/Polygon_2_simplicity.h +++ b/Polygon/include/CGAL/Polygon_2/Polygon_2_simplicity.h @@ -74,6 +74,8 @@ struct Vertex_index { explicit Vertex_index(Index_t i): m_i(i) {} Index_t as_int() const {return m_i;} Vertex_index operator++() {++m_i; return *this; } + bool operator==(const Vertex_index& other) const = default; + private: Index_t m_i; };