mirror of https://github.com/CGAL/cgal
Replaced Object
This commit is contained in:
parent
4a20a898d7
commit
b8817aa69c
|
|
@ -1,195 +1,209 @@
|
|||
\section{Issuing Queries on an Arrangement\label{arr_sec:queries}}
|
||||
%==========================================
|
||||
|
||||
% ==============================================================================
|
||||
One of the most important query types defined on arrangements is
|
||||
the {\em 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 \emph{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_sec:gl_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_sec:gl_funcs}). Therefore, it is crucial to have the
|
||||
ability to answer such queries effectively.
|
||||
|
||||
\subsection{Point-Location Queries\label{arr_ssec:pl}}
|
||||
%----------------------------------
|
||||
% ------------------------------------------------------------------------------
|
||||
The \ccc{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 \emph{2D Arrangements}
|
||||
package includes a set of classe templates that are capable of
|
||||
answering such queries; all are models of the concept
|
||||
\ccc{ArrangementPointLocation_2}. Each model employs a different
|
||||
algorithm or \emph{strategy} for answering queries. A model of this
|
||||
concept must define the \ccc{locate()} member function, which accepts an
|
||||
input query-point and returns a polymorphic object representing the
|
||||
arrangement cell that contains this point. The returned object, which is
|
||||
of type \ccc{CGAL::Object}, can be assigned to a \ccc{Face_const_handle},
|
||||
a \ccc{Halfedge_const_handle}, or a \ccc{Vertex_const_handle}, depending
|
||||
on whether the query point is located inside a face, on an edge, or on a
|
||||
vertex.
|
||||
|
||||
The arrangement package includes several classes (more precisely,
|
||||
class templates parameterized by an arrangement class) that model
|
||||
the \ccc{ArrangementPointLocation_2} concept. Namely, they all
|
||||
have a member function called \ccc{locate(q)} that accepts a query
|
||||
point $q$ and result with a \cgal\ \ccc{Object} that wraps a handle
|
||||
to the arrangement cell containing the query point. This object can
|
||||
be assigned to either a \ccc{Face_const_handle},
|
||||
\ccc{Halfedge_const_handle} or a \ccc{Vertex_const_handle}, depending
|
||||
on whether the query point is located inside a face, on an edge or
|
||||
on a vertex.
|
||||
Note that the handles returned by the \ccc{locate()} functionss are
|
||||
non-mutable (\ccc{const}). If necessary, such handles may
|
||||
be cast to mutable handles using the \ccc{non_const_handle()} methods
|
||||
\ccc{Arrangement_2::non_const_handle()} provided by the
|
||||
\ccc{Arrangement_2} class.
|
||||
|
||||
Note that the handles returned by the \ccc{locate()} functions are
|
||||
\ccc{const} (non-mutable) handles. If necessary, such handles may
|
||||
be casted to mutable handles using the static functions
|
||||
\ccc{Arrangement_on_surface_2::non_const_handle()} provided by the
|
||||
arrangement class.
|
||||
An object \ccc{pl} of any point-location class must be attached to an
|
||||
\ccc{Arrangement_2} object \ccc{arr} before it is used to answer
|
||||
point-location queries on \ccc{arr}. This attachment can be performed
|
||||
when \ccc{pl} is constructed or at a later time using the
|
||||
\ccc{pl.init(arr)} call.
|
||||
|
||||
An instance of any point-location class must be attached to an
|
||||
\ccc{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 \ccc{init(arr)}
|
||||
method, where \ccc{arr} is the attached \ccc{Arrangement_on_surface_2} instance.
|
||||
In this chapter we always use the first option.
|
||||
|
||||
The following function template, which can be found in the example
|
||||
file \ccc{point_location_utils.h}, accepts a point-location object
|
||||
(whose type can be any of the models to the
|
||||
\ccc{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 \ccc{CGAL::assign()} is order
|
||||
to cast the resulting \ccc{CGAL::Object} into a handle to an arrangement
|
||||
feature. The point-location object \ccc{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 \ccc{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 \ccc{point_location_utils.h}.
|
||||
|
||||
\label{lst:pl}
|
||||
\begin{alltt}
|
||||
template <class PointLocation>
|
||||
void point_location_query
|
||||
(const PointLocation& pl,
|
||||
const typename PointLocation::Arrangement_on_surface_2::Point_2& q)
|
||||
template <typename PointLocation>
|
||||
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);
|
||||
CGAL::Object obj = pl.locate(q); // Perform the point-location query.
|
||||
|
||||
// Print the result.
|
||||
typedef typename PointLocation::Arrangement_on_surface_2 Arrangement_on_surface_2;
|
||||
print_point_location<typename Point_location::Arrangement_2>(q, obj);
|
||||
\}
|
||||
\end{alltt}
|
||||
|
||||
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 \ccc{locate_point()} calls an instance of the
|
||||
function template \ccc{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 \ccc{point_location_utils.h}.
|
||||
Observe how the function \ccc{assign()} is used to cast the
|
||||
resulting \ccc{CGAL::Object} into a handle to an arrangement feature.
|
||||
The point-location object \ccc{pl} is assumed to be already attached
|
||||
to an arrangement.
|
||||
|
||||
\begin{alltt}
|
||||
template <typename Arrangement_>
|
||||
void
|
||||
print_point_location(const typename PointLocation::Arrangement_2::Point_2& q
|
||||
const CGAL::Object& obj)
|
||||
\{
|
||||
typedef typename Arrangement_ Arrangement_2;
|
||||
|
||||
typename Arrangement_2::Vertex_const_handle v;
|
||||
typename Arrangement_2::Halfedge_const_handle e;
|
||||
typename Arrangement_2::Face_const_handle f;
|
||||
|
||||
std::cout << "The point " << q << " is located ";
|
||||
if (CGAL::assign (f, obj)) \{
|
||||
// q is located inside a face:
|
||||
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:
|
||||
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:
|
||||
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.");
|
||||
\}
|
||||
else CGAL_assertion_msg (false, "Invalid object.");
|
||||
\}
|
||||
\end{alltt}
|
||||
|
||||
\subsubsection{Choosing a Point-Location Strategy\label{arr_sssec:pl_strat}}
|
||||
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Each of the various point-location classes employs a different
|
||||
algorithm or {\em strategy}\footnote{We use the term {\em strategy}
|
||||
following the design pattern taxonomy~\cite{cgal:ghjv-dpero-95}.}
|
||||
for answering queries:
|
||||
% ------------------------------------------------------------------------------
|
||||
Each of the various point-location class templates employs a different
|
||||
algorithm or \emph{strategy}\footnote{The term \emph{strategy}
|
||||
is borrowed from the design-pattern
|
||||
taxonomy~\cite[Chapter~5]{ghjv-dp-95}.} for answering queries:
|
||||
\begin{itemize}
|
||||
\item \ccc{Arr_naive_point_location<Arrangement>} locates the query
|
||||
point naively, by exhaustively scanning all arrangement cells.
|
||||
%
|
||||
\item \ccc{Arr_walk_along_a_line_point_location<Arrangement>}
|
||||
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.
|
||||
%
|
||||
\item \ccc{Arr_naive_point_location<Arrangement>} employes the
|
||||
\emph{naive} strategy. It locates the query point naively,
|
||||
exhaustively scanning all arrangement cells.
|
||||
%
|
||||
\item \ccc{Arr_walk_along_a_line_point_location<Arrangement>} employs
|
||||
the \emph{walk-along-a-line} (or \emph{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.
|
||||
%
|
||||
\item \ccc{Arr_landmarks_point_location<Arrangement,Generator>}
|
||||
uses a set of ``landmark'' points whose location in the
|
||||
arrangement is known. Given a query point, it uses a \kdtree\ to
|
||||
find the nearest landmark and then traverses the straight line
|
||||
segment connecting this landmark to the query point.
|
||||
uses a set of ``landmark'' points the location of which in the
|
||||
arrangement is known. It employs the
|
||||
\emph{landmark} strategy. Given a query point, it uses a
|
||||
nearest-neighbor search-structure (a \kdtree{} 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, determined by the \ccc{Generator} template parameter.
|
||||
By default, the generator
|
||||
class \ccc{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.
|
||||
%
|
||||
There are various ways to select the landmark set in the
|
||||
arrangement. The selection is governed by the \ccc{Generator}
|
||||
template parameter. The default generator class, namely
|
||||
\ccc{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 \ccc{Arrangement_2<Traits,Dcel>}
|
||||
class template, where the \ccc{Traits} parameter is substituted with
|
||||
a geometry-traits class that models the
|
||||
\ccc{ArrangementLandmarkTraits_2} concept, which refines the basic
|
||||
\ccc{ArrangementBasicTraits_2} concept; see
|
||||
Section~\ref{arr_sssec:tr_lanmarks_concept} for details. Most traits
|
||||
classes included in the \emph{2D Arrangement} package are models of
|
||||
this refined concept.
|
||||
%
|
||||
\item \ccc{Arr_trapezoid_ric_point_location<Arrangement>} implements
|
||||
Mulmuley's point-location algorithm~\cite{m-fppa-90} (see
|
||||
also~\cite[Chapter~6]{bkos-cgaa-00}). The
|
||||
arrangement faces are decomposed into simpler cells of constant
|
||||
complexity known as {\em 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 expected logarithmic time.
|
||||
Mulmuley's point-location algorithm~\cite{m-fppa-90}; see
|
||||
also~\cite[Chapter~6]{bkos-cgaa-00}). The arrangement faces are
|
||||
decomposed into simpler cells each of constant complexity, known as
|
||||
\emph{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).
|
||||
\end{itemize}
|
||||
|
||||
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 structures needed by both strategies can be constructed
|
||||
in $O(N \log N)$ time (where $N$ is the overall number of edges in
|
||||
the arrangement),
|
||||
but the construction needed by the landmark algorithm is in
|
||||
practice significantly faster. In addition, although both
|
||||
resulting data structures are asymptotically linear in size, the
|
||||
\kdtree\ that the landmark algorithm stores needs significantly
|
||||
less memory. We note that Mulmuley's algorithm guarantees a
|
||||
logarithmic query time, while the query time for the landmark
|
||||
strategy is only logarithmic on average --- and we may have
|
||||
scenarios where the query time can be linear. In practice however,
|
||||
the query times of both strategies are competitive. For a detailed
|
||||
experimental comparison, see \cite{cgal:hh-eplca-05}
|
||||
in $O(N \log N)$ time, where $N$ is the overall number of edges in
|
||||
the arrangement, but the constant hidden in the $O()$ 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 \kdtree{} 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{cgal:hh-eplca-05}
|
||||
|
||||
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 \kdtree\ 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 \ccc{ArrangementLandmarkTraits_2}; see
|
||||
Section~\ref{arr_sec:traits} 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
|
||||
\ccc{Arr_landmarks_point_location} class 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
|
||||
\ccc{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 \kdtree{} is used, as it must be rebuilt each time the arrangement
|
||||
changes. It is therefore recommended that the
|
||||
\ccc{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 \ccc{Arr_trapezoid_ric_point_location}
|
||||
class template should be the selected point-location strategy.
|
||||
|
||||
\subsubsection{An Example\label{arr_sssec:pl_ex}}
|
||||
%~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
% ------------------------------------------------------------------------------
|
||||
\begin{figure}[t]
|
||||
\begin{ccTexOnly}
|
||||
\begin{center}
|
||||
|
|
@ -208,96 +222,80 @@ arrangement vertices are drawn as small discs, while the query
|
|||
points $q_1, \ldots, q_6$ are marked with crosses.\label{arr_fig:ex_5}}
|
||||
\end{figure}
|
||||
|
||||
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 Figure~\ref{arr_fig:ex_5}
|
||||
(the arrangement construction is performed by the function
|
||||
\ccc{construct_segment_arr()} whose listing is omitted here and
|
||||
can be found in \ccc{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~\ref{arr_fig:ex_5}.
|
||||
Notice that we use the same arrangement structure in the next
|
||||
three example programs. The arrangement construction is performed by
|
||||
the function \ccc{construct_segment_arr()} defined in the heade file
|
||||
\ccc{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.
|
||||
|
||||
\ccIncludeExampleCode{Arrangement_on_surface_2/point_location.cpp}
|
||||
|
||||
Note that the program uses the auxiliary
|
||||
\ccc{point_location_query()} function template to nicely print the
|
||||
result of each query. This function can be found in the header file
|
||||
\ccc{point_location_utils.h}.
|
||||
Note that the program uses the \ccc{locate_point()} function template
|
||||
to locate a point and nicely print the result of each query; see
|
||||
Page~\pageref{lst:pl}.
|
||||
|
||||
\subsection{Vertical Ray Shooting\label{arr_ssec:ray_shoot}}
|
||||
%---------------------------------
|
||||
|
||||
Another important query issued on arrangements is the vertical
|
||||
% ------------------------------------------------------------------------------
|
||||
Another query frequently 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 \ccc{ArrangementVerticalRayShoot_2} concept. That is, they all
|
||||
have member functions called \ccc{ray_shoot_up(q)} and
|
||||
\ccc{ray_shoot_down(q)} that accept a query point $q$ and output a
|
||||
\cgal\ \ccc{Object}. This can be assigned to either a
|
||||
\ccc{Halfedge_const_handle} or to a \ccc{Vertex_const_handle}.
|
||||
Alternatively, the returned value is a \ccc{Face_const_handle}
|
||||
for the unbounded face of the arrangement, in case there is no edge
|
||||
or vertex lying directly above (or below) $q$.
|
||||
All point-location classes listed in the previous section are also
|
||||
models of the \ccc{ArrangementVerticalRayShoot_2} concept. That is, t
|
||||
hey all have member functions called \ccc{ray_shoot_up(q)} and
|
||||
\ccc{ray_shoot_down(q)} that accept a query point $q$. These functions
|
||||
output a polymorphic object of type \ccc{CGAL::Object}, which wraps a
|
||||
\ccc{Halfedge_const_handle}, a \ccc{Vertex_const_handle}, or a
|
||||
\ccc{Face_const_handle} object. 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, \ccc{vertical_ray_shooting_query()},
|
||||
which also located in the header file \ccc{point_location_utils.h},
|
||||
accepts a vertical ray-shooting
|
||||
object, whose type can be any of the models to the
|
||||
\ccc{ArrangementVerticalRayShoot_2} concept and prints out the
|
||||
result of the upward vertical ray-shooting operations from a given
|
||||
query point. The ray-shooting object \ccc{vrs} is assumed to be
|
||||
already associated with an arrangement:
|
||||
The function template \ccc{vertical_ray_shooting_query()} listed
|
||||
below accepts a vertical ray-shooting object, the type of which
|
||||
models the \ccc{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 \ccc{vrs} is assumed to be already attached to an arrangement.
|
||||
The function template is defined in the header file
|
||||
\ccc{point_location_utils.h}.
|
||||
|
||||
\begin{alltt}
|
||||
template <class VerticalRayShoot>
|
||||
void vertical_ray_shooting_query
|
||||
(const VerticalRayShoot& vrs,
|
||||
const typename VerticalRayShoot::Arrangement_on_surface_2::Point_2& q)
|
||||
template <typename Ray_shooting>
|
||||
shoot_vertical_ray(const Ray_shooting& vrs,
|
||||
const typename Ray_shooting::Arrangement_2::Point_2& q)
|
||||
\{
|
||||
// Perform the point-location query.
|
||||
CGAL::Object 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;
|
||||
typename Ray_shooting::Arrangement_2::Vertex_const_handle v;
|
||||
typename Ray_shooting::Arrangement_2::Halfedge_const_handle e;
|
||||
typename Ray_shooting::Arrangement_2::Face_const_handle f;
|
||||
|
||||
std::cout << "Shooting up from " << q << " : ";
|
||||
if (CGAL::assign (e, obj)) \{
|
||||
// We hit an edge:
|
||||
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:
|
||||
else if (CGAL::assign (v, obj)) // We hit a vertex
|
||||
std::cout << "hit `` << (v->is_isolated()) ? "an isolated" ? "a")
|
||||
<< "vertex: " << v->point() << std::endl;
|
||||
else if (CGAL::assign (f, obj)) \{ // We did not hit anything
|
||||
CGAL_assertion (f->is_unbounded());
|
||||
|
||||
std::cout << "hit nothing." << std::endl;
|
||||
\}
|
||||
else \{
|
||||
CGAL_assertion_msg (false, "Invalid object.");
|
||||
\}
|
||||
else CGAL_error();
|
||||
\}
|
||||
\end{alltt}
|
||||
|
||||
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
|
||||
\ccc{point_location.cpp} (see Figure~\ref{arr_fig:ex_5}):
|
||||
The program below uses the auxiliary 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
|
||||
\ccc{point_location.cpp}; see Figure~\ref{arr_fig:ex_5}.:
|
||||
|
||||
\ccIncludeExampleCode{Arrangement_on_surface_2/vertical_ray_shooting.cpp}
|
||||
|
||||
|
|
@ -308,8 +306,7 @@ integer or from a machine \ccc{float} or \ccc{double} and performs additions,
|
|||
subtractions and multiplications in an exact number.
|
||||
|
||||
\subsection{Batched Point-Location\label{arr_ssec:batched_pl}}
|
||||
%----------------------------------
|
||||
|
||||
% ------------------------------------------------------------------------------
|
||||
Suppose that at a given moment our application has to issue a
|
||||
relatively large number $m$ of point-location queries on a
|
||||
specific arrangement instance. It is possible of course to define
|
||||
|
|
|
|||
Loading…
Reference in New Issue