%----------------------------------------------------------------------------- % 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}, 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} 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}, \ccc{Homogeneous}, or \ccc{Cartesian}. \ccCommentHeading{\ccc{Container}} The container type \ccStyle{Container} for a polygon. The user must pre-instantiate this for instance by \ccStyle{list > >}. \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::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::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} \\ \hline \ccc{Traits::Point} & 2D point & \ccc{Point_2 >} \\ \hline \ccc{Traits::Segment} & 2D segment & \ccc{Segment_2 >} \\ \hline \ccc{Traits::Triangle} & 2D triangle & \ccc{Triangle_2} \\ \hline \ccc{Traits::Iso_rectangle} & 2D iso-oriented rectangle & \ccc{Iso_rectangle_2} \\ \hline \ccc{Traits::Container} & container type for polygon & \ccc{list >} \\ \hline \ccc{Traits::Polygon} & 2D polygon & \ccc{Polygon_2, 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 bool do_intersect(const Iso_rectangle_2 &A, const Iso_rectangle_2 &B);} { returns \ccStyle{true} if the iso-oriented rectangles $A$ and $B$ do intersect.} % --------------- INTERSECTION \ccFunction{template OutputIterator intersection(const Iso_rectangle_2 &A, const Iso_rectangle_2 &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 OutputIterator union(const Iso_rectangle_2 &A, const Iso_rectangle_2 &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 OutputIterator difference(const Iso_rectangle_2 &A, const Iso_rectangle_2 &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 bool do_intersect( const Triangle_2 &A, const Triangle_2 &B);} { returns \ccStyle{true} if the triangles $A$ and $B$ do intersect.} \ccFunction{template OutputIterator intersection( const Triangle_2 &A, const Triangle_2 &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 OutputIterator union(const Triangle_2 &A, const Triangle_2 &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 OutputIterator difference(const Triangle_2 &A, const Triangle_2 &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 bool do_intersect( const Polygon_2,Container> &A, const Polygon_2,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 OutputIterator intersection( const Polygon_2,Container> &A, const Polygon_2,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 OutputIterator union( const Polygon_2,Container> &A, const Polygon_2,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 OutputIterator difference( const Polygon_2,Container> &A, const Polygon_2,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 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 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 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 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}, 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 #include typedef Cartesian R; typedef bops_traits_2 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}, 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} \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 Point;}{} \ccTypedef{ typedef Segment_2 Segment;}{} \ccTypedef{ typedef Triangle_2 Triangle;}{} \ccTypedef{ typedef Iso_rectangle_2 Iso_rectangle;}{} \ccTypedef{ typedef list Output_object_container;}{} \ccTypedef{ typedef list Container;}{} \ccTypedef{ typedef Container Input_polygon_container;}{} \ccTypedef{ typedef list Output_polygon_container;}{} \ccTypedef{ typedef Polygon_2,Container> Polygon;}{} \ccTypedef{ typedef Polygon Input_polygon;}{} \ccTypedef{ typedef Polygon::Vertex_const_iterator Polygon_vertex_const_iterator;}{} \ccTypedef{ typedef Polygon_2 Output_polygon;}{} %\ccTypedef{ typedef Direction_2 Direction;}{} For more information about these types see \ref{B_ops_SectReq}. \ccSetTwoOfThreeColumns{6cm}{5cm} \ccCreation \ccConstructor{ Traits(); }{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} \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(); }{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}