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}}
|
\section{Issuing Queries on an Arrangement\label{arr_sec:queries}}
|
||||||
%==========================================
|
% ==============================================================================
|
||||||
|
|
||||||
One of the most important query types defined on arrangements is
|
One of the most important query types defined on arrangements is
|
||||||
the {\em point-location} query: Given a point, find the
|
the \emph{point-location} query: Given a point, find the arrangement
|
||||||
arrangement cell that contains it. Typically, the result of a
|
cell that contains it. Typically, the result of a point-location
|
||||||
point-location query is one of the arrangement faces, but in
|
query is one of the arrangement faces, but in degenerate situations
|
||||||
degenerate situations the query point can be located on an edge or
|
the query point can be located on an edge or it may coincide with a
|
||||||
coincide with a vertex.
|
vertex.
|
||||||
|
|
||||||
Point-location queries are not only common in many applications,
|
Point-location queries are common in many applications, and also
|
||||||
they also play an important role in the free insertion-functions
|
play an important role in the incremental construction of arrangements
|
||||||
(see Section~\ref{arr_sec:gl_funcs}). Therefore, it is crucial to
|
(and more specifically in the free insertion-functions described in
|
||||||
have the ability to answer such queries effectively for any
|
Section~\ref{arr_sec:gl_funcs}). Therefore, it is crucial to have the
|
||||||
arrangement instance.
|
ability to answer such queries effectively.
|
||||||
|
|
||||||
\subsection{Point-Location Queries\label{arr_ssec:pl}}
|
\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,
|
Note that the handles returned by the \ccc{locate()} functionss are
|
||||||
class templates parameterized by an arrangement class) that model
|
non-mutable (\ccc{const}). If necessary, such handles may
|
||||||
the \ccc{ArrangementPointLocation_2} concept. Namely, they all
|
be cast to mutable handles using the \ccc{non_const_handle()} methods
|
||||||
have a member function called \ccc{locate(q)} that accepts a query
|
\ccc{Arrangement_2::non_const_handle()} provided by the
|
||||||
point $q$ and result with a \cgal\ \ccc{Object} that wraps a handle
|
\ccc{Arrangement_2} class.
|
||||||
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()} functions are
|
An object \ccc{pl} of any point-location class must be attached to an
|
||||||
\ccc{const} (non-mutable) handles. If necessary, such handles may
|
\ccc{Arrangement_2} object \ccc{arr} before it is used to answer
|
||||||
be casted to mutable handles using the static functions
|
point-location queries on \ccc{arr}. This attachment can be performed
|
||||||
\ccc{Arrangement_on_surface_2::non_const_handle()} provided by the
|
when \ccc{pl} is constructed or at a later time using the
|
||||||
arrangement class.
|
\ccc{pl.init(arr)} call.
|
||||||
|
|
||||||
An instance of any point-location class must be attached to an
|
The function template listed below accepts a point-location object,
|
||||||
\ccc{Arrangement_on_surface_2} instance so we can use it to issue point-location
|
the type of which is a model of the \ccc{ArrangementPointLocation_2}
|
||||||
queries. This attachment can be performed when the point-location
|
concept, and a query point. The function template issues a
|
||||||
instance is constructed, or at a later time, using the \ccc{init(arr)}
|
point-location query for the given point, and prints out the result.
|
||||||
method, where \ccc{arr} is the attached \ccc{Arrangement_on_surface_2} instance.
|
It is defined in the header file \ccc{point_location_utils.h}.
|
||||||
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:
|
|
||||||
|
|
||||||
|
\label{lst:pl}
|
||||||
\begin{alltt}
|
\begin{alltt}
|
||||||
template <class PointLocation>
|
template <typename PointLocation>
|
||||||
void point_location_query
|
void
|
||||||
(const PointLocation& pl,
|
locate_point(const PointLocation& pl,
|
||||||
const typename PointLocation::Arrangement_on_surface_2::Point_2& q)
|
const typename PointLocation::Arrangement_2::Point_2& q)
|
||||||
\{
|
\{
|
||||||
// Perform the point-location query.
|
CGAL::Object obj = pl.locate(q); // Perform the point-location query.
|
||||||
CGAL::Object obj = pl.locate (q);
|
|
||||||
|
|
||||||
// Print the result.
|
// 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;
|
The function template \ccc{locate_point()} calls an instance of the
|
||||||
typename Arrangement_on_surface_2::Halfedge_const_handle e;
|
function template \ccc{print_point_location()}, which inserts the
|
||||||
typename Arrangement_on_surface_2::Face_const_handle f;
|
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 ";
|
std::cout << "The point " << q << " is located ";
|
||||||
if (CGAL::assign (f, obj)) \{
|
if (CGAL::assign (f, obj)) \{ // q is located inside a face.
|
||||||
// q is located inside a face:
|
|
||||||
if (f->is_unbounded())
|
if (f->is_unbounded())
|
||||||
std::cout << "inside the unbounded face." << std::endl;
|
std::cout << "inside the unbounded face." << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "inside a bounded face." << std::endl;
|
std::cout << "inside a bounded face." << std::endl;
|
||||||
\}
|
\}
|
||||||
else if (CGAL::assign (e, obj)) \{
|
else if (CGAL::assign (e, obj)) \{ // q is located on an edge.
|
||||||
// q is located on an edge:
|
|
||||||
std::cout << "on an edge: " << e->curve() << std::endl;
|
std::cout << "on an edge: " << e->curve() << std::endl;
|
||||||
\}
|
\}
|
||||||
else if (CGAL::assign (v, obj)) \{
|
else if (CGAL::assign (v, obj)) \{ // q is located on a vertex.
|
||||||
// q is located on a vertex:
|
|
||||||
if (v->is_isolated())
|
if (v->is_isolated())
|
||||||
std::cout << "on an isolated vertex: " << v->point() << std::endl;
|
std::cout << "on an isolated vertex: " << v->point() << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "on a vertex: " << v->point() << std::endl;
|
std::cout << "on a vertex: " << v->point() << std::endl;
|
||||||
\}
|
\}
|
||||||
else \{
|
else CGAL_assertion_msg (false, "Invalid object.");
|
||||||
CGAL_assertion_msg (false, "Invalid object.");
|
|
||||||
\}
|
|
||||||
\}
|
\}
|
||||||
\end{alltt}
|
\end{alltt}
|
||||||
|
|
||||||
\subsubsection{Choosing a Point-Location Strategy\label{arr_sssec:pl_strat}}
|
\subsubsection{Choosing a Point-Location Strategy\label{arr_sssec:pl_strat}}
|
||||||
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
% ------------------------------------------------------------------------------
|
||||||
|
Each of the various point-location class templates employs a different
|
||||||
Each of the various point-location classes employs a different
|
algorithm or \emph{strategy}\footnote{The term \emph{strategy}
|
||||||
algorithm or {\em strategy}\footnote{We use the term {\em strategy}
|
is borrowed from the design-pattern
|
||||||
following the design pattern taxonomy~\cite{cgal:ghjv-dpero-95}.}
|
taxonomy~\cite[Chapter~5]{ghjv-dp-95}.} for answering queries:
|
||||||
for answering queries:
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \ccc{Arr_naive_point_location<Arrangement>} locates the query
|
\item \ccc{Arr_naive_point_location<Arrangement>} employes the
|
||||||
point naively, by exhaustively scanning all arrangement cells.
|
\emph{naive} strategy. It locates the query point naively,
|
||||||
%
|
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
|
\item \ccc{Arr_walk_along_a_line_point_location<Arrangement>} employs
|
||||||
ray emanating
|
the \emph{walk-along-a-line} (or \emph{walk} for short) strategy.
|
||||||
from the query point: It starts from the unbounded face of the
|
It simulates a traversal, in reverse order, along an imaginary
|
||||||
arrangement and moves downward toward the query point until
|
vertical ray emanating from the query point. It starts from the
|
||||||
locating the arrangement cell containing it.
|
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>}
|
\item \ccc{Arr_landmarks_point_location<Arrangement,Generator>}
|
||||||
uses a set of ``landmark'' points whose location in the
|
uses a set of ``landmark'' points the location of which in the
|
||||||
arrangement is known. Given a query point, it uses a \kdtree\ to
|
arrangement is known. It employs the
|
||||||
find the nearest landmark and then traverses the straight line
|
\emph{landmark} strategy. Given a query point, it uses a
|
||||||
segment connecting this landmark to the query point.
|
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
|
There are various ways to select the landmark set in the
|
||||||
arrangement, determined by the \ccc{Generator} template parameter.
|
arrangement. The selection is governed by the \ccc{Generator}
|
||||||
By default, the generator
|
template parameter. The default generator class, namely
|
||||||
class \ccc{Arr_landmarks_vertices_generator} is used and the
|
\ccc{Arr_landmarks_vertices_generator}, selects all the vertices of
|
||||||
arrangement vertices are the selected landmarks, but other
|
the attached arrangement as landmarks. Additional generators that
|
||||||
landmark generators, such as sampling random points or
|
select the set in other ways, such as by sampling random
|
||||||
choosing points on a grid, are also available; see the
|
points or choosing points on a grid, are also available; see the
|
||||||
Reference Manual for more details.
|
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
|
\item \ccc{Arr_trapezoid_ric_point_location<Arrangement>} implements
|
||||||
Mulmuley's point-location algorithm~\cite{m-fppa-90} (see
|
Mulmuley's point-location algorithm~\cite{m-fppa-90}; see
|
||||||
also~\cite[Chapter~6]{bkos-cgaa-00}). The
|
also~\cite[Chapter~6]{bkos-cgaa-00}). The arrangement faces are
|
||||||
arrangement faces are decomposed into simpler cells of constant
|
decomposed into simpler cells each of constant complexity, known as
|
||||||
complexity known as {\em pseudo-trapezoids} and a search-structure
|
\emph{pseudo-trapezoids}, and a search structure (a directed acyclic
|
||||||
(a directed acyclic graph) is constructed on top of these cells,
|
graph) is constructed on top of these cells, facilitating the search
|
||||||
allowing to locate the pseudo-trapezoid (hence the arrangement
|
of the pseudo trapezoid (hence the arrangement cell) containing a
|
||||||
cell) containing a query point in expected logarithmic time.
|
query point in expected logarithmic time. The trapezoidal map and
|
||||||
|
the search structure are built by a algorithm (RIC).
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
The main advantage of the first two strategies is that they do not
|
The first two strategies do not require any extra data. The class
|
||||||
require any extra data, so the respective classes just store a
|
templates that implement them store a pointer to an arrangement object
|
||||||
pointer to an arrangement object and operate directly on it.
|
and operate directly on it. Attaching such point-location objects to
|
||||||
Attaching such point-location objects to an existing arrangement
|
an existing arrangement has virtually no running-time cost at all, but
|
||||||
has virtually no running-time cost at all, but the query time is
|
the query time is linear in the size of the arrangement (the
|
||||||
linear in the size of the arrangement (the performance of the
|
performance of the walk strategy is much better in practice, but
|
||||||
``walk'' strategy is much better in practice, but its worst-case
|
its worst-case performance is linear). Using these strategies is
|
||||||
performance is linear). Using these strategies is therefore
|
therefore recommended only when a relatively small number of
|
||||||
recommended only when a relatively small number of point-location
|
point-location queries are issued by the application, or when the
|
||||||
queries are issued by the application, or when the arrangement is
|
arrangement is constantly changing (That is, changes in the arrangement
|
||||||
constantly changing (i.e., changes in the arrangement structure
|
structure are more frequent than point-location queries).
|
||||||
are more frequent than point-location queries).
|
|
||||||
|
|
||||||
On the other hand, the landmarks and the trapezoid RIC strategies
|
On the other hand, the landmarks and the trapezoid RIC strategies
|
||||||
require auxiliary data structures on top of the arrangement, which
|
require auxiliary data structures on top of the arrangement, which
|
||||||
they need to construct once they are attached to an arrangement
|
they need to construct once they are attached to an arrangement
|
||||||
object and need to keep up-to-date as this arrangement changes.
|
object and need to keep up-to-date as this arrangement changes.
|
||||||
The data structures needed by both strategies can be constructed
|
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
|
in $O(N \log N)$ time, where $N$ is the overall number of edges in
|
||||||
the arrangement),
|
the arrangement, but the constant hidden in the $O()$ notation for the
|
||||||
but the construction needed by the landmark algorithm is in
|
trapezoidal map RIC strategy is much larger. Thus, construction needed
|
||||||
practice significantly faster. In addition, although both
|
by the landmark algorithm is in practice significantly faster than the
|
||||||
resulting data structures are asymptotically linear in size, the
|
construction needed by the trapezoidal map RIC strategy. In addition,
|
||||||
\kdtree\ that the landmark algorithm stores needs significantly
|
although both resulting data structures are asymptotically linear in
|
||||||
less memory. We note that Mulmuley's algorithm guarantees a
|
size, using a \kdtree{} as the nearest-neighbor search-structure that
|
||||||
logarithmic query time, while the query time for the landmark
|
the landmark algorithm stores significantly reduces memory consumption.
|
||||||
strategy is only logarithmic on average --- and we may have
|
The trapezoidal map RIC algorithm has expected logarithmic query time,
|
||||||
scenarios where the query time can be linear. In practice however,
|
while the query time for the landmark strategy may be as large as
|
||||||
the query times of both strategies are competitive. For a detailed
|
linear. In practice however, the query times of both strategies are
|
||||||
experimental comparison, see \cite{cgal:hh-eplca-05}
|
competitive. For a detailed experimental comparison
|
||||||
|
see~\cite{cgal:hh-eplca-05}
|
||||||
|
|
||||||
The main drawback in the current implementation of the landmark
|
Updating the auxiliary data structures of the trapezoidal map RIC
|
||||||
strategy, compared to the trapezoidal RIC strategy, is that while
|
algorithm is done very efficiently. On the other hand, updating the
|
||||||
the updating the auxiliary data structures
|
nearest-neighbor search-structure of the landmark algorithm may consume
|
||||||
related to the trapezoidal decomposition is done very efficiently,
|
more time when the arrangement changes frequently, especially when
|
||||||
the \kdtree\ maintained by the landmark algorithm needs to be
|
a \kdtree{} is used, as it must be rebuilt each time the arrangement
|
||||||
frequently rebuilt as the arrangement changes. In addition, using
|
changes. It is therefore recommended that the
|
||||||
the landmark point-location class adds some extra requirement
|
\ccc{Arr_landmarks_point_location} class template be used when the
|
||||||
from the traits class (that is, the traits class should be a model
|
application frequently issues point-location queries on an arrangement
|
||||||
of a refined concept \ccc{ArrangementLandmarkTraits_2}; see
|
that only seldom changes. If the arrangement is more dynamic and is
|
||||||
Section~\ref{arr_sec:traits} for the details). However, most
|
frequently going through changes, the \ccc{Arr_trapezoid_ric_point_location}
|
||||||
built-in traits classes that come with the \cgal\ public release
|
class template should be the selected point-location strategy.
|
||||||
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.
|
|
||||||
|
|
||||||
\subsubsection{An Example\label{arr_sssec:pl_ex}}
|
\subsubsection{An Example\label{arr_sssec:pl_ex}}
|
||||||
%~~~~~~~~~~~~~~~~~~~~~~~~~
|
% ------------------------------------------------------------------------------
|
||||||
|
|
||||||
\begin{figure}[t]
|
\begin{figure}[t]
|
||||||
\begin{ccTexOnly}
|
\begin{ccTexOnly}
|
||||||
\begin{center}
|
\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}}
|
points $q_1, \ldots, q_6$ are marked with crosses.\label{arr_fig:ex_5}}
|
||||||
\end{figure}
|
\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
|
segments that form a pentagonal face, with a single isolated
|
||||||
vertex in its interior, as depicted in Figure~\ref{arr_fig:ex_5}
|
vertex in its interior, as depicted in Figure~\ref{arr_fig:ex_5}.
|
||||||
(the arrangement construction is performed by the function
|
Notice that we use the same arrangement structure in the next
|
||||||
\ccc{construct_segment_arr()} whose listing is omitted here and
|
three example programs. The arrangement construction is performed by
|
||||||
can be found in \ccc{point_location_utils.h}).
|
the function \ccc{construct_segment_arr()} defined in the heade file
|
||||||
It then employs the naive and the landmark strategies to issue
|
\ccc{point_location_utils.h}. (Its listing is omitted here.) The
|
||||||
several point-location queries on this arrangement:
|
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}
|
\ccIncludeExampleCode{Arrangement_on_surface_2/point_location.cpp}
|
||||||
|
|
||||||
Note that the program uses the auxiliary
|
Note that the program uses the \ccc{locate_point()} function template
|
||||||
\ccc{point_location_query()} function template to nicely print the
|
to locate a point and nicely print the result of each query; see
|
||||||
result of each query. This function can be found in the header file
|
Page~\pageref{lst:pl}.
|
||||||
\ccc{point_location_utils.h}.
|
|
||||||
|
|
||||||
\subsection{Vertical Ray Shooting\label{arr_ssec:ray_shoot}}
|
\subsection{Vertical Ray Shooting\label{arr_ssec:ray_shoot}}
|
||||||
%---------------------------------
|
% ------------------------------------------------------------------------------
|
||||||
|
Another query frequently issued on arrangements is the vertical
|
||||||
Another important query issued on arrangements is the vertical
|
|
||||||
ray-shooting query: Given a query point, which arrangement feature
|
ray-shooting query: Given a query point, which arrangement feature
|
||||||
do we encounter if we shoot a vertical ray emanating upward (or
|
do we encounter by a vertical ray shot upward (or downward) from this
|
||||||
downward) from this point? In the general case the ray hits an
|
point? In the general case the ray hits an edge, but it is possible
|
||||||
edge, but it is possible that it hits a vertex, or that the
|
that it hits a vertex, or that the arrangement does not have any
|
||||||
arrangement does not have any feature lying directly above (or
|
vertex or edge lying directly above (or below) the query point.
|
||||||
below) the query point.
|
|
||||||
|
|
||||||
All point-location classes listed in the previous section are also models
|
All point-location classes listed in the previous section are also
|
||||||
of the \ccc{ArrangementVerticalRayShoot_2} concept. That is, they all
|
models of the \ccc{ArrangementVerticalRayShoot_2} concept. That is, t
|
||||||
have member functions called \ccc{ray_shoot_up(q)} and
|
hey 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
|
\ccc{ray_shoot_down(q)} that accept a query point $q$. These functions
|
||||||
\cgal\ \ccc{Object}. This can be assigned to either a
|
output a polymorphic object of type \ccc{CGAL::Object}, which wraps a
|
||||||
\ccc{Halfedge_const_handle} or to a \ccc{Vertex_const_handle}.
|
\ccc{Halfedge_const_handle}, a \ccc{Vertex_const_handle}, or a
|
||||||
Alternatively, the returned value is a \ccc{Face_const_handle}
|
\ccc{Face_const_handle} object. The latter type is used for the
|
||||||
for the unbounded face of the arrangement, in case there is no edge
|
unbounded face of the arrangement, in case there is no edge or
|
||||||
or vertex lying directly above (or below) $q$.
|
vertex lying directly above (or below) $q$.
|
||||||
|
|
||||||
The following function template, \ccc{vertical_ray_shooting_query()},
|
The function template \ccc{vertical_ray_shooting_query()} listed
|
||||||
which also located in the header file \ccc{point_location_utils.h},
|
below accepts a vertical ray-shooting object, the type of which
|
||||||
accepts a vertical ray-shooting
|
models the \ccc{ArrangementVerticalRayShoot_2} concept. It exports
|
||||||
object, whose type can be any of the models to the
|
the result of the upward vertical ray-shooting operation from a
|
||||||
\ccc{ArrangementVerticalRayShoot_2} concept and prints out the
|
given query point to the standard output-stream. The ray-shooting
|
||||||
result of the upward vertical ray-shooting operations from a given
|
object \ccc{vrs} is assumed to be already attached to an arrangement.
|
||||||
query point. The ray-shooting object \ccc{vrs} is assumed to be
|
The function template is defined in the header file
|
||||||
already associated with an arrangement:
|
\ccc{point_location_utils.h}.
|
||||||
|
|
||||||
\begin{alltt}
|
\begin{alltt}
|
||||||
template <class VerticalRayShoot>
|
template <typename Ray_shooting>
|
||||||
void vertical_ray_shooting_query
|
shoot_vertical_ray(const Ray_shooting& vrs,
|
||||||
(const VerticalRayShoot& vrs,
|
const typename Ray_shooting::Arrangement_2::Point_2& q)
|
||||||
const typename VerticalRayShoot::Arrangement_on_surface_2::Point_2& q)
|
|
||||||
\{
|
\{
|
||||||
// Perform the point-location query.
|
// Perform the point-location query.
|
||||||
CGAL::Object obj = vrs.ray_shoot_up (q);
|
CGAL::Object obj = vrs.ray_shoot_up (q);
|
||||||
|
|
||||||
// Print the result.
|
typename Ray_shooting::Arrangement_2::Vertex_const_handle v;
|
||||||
typedef typename VerticalRayShoot::Arrangement_on_surface_2 Arrangement_on_surface_2;
|
typename Ray_shooting::Arrangement_2::Halfedge_const_handle e;
|
||||||
|
typename Ray_shooting::Arrangement_2::Face_const_handle f;
|
||||||
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 << " : ";
|
std::cout << "Shooting up from " << q << " : ";
|
||||||
if (CGAL::assign (e, obj)) \{
|
if (CGAL::assign (e, obj)) // We hit an edge
|
||||||
// We hit an edge:
|
|
||||||
std::cout << "hit an edge: " << e->curve() << std::endl;
|
std::cout << "hit an edge: " << e->curve() << std::endl;
|
||||||
\}
|
else if (CGAL::assign (v, obj)) // We hit a vertex
|
||||||
else if (CGAL::assign (v, obj)) \{
|
std::cout << "hit `` << (v->is_isolated()) ? "an isolated" ? "a")
|
||||||
// We hit a vertex:
|
<< "vertex: " << v->point() << std::endl;
|
||||||
if (v->is_isolated())
|
else if (CGAL::assign (f, obj)) \{ // We did not hit anything
|
||||||
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());
|
CGAL_assertion (f->is_unbounded());
|
||||||
|
|
||||||
std::cout << "hit nothing." << std::endl;
|
std::cout << "hit nothing." << std::endl;
|
||||||
\}
|
\}
|
||||||
else \{
|
else CGAL_error();
|
||||||
CGAL_assertion_msg (false, "Invalid object.");
|
|
||||||
\}
|
|
||||||
\}
|
\}
|
||||||
\end{alltt}
|
\end{alltt}
|
||||||
|
|
||||||
The following program uses the auxiliary function listed above to
|
The program below uses the auxiliary function template listed above to
|
||||||
perform vertical ray-shooting queries on an arrangement.
|
perform vertical ray-shooting queries on an arrangement. The
|
||||||
The arrangement and the query points are exactly the same as in
|
arrangement and the query points are exactly the same as in
|
||||||
\ccc{point_location.cpp} (see Figure~\ref{arr_fig:ex_5}):
|
\ccc{point_location.cpp}; see Figure~\ref{arr_fig:ex_5}.:
|
||||||
|
|
||||||
\ccIncludeExampleCode{Arrangement_on_surface_2/vertical_ray_shooting.cpp}
|
\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.
|
subtractions and multiplications in an exact number.
|
||||||
|
|
||||||
\subsection{Batched Point-Location\label{arr_ssec:batched_pl}}
|
\subsection{Batched Point-Location\label{arr_ssec:batched_pl}}
|
||||||
%----------------------------------
|
% ------------------------------------------------------------------------------
|
||||||
|
|
||||||
Suppose that at a given moment our application has to issue a
|
Suppose that at a given moment our application has to issue a
|
||||||
relatively large number $m$ of point-location queries on a
|
relatively large number $m$ of point-location queries on a
|
||||||
specific arrangement instance. It is possible of course to define
|
specific arrangement instance. It is possible of course to define
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue