Replaced Object

This commit is contained in:
Efi Fogel 2012-02-09 16:20:43 +00:00
parent 4a20a898d7
commit b8817aa69c
1 changed files with 210 additions and 213 deletions

View File

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