mirror of https://github.com/CGAL/cgal
1034 lines
39 KiB
TeX
1034 lines
39 KiB
TeX
|
|
%-----------------------------------------------------------------------------
|
|
% Boolean operations
|
|
% ================== specification 10.Feb.98 RISC
|
|
%
|
|
% Wolfgang Freiseisen email: Wolfgang.Freiseisen@risc.uni-linz.ac.at
|
|
%-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
\cleardoublepage
|
|
\chapter{Boolean Operations in 2D} \label{Bops}
|
|
|
|
%---------------------------------------------
|
|
% INTRODUCTION
|
|
%---------------------------------------------
|
|
\section{Introduction}
|
|
|
|
\cgal\ provides boolean operations for polytopes in the 2-dimensional
|
|
Euclidean space. The functions described in
|
|
the next section apply to two simple
|
|
polygons. Both boundary and interior are considered as part of a polygon.
|
|
Boolean operations on polygons are therefore not limited to operations
|
|
on the boundary of the objects.
|
|
The functions described in this chapter
|
|
allow to perform the purely geometric operations
|
|
intersection, union, and difference on two polygons
|
|
in the 2-dimensional Euclidean space. They should not be confused with
|
|
the regularised operations in the context of solid modeling.
|
|
|
|
A clear distinction should be made between two sorts of functions
|
|
described in this chapter. Some operations perform an intersection
|
|
test without computing the actual result of the intersection.
|
|
Other operations perform a boolean operation (intersection,
|
|
union, or difference): they explicitly compute and return the result
|
|
of the boolean operation on two polygons.
|
|
|
|
Note that particular classes of polytopes are not closed under
|
|
boolean operations. For instance, the union of two simple polygons is
|
|
not necessarily a simple polygon, or the intersection of two triangles
|
|
is not necessarily a triangle.
|
|
|
|
All functions described below are template functions. Some are
|
|
parameterized only by the number type (denoted by \ccStyle{R}),
|
|
others are parameterized with a traits class (denoted by
|
|
\ccStyle{Traits}).
|
|
Where we use polygons of type
|
|
\ccStyle{Polygon_2} the functions are parameterized by a
|
|
number type (denoted by \ccStyle{R}) and container (denoted by
|
|
\ccStyle{Container}), as it is the case for \ccStyle{Polygon_2}.
|
|
For more details we refer to the description of \ccStyle{Polygon_2}.
|
|
In a boolean operations traits
|
|
class some types and functions needed for the computation of
|
|
boolean operations are defined. We provide a default version of the
|
|
traits class for boolean operations, which we describe in detail below.
|
|
So the user need not (but can if desired) provide ones own boolean operations
|
|
traits class.
|
|
|
|
|
|
%%%%%%%%%%%
|
|
% WARNING
|
|
%%%%%%%%%%%
|
|
Note:
|
|
The current version of boolean operations is robust only when exact arithmetic,
|
|
for instance \ccStyle{Cartesian<Rational>}, is used.
|
|
In nearly degenerate configurations, correct results are not guaranteed
|
|
when floating point numbers are used.
|
|
|
|
|
|
%---------------------------------------------
|
|
% BOPS ON POLYGONS
|
|
%---------------------------------------------
|
|
\newpage
|
|
\section{Boolean Operations on Polygons}
|
|
|
|
\ccDefinition
|
|
Boolean operations are provided for two simple polygons (for the
|
|
definition of simple polygons, see Chapter~2.1
|
|
%Chapter~\ref{Polygon}
|
|
).
|
|
A triangle and an iso-oriented rectangle clearly are special cases of
|
|
simple polygons.
|
|
|
|
A polygon on which the boolean operations can be performed
|
|
can be stored in one of the following \cgal-objects:
|
|
\begin{itemize}
|
|
\item \ccStyle{Triangle_2}, a 2-dimensional triangle.
|
|
\item \ccStyle{Iso_rectangle_2}, a 2-dimensional iso-oriented rectangle.
|
|
\item \ccStyle{Polygon_2}, a 2-dimensional polygon.
|
|
It must be simple, but not necessarily convex.
|
|
So, non-adjacent edges do not intersect and there are no holes in the polygon.
|
|
The vertices of such a polygon must be ordered in counterclockwise
|
|
order.
|
|
\end{itemize}
|
|
|
|
We consider polygons as being closed and filled objects, i.e.\ we consider
|
|
both its boundary and its interior.
|
|
The edge cycle of the polygon will be referred
|
|
to explicitly as the polygon boundary.
|
|
For boolean operations the distinction between the interior and
|
|
the exterior of a polygon is determined by the order of its vertices.
|
|
|
|
The result of an intersection test is one of the boolean
|
|
values \ccc{true} or \ccc{false}.
|
|
The result of an intersection, union, or difference can be empty, a single
|
|
object, or several objects.
|
|
An object can be a point, a segment,
|
|
a triangle, an iso-oriented rectangle, a polygon, or a polygon with
|
|
one or several holes.
|
|
|
|
There, where the result cannot be more than one object (in the case of
|
|
the intersection of two triangles, and in the case of the
|
|
intersection of two iso-rectangles) the corresponding function returns
|
|
a possibly empty object. In all other cases the functions return a
|
|
possibly empty sequence of objects.
|
|
|
|
Note that whenever we refer to a
|
|
``sequence'' of objects we actually mean a collection of objects
|
|
independent of the way in which they are stored. We provide
|
|
a mechanism which allows the user to define the type of ``sequence'' in
|
|
which the output will be stored (the template
|
|
\ccStyle{OutputIterator}, see further for details).
|
|
|
|
Vertices of input polygons must be ordered counterclockwise.
|
|
Vertices of output polygons are ordered counterclockwise.
|
|
However, vertices of polygons representing holes (as part of
|
|
the output) are ordered clockwise.
|
|
For instance, if the result of a boolean operation is a polygon with some
|
|
holes, then this result will be represented as a sequence of polygons,
|
|
where the first one
|
|
representing the outer boundary of the contour is ordered counterclockwise
|
|
and the following ones representing the inner contours (holes) are ordered
|
|
clockwise.
|
|
|
|
For two simple polygons $A$ and $B$, the boolean operations are
|
|
defined:
|
|
\begin{description}
|
|
|
|
\item [Intersection test] of two polygons (\ccStyle{do_intersect(A,B)}):
|
|
This checks if the two polygons $A$ and $B$ do intersect without computing
|
|
the intersection area.
|
|
It returns \ccStyle{true} if the polygons $A$ and $B$ do intersect,
|
|
otherwise \ccStyle{false} will be returned.
|
|
|
|
\item [Intersection] of two polygons (\ccStyle{intersection(A,B)}):
|
|
It performs the operation $C:=A \cap B$ and returns the result $C$
|
|
as a maybe empty sequence of objects (\ccStyle{Object}),
|
|
i.e.\ a sequence containing objects of type \ccStyle{Point_2},
|
|
\ccStyle{Segment_2}, and \ccStyle{Polygon_2}.
|
|
When $A$ and $B$ are both triangles (\ccStyle{Triangle_2})
|
|
or when $A$
|
|
and $B$ are both iso-oriented rectangles
|
|
(\ccStyle{Iso_rectangle}) the result can
|
|
only be a single object and therefore the intersection will return
|
|
a \ccStyle{Object} instead of a sequence of objects.
|
|
|
|
\item [Union] of two polygons ( \ccStyle{union(A,B)}): It
|
|
performs the operation $C:=A \cup B$ and returns the result $C$ as
|
|
a maybe empty sequence of objects (\ccStyle{Object}), i.e.\ a
|
|
sequence containing objects of type \ccStyle{Polygon_2}. The
|
|
first polygon gives the counterclockwise-ordered outer boundary of
|
|
the contour of the union and the following polygons (if existing)
|
|
define the inner clockwise-ordered contours (the holes). If $A
|
|
\cap B$ is exactly one point (a vertex of at least one of the two
|
|
input polygons), the union returns one non-simple polygon. If $A
|
|
\cap B$ is empty, then a sequence will be returned consisting of $A$
|
|
and $B$ both represented as polygons with counterclockwise ordered
|
|
contour.
|
|
|
|
\item [Difference] of two polygons (\ccStyle{difference(A,B)}):
|
|
This performs the operation $C:=A \setminus interior(B)$ and
|
|
returns the result $C$
|
|
as a maybe empty sequence of objects (\ccStyle{Object}),
|
|
i.e.\ a sequence containing objects of type \ccStyle{Point_2},
|
|
\ccStyle{Segment_2}, and \ccStyle{Polygon_2}.
|
|
If $A \cap B$ is empty
|
|
then $A$ will be returned.
|
|
If $A \cap B = A$ (i.e. $A \subseteq B$),
|
|
then the empty sequence will be returned.
|
|
If $A \cap B = B$ (i.e. $B \subseteq A$, that means $B$ is a
|
|
hole of $A$),
|
|
then a sequence containing (two) objects $(A,B)$ of type
|
|
\ccStyle{Polygon_2} will be returned, where the second one
|
|
represents a hole and has clockwise order.
|
|
\end{description}
|
|
|
|
\ccParameters
|
|
The boolean operations described in the following have one or more
|
|
template parameters. The number of template parameters as well as the
|
|
type of template parameters differs for the different operations.
|
|
Here we give a list of all template parameters which might occur
|
|
and some explanation of where they stand for.
|
|
|
|
|
|
\ccCommentHeading{\ccc{Traits}}
|
|
|
|
A value for the template parameter \ccStyle{Traits} is a
|
|
boolean operations traits class. We provide a standard boolean
|
|
operations traits class for convenience to the user, but the user
|
|
can define ones own traits class as well. For more details about
|
|
boolean operations traits classes look at the table in the following paragraph
|
|
on Types, and in the section on the standard traits class
|
|
(\ref{B_ops_Predef}).
|
|
|
|
%\ccTypes
|
|
%A \ccStyle{list<element_type>} denotes the \emph{STL list container},
|
|
%which implements a double connected list (include file: \ccStyle{list.h}).
|
|
|
|
\ccCommentHeading{\ccc{R}}
|
|
|
|
This template parameter defines the representation class\footnote{
|
|
A detailed description of the representation class can
|
|
be found in Part 1 of the \cgal-Reference Manual}.
|
|
Common examples of \ccc{R} are:
|
|
\ccc{Cartesian<double>},
|
|
\ccc{Homogeneous<float>}, or
|
|
\ccc{Cartesian<Rational>}.
|
|
|
|
\ccCommentHeading{\ccc{Container}}
|
|
|
|
The container type \ccStyle{Container} for a polygon.
|
|
The user must pre-instantiate this for instance by
|
|
\ccStyle{list<Point_2<Cartesian<Rational> > >}.
|
|
|
|
|
|
\ccCommentHeading{\ccc{OutputIterator}}
|
|
|
|
The type of the iterator pointing to the container in which the output
|
|
is stored: \ccStyle{OutputIterator}. The user must
|
|
pre-instantiate this for instance by
|
|
\ccStyle{list<Object>::const_iterator}.
|
|
|
|
|
|
\ccCommentHeading{\ccc{ForwardIterator}}
|
|
|
|
The type of the iterator pointing to the container in which the
|
|
input is stored: \ccStyle{ForwardIterator}. The user must
|
|
pre-instantiate this for instance by
|
|
\ccStyle{list<Point>::const_iterator}.
|
|
|
|
|
|
|
|
In the table below we describe the types which are defined in a
|
|
boolean operations treats class. Such a traits class contains the most
|
|
important type definitions used in the algorithms. These types can be
|
|
changed by the user, if needed. In the first column of the table the
|
|
types present in a boolean operations treats class are listed. In the
|
|
second column a brief description of the respective types is given,
|
|
and in the third column the default value for each of the types in
|
|
given as they are defined in the standard boolean operations treats class.
|
|
For more details on the standard boolean operations treats class we
|
|
refer to Section \ref{B_ops_Predef}.
|
|
\begin{center}
|
|
\small
|
|
\begin{tabular}{|l|l|l|} \hline
|
|
type & description & standard \\ \hline \hline
|
|
%\ccc{Traits::R} & Representation class & \ccc{Cartesian<Rational>} \\ \hline
|
|
\ccc{Traits::Point} & 2D point & \ccc{Point_2<R> >} \\ \hline
|
|
\ccc{Traits::Segment} & 2D segment & \ccc{Segment_2<R> >} \\ \hline
|
|
\ccc{Traits::Triangle} & 2D triangle & \ccc{Triangle_2<R >} \\ \hline
|
|
\ccc{Traits::Iso_rectangle} & 2D iso-oriented rectangle & \ccc{Iso_rectangle_2<R >} \\ \hline
|
|
\ccc{Traits::Container} & container type for polygon & \ccc{list<Point_2<R> >} \\ \hline
|
|
\ccc{Traits::Polygon} & 2D polygon & \ccc{Polygon_2<Polygon_traits_2<R>, Container >} \\ \hline
|
|
\end{tabular}
|
|
\end{center}
|
|
|
|
\ccOperations
|
|
\ccSetThreeColumns{4cm}{}{\hspace*{11cm}}
|
|
%\ccThreeToTwo
|
|
%\threecolumns{3.5cm}{4cm}
|
|
|
|
|
|
% *******************************************
|
|
\ccHeading{Operations on 2D Iso rectangles}
|
|
% *******************************************
|
|
|
|
\ccInclude{CGAL/bops_Iso_rectangle_2.h}
|
|
|
|
% --------------- INTERSECTION-TEST
|
|
\ccFunction{template <class R>
|
|
bool do_intersect(const
|
|
Iso_rectangle_2<R> &A, const Iso_rectangle_2<R> &B);}
|
|
{ returns \ccStyle{true} if the iso-oriented rectangles $A$ and $B$
|
|
do intersect.}
|
|
|
|
% --------------- INTERSECTION
|
|
\ccFunction{template <class R, class OutputIterator>
|
|
OutputIterator intersection(const
|
|
Iso_rectangle_2<R> &A, const Iso_rectangle_2<R> &B,
|
|
OutputIterator object_it);}
|
|
{computes the intersection of two iso-oriented rectangles and
|
|
places the resulting object
|
|
of type \ccStyle{Object} in a container
|
|
of the type corresponding to
|
|
the output iterator (\ccStyle{OutputIterator})
|
|
\ccc{object_it} which points to the resulting object.
|
|
The function returns
|
|
an output iterator (\ccStyle{OutputIterator}) pointing to the position
|
|
beyond the end of the container.
|
|
Each object part of the output is either
|
|
a point (\ccStyle{Point_2}),
|
|
or a segment (\ccStyle{Segment_2}),
|
|
or an iso-oriented rectangle (\ccStyle{Iso_rectangle_2}).
|
|
In case of an empty intersection
|
|
no objects are put into the output operator.
|
|
}
|
|
|
|
|
|
% --------------- UNION
|
|
\ccFunction{template <class R, class OutputIterator>
|
|
OutputIterator union(const Iso_rectangle_2<R>
|
|
&A, const Iso_rectangle_2<R> &B, OutputIterator list_of_objects_it);}
|
|
{computes the union of two iso-oriented rectangles and
|
|
places all
|
|
resulting objects as a sequence of objects of type \ccStyle{Object}
|
|
in a container of type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator})
|
|
\ccc{list_of_objects_it} which points to the first object in the
|
|
sequence.
|
|
The function returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to the position beyond the end of the sequence.
|
|
The sequence may contain
|
|
an iso-oriented rectangle (\ccStyle{Iso_rectangle_2}),
|
|
or a simple polygon (\ccStyle{Polygon_2}),
|
|
or two iso-oriented rectangles (\ccStyle{Iso_rectangle_2},
|
|
in case $A \cap B$ is empty).
|
|
}
|
|
|
|
% --------------- DIFFERENCE
|
|
\ccFunction{template <class R, class OutputIterator>
|
|
OutputIterator difference(const
|
|
Iso_rectangle_2<R> &A, const Iso_rectangle_2<R> &B,
|
|
OutputIterator list_of_objects_it);}
|
|
{ computes
|
|
the difference ($A \setminus B$) of two iso-oriented
|
|
rectangles and places the
|
|
resulting objects as \ccStyle{Object}
|
|
in a container of type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator})
|
|
\ccc{list_of_objects_it} which points to the first object in the
|
|
sequence.
|
|
The function returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to the position beyond the end of the sequence.
|
|
Each object is either
|
|
a simple polygon (\ccStyle{Polygon_2)} or
|
|
an iso-oriented rectangle (\ccStyle{Iso_rectangle_2}).
|
|
If $B \subseteq A$ no object will be put into the output iterator.
|
|
}
|
|
|
|
% *******************************************
|
|
\ccHeading{Operations on 2D Triangles}
|
|
% *******************************************
|
|
|
|
\ccInclude{CGAL/bops_Triangle_2.h}
|
|
|
|
\ccFunction{template <class R>
|
|
bool do_intersect(
|
|
const Triangle_2<R> &A,
|
|
const Triangle_2<R> &B);}
|
|
{ returns \ccStyle{true} if the triangles $A$ and $B$ do intersect.}
|
|
|
|
\ccFunction{template <class R, class OutputIterator>
|
|
OutputIterator intersection(
|
|
const Triangle_2<R> &A, const Triangle_2<R> &B,
|
|
OutputIterator object_it);}
|
|
{computes the intersection of two triangles and places the
|
|
resulting object of type \ccStyle{Object}
|
|
in a container of the type corresponding to the
|
|
output iterator (\ccStyle{OutputIterator}) \ccc{object_it} which
|
|
points to the resulting object. The function returns
|
|
an output iterator (\ccStyle{OutputIterator}) pointing to the position
|
|
beyond the end of the container.
|
|
The resulting object is either
|
|
a point (\ccStyle{Point_2}),
|
|
or a segment (\ccStyle{Segment_2}),
|
|
or a triangle (\ccStyle{Triangle_2}),
|
|
or a convex polygon (\ccStyle{Polygon_2} with
|
|
\ccStyle{is_convex() == true}). In case of an empty intersection
|
|
no object is put into the output operator.}
|
|
|
|
% --------------- UNION
|
|
\ccFunction{template <class R, class OutputIterator>
|
|
OutputIterator union(const Triangle_2<R>
|
|
&A, const Triangle_2<R> &B, OutputIterator list_of_objects_it);}
|
|
{computes the union of two triangles and
|
|
places all
|
|
resulting objects as a sequence of objects of type \ccStyle{Object}
|
|
in a container of type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator})
|
|
\ccc{list_of_objects_it} which points to the first object in the
|
|
sequence.
|
|
The function returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to the position beyond the end of the sequence.
|
|
The sequence may contain
|
|
a triangle (\ccStyle{Triangle_2}),
|
|
or a simple polygon (\ccStyle{Polygon_2}),
|
|
or two triangles (\ccStyle{Polygon_2}, in case $A \cap B$ is empty).
|
|
}
|
|
|
|
%\subsection*{Difference}
|
|
% --------------- DIFFERENCE
|
|
\ccFunction{template <class R, class OutputIterator>
|
|
OutputIterator difference(const
|
|
Triangle_2<R> &A, const Triangle_2<R> &B,
|
|
OutputIterator list_of_objects_it);}
|
|
{Computes the difference ($A \setminus B$) of two triangles and
|
|
places all
|
|
resulting objects as a sequence of objects of type \ccStyle{Object}
|
|
in a container of type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator})
|
|
\ccc{list_of_objects_it} which points to the first object in the
|
|
sequence.
|
|
It returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to position beyond the end of the sequence.
|
|
Each object in the sequence is either a triangle
|
|
(\ccStyle{Triangle_2}), or
|
|
a simple polygon (\ccStyle{Polygon_2}).
|
|
If $B \subseteq A$ no object will be put into the output iterator.
|
|
}
|
|
|
|
|
|
% *******************************************
|
|
\ccHeading{Operations on 2D Polygons}
|
|
% *******************************************
|
|
|
|
\ccInclude{CGAL/bops_Polygon_2.h}
|
|
|
|
\ccFunction{template <class R, class Container>
|
|
bool do_intersect(
|
|
const Polygon_2<Polygon_traits_2<R>,Container> &A,
|
|
const Polygon_2<Polygon_traits_2<R>,Container> &B);
|
|
}
|
|
{ returns \ccStyle{true} if the polygons $A$ and $B$ do intersect.
|
|
\ccPrecond $A$ and $B$ simple polygons, their vertices are in
|
|
counterclockwise order.}
|
|
|
|
\ccFunction{template <class R, class Container, class OutputIterator>
|
|
OutputIterator intersection(
|
|
const Polygon_2<Polygon_traits_2<R>,Container> &A,
|
|
const Polygon_2<Polygon_traits_2<R>,Container> &B,
|
|
OutputIterator list_of_objects_it);
|
|
}
|
|
{computes the intersection of two simple polygons and places all
|
|
resulting objects as a sequence of objects of type \ccStyle{Object}
|
|
in a container of type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator})
|
|
\ccc{list_of_objects_it} which points to the first object in the
|
|
sequence.
|
|
The function returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to the position beyond the end of the sequence.
|
|
In case of an
|
|
empty intersection no objects are put into the output operator.
|
|
\ccPrecond $A$ and $B$ simple polygons, their vertices are in
|
|
counterclockwise order.
|
|
}
|
|
|
|
|
|
% --------------- UNION
|
|
\ccFunction{template <class R, class Container, class OutputIterator>
|
|
OutputIterator union(
|
|
const Polygon_2<Polygon_traits_2<R>,Container> &A,
|
|
const Polygon_2<Polygon_traits_2<R>,Container> &B,
|
|
OutputIterator list_of_objects_it);
|
|
}
|
|
{computes the union of two simple polygons and places all
|
|
resulting objects as a sequence of objects of type \ccStyle{Object}
|
|
in a container of type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator})
|
|
\ccc{list_of_objects_it} which points to the first object in the
|
|
sequence.
|
|
The function returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to the position beyond the end of the sequence.
|
|
\ccPrecond $A$ and $B$ are simple polygons, their vertices are in
|
|
counterclockwise order.
|
|
}
|
|
|
|
% --------------- DIFFERENCE
|
|
\ccFunction{template <class R, class Container, class OutputIterator>
|
|
OutputIterator difference(
|
|
const Polygon_2<Polygon_traits_2<R>,Container> &A,
|
|
const Polygon_2<Polygon_traits_2<R>,Container> &B,
|
|
OutputIterator list_of_objects_it);
|
|
}
|
|
{computes the difference of two simple polygons ($A \setminus B$) and
|
|
places the
|
|
resulting object as \ccStyle{Object}
|
|
in a container of type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator})
|
|
\ccc{list_of_objects_it} which points to the first object in the
|
|
sequence.
|
|
The function returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to the position beyond the end of the sequence.
|
|
The difference can be empty in which case no object will be put
|
|
in the output iterator.
|
|
\ccPrecond $A$ and $B$ simple polygons, their vertices are in
|
|
counterclockwise order.
|
|
}
|
|
|
|
% **********************************************************
|
|
\ccHeading{Operations on 2D Polygons defined by containers}
|
|
% **********************************************************
|
|
|
|
\ccInclude{CGAL/bops_Container_Polygon_2.h}
|
|
|
|
% --------------- INTERSECTION-TEST
|
|
\ccGlobalFunction{template <class ForwardIterator, class Traits>
|
|
bool do_intersect( ForwardIterator Afirst, ForwardIterator Alast,
|
|
ForwardIterator Bfirst, ForwardIterator Blast,
|
|
Traits &);}
|
|
{with polygon \ccStyle{A} of type \ccStyle{Traits::Polygon} defined by the
|
|
vertices of type
|
|
\ccStyle{Traits::Point} in the range
|
|
$[Afirst,Alast)$
|
|
and for polygon \ccStyle{B} of type \ccStyle{Traits::Polygon} defined by the
|
|
vertices of type \ccStyle{Traits::Point} in the range $[Bfirst,Blast)$.
|
|
It returns \ccStyle{true} if the polygons $A$ and $B$ do intersect.
|
|
\ccPrecond $A$ and $B$ simple polygons, their vertices are in
|
|
counterclockwise order.}
|
|
|
|
|
|
|
|
% --------------- INTERSECTION
|
|
\ccGlobalFunction{template <class ForwardIterator, class OutputIterator, class Traits>
|
|
OutputIterator
|
|
intersection( ForwardIterator Afirst, ForwardIterator Alast,
|
|
ForwardIterator Bfirst, ForwardIterator Blast,
|
|
Traits &,
|
|
OutputIterator list_of_objects_it);}
|
|
{with polygon \ccStyle{A} of type \ccStyle{Traits::Polygon} defined by the
|
|
vertices of type \ccStyle{Traits::Point} in the range
|
|
$[Afirst,Alast)$
|
|
and with polygon \ccStyle{B} of type \ccStyle{Traits::Polygon} defined by the
|
|
vertices of type \ccStyle{Traits::Point} in the range $[Bfirst,Blast)$,
|
|
computes the intersection of two simple polygons and places all
|
|
resulting objects as a sequence of objects of type \ccStyle{Object}
|
|
in a container of type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator})
|
|
\ccc{list_of_objects_it} which points to the first object in the
|
|
sequence.
|
|
The function returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to the position beyond the end of the sequence.
|
|
In case of an
|
|
empty intersection no objects are put into the output operator.
|
|
If an object in the sequence to which the output iterator refers is a
|
|
polygon, then this polygon is of type \ccStyle{Traits::Polygon} with
|
|
vertices of type \ccStyle{Traits::Point} and container
|
|
\ccStyle{Traits::Container}.
|
|
\ccPrecond $A$ and $B$ simple polygons, their vertices are in
|
|
counterclockwise order.
|
|
}
|
|
|
|
|
|
% --------------- UNION
|
|
\ccGlobalFunction{template <class ForwardIterator, class OutputIterator, class Traits>
|
|
OutputIterator union(ForwardIterator Afirst, ForwardIterator Alast,
|
|
ForwardIterator Bfirst, ForwardIterator Blast,
|
|
Traits &,
|
|
OutputIterator list_of_objects_it);}
|
|
{with polygon \ccStyle{A} of type \ccStyle{Traits::Polygon} defined by the
|
|
vertices of type
|
|
\ccStyle{Traits::Point} in the range
|
|
$[Afirst,Alast)$
|
|
and with polygon \ccStyle{B} of type \ccStyle{Traits::Polygon} defined by the
|
|
vertices of type \ccStyle{Traits::Point} in the range $[Bfirst,Blast)$.
|
|
Computes the union of two simple polygons ($A \cup B$) and places all
|
|
resulting objects as a sequence of objects of type \ccStyle{Object}
|
|
in a container of type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator})
|
|
\ccc{list_of_objects_it} which points to the first object in the
|
|
sequence.
|
|
It returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to position beyond the end of the sequence.
|
|
If an object in the sequence to which the output iterator refers is a
|
|
polygon, then this polygon is of type \ccStyle{Traits::Polygon} with
|
|
vertices of type \ccStyle{Traits::Point} and container
|
|
\ccStyle{Traits::Container}.
|
|
\ccPrecond $A$ and $B$ simple polygons, their vertices are in
|
|
counterclockwise order.
|
|
}
|
|
|
|
|
|
% --------------- DIFFERENCE
|
|
\ccGlobalFunction{template <class ForwardIterator, class OutputIterator, class Traits>
|
|
OutputIterator difference(ForwardIterator Afirst, ForwardIterator Alast,
|
|
ForwardIterator Bfirst, ForwardIterator Blast,
|
|
Traits &,
|
|
OutputIterator list_of_objects_it);}
|
|
{with polygon \ccStyle{A} of type \ccStyle{Traits::Polygon} defined by the
|
|
vertices of type
|
|
\ccStyle{Traits::Point} in the range
|
|
$[Afirst,Alast)$
|
|
and with polygon \ccStyle{B} of type \ccStyle{Traits::Polygon} defined by the
|
|
vertices of type \ccStyle{Traits::Point} in the range $[Bfirst,Blast)$,
|
|
computes the difference of two simple polygons ($A \setminus B$) and places
|
|
all resulting objects of type \ccStyle{Object} in a container of
|
|
type corresponding to the type of
|
|
output iterator (\ccStyle{OutputIterator}) \ccc{list_of_objects_it}
|
|
which points to the first object in the
|
|
sequence.
|
|
The function returns an output iterator (\ccStyle{OutputIterator})
|
|
pointing to the position beyond the end of the sequence.
|
|
The difference can be empty in which case no object will be put
|
|
in the output iterator.
|
|
If an object in the sequence to which the output iterator refers is a
|
|
polygon, then this polygon is of type \ccStyle{Traits::Polygon} with
|
|
vertices of type \ccStyle{Traits::Point} and container
|
|
\ccStyle{Traits::Container}.
|
|
\ccPrecond $A$ and $B$ simple polygons, their vertices are in
|
|
counterclockwise order.
|
|
}
|
|
|
|
|
|
% **********************************************************************
|
|
|
|
|
|
|
|
\ccExample
|
|
|
|
Principally, Boolean operations work as follows, illustrated by the example
|
|
of intersecting two polygons:
|
|
\begin{enumerate}
|
|
|
|
\item
|
|
To use the predefined boolean operations traits class
|
|
\ccc{bops_traits_2<R>},
|
|
include the file \ccStyle{bops_traits_2.h}.
|
|
For details see Section \ref{B_ops_Predef}.
|
|
|
|
\item
|
|
Instantiation of two polygons that can be triangles,
|
|
iso oriented rectangles, or simple polygons.
|
|
A polygon can be represented as an object (e.g. \ccStyle{Polygon_2})
|
|
or as a sequence of points held
|
|
in a sequence container (e.g. \emph{STL}-list).
|
|
|
|
\item Performing the boolean operation:
|
|
|
|
\begin{verbatim}
|
|
intersection(A.begin(), A.end(), B.begin(), B.end(), traits, result);
|
|
intersection(A, B, result);
|
|
\end{verbatim}
|
|
|
|
\item Taking the result of the operation:
|
|
|
|
The result consists of a sequence of points, segments, and simple
|
|
polygons. Hence,
|
|
the user has to check what type of element has to be performed for further
|
|
computations.
|
|
|
|
\end{enumerate}
|
|
|
|
The full example (depicted in figure \ref{fig-example-1})
|
|
instantiates two simple polygons and computes their intersection.
|
|
Note: here the non-exact (builtin) number type \ccc{float} is used.
|
|
|
|
\begin{figure}[th]
|
|
\begin{center}
|
|
\includegraphics{b-ops-2D-example-1.eps}
|
|
\caption{Intersection example of two simple polygons
|
|
(in cartesian coordinates).}
|
|
\label{fig-example-1}
|
|
\end{center}
|
|
\end{figure}
|
|
|
|
\cprogfile{b-ops-2D-example-1.C}
|
|
|
|
The output of our small example program looks like as follows:
|
|
|
|
\begin{verbatim}
|
|
result size=2
|
|
PGN: 3 1 1 1 15 20 10 5 20 10
|
|
PGN: 3 25 20 10 3 1 1 35 20 10
|
|
\end{verbatim}
|
|
|
|
Its interpretation says that the result consists of two polygons
|
|
with size three (i.e. two triangles)
|
|
given by their vertices in homogeneous coordinates and counterclockwise order:
|
|
((1,1,1), (15,20,10), (5,20,10)) and ((25,20,10),(3,1,1),(35,20,10)).
|
|
|
|
|
|
From this (full) example can be seen how a boolean operation
|
|
could be applied in a safe and practical way.
|
|
The following sketch of a more advanced example shows how traits classes
|
|
can be used for performing boolean operations.
|
|
|
|
\begin{ccAdvanced}
|
|
%\cprogfile{b-ops-2D-example-2.C}
|
|
|
|
\begin{cprog}
|
|
|
|
#include <CGAL/bops_traits_2.h>
|
|
#include <CGAL/bops_Polygon_2_container.h>
|
|
|
|
typedef Cartesian<double> R;
|
|
typedef bops_traits_2<R> Traits;
|
|
typedef Traits::Polygon Polygon;
|
|
typedef Traits::Output_object_container Output_container;
|
|
|
|
void myFunction() {
|
|
Polygon polygon;
|
|
Traits traits_class;
|
|
|
|
polygon A, B; /* instantiate A and B */
|
|
/* ... */
|
|
|
|
Output_container result;
|
|
|
|
/* apply a boolean operation: */
|
|
intersection(A.begin(), A.end(), B.begin(), B.end(),
|
|
traits_class, back_inserter(result));
|
|
|
|
/* do something with the result: */
|
|
/* ... */
|
|
|
|
}
|
|
\end{cprog}
|
|
|
|
\end{ccAdvanced}
|
|
|
|
|
|
|
|
|
|
\ccImplementation
|
|
|
|
The algorithms for boolean operations of two polygons are (efficient)
|
|
specialized methods for specific objects.
|
|
Depending on the polygon type we switch internally to the best suited
|
|
routines. For instance, for two triangles we switch to a more
|
|
efficient algorithm than the general one on polygons.
|
|
|
|
The memory consumption is $O(n)$
|
|
(where $n$ is the whole number of vertices of the input polygons).
|
|
The time complexity is $O(n^2)$ for simple polygons,
|
|
and $O(1)$ for triangles and iso-oriented rectangles.
|
|
|
|
Note: As mentioned above,
|
|
the result is sometimes returned as iterators pointing to
|
|
a \ccStyle{list<Object>}, where \ccStyle{list} is
|
|
a \emph{STL list container}, which implements a double
|
|
connected list (include file: \ccStyle{list.h}).
|
|
|
|
\ccSeeAlso
|
|
\ccc{Intersection}, \ccc{Polygon}, \ccc{Triangle}, and
|
|
\ccc{Iso_rectangle}.
|
|
|
|
|
|
\newpage
|
|
\section{Boolean Operations Traits Class Implementations}
|
|
|
|
\begin{ccClassTemplate}{bops_traits_2<R>}
|
|
\ccCreationVariable{Traits}
|
|
|
|
\ccSubsection{Traits Class Implementation
|
|
using the two-dimensional CGAL Kernel}
|
|
\label{B_ops_Predef}
|
|
%using the two-dimensional \cgal\ Kernel}
|
|
|
|
Since all geometric objects on which boolean operations act are
|
|
parameterized with a template for the representation class, also the
|
|
predefined boolean operations traits class is a template class with
|
|
a parameter for the representation class \ccTemplateParameters.
|
|
The predefined boolean
|
|
operations traits class is called \ccClassTemplateName.
|
|
|
|
|
|
\ccInclude{CGAL/bops_traits_2.h}
|
|
|
|
|
|
\ccTypes
|
|
|
|
%\ccSetThreeColumns{Oriented_side}{}{\hspace*{10cm}}
|
|
\ccSetTwoOfThreeColumns{10cm}{4cm}
|
|
|
|
\ccTypedef{ typedef Object Object;}{}
|
|
\ccTypedef{ typedef Bbox_2 Bbox;}{}
|
|
\ccTypedef{ typedef Point_2<R> Point;}{}
|
|
\ccTypedef{ typedef Segment_2<R> Segment;}{}
|
|
\ccTypedef{ typedef Triangle_2<R> Triangle;}{}
|
|
\ccTypedef{ typedef Iso_rectangle_2<R> Iso_rectangle;}{}
|
|
\ccTypedef{ typedef list<Object> Output_object_container;}{}
|
|
\ccTypedef{ typedef list<Point> Container;}{}
|
|
\ccTypedef{ typedef Container Input_polygon_container;}{}
|
|
\ccTypedef{ typedef list<Point> Output_polygon_container;}{}
|
|
\ccTypedef{ typedef Polygon_2<Polygon_traits_2<R>,Container> Polygon;}{}
|
|
\ccTypedef{ typedef Polygon Input_polygon;}{}
|
|
\ccTypedef{ typedef Polygon::Vertex_const_iterator Polygon_vertex_const_iterator;}{}
|
|
\ccTypedef{ typedef Polygon_2<R,Output_polygon_container> Output_polygon;}{}
|
|
%\ccTypedef{ typedef Direction_2<R> Direction;}{}
|
|
|
|
For more information about these types see \ref{B_ops_SectReq}.
|
|
|
|
\ccSetTwoOfThreeColumns{6cm}{5cm}
|
|
|
|
\ccCreation
|
|
\ccConstructor{ Traits<R>(); }{default constructor}
|
|
|
|
\ccSetTwoOfThreeColumns{2cm}{3cm}
|
|
|
|
\ccOperations
|
|
\ccMethod{ bool do_overlap( const Bbox& a, const Bbox& b) const;}{
|
|
returns \ccc{do_overlap(a,b)}.
|
|
}
|
|
\ccMethod{ bool box_is_contained_in_box( const Bbox& a, const Bbox& b) const;}
|
|
{
|
|
returns \ccc{true}
|
|
iff \ccc{ xmin(b) <= xmin(a) and
|
|
xmax(b) >= xmax(a) and
|
|
ymin(b) <= ymin(a) and
|
|
ymax(b) >= ymax(a) }.
|
|
}
|
|
|
|
\ccMethod{ bool is_equal(const Point& p1, const Point& p2) const;}{
|
|
returns \ccc{p1 == p2}.
|
|
}
|
|
\ccMethod{ bool less_x(const Point& p1, const Point& p2) const;} {
|
|
returns \ccc{p1.x() < p2.x();}
|
|
}
|
|
|
|
\ccMethod{ bool is_leftturn(const Point& p0, const Point& p1, const Point& p2) const;}{
|
|
returns \ccc{leftturn(p0, p1, p2)}.
|
|
}
|
|
|
|
\ccMethod{ Object Make_object(const Point& p) const;}{
|
|
returns \ccc{make_object(p)}.
|
|
}
|
|
\ccMethod{ Object Make_object(const Segment& seg) const;}{
|
|
returns \ccc{make_object(seg)}.
|
|
}
|
|
\ccMethod{ Object Make_object(const Output_polygon& pgon) const;}{
|
|
returns \ccc{make_object(pgon)}.
|
|
}
|
|
\ccMethod{ Object Make_object(const Iso_rectangle& irect) const;}{
|
|
returns \ccc{make_object(irect)}.
|
|
}
|
|
\ccMethod{ Object Make_object(const Triangle& triangle) const;}{
|
|
returns \ccc{make_object(triangle)}.
|
|
}
|
|
|
|
\ccMethod{ Bbox get_Bbox(const Polygon& pgon) const;} {
|
|
returns \ccc{pgon.bbox()}.
|
|
}
|
|
|
|
\ccMethod{ bool has_on_bounded_side(const Polygon& pgon, const Point& pt) const;} {
|
|
returns \ccc{pgon.has_on_bounded_side(pt)}.
|
|
}
|
|
\ccMethod{ void reverse_orientation(Polygon& pgon) const;}{
|
|
performs \ccc{pgon.reverse_orientation()}.
|
|
}
|
|
\ccMethod{ Polygon_vertex_const_iterator most_left_vertex(const Polygon& pgon) const;}{
|
|
returns \ccc{pgon.left_vertex()}.
|
|
}
|
|
|
|
\end{ccClassTemplate}
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
%% REQUIREMENTS FOR BOOLEAN OPERATIONS TRAITS CLASSES:
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
\begin{ccClassTemplate}{Traits<R>}
|
|
\ccCreationVariable{bops_traits}
|
|
|
|
\ccSection{Boolean Operations Traits Class Requirements}
|
|
\label{B_ops_SectReq}
|
|
|
|
\ccSetTwoOfThreeColumns{6cm}{5cm}
|
|
\ccSetOneOfTwoColumns{6cm}
|
|
|
|
\ccTypes
|
|
|
|
\ccNestedType{ Object;}{
|
|
A common object type like \ccc{object}.
|
|
The ''real'' objects (e.g. \ccc{Output_polygon}, \ccc{Segment},
|
|
\ccc{Point}, \dots)
|
|
are mapped into \ccc{Object} using the member function
|
|
\ccc{Make_object} (see below to the operations description).
|
|
}
|
|
|
|
\ccNestedType{ Point;} {
|
|
The point type on which the boolean operations algorithms operate.
|
|
It should represent a two dimensional point with coordinates of
|
|
type~\ccc{R::NT}.
|
|
The type must provide a copy constructor, an assignment, and an
|
|
equality test. Furthermore
|
|
a constructor for cartesian coordinates (\ccc{Point(R::NT,R::NT)}),
|
|
a constructor for homogeneous coordinates (\ccc{Point(R::NT,R::NT,R::NT)}),
|
|
and the operations
|
|
\ccc{R::NT Point::x()} and \ccc{R::NT Point::y()} are needed,
|
|
which returns the value of the \ccc{x}- or \ccc{y}-coordinate, respectively.
|
|
This point type represents the vertices of segments, triangles,
|
|
iso-oriented rectangles, and polygons,
|
|
which occur as possible results of a boolean operation.
|
|
}
|
|
\ccNestedType{ Segment;}{ Line segment type.
|
|
It should represent a two dimensional
|
|
segment defined by the two extremal points of type \ccc{Point}.
|
|
The type must provide a copy constructor, an assignment, and an equality test.
|
|
Furthermore a constructor by two points (\ccc{Segment(Point,Point)})
|
|
will be needed.
|
|
}
|
|
\ccNestedType{ Triangle;}{
|
|
The type of triangles on which boolean operations can be performed.
|
|
It should represent a triangle in two
|
|
dimensional Euclidean space with vertices of type \ccc{Point}.
|
|
The type must provide a copy constructor, an assignment, and an equality test.
|
|
Furthermore a constructor by three points (\ccc{Triangle(Point,Point,Point)})
|
|
will be needed.
|
|
}
|
|
\ccNestedType{ Iso_rectangle;}{
|
|
The type of iso-oriented rectangles on which boolean operations
|
|
can be performed.
|
|
It should represent an iso-oriented rectangle in two dimensional
|
|
Euclidean space with vertices of type \ccc{Point}.
|
|
The type must provide a copy constructor, an assignment, and an equality test.
|
|
Furthermore a constructor by three points
|
|
(\ccc{Iso_rectangle(Point,Point,Point)}) will be needed.
|
|
}
|
|
\ccNestedType{ Polygon;}{
|
|
The type of polygons on which boolean operations will be performed
|
|
(i.e. \ccc{Input_polygon}, there also exists an \ccc{Output_polygon}).
|
|
This type should represent a simple polygon
|
|
in two dimensional Euclidean space with vertices of type \ccc{Point}.
|
|
Usually it is based on \ccc{Container}.
|
|
The type must provide a copy constructor, an assignment, and an equality test.
|
|
}
|
|
\ccNestedType{ Polygon_vertex_const_iterator;}{
|
|
A (const) vertex forward iterator for \ccc{Polygon}.
|
|
}
|
|
\ccTypedef{typedef Polygon Input_polygon;}{}
|
|
\ccNestedType{ Output_polygon;}{ The resulting polygon type.
|
|
Usually based on \ccc{Output_polygon_container}.
|
|
This type must represent a simple polygon
|
|
in two dimensional Euclidean space with vertices of type \ccc{Point}.
|
|
}
|
|
|
|
\ccNestedType{ Bbox;}{
|
|
A bounding box type used
|
|
internally in the computation of boolean operations.
|
|
The type must provide an equality test.
|
|
}
|
|
|
|
\ccNestedType{ Container;}{
|
|
The container in which
|
|
points of type \ccc{Point} are stored for further use in
|
|
polygons on which boolean operations are to be performed
|
|
(\ccc{Input_polygon_container}).
|
|
Note: The only usage of \ccc{Container} is to define
|
|
\ccc{Polygon}.
|
|
}
|
|
\ccTypedef{ typedef Container Input_polygon_container;}{}
|
|
\ccNestedType{ Output_polygon_container;}{
|
|
The container in which
|
|
points of type \ccc{Point} are stored for further use in
|
|
polygons (\ccc{Output_polygon})
|
|
which result by performing boolean operations.
|
|
Note: The only usage of \ccc{Output_polygon_container} is to define
|
|
\ccc{Output_polygon}.
|
|
}
|
|
\ccNestedType{ Output_object_container;}{
|
|
The container in which objects of type \ccc{Object} are stored.
|
|
This container represents the result of a boolean operation,
|
|
since each resulting object (e.g. \ccc{Output_Polygon}, \ccc{Segment},
|
|
\dots) is mapped into a \ccc{Object}.
|
|
and afterwards stored
|
|
into a container of this type \ccc{Output_object_container}.
|
|
It must provide a operation
|
|
\ccc{Output_object_container::push_back(Object)}.
|
|
}
|
|
|
|
|
|
|
|
\ccCreation
|
|
\ccConstructor{ Traits<R>(); }{default constructor}
|
|
|
|
\ccSetTwoOfThreeColumns{2cm}{3cm}
|
|
|
|
\ccOperations
|
|
\ccMethod{ bool do_overlap( const Bbox& a, const Bbox& b) const;}{
|
|
returns \ccc{true} iff the boxes do overlap.
|
|
}
|
|
\ccMethod{ bool box_is_contained_in_box( const Bbox& a, const Bbox& b) const;} {
|
|
returns \ccc{true} iff \ccc{a} is contained in \ccc{b}, entirely.
|
|
}
|
|
|
|
\ccMethod{ bool is_equal(const Point& p1, const Point& p2) const;}{
|
|
returns \ccc{true} iff the value of \ccc{p1} is equal to the value of \ccc{p2}.
|
|
}
|
|
\ccMethod{ bool less_x(const Point& p1, const Point& p2) const;} {
|
|
returns \ccc{true} iff the x-coordinate of \ccc{p1} is smaller than that
|
|
of \ccc{p2}.
|
|
}
|
|
|
|
|
|
\ccMethod{ bool is_leftturn(const Point& p0, const Point& p1, const Point& p2) const;}{
|
|
returns \ccc{true} iff \ccc{p2} lies on the left of the oriented line
|
|
through \ccc{p0} and \ccc{p1}.
|
|
}
|
|
|
|
\ccMethod{ Object Make_object(const Point& p) const;}{
|
|
maps \ccc{Point} into \ccc{Object} and returns it.
|
|
}
|
|
\ccMethod{ Object Make_object(const Segment& p) const;}{
|
|
maps \ccc{Segment} into \ccc{Object} and returns it.
|
|
}
|
|
\ccMethod{ Object Make_object(const Output_polygon& p) const;}{
|
|
maps \ccc{Output_polygon} into \ccc{Object} and returns it.
|
|
}
|
|
\ccMethod{ Object Make_object(const Iso_rectangle& p) const;}{
|
|
maps \ccc{Iso_rectangle} into \ccc{Object} and returns it.
|
|
}
|
|
\ccMethod{ Object Make_object(const Triangle& p) const;}{
|
|
Maps \ccc{Triangle} into \ccc{Object} and returns it.
|
|
}
|
|
|
|
|
|
\ccMethod{ Bbox get_Bbox(const Polygon& pgon) const;} {
|
|
returns the bounding box of \ccc{Polygon}.
|
|
}
|
|
|
|
\ccMethod{ bool has_on_bounded_side(const Polygon& pgon, const Point& pt) const;} {
|
|
returns \ccc{true} iff point \ccc{pt} lies on the bounded side of
|
|
polygon \ccc{pgon}.
|
|
}
|
|
\ccMethod{ void reverse_orientation();(Polygon& pgon) const;}{
|
|
reverses the orientation of polygon \ccc{pgon}.
|
|
}
|
|
\ccMethod{ Polygon_vertex_const_iterator most_left_vertex(const Polygon& pgon) const;}{
|
|
returns the most left vertex of polygon \ccc{pgon}.
|
|
}
|
|
|
|
\end{ccClassTemplate}
|
|
|