diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt
index 11522e9aff5..a47395820b0 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt
@@ -756,197 +756,207 @@ arrangement operations - see more details in the Reference Manual.
\section arr_secqueries Issuing Queries on an Arrangement
One of the most important query types defined on arrangements is
-the point-location query: Given a point, find the
-arrangement cell that contains it. Typically, the result of a
-point-location query is one of the arrangement faces, but in
-degenerate situations the query point can be located on an edge or
-coincide with a vertex.
+the point-location query: Given a point, find the arrangement
+cell that contains it. Typically, the result of a point-location
+query is one of the arrangement faces, but in degenerate situations
+the query point can be located on an edge or it may coincide with a
+vertex.
-Point-location queries are not only common in many applications,
-they also play an important role in the free insertion-functions
-(see Section \ref arr_secgl_funcs). Therefore, it is crucial to
-have the ability to answer such queries effectively for any
-arrangement instance.
+Point-location queries are common in many applications, and also
+play an important role in the incremental construction of arrangements
+(and more specifically in the free insertion-functions described in
+Section \ref arr_secgl_funcs). Therefore, it is crucial to have the
+ability to answer such queries effectively.
\subsection arr_ssecpl Point-Location Queries
-The arrangement package includes several classes (more precisely,
-class templates parameterized by an arrangement class) that model
-the `ArrangementPointLocation_2` concept. Namely, they all
-have a member function called `locate(q)` that accepts a query
-point \f$ q\f$ and result with a \cgal `Object` that wraps a handle
-to the arrangement cell containing the query point. This object can
-be assigned to either a `Face_const_handle`,
-`Halfedge_const_handle` or a `Vertex_const_handle`, depending
-on whether the query point is located inside a face, on an edge or
-on a vertex.
+The `Arrangement_2` class template does not support point-location
+queries directly, as the arrangement representation is decoupled from
+the geometric algorithms that operate on it. The 2D Arrangements
+package includes a set of classe templates that are capable of
+answering such queries; all are models of the concept
+`ArrangementPointLocation_2`. Each model employs a different
+algorithm or strategy for answering queries. A model of this
+concept must define the `locate()` member function, which accepts
+an input query-point and returns an object that represents the
+arrangement cell that contains this point. This object is is type
+`Arr_point_location_result::%Type`---a discriminated
+union container of the bounded types `Vertex_const_handle`,
+`Halfedge_const_handle`, or `Face_const_handle`. Depending on
+whether the query point is located inside a face, on an edge, or on a
+vertex, the appropriate handle can be obtained with value retrieval
+by `boost::get` as demonstrated in the example below.
Note that the handles returned by the `locate()` functions are
-`const` (non-mutable) handles. If necessary, such handles may
-be casted to mutable handles using the static functions
-`Arrangement_on_surface_2::non_const_handle()` provided by the
-arrangement class.
+non-mutable (`const`). If necessary, such handles may
+be cast to mutable handles using the `non_const_handle()` methods
+`Arrangement_2::non_const_handle()` provided by the
+`Arrangement_2` class.
-An instance of any point-location class must be attached to an
-`Arrangement_on_surface_2` instance so we can use it to issue point-location
-queries. This attachment can be performed when the point-location
-instance is constructed, or at a later time, using the `init(arr)`
-method, where `arr` is the attached `Arrangement_on_surface_2` instance.
-In this chapter we always use the first option.
+An object `pl` of any point-location class must be attached to an
+`Arrangement_2` object `arr` before it is used to answer
+point-location queries on `arr`. This attachment can be performed
+when `pl` is constructed or at a later time using the
+`pl.init(arr)` call.
-The following function template, which can be found in the example
-file `point_location_utils.h`, accepts a point-location object
-(whose type can be any of the models to the
-`ArrangementPointLocation_2` concept) and a query point, and
-prints out the result of the point-location query for the given
-point. Observe how we use the function `assign()` is order
-to cast the resulting `Object` into a handle to an arrangement
-feature. The point-location object `pl` is assumed to be already
-associated with an arrangement:
+The function template listed below accepts a point-location object,
+the type of which is a model of the `ArrangementPointLocation_2`
+concept, and a query point. The function template issues a
+point-location query for the given point, and prints out the result.
+It is defined in the header file `point_location_utils.h`.
+\anchor lst_pl
\code
-template
-void point_location_query
- (const PointLocation& pl,
- const typename PointLocation::Arrangement_on_surface_2::Point_2& q)
+template
+void locate_point(const PointLocation& pl,
+ const typename PointLocation::Arrangement_2::Point_2& q)
{
- // Perform the point-location query.
- CGAL::Object obj = pl.locate (q);
+ typedef PointLocation Point_location;
+ typedef typename Point_location::Arrangement_2 Arrangement_2;
+ typename CGAL::Arr_point_location_result::Type obj =
+ pl.locate(q);
// Print the result.
- typedef typename PointLocation::Arrangement_on_surface_2 Arrangement_on_surface_2;
+ print_point_location(q, obj);
+}
+\endcode
- typename Arrangement_on_surface_2::Vertex_const_handle v;
- typename Arrangement_on_surface_2::Halfedge_const_handle e;
- typename Arrangement_on_surface_2::Face_const_handle f;
+The function template `locate_point()` calls an instance of the
+function template `print_point_location()`, which inserts the
+result of the query into the standard output-stream. It is listed
+below, and defined in the header file `point_location_utils.h`.
+Observe how the function `boost::get()` is used to cast the
+resulting object into a handle to an arrangement feature. The
+point-location object `pl` is assumed to be already attached
+to an arrangement.
- std::cout << "The point " << q << " is located ";
- if (CGAL::assign (f, obj)) {
- // q is located inside a face:
- if (f->is_unbounded())
- std::cout << "inside the unbounded face." << std::endl;
- else
- std::cout << "inside a bounded face." << std::endl;
- } else if (CGAL::assign (e, obj)) {
- // q is located on an edge:
- std::cout << "on an edge: " << e->curve() << std::endl;
- } else if (CGAL::assign (v, obj)) {
- // q is located on a vertex:
- if (v->is_isolated())
- std::cout << "on an isolated vertex: " << v->point() << std::endl;
- else
- std::cout << "on a vertex: " << v->point() << std::endl;
- } else {
- CGAL_assertion_msg (false, "Invalid object.");
- }
+\code
+template
+void
+print_point_location
+(const typename PointLocation::Arrangement_2::Point_2& q
+ typename CGAL::Arr_point_location_result::Type obj)
+{
+ typedef Arrangement_ Arrangement_2;
+
+ 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;
+
+ const Vertex_const_handle* v;
+ const Halfedge_const_handle* e;
+ const Face_const_handle* f;
+
+ std::cout << "The point (" << q << ") is located ";
+ if (f = boost::get(&obj)) // located inside a face
+ std::cout << "inside "
+ << (((*f)->is_unbounded()) ? "the unbounded" : "a bounded")
+ << " face." << std::endl;
+ else if (e = boost::get(&obj)) // located on an edge
+ std::cout << "on an edge: " << (*e)->curve() << std::endl;
+ else if (v = boost::get(&obj)) // located on a vertex
+ std::cout << "on " << (((*v)->is_isolated()) ? "an isolated" : "a")
+ << " vertex: " << (*v)->point() << std::endl;
+ else CGAL_error_msg("Invalid object.");
}
\endcode
\subsection arr_sssecpl_strat Choosing a Point-Location Strategy
-Each of the various point-location classes employs a different
-algorithm or strategy\cgalFootnote{We use the term strategy following the design pattern taxonomy \cite cgal:ghjv-dpero-95.}
+Each of the various point-location class templates employs a different
+algorithm or strategy\cgalFootnote{We use the term strategy
+is borrowed from the design-pattern taxonomy \cite cgal:ghjv-dpero-95, Chapter 5.}
for answering queries:
-- `Arr_naive_point_location` locates the query
-point naively, by exhaustively scanning all arrangement cells.
-
- `Arr_walk_along_a_line_point_location`
-simulates a traversal, in reverse order, along an imaginary vertical
-ray emanating
-from the query point: It starts from the unbounded face of the
-arrangement and moves downward toward the query point until
-locating the arrangement cell containing it.
+
- `Arr_naive_point_location` employes the
+ naive strategy. It locates the query point naively,
+ exhaustively scanning all arrangement cells.
+ %
+
- `Arr_walk_along_a_line_point_location`} employs
+ the walk-along-a-line (or walk for short) strategy.
+ It simulates a traversal, in reverse order, along an imaginary
+ vertical ray emanating from the query point. It starts from the
+ unbounded face of the arrangement and moves downward toward the
+ query point until locating the arrangement cell containing it.
- `Arr_landmarks_point_location`
-uses a set of "landmark" points whose location in the
-arrangement is known. Given a query point, it uses a Kd-tree to
-find the nearest landmark and then traverses the straight line
-segment connecting this landmark to the query point.
-There are various ways to select the landmark set in the
-arrangement, determined by the `Generator` template parameter.
-By default, the generator
-class `Arr_landmarks_vertices_generator` is used and the
-arrangement vertices are the selected landmarks, but other
-landmark generators, such as sampling random points or
-choosing points on a grid, are also available; see the
-Reference Manual for more details.
+ uses a set of landmark points the location of which in the
+ arrangement is known. It employs the
+ landmark strategy. Given a query point, it uses a
+ nearest-neighbor search-structure (a Kd-tree is used by default)
+ to find the nearest landmark and then traverses the straight-line
+ segment connecting this landmark to the query point.
+
+ There are various ways to select the landmark set in the
+ arrangement. The selection is governed by the `Generator`
+ template parameter. The default generator class, namely
+ `Arr_landmarks_vertices_generator`, selects all the vertices of
+ the attached arrangement as landmarks. Additional generators that
+ select the set in other ways, such as by sampling random
+ points or choosing points on a grid, are also available; see the
+ Reference Manual for more details.
+
+ The landmark strategy requires that the type of the attached
+ arrangement be an instance of the `Arrangement_2`
+ class template, where the `Traits` parameter is substituted with
+ a geometry-traits class that models the
+ `ArrangementLandmarkTraits_2` concept, which refines the basic
+ `ArrangementBasicTraits_2` concept; see
+ Section \ref arr_sssectr_lanmarks_concept for details. Most traits
+ classes included in the 2D Arrangement package are models of
+ this refined concept.
- `Arr_trapezoid_ric_point_location` implements
-a point location algorithm presented by Seidel \cite s-sfira-91, which uses the
-randomized incremental construction described by Mulmuley \cite m-fppa-90 (see
-also [\cite bkos-cgaa-00 Chapter 6). The
-arrangement faces are decomposed into simpler cells of constant
-complexity known as pseudo-trapezoids and a search-structure
-(a directed acyclic graph) is constructed on top of these cells,
-allowing to locate the pseudo-trapezoid (hence the arrangement
-cell) containing a query point in logarithmic time.
+ Mulmuley's point-location algorithm \cite m-fppa-90; see
+ also \cite bkos-cgaa-00, Chapter 6. The arrangement faces are
+ decomposed into simpler cells each of constant complexity, known as
+ pseudo-trapezoids, and a search structure (a directed acyclic
+ graph) is constructed on top of these cells, facilitating the search
+ of the pseudo trapezoid (hence the arrangement cell) containing a
+ query point in expected logarithmic time. The trapezoidal map and
+ the search structure are built by a algorithm (RIC).
-The main advantage of the first two strategies is that they do not
-require any extra data, so the respective classes just store a
-pointer to an arrangement object and operate directly on it.
-Attaching such point-location objects to an existing arrangement
-has virtually no running-time cost at all, but the query time is
-linear in the size of the arrangement (the performance of the
-"walk" strategy is much better in practice, but its worst-case
-performance is linear). Using these strategies is therefore
-recommended only when a relatively small number of point-location
-queries are issued by the application, or when the arrangement is
-constantly changing (i.e., changes in the arrangement structure
-are more frequent than point-location queries).
+The first two strategies do not require any extra data. The class
+templates that implement them store a pointer to an arrangement object
+and operate directly on it. Attaching such point-location objects to
+an existing arrangement has virtually no running-time cost at all, but
+the query time is linear in the size of the arrangement (the
+performance of the walk strategy is much better in practice, but
+its worst-case performance is linear). Using these strategies is
+therefore recommended only when a relatively small number of
+point-location queries are issued by the application, or when the
+arrangement is constantly changing (That is, changes in the arrangement
+structure are more frequent than point-location queries).
On the other hand, the landmarks and the trapezoid RIC strategies
require auxiliary data structures on top of the arrangement, which
they need to construct once they are attached to an arrangement
object and need to keep up-to-date as this arrangement changes.
The data structure needed by the landmarks strategy can be constructed
-in \f$ O(N \log N)\f$ time (where \f$ N\f$ is the overall number of edges in
-the arrangement), whereas the construction of the data structure needed
-by the trapezoid RIC strategy takes expected \f$ O(N \log N)\f$, but
-may require several rebuilds. As shown in \cite hkh-iiplgtds-12, one can
-expect only a small number of rebuilds.
-In practice, the construction needed by the landmark algorithm is
-significantly faster.
-In addition, although both
-resulting data structures are asymptotically linear in size, the
-Kd-tree that the landmark algorithm stores needs significantly
-less memory.
+in \f$ O(N \log N) \f$ time, where \f$ N \f$ is the overall number of edges in
+the arrangement, but the constant hidden in the \f$ O() \f$ notation for the
+trapezoidal map RIC strategy is much larger. Thus, construction needed
+by the landmark algorithm is in practice significantly faster than the
+construction needed by the trapezoidal map RIC strategy. In addition,
+although both resulting data structures are asymptotically linear in
+size, using a Kd-tree as the nearest-neighbor search-structure that
+the landmark algorithm stores significantly reduces memory consumption.
+The trapezoidal map RIC algorithm has expected logarithmic query time,
+while the query time for the landmark strategy may be as large as
+linear. In practice however, the query times of both strategies are
+competitive. For a detailed experimental comparison
+see \cite hh-eplca-05
-We note that the trapezoid RIC algorithm guarantees a
-logarithmic query time for any scenario
-making it advantageous comparing to other strategies.
-The query time of the landmarks strategy, on the other hand,
-is only logarithmic on average - and we may have
-scenarios where the query time can be linear.
-In practice, in many scenarios
-the query times of both strategies are competitive. For a detailed
-experimental comparison, see \cite hh-esplp-08.
-
-Another advantageous feature of the trapezoid RIC strategy
-when compared with other methods
-is the unbounded curves support.
-Currently, this is the most efficient strategy
-suitable for general unbounded subdivisions.
-
-The main drawback in the current implementation of the landmark
-strategy, compared to the trapezoidal RIC strategy, is that while
-the updating the auxiliary data structures
-related to the trapezoidal decomposition is done very efficiently,
-the Kd-tree maintained by the landmark algorithm needs to be
-frequently rebuilt as the arrangement changes. In addition, using
-the landmark point-location class adds some extra requirement
-from the traits class (that is, the traits class should be a model
-of a refined concept `ArrangementLandmarkTraits_2`; see
-Section \ref arr_sectraits for the details). However, most
-built-in traits classes that come with the \cgal public release
-support these extra operations.
-
-It is therefore recommended to use the
-`Arr_landmarks_point_location` class when the application
-frequently issues point-location queries on a bounded
-arrangement that only seldom changes. If the arrangement
-consists of unbounded curves or is more
-dynamic and is frequently going through changes, the
-`Arr_trapezoid_ric_point_location` class should be the
-selected point-location strategy.
+Updating the auxiliary data structures of the trapezoidal map RIC
+algorithm is done very efficiently. On the other hand, updating the
+nearest-neighbor search-structure of the landmark algorithm may consume
+more time when the arrangement changes frequently, especially when
+a Kd-tree is used, as it must be rebuilt each time the arrangement
+changes. It is therefore recommended that the
+`Arr_landmarks_point_location` class template be used when the
+application frequently issues point-location queries on an arrangement
+that only seldom changes. If the arrangement is more dynamic and is
+frequently going through changes, the `Arr_trapezoid_ric_point_location`
+class template should be the selected point-location strategy.
\subsection arr_sssecpl_ex An Example
@@ -954,135 +964,136 @@ selected point-location strategy.
The arrangement of line segments, as constructed in `point_location_example.cpp`, `vertical_ray_shooting.cpp`, and `batched_point_location.cpp`. The arrangement vertices are drawn as small discs, while the query points \f$ q_1, \ldots, q_6\f$ are marked with crosses.
\cgalFigureEnd
-The following program constructs a simple arrangement of five line
+The program listed below constructs a simple arrangement of five line
segments that form a pentagonal face, with a single isolated
-vertex in its interior, as depicted in \cgalFigureRef{arr_figex_5}
-(the arrangement construction is performed by the function
-`construct_segment_arr()` whose listing is omitted here and
-can be found in `point_location_utils.h`).
-It then employs the naive and the landmark strategies to issue
-several point-location queries on this arrangement:
+vertex in its interior, as depicted in Figure \cgalFigureRef{arr_figex_5}.
+Notice that we use the same arrangement structure in the next
+three example programs. The arrangement construction is performed by
+the function `construct_segment_arr()` defined in the heade file
+`point_location_utils.h`. (Its listing is omitted here.) The
+program employs the naive and the landmark strategies to issue
+several point-location queries on this arrangement.
\cgalExample{Arrangement_on_surface_2/point_location_example.cpp}
-Note that the program uses the auxiliary
-`point_location_query()` function template to nicely print the
-result of each query. This function can be found in the header file
-`point_location_utils.h`.
+Note that the program uses the `locate_point()` function template
+to locate a point and nicely print the result of each query; see
+\ref lst_pl "here".
\subsection arr_ssecray_shoot Vertical Ray Shooting
Another important query issued on arrangements is the vertical
ray-shooting query: Given a query point, which arrangement feature
-do we encounter if we shoot a vertical ray emanating upward (or
-downward) from this point? In the general case the ray hits an
-edge, but it is possible that it hits a vertex, or that the
-arrangement does not have any feature lying directly above (or
-below) the query point.
+do we encounter by a vertical ray shot upward (or downward) from this
+point? In the general case the ray hits an edge, but it is possible
+that it hits a vertex, or that the arrangement does not have any
+vertex or edge lying directly above (or below) the query point.
-All point-location classes listed in the previous section are also models
-of the `ArrangementVerticalRayShoot_2` concept. That is, they all
-have member functions called `ray_shoot_up(q)` and
-`ray_shoot_down(q)` that accept a query point \f$ q\f$ and output a
-\cgal `Object`. This can be assigned to either a
-`Halfedge_const_handle` or to a `Vertex_const_handle`.
-Alternatively, the returned value is a `Face_const_handle`
-for the unbounded face of the arrangement, in case there is no edge
-or vertex lying directly above (or below) \f$ q\f$.
+All point-location classes listed in the previous section are also
+models of the `ArrangementVerticalRayShoot_2` concept. That is,
+they all have member functions called `ray_shoot_up(q)` and
+`ray_shoot_down(q)` that accept a query point `q`. These functions
+output an object of type type
+`Arr_point_location_result::%Type`---a discriminated
+union container of the bounded types `Vertex_const_handle`,
+`Halfedge_const_handle`, or `Face_const_handle`. The latter type
+is used for the unbounded face of the arrangement, in case there is no
+edge or vertex lying directly above (or below) `q`.
-The following function template, `vertical_ray_shooting_query()`,
-which also located in the header file `point_location_utils.h`,
-accepts a vertical ray-shooting
-object, whose type can be any of the models to the
-`ArrangementVerticalRayShoot_2` concept and prints out the
-result of the upward vertical ray-shooting operations from a given
-query point. The ray-shooting object `vrs` is assumed to be
-already associated with an arrangement:
+The function template `vertical_ray_shooting_query()` listed
+below accepts a vertical ray-shooting object, the type of which
+models the `ArrangementVerticalRayShoot_2` concept. It exports
+the result of the upward vertical ray-shooting operation from a
+given query point to the standard output-stream. The ray-shooting
+object `vrs` is assumed to be already attached to an arrangement.
+The function template is defined in the header file
+`point_location_utils.h.
\code
-template
-void vertical_ray_shooting_query
- (const VerticalRayShoot& vrs,
- const typename VerticalRayShoot::Arrangement_on_surface_2::Point_2& q)
+template
+void shoot_vertical_ray(const RayShoot& vrs,
+ const typename RayShoot::Arrangement_2::Point_2& q)
{
+ typedef RayShoot Vertical_ray_shooting;
+
// Perform the point-location query.
- CGAL::Object obj = vrs.ray_shoot_up (q);
+ typename Vertical_ray_shooting::result_type obj = vrs.ray_shoot_up(q);
// Print the result.
- typedef typename VerticalRayShoot::Arrangement_on_surface_2 Arrangement_on_surface_2;
-
- typename Arrangement_on_surface_2::Vertex_const_handle v;
- typename Arrangement_on_surface_2::Halfedge_const_handle e;
- typename Arrangement_on_surface_2::Face_const_handle f;
-
- std::cout << "Shooting up from " << q << " : ";
- if (CGAL::assign (e, obj)) {
- // We hit an edge:
- std::cout << "hit an edge: " << e->curve() << std::endl;
- } else if (CGAL::assign (v, obj)) {
- // We hit a vertex:
- if (v->is_isolated())
- std::cout << "hit an isolated vertex: " << v->point() << std::endl;
- else
- std::cout << "hit a vertex: " << v->point() << std::endl;
- } else if (CGAL::assign (f, obj)) {
- // We did not hit anything:
- CGAL_assertion (f->is_unbounded());
+ typedef typename Vertical_ray_shooting::Arrangement_2 Arrangement_2;
+ 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;
+ const Vertex_const_handle* v;
+ const Halfedge_const_handle* e;
+ const Face_const_handle* f;
+
+ std::cout << "Shooting up from (" << q << ") : ";
+ if (v = boost::get(&obj)) // we hit a vertex
+ std::cout << "hit " << (((*v)->is_isolated()) ? "an isolated" : "a")
+ << " vertex: " << (*v)->point() << std::endl;
+ else if (e = boost::get(&obj)) // we hit an edge
+ std::cout << "hit an edge: " << (*e)->curve() << std::endl;
+ else if (f = boost::get(&obj)) \{ // we hit nothing
+ CGAL_assertion((*f)->is_unbounded());
std::cout << "hit nothing." << std::endl;
- } else {
- CGAL_assertion_msg (false, "Invalid object.");
- }
+ else CGAL_error();
}
\endcode
-The following program uses the auxiliary function listed above to
-perform vertical ray-shooting queries on an arrangement.
-The arrangement and the query points are exactly the same as in
-`point_location_example.cpp` (see \cgalFigureRef{arr_figex_5}):
+The program below uses the function template listed above to
+perform vertical ray-shooting queries on an arrangement. The
+arrangement and the query points are exactly the same as in
+`point_location.cpp`; see \cgalFigureRef{arr_figex_5}.
\cgalExample{Arrangement_on_surface_2/vertical_ray_shooting.cpp}
The number type we use in this example is \cgal's built-in
-`MP_Float` type which is a floating-point number with an
-unbounded mantissa and a 32-bit exponent. It supports construction from an
-integer or from a machine `float` or `double` and performs additions,
-subtractions and multiplications in an exact number.
+`MP_Float` type, which is a floating-point number with an
+unbounded mantissa and a 32-bit exponent. It supports construction
+from an integer or from a machine `float` or `double` and
+performs additions, subtractions and multiplications in an exact
+number.
\subsection arr_ssecbatched_pl Batched Point-Location
Suppose that at a given moment our application has to issue a
relatively large number \f$ m\f$ of point-location queries on a
-specific arrangement instance. It is possible of course to define
-a point-location object and to issue separate queries on the
-arrangement. However, as explained in Section \ref arr_ssecpl,
+specific arrangement object. Naturally, It is possible to define
+a point-location object and use it to issue separate queries on
+the arrangement. However, as explained in Section \ref arr_ssecpl
choosing a simple point-location strategy (either the naive or
the walk strategy) means inefficient queries, while the more
sophisticated strategies need to construct auxiliary structures
that incur considerable overhead in running time.
-On the other hand, the arrangement package includes a free
-`locate()` function that accepts an arrangement a range of
+Alternatively, the 2D Arrangement package includes a free
+`locate()` function that accepts an arrangement and a range of
query points as its input and sweeps through the arrangement to
locate all query points in one pass. The function outputs the query
-results as pairs, where each pair is comprised of a query point
-and a \cgal `Object` that represents the cell containing the
-point (see Section \ref arr_ssecpl). The output pairs are
-sorted in increasing \f$ xy\f$-lexicographical order of the query point.
+results as pairs, where each pair consists of a query point
+and a discriminated union container, which represents the
+cell containing the point; see Section \ref arr_ssecpl. The output
+pairs are sorted in increasing $xy$-lexicographical order of the
+query point.
-The batched point-location operation can be performed in
-\f$ O\left((m+N)\log{(m+N)}\right)\f$ time, where \f$ N\f$ is the number of
-edges in the arrangement. This means that when the number \f$ m\f$ of
+The batched point-location operation is carried out by sweeping the
+arrangement. Thus, it takes \f$ O((m+N)\log{(m+N)}) \f$ time, where \f$ N \f$
+is the number of edges in the arrangement. Issuing separate queries
+exploiting a point-location strategy with logarithmic query time
+per query, such as the trapezoidal map RIC strategy (see
+Section \ref arr_sssecpl_strat), is asymptotically more
+efficient. However, experiments show that when the number \f$ m \f$ of
point-location queries is of the same order of magnitude as \f$ N\f$,
-this operation is more efficient than issuing separate queries.
-This suggestion is also backed up by experimental results.
-Moreover, the batched point-location operation is also
-advantageous as it does not have to construct and maintain
-additional data structures.
+the batched point-location operation is more efficient in practice.
+One of the reasons for the inferior performance of the alternative
+(asymptotically faster) procedures is the necessity to construct
+and maintain complex additional data structures.
-The following program issues a batched point-location query, which
+The program below issues a batched point-location query, which
is essentially equivalent to the six separate queries performed in
-`point_location_example.cpp` (see Section \ref arr_ssecpl):
+`point_location_example.cpp`; see Section \ref arr_ssecpl.
\cgalExample{Arrangement_on_surface_2/batched_point_location.cpp}
@@ -3266,8 +3277,8 @@ segments, as depicted in \cgalFigureRef{arr_figex_24}, while maintaining
the curve history. The example demonstrates the usage of the special
traversal functions. It also shows how to issue point-location queries
on the resulting arrangement, using the auxiliary function
-`point_location_query()` defined in the header file
-`point_location_utils.h` (see also Section \ref arr_ssecpl).
+`locate_point()` defined in the header file
+`point_location_utils.h`; see also Section \ref arr_ssecpl.
\cgalExample{Arrangement_on_surface_2/curve_history.cpp}
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_batched_point_location.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_batched_point_location.h
index fb52bd5c7de..8767539a534 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_batched_point_location.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_batched_point_location.h
@@ -6,10 +6,10 @@ namespace CGAL {
The function `locate` performs a batched point-location operation on a
given arrangement. It accepts a range of query points, and locates each
point in the arrangement. The query results are returned through the output
-iterator. Each result is given as a pair of the query point and an object
-representing the arrangement feature that contains it, namely an
-`Object` that may be either `Face_const_handle`,
-`Halfedge_const_handle`, or `Vertex_const_hanlde`. The resulting
+iterator. Each query result is given as a pair of the query point and an
+object representing the arrangement feature that contains it, namely a
+discriminated union container of the bounded types`Face_const_handle`,
+`Halfedge_const_handle`, and `Vertex_const_hanlde`. The resulting
pairs in the output sequence are sorted in increasing \f$ xy\f$-lexicographical
order of the query points. The function returns a past-the-end iterator of
the output sequence.
@@ -17,17 +17,30 @@ the output sequence.
\cgalHeading{Requirements}
-- `InputIterator::value_type` must be `Traits::Point_2`.
-
- `OutputIterator::value_type` must be
-`std::pair`.
-
+`InputIterator::value_type` must be `Arrangement_2::Point_2`.
+`OutputIterator::value_type` must be convertible to
+`std::pair::%Type>`.
+
+
+\cgalHeading{A Note on Backwards Compatibility}
+This function used to return `CGAL::Object` up to
+\cgal version 4.2. Starting with \cgal version 4.3 the return type
+is determined by a metafunction. To preserve backwards compatibility
+`CGAL::Object` can be constructed from the new return type
+implicitly, but switching to the new style is recommended. To enable
+the old style without any overhead, the macro
+`CGAL_ARR_POINT_LOCATION_VERSION` can be defined to 1 before any
+\cgal header is included.
+
+\sa `CGAL::Arr_point_location_result`
+\sa `CGAL_ARR_POINT_LOCATION_VERSION`
*/
template
+typename InputIterator, typename OutputIterator>
OutputIterator locate (const Arrangement_2& arr,
-PointsIterator points_begin,
-PointsIterator points_end,
+InputIterator points_begin,
+InputIterator points_end,
OutputIterator oi);
} /* namespace CGAL */
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_circle_segment_traits_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_circle_segment_traits_2.h
index a4e962379ad..c8cae637b6f 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_circle_segment_traits_2.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_circle_segment_traits_2.h
@@ -22,12 +22,12 @@ and segments to have rational coordinates.
The nested `Point_2` type defined by the traits class is therefore
different than the `Kernel::Point_2` type. Its coordinates are
of type `CoordNT`, which an instantiation of
-`CGAL::Sqrt_extension` where `NT = ROOT = Kernel::FT`.
+`Sqrt_extension` where `NT = ROOT = Kernel::FT`.
Moreover, the third and fourth (hidden) template parameters of
-`CGAL::Sqrt_extension` are set to `CGAL::Tag_true`, which
+`Sqrt_extension` are set to `CGAL::Tag_true`, which
enables efficient comparison among different extensions.
-For more details see the documentation of \ref ::CGAL::Sqrt_extension
+For more details see the documentation of `Sqrt_extension`.
While `Arr_circle_segment_traits_2` models the concept
`ArrangementDirectionalXMonotoneTraits_2`, the implementation of
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_landmarks_point_location.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_landmarks_point_location.h
index f021238cd73..e97890e2da3 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_landmarks_point_location.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_landmarks_point_location.h
@@ -50,6 +50,11 @@ insertions of curves and not deletions of them.
\cgalModels `ArrangementPointLocation_2`
\cgalModels `ArrangementVerticalRayShoot_2`
+\sa `ArrangementPointLocation_2`
+\sa `ArrangementVerticalRayShoot_2`
+\sa `CGAL::Arr_point_location_result`
+\sa `CGAL_ARR_POINT_LOCATION_VERSION`
+
*/
template< typename Arrangement, typename Generator >
class Arr_landmarks_point_location {
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_naive_point_location.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_naive_point_location.h
index bc49bee67a5..490b967a9ca 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_naive_point_location.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_naive_point_location.h
@@ -16,6 +16,11 @@ time-consuming process when applied to dense arrangements.
\cgalModels `ArrangementPointLocation_2`
\cgalModels `ArrangementVerticalRayShoot_2`
+\sa `ArrangementPointLocation_2`
+\sa `ArrangementVerticalRayShoot_2`
+\sa `CGAL::Arr_point_location_result`
+\sa `CGAL_ARR_POINT_LOCATION_VERSION`
+
*/
template< typename Arrangement >
class Arr_naive_point_location {
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_point_location_result.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_point_location_result.h
new file mode 100644
index 00000000000..5877dda0ff6
--- /dev/null
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_point_location_result.h
@@ -0,0 +1,49 @@
+/*!
+\ingroup PkgArrangement2PointLocation
+
+The macro `CGAL_ARR_POINT_LOCATION_VERSION` can be used to configure
+the point-location query API. In particular, it determines which version
+of the result type of the point-location and vertical ray-shooting queries
+should be used by models of the concepts `ArrangementPointLocation_2`
+and `ArrangementVerticalRayShoot_2`, and by the free function
+`locate`. The `CGAL_ARR_POINT_LOCATION_VERSION` should be defined before any \cgal header
+is included.
+
+`CGAL_ARR_POINT_LOCATION_VERSION` == 1, the result type is set to be `CGAL::Object`.
+`CGAL_ARR_POINT_LOCATION_VERSION` == 2, the result type is set to be
+`boost::variant`, where `Vertex_const_handle`, `Halfedge_const_handle`, and
+`Face_const_handle` are the corresponding nested types in an `Arrangement_2` instance.
+
+
+\sa `ArrangementPointLocation_2`
+\sa `ArrangementVerticalRayShoot_2`
+\sa `CGAL::Arr_point_location_result`
+*/
+#define CGAL_ARR_POINT_LOCATION_VERSION
+
+namespace CGAL {
+
+/*!
+\ingroup PkgArrangement2PointLocation
+
+A binary metafunction to determine the return type of a point-location
+or vertical ray-shoot query.
+
+\tparam Arrangement must be an instance of the `Arrangement` class template.
+
+\sa `ArrangementPointLocation_2`
+\sa `ArrangementVerticalRayShoot_2`
+\sa `CGAL::Arr_naive_point_location`
+\sa `CGAL::Arr_walk_along_line_point_location`
+\sa `CGAL::Arr_landmarks_point_location`
+\sa `CGAL::Arr_trapezoid_ric_point_location`
+\sa `CGAL_ARR_POINT_LOCATION_VERSION`
+*/
+template
+class Arr_point_location_result
+{
+public:
+ /// The type of a point-location or vertical ray-shoot query return type.
+ typedef Hidden_type Type;
+}; /* end Arr_walk_along_line_point_location */
+} /* end namespace CGAL */
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_trapezoid_ric_point_location.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_trapezoid_ric_point_location.h
index b63daee4b2a..9a561424e3f 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_trapezoid_ric_point_location.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_trapezoid_ric_point_location.h
@@ -29,6 +29,11 @@ This strategy supports arbitrary subdivisions, including unbounded ones.
\cgalModels `ArrangementPointLocation_2`
\cgalModels `ArrangementVerticalRayShoot_2`
+\sa `ArrangementPointLocation_2`
+\sa `ArrangementVerticalRayShoot_2`
+\sa `CGAL::Arr_point_location_result`
+\sa `CGAL_ARR_POINT_LOCATION_VERSION`
+
*/
template< typename Arrangement >
class Arr_trapezoid_ric_point_location {
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_walk_along_line_point_location.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_walk_along_line_point_location.h
index 1cf854a1253..4037b4030ec 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_walk_along_line_point_location.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_walk_along_line_point_location.h
@@ -26,6 +26,11 @@ of issued queries is not large.
\cgalModels `ArrangementPointLocation_2`
\cgalModels `ArrangementVerticalRayShoot_2`
+\sa `ArrangementPointLocation_2`
+\sa `ArrangementVerticalRayShoot_2`
+\sa `CGAL::Arr_point_location_result`
+\sa `CGAL_ARR_POINT_LOCATION_VERSION`
+
*/
template< typename Arrangement >
class Arr_walk_along_line_point_location {
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementPointLocation_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementPointLocation_2.h
index d17831c1165..c0501a129b1 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementPointLocation_2.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementPointLocation_2.h
@@ -3,18 +3,35 @@
\ingroup PkgArrangement2Concepts
\cgalConcept
-A model of the `ArrangementPointLocation_2` concept can be attached to an `Arrangement_2`
-instance and answer point-location queries on this arrangement. Namely, given
-a `Arrangement_2::Point_2` object, representing a point in the plane,
-it returns the arrangement cell containing it. In the general case, the
-query point is contained inside an arrangement face, but in degenerate
-situations it may lie on an edge or coincide with an arrangement vertex.
+A model of the `ArrangementPointLocation_2` concept can answer point-location queries on
+an arrangement attached to it. Namely, given a `Arrangement_2::Point_2`
+object, representing a point in the plane, it returns the arrangement cell
+containing it. In the general case, the query point is contained inside an
+arrangement face, but in degenerate situations it may lie on an edge or
+coincide with an arrangement vertex.
+
+\cgalHeading{A note on Backwards compatibility}
+The `locate` member function used to return `CGAL::Object` up to
+\cgal version 4.2. Starting with \cgal version 4.3 the return type
+is determined by a metafunction. To preserve backwards compatibility
+`CGAL::Object` can be constructed from the new return types
+implicitly, but switching to the new style is recommended. To enable
+the old style without any overhead, the macro
+`CGAL_ARR_POINT_LOCATION_VERSION` can be defined to 1 before any
+\cgal header is included.
\cgalHasModel `CGAL::Arr_naive_point_location`
\cgalHasModel `CGAL::Arr_walk_along_line_point_location`
\cgalHasModel `CGAL::Arr_trapezoid_ric_point_location`
\cgalHasModel `CGAL::Arr_landmarks_point_location`
+\sa `CGAL::Arr_naive_point_location`
+\sa `CGAL::Arr_walk_along_line_point_location`
+\sa `CGAL::Arr_trapezoid_ric_point_location`
+\sa `CGAL::Arr_landmarks_point_location`
+\sa `CGAL::Arr_point_location_result`
+\sa `CGAL_ARR_POINT_LOCATION_VERSION`
+
*/
class ArrangementPointLocation_2 {
@@ -56,9 +73,9 @@ ArrangementPointLocation_2 (const Arrangement_2& arr);
/*!
locates the arrangement cell that contains the query point `q`
-and returns a handle for this cell.
-The function returns an `Object` instance that wraps either of the
-following types:
+and returns a discriminated union container of the following bounded
+types:
+
- `Arrangement_2::Face_const_handle`, in case `q` is
contained inside an arrangement face;
@@ -67,9 +84,9 @@ on an arrangement edge;
- `Arrangement_2::Vertex_const_handle`, in case `q` coincides
with an arrangement vertex.
-\pre `pl` is attached to a valid arrangement instance.
+\pre `pl` is attached to a valid arrangement object.
*/
-Object locate (const Point_2& q) const;
+Arr_point_location_result::Type locate(const Point_2& q) const;
/// @}
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementVerticalRayShoot_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementVerticalRayShoot_2.h
index 947241c6cd1..d8144969d28 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementVerticalRayShoot_2.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementVerticalRayShoot_2.h
@@ -3,25 +3,42 @@
\ingroup PkgArrangement2Concepts
\cgalConcept
-A model of the `ArrangementVerticalRayShoot_2` concept can be attached to an `Arrangement_2`
-instance and answer vertical ray-shooting queries on this arrangement.
-Namely, given a `Arrangement_2::Point_2` object, representing a point in
-the plane, it returns the arrangement feature (edge or vertex) that lies
+A model of the `ArrangementVerticalRayShoot_2` concept can answer vertical ray-shooting
+queries on an arrangement attached to it. Namely, given a
+`Arrangement_2::Point_2` object, representing a point in the plane,
+it returns the arrangement feature (edge or vertex) that lies
strictly above it (or below it). By "strictly" we mean that if the
-query point lies on an arrangement edge (or on an arrangement vertex) this
-edge will not be the query result, but the feature lying above or
-below it. (An exception to this rule is the degenerate situation where the
-query point lies in the interior of a vertical edge.) Note that it may happen
-that the query point lies above the upper envelope (or below the lower
-envelope) of the arrangement, so that the vertical ray emanating from it
-may go to infinity without hitting any arrangement feature on its way. In this
-case the unbounded face is returned.
+query point lies on an arrangement edge (or on an arrangement vertex)
+this edge will not be the query result, but the feature lying
+above or below it. (An exception to this rule is the degenerate case
+where the query point lies in the interior of a vertical edge.) Note
+that it may happen that the query point lies above the upper envelope
+(or below the lower envelope) of the arrangement, and the vertical ray
+emanating from the query point goes to infinity without hitting any
+arrangement feature on its way. In this case the unbounded face is
+returned.
+
+\cgalHeading{A Note on Backwards Compatibility}
+The `ray_shoot_up` and `ray_shoot_down` member functions used
+to return `CGAL::Object` up to \cgal version 4.2. Starting with
+\cgal version 4.3 the return type is determined by a metafunction. To
+preserve backwards compatibility `CGAL::Object` can be constructed
+from the new return types implicitly, but switching to the new style
+is recommended. To enable the old style without any overhead, the macro
+`CGAL_ARR_POINT_LOCATION_VERSION` can be defined to 1 before any
+\cgal header is included.
\cgalHasModel `CGAL::Arr_naive_point_location`
-\cgalHasModel `CGAL::Arr_walk_along_a_line_point_location`
+\cgalHasModel `CGAL::Arr_walk_along_line_point_location`
\cgalHasModel `CGAL::Arr_trapezoid_ric_point_location`
\cgalHasModel `CGAL::Arr_landmarks_point_location`
+\sa `CGAL::Arr_naive_point_location`
+\sa `CGAL::Arr_walk_along_line_point_location`
+\sa `CGAL::Arr_trapezoid_ric_point_location`
+\sa `CGAL::Arr_landmarks_point_location`
+\sa `CGAL::Arr_point_location_result`
+\sa `CGAL_ARR_POINT_LOCATION_VERSION`
*/
class ArrangementVerticalRayShoot_2 {
@@ -64,9 +81,8 @@ ArrangementVerticalRayShoot_2 (const Arrangement_2& arr);
/*!
locates the arrangement feature that is first hit by an upward-directed
vertical ray emanating from the query point `q`,
-and returns a handle for this feature.
-The function returns an `Object` instance that is a wrapper for
-one of the following types:
+and returns a handle for this feature. The function returns a
+discriminated union container of the following bounded types:
- `Arrangement_2::Halfedge_const_handle`, in case the vertical
ray hits an arrangement edge;
@@ -78,14 +94,13 @@ arrangement.
\pre `rs` is attached to a valid arrangement instance.
*/
-Object ray_shoot_up (const Point_2& q) const;
+Arr_point_location_result::Type ray_shoot_up(const Point_2& q) const;
/*!
locates the arrangement feature that is first hit by a downward-directed
vertical ray emanating from the query point `q`,
-and returns a handle for this feature.
-The function returns an `Object` instance that is a wrapper for
-one of the following types:
+and returns a handle for this feature. The function returns a
+discriminated union container of the following bounded types:
- `Arrangement_2::Halfedge_const_handle`, in case the vertical
ray hits an arrangement edge;
@@ -97,7 +112,7 @@ arrangement.
\pre `rs` is attached to a valid arrangement instance.
*/
-Object ray_shoot_down (const Point_2& q) const;
+Arr_point_location_result::Type ray_shoot_down (const Point_2& q) const;
/// @}
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt
index df2f175f8b4..e3bfbc832b2 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt
@@ -180,12 +180,17 @@ implemented as peripheral classes or as free (global) functions.
- `CGAL::Arr_walk_along_line_point_location`
- `CGAL::Arr_trapezoid_ric_point_location`
- `CGAL::Arr_landmarks_point_location`
-
+- `CGAL::Arr_vertex_index_map`
+- `CGAL::Arr_face_index_map`
+- `CGAL::Arr_point_location_result`
## Tags ##
- `CGAL::Arr_oblivious_side_tag`
- `CGAL::Arr_open_side_tag`
+## Macros ##
+- \link CGAL_ARR_POINT_LOCATION_VERSION `CGAL_ARR_POINT_LOCATION_VERSION` \endlink
+
## Functions ##
- `CGAL::is_valid()`