// Copyright (c) 2007,2008,2009,2010,2011 Tel-Aviv University (Israel). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // You can redistribute it and/or modify it under the terms of the GNU // General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // // // Author(s) : Idit Haran // Ron Wein #ifndef CGAL_ARR_LANDMARKS_POINT_LOCATION_H #define CGAL_ARR_LANDMARKS_POINT_LOCATION_H #include #include /*! \file * Definition of the Arr_landmarks_point_location template. */ //#define CGAL_DEBUG_LM #include #include #include #include namespace CGAL { /*! \class Arr_landmarks_point_location * A class that answers point-location queries on an arrangement using the * landmarks algorithm, namely by locating the (approximately) nearest * landmark point to the qury point and walking from it toward the query * point. * This class-template has two parameters: * Arrangement corresponds to an arrangement-on-surface instantiation. * Generator is a class that generates the set of landmarks. */ template > class Arr_landmarks_point_location { public: typedef Arrangement_ Arrangement_2; typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2; typedef Generator_ Generator; typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; typedef typename Arrangement_2::Face_const_handle Face_const_handle; typedef typename Arrangement_2::Vertex_const_iterator Vertex_const_iterator; typedef typename Arrangement_2::Halfedge_const_iterator Halfedge_const_iterator; typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; typedef typename Arrangement_2::Ccb_halfedge_const_circulator Ccb_halfedge_const_circulator; typedef typename Arrangement_2::Outer_ccb_const_iterator Outer_ccb_const_iterator; typedef typename Arrangement_2::Inner_ccb_const_iterator Inner_ccb_const_iterator; typedef typename Arrangement_2::Isolated_vertex_const_iterator Isolated_vertex_const_iterator; typedef typename Arrangement_2::Point_2 Point_2; typedef typename Arrangement_2::X_monotone_curve_2 X_monotone_curve_2; typedef Arr_point_location_result Result; typedef typename Result::Type Result_type; // Support cpp11::result_of typedef Result_type result_type; protected: typedef Arr_traits_basic_adaptor_2 Traits_adaptor_2; /*! \struct Less_halfedge_handle * Used to sort handles. */ struct Less_halfedge_handle { bool operator()(Halfedge_const_handle h1, Halfedge_const_handle h2) const { return (&(*h1) < &(*h2)); } }; typedef std::set Halfedge_set; // Data members: const Arrangement_2* p_arr; // The associated arrangement. const Traits_adaptor_2* m_traits; // Its associated traits object. Generator* lm_gen; // The associated landmark generator. bool own_gen; // Indicates whether the generator // has been locally allocated. template Result_type make_result(T t) const { return Result::make_result(t); } inline Result_type default_result() const { return Result::default_result(); } public: /*! Default constructor. */ Arr_landmarks_point_location() : p_arr(NULL), m_traits(NULL), lm_gen(NULL), own_gen(false) {} /*! Constructor given an arrangement only. */ Arr_landmarks_point_location(const Arrangement_2& arr) : p_arr(&arr), m_traits(static_cast(p_arr->geometry_traits())), lm_gen(new Generator(arr)), // allocate the landmarks generator. own_gen(true) { } /*! Constructor given an arrangement, and landmarks generator. */ Arr_landmarks_point_location(const Arrangement_2& arr, Generator* gen) : p_arr(&arr), m_traits(static_cast(p_arr->geometry_traits())), lm_gen(gen), own_gen(false) { } /*! Destructor. */ ~Arr_landmarks_point_location() { if (own_gen) { delete lm_gen; lm_gen = NULL; } } /*! Attach an arrangement object (and a generator, if supplied). */ void attach(const Arrangement_2& arr, Generator* gen = NULL) { // Keep a pointer to the associated arrangement. p_arr = &arr; m_traits = static_cast(p_arr->geometry_traits()); // Update the landmarks generator. if (gen != NULL) { // In case a generator is given, keep a pointer to it. CGAL_assertion(lm_gen == NULL); lm_gen = gen; own_gen = false; } else if (lm_gen != NULL) { // In case a generator exists internally, make sure it is attached to // the given arrangement. Arrangement_2& non_const_arr = const_cast(*p_arr); lm_gen->attach(non_const_arr); } else { // Allocate a new generator, attached to the given arrangement. lm_gen = new Generator(arr); own_gen = true; } } /*! Detach the instance from the arrangement object. */ void detach() { p_arr = NULL; m_traits = NULL; CGAL_assertion(lm_gen != NULL); if (lm_gen) lm_gen->detach(); } /*! * Locate the arrangement feature containing the given point. * \param p The query point. * \return An object representing the arrangement feature containing the * query point. This object is either a Face_const_handle or a * Halfedge_const_handle or a Vertex_const_handle. */ result_type locate(const Point_2& p) const; protected: /*! Walk from the given vertex to the query point. * \param vh The given vertex handle. * \param p The query point. * \param crossed_edges In/Out: The set of edges crossed so far. * \return An object representing the arrangement feature containing the * query point. This object is either a Face_const_handle or a * Halfedge_const_handle or a Vertex_const_handle. */ result_type _walk_from_vertex(Vertex_const_handle vh, const Point_2& p, Halfedge_set& crossed_edges) const; /*! Locate an edge around a given vertex that is the predecessor of the * curve connecting the vertex to the query point in a clockwise order. * \param vh The vertex. * \param p The query point. * \param new_vertex Output: Whether a closer vertex to p was found. * \return The desired object (a halfedge handle or a vertex handle). */ result_type _find_face_around_vertex(Vertex_const_handle vh, const Point_2& p, bool& new_vertex) const; /*! Walk from a point on a given halfedge to the query point. * \param eh The given halfedge handle. * \param np The point that the walk starts from. * \param p The query point. * \param crossed_edges In/Out: The set of edges crossed so far. * \return An object representing the arrangement feature containing the * query point. This object is either a Face_const_handle or a * Halfedge_const_handle or a Vertex_const_handle. */ result_type _walk_from_edge(Halfedge_const_handle eh, const Point_2& np, const Point_2& p, Halfedge_set& crossed_edges) const; /*! In case the arrangement's curve contained in the segment * from the nearest landmark to the query point * \param he The given halfedge handle. * \param p_is_left Is the query point the left endpoint of seg. * \param p The query point. * \param crossed_edges In/Out: The set of edges crossed so far. * \return An object representing the arrangement feature containing the * query point. This object is either a Face_const_handle or a * Halfedge_const_handle or a Vertex_const_handle. */ result_type _deal_with_curve_contained_in_segment(Halfedge_const_handle he, bool p_is_left, const Point_2& p, Halfedge_set& crossed_edges) const; /*! Walk from a point in a face to the query point. * \param fh A halfedge handle that points to the face. * \param np The point that the walk starts from. * \param p The query point. * \param crossed_edges In/Out: The set of edges crossed so far. * \return An object representing the arrangement feature containing the * query point. This object is either a Face_const_handle or a * Halfedge_const_handle or a Vertex_const_handle. */ result_type _walk_from_face(Face_const_handle fh, const Point_2& np, const Point_2& p, Halfedge_set& crossed_edges) const; /*! Find a halfedge on the given CCB that intersects the given x-monotone * curve, connecting the current landmark to the query point. * \param circ The CCB circulator. * \param seg The segment connecting the landmark and the query point. * \param p The query point. * \param p_is_left Is the query point the left endpoint of seg. * \param crossed_edges In/Out: The set of edges crossed so far. * \param is_on_edge Output: Does the query point p lies on the edge. * \param is_target Output: Is the query point p equal to the target vertex. * \param new_vertex Output: if found a closer vertex to the query point. * \param cv_is_contained_in_seg Output: Whether cv is contained inside seg. * \return A handle to the halfedge (if no intersecting edge is found, the * function returns an ivalid halfedge handle). */ Halfedge_const_handle _intersection_with_ccb(Ccb_halfedge_const_circulator circ, const X_monotone_curve_2& seg, const Point_2& p, bool p_is_left, Halfedge_set& crossed_edges, bool& is_on_edge, bool& is_target, bool& cv_is_contained_in_seg, Vertex_const_handle& new_vertex) const; /*! Return the halfedge that contains the query point. * \param he The halfedge handle. * \param crossed_edges In/Out: The set of edges crossed so far. * \param p The query point. * \param is_target Output: Is the query point p equal to the target vertex. */ Halfedge_const_handle _in_case_p_is_on_edge(Halfedge_const_handle he, Halfedge_set& crossed_edges, const Point_2& p, bool& is_target) const; /*! Check whether the given curve intersects a simple segment, which connects * the current landmark to the query point, an odd number of times. * \param cv The curve. * \param seg The segment connecting the landmark and the query point. * \param p_is_left Is the query point the left endpoint of seg. * \param p_on_curve Output: Whether p lies on cv. * \param cv_and_seg_overlap Output: Whether cv and seg overlap. * \param cv_is_contained_in_seg Output: Whether cv is contained inside seg. * \return Whether the two curves have an odd number of intersections. */ bool _have_odd_intersections(const X_monotone_curve_2& cv, const X_monotone_curve_2& seg, bool p_is_left, bool& p_on_curve, bool& cv_and_seg_overlap, bool& cv_is_contained_in_seg) const; }; } //namespace CGAL // The member-function definitions can be found under: #include #include #endif