Fixed for arrangement on sphere; cleaned up.

This commit is contained in:
Efi Fogel 2024-11-16 22:12:56 +02:00
parent ddeaeb497a
commit 54a05c2a1f
2 changed files with 84 additions and 25 deletions

View File

@ -27,6 +27,7 @@
#include <CGAL/Arr_point_location_result.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location/Arr_lm_vertices_generator.h>
#include <CGAL/Arr_tags.h>
#include <set>
@ -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<Gt2>::Category;
using Right_side_category =
typename internal::Arr_complete_right_side_category<Gt2>::Category;
using Left_or_right_sides_category =
typename Arr_two_sides_category<Left_side_category,
Right_side_category>::result;
protected:
using Traits_adaptor_2 = Arr_traits_basic_adaptor_2<Geometry_traits_2>;
@ -299,6 +310,59 @@ protected:
bool& p_on_curve,
bool& cv_and_seg_overlap,
bool& cv_is_contained_in_seg) const;
//!
template <typename T>
std::pair<X_monotone_curve_2, Comparison_result>
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 <typename T, typename = typename T::Compare_endpoints_xy_2>
std::pair<X_monotone_curve_2, Comparison_result>
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

View File

@ -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;
}