diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_landmarks_point_location.h b/Arrangement_on_surface_2/include/CGAL/Arr_landmarks_point_location.h index 923009e4456..8db96653d1b 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_landmarks_point_location.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_landmarks_point_location.h @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -78,6 +79,16 @@ public: // Support cpp11::result_of using result_type = Result_type; +private: + using Gt2 = Geometry_traits_2; + using Left_side_category = + typename internal::Arr_complete_left_side_category::Category; + using Right_side_category = + typename internal::Arr_complete_right_side_category::Category; + using Left_or_right_sides_category = + typename Arr_two_sides_category::result; + protected: using Traits_adaptor_2 = Arr_traits_basic_adaptor_2; @@ -299,6 +310,59 @@ protected: bool& p_on_curve, bool& cv_and_seg_overlap, bool& cv_is_contained_in_seg) const; + + //! + template + std::pair + construct_segment(const Point_2& p, const Point_2& q, T const& traits, + ...) const { + X_monotone_curve_2 seg = traits.construct_x_monotone_curve_2_object()(p, q); + Comparison_result res = traits.compare_xy_2_object()(p, q); + return std::make_pair(seg, res); + } + + //*! + template + std::pair + construct_segment(const Point_2& p, const Point_2& q, T const& traits, + int) const { + X_monotone_curve_2 seg = traits.construct_x_monotone_curve_2_object()(p, q); + Comparison_result res = traits.compare_endpoints_xy_2_object()(seg); + return std::make_pair(seg, res); + } + + /*! Determines whether the $x$-coordinates of two points are equal. + */ + bool equal_x_2(const Point_2& p, const Point_2& q, + Arr_all_sides_oblivious_tag) const + { return (m_traits->compare_x_2_object()(p, q) == EQUAL); } + + /*! Determines whether the $x$-coordinates of two points are equal. + */ + bool equal_x_2(const Point_2& p, const Point_2& q, + Arr_has_identified_side_tag) const { + auto is_on_y_identification = m_traits->is_on_y_identification_2_object(); + if (is_on_y_identification(p)) { + return is_on_y_identification(q); + } + if (is_on_y_identification(q)) return false; + return (m_traits->compare_x_2_object()(p, q) == EQUAL); + } + + /*! Determines whether the $x$-coordinates of two points are equal. + */ + bool equal_x_2(const Point_2& p, const Point_2& q, + Arr_boundary_cond_tag) const { + auto param_space_in_x = m_traits->parameter_space_in_x_2_object(); + switch (param_space_in_x(p)) { + case ARR_LEFT_BOUNDARY: return (param_space_in_x(q) == ARR_LEFT_BOUNDARY); + case ARR_RIGHT_BOUNDARY: return (param_space_in_x(q) == ARR_LEFT_BOUNDARY); + case ARR_INTERIOR: return (m_traits->compare_x_2_object()(p, q) == EQUAL); + default: CGAL_error(); + } + CGAL_error(); + return false; + } }; } // namespace CGAL diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Arr_landmarks_pl_impl.h b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Arr_landmarks_pl_impl.h index 7b2020843e8..01cb50c20ae 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Arr_landmarks_pl_impl.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Arr_landmarks_pl_impl.h @@ -111,17 +111,16 @@ _walk_from_vertex(Vertex_const_handle nearest_vertex, const Point_2& p, // Create an x-monotone curve connecting the point associated with the // vertex vp and the query point p. const Point_2& vp = vh->point(); - X_monotone_curve_2 seg = - m_traits->construct_x_monotone_curve_2_object()(vp, p); - const bool seg_dir_right = - (m_traits->compare_xy_2_object()(vp, p) == SMALLER); + X_monotone_curve_2 seg; + Comparison_result res; + std::tie(seg, res) = construct_segment(vp, p, *m_traits, 0); + bool seg_dir_right = (res == SMALLER); Halfedge_around_vertex_const_circulator curr_iter = first; Halfedge_around_vertex_const_circulator next_iter = curr_iter; ++next_iter; auto is_between_cw = m_traits->is_between_cw_2_object(); // Traverse the halfedges around vp until we find the pair of adjacent // halfedges such as seg is located clockwise in between them. - do { bool eq_curr_iter, eq_next_iter; if (is_between_cw(seg, seg_dir_right, curr_iter->curve(), @@ -188,11 +187,10 @@ _find_face_around_vertex(Vertex_const_handle vh, const Point_2& p, // Create an x-monotone curve connecting the point associated with the // vertex vp and the query point p. const Point_2& vp = vh->point(); - X_monotone_curve_2 seg = - m_traits->construct_x_monotone_curve_2_object()(vp, p); - const bool seg_dir_right = - (m_traits->compare_xy_2_object()(vp, p) == SMALLER); - + X_monotone_curve_2 seg; + Comparison_result res; + std::tie(seg, res) = construct_segment(vp, p, *m_traits, 0); + bool seg_dir_right = (res == SMALLER); // Get the first incident halfedge around v and the next halfedge. Halfedge_around_vertex_const_circulator first = vh->incident_halfedges(); Halfedge_around_vertex_const_circulator curr, next; @@ -443,9 +441,10 @@ _walk_from_face(Face_const_handle face, const Point_2& np, const Point_2& p, Halfedge_set& crossed_edges) const { // Construct an x-monotone curve connecting the nearest landmark point np // to the query point p and check which CCB intersects this segment. - X_monotone_curve_2 seg = - m_traits->construct_x_monotone_curve_2_object()(np, p); - const bool p_is_left = (m_traits->compare_xy_2_object()(np, p) == LARGER); + X_monotone_curve_2 seg; + Comparison_result res; + std::tie(seg, res) = construct_segment(np, p, *m_traits, 0); + const bool p_is_left = (res == LARGER); const Halfedge_const_handle invalid_he; const Vertex_const_handle invalid_vertex; @@ -679,12 +678,12 @@ _in_case_p_is_on_edge(Halfedge_const_handle he, crossed_edges.insert(he->twin()); // Check if p equals one of the edge end-vertices. if (! he->target()->is_at_open_boundary() && - m_traits->compare_xy_2_object()(he->target()->point(), p) == EQUAL) { + m_traits->equal_2_object()(he->target()->point(), p)) { // p is the target of the current halfedge. is_target = true; } else if (! he->source()->is_at_open_boundary() && - m_traits->compare_xy_2_object()(he->source()->point(), p) == EQUAL) { + m_traits->equal_2_object()(he->source()->point(), p)) { // Take the twin halfedge, so p equals its target. he = he->twin(); is_target = true; @@ -736,11 +735,9 @@ _have_odd_intersections(const X_monotone_curve_2& cv, if (cv_left_is_closed) { // Check if the left endpoint of cv has the same x-coordinate as the // right endpoint of seg. - if (m_traits->compare_x_2_object() - (m_traits->construct_min_vertex_2_object()(cv), seg_right) == EQUAL) { - if (! p_is_left && - m_traits->compare_xy_2_object() - (m_traits->construct_min_vertex_2_object()(cv), seg_right) == EQUAL) { + auto min_p = m_traits->construct_min_vertex_2_object()(cv); + if (equal_x_2(min_p, seg_right, Left_or_right_sides_category())) { + if (! p_is_left && m_traits->equal_2_object()(min_p, seg_right)) { p_on_curve = true; return true; } @@ -761,11 +758,9 @@ _have_odd_intersections(const X_monotone_curve_2& cv, if (cv_right_is_closed) { // Check if the right endpoint of cv has the same x-coordinate as the // left endpoint of seg. - if (m_traits->compare_x_2_object() - (m_traits->construct_max_vertex_2_object()(cv), seg_left) == EQUAL) { - if (p_is_left && - m_traits->compare_xy_2_object() - (m_traits->construct_max_vertex_2_object()(cv), seg_left) == EQUAL) { + auto max_p = m_traits->construct_max_vertex_2_object()(cv); + if (equal_x_2(max_p, seg_left, Left_or_right_sides_category())) { + if (p_is_left && m_traits->equal_2_object()(max_p, seg_left)) { p_on_curve = true; return true; }