%+------------------------------------------------------- %| CGAL Manual : pmwx.tex %+-------------------------------------------------------- %| update log %| %| 04 May 2001 - Eyal Flato %| Created from arr documentation %| 15 May 2003 - Efi Fogel %| Cleanup %| 1 July 2003 - Ron Wein %| Some more revisions %-------------------------------------------------------- \section{Introduction} Given a collection ${\mathcal C}$ of (possibly intersecting and not necessarily $x$-monotone curves) in the plane, we construct a collection ${\mathcal C}''$ in two steps, as follows: First, we decompose each curve in ${\mathcal C}$ into maximal $x$-monotone curves, thus obtaining the collection ${\mathcal C}'$. Second, We decompose each curve in ${\mathcal C}'$ into maximal connected pieces not intersecting any other curve in ${\mathcal C}'$. This way we obtain the collection ${\mathcal C}''$ of $x$-monotone, pairwise interior disjoint curves. Constructing the {\it planar map with intersection} of the curves in ${\mathcal C}$ is therefore equivalent to the construction of the {\it planar map}(see Chapter~\ref{I1_ChapterPlanarMap}) induced by the curves in ${\mathcal C}''$. The \ccc{Planar Map with Intersections} package extends the functionality of the \ccc{Planar Map} package by enabling simple insertion of intersecting and not necessarily $x$-monotone curves. The \ccc{Planar_map_with_intersections_2} class has different insertion functions but it uses the same data structures as the \ccc{Planar_map_2} class. Therefore, almost any functionality of the planar map is also supported here (e.g., traversal of planar map features, point location queries and I/O operations are supported but infinite objects are not supported). However, to maintain a planar map with intersections one obviously needs to support some additional functions in the geometric traits class, handling with intersections and $x$-monotonicity. Note that if one needs to build a planar map of $x$-monotone, pairwise interior disjoint curves, then it would be more efficient (in running time) and less demanding (in traits class functionality) to use the \ccc{Planar_map_2} class instead. \paragraph{Degeneracies} Like the \ccc{Planar Map} package (see Chapter~\ref{I1_ChapterPlanarMap}), the \ccc{Planar Map with Intersections} package can deal with $x$-degenerate input (including vertical segments). However, while in the planar map the input curves were assumed to be non-intersecting in their interiors, there is no such assumption when using planar map with intersections. Furthermore, overlapping curves are also supported: If two curves overlap the traits intersection function must return the two endpoints of the common part. %--------------------------------------------------- \subsection{A Simple Program} \label{ssec:example1} The simple program listed below demonstrates the construction of an $X$-shaped planar subdivision out of two intersecting segments. The coordinates of the halfedges of the constructed subdivision are printed to standard output. \ccIncludeExampleCode{Pm_with_intersections/example1.C} The output of the program looks like this: \begin{verbatim} Inserting the segments: 0 0 1 1 0 1 1 0 Edges of the planar map: 0 0 --- 0.5 0.5 0.5 0.5 --- 1 1 0 1 --- 0.5 0.5 1 0 --- 0.5 0.5 \end{verbatim} \section{Architecture} The \ccc{Planar_map_with_intersections_2 >} class is parameterized with the \ccc{Planar_map_2} class it inherits from, which includes the \ccc{Dcel} object represents the underlying topological data structure and maintains a {\em doubly-connected edge list}. The geometric functionality is provided by the \ccc{Traits} class, and is tailored to handle a specific family of curves. It encapsulates the number type used and the coordinate representation. This package contains traits classes that handle various types of curves (e.g., segments, polylines, conics, etc.). \subsection{Operations} The set of operations that can be applied to a planar map with intersection is divided into four subsets, namely constructors, modifiers, queries, and input/output operations. These operations are overviewed in detail in section~\ref{I1_ChapterPlanarMap}, so next we will just emphasize the differences between the two classes. % RWRW - Give a more exact reference. \subsubsection{Aggregated Insert} A \ccc{Planar Map with Intersections} can be built incrementally by inserting one curve after the other into the map. However, for a large number of curves that intersect rather sparsely, it can be more efficient to use the aggregate insertion method, that inserts a set of curves to an empty map at once by performing the sweep-line algorithm on the set of input curves. The aggregate insertion method is more efficient in many cases and it also has less requirements from the traits class, in comparison with the the incremental insertion function. Namely, the \ccc{curves_compare_y_at_x_left()} and the \ccc{nearest_intersection_to_left()} functions are not required, nor do the various reflection functions. \subsubsection{Example of Aggregate Insertion} \label{sssec:example1_aggrinsrt} The following example demonstrates the usage of the aggregate insertion method. It constructs a planar map out of four segments --- $(0,0)-(1,1)$ , $(0,1)-(1,0)$ , $(0,0)-(1,0)$ and $(0,1)-(1,1)$ (an hourglass shape), two of them are intersecting in their interior. The resulting planar map will contain all the disjoint interior sub-segments obtained by the calculation of the sweep line algorithm. For clarity, we printed all the halfedges of the resulting planar map to the standard output. % RWRW - where are the examples? %\ccIncludeExampleCode{Sweep_line_2/example1.C} The output of the program looks like this: % RWRW - Where are the examples? %\ccIncludeExampleCode{Sweep_line_2/example1.cout} \subsubsection{Non Intersecting Insertion Functions} In some cases the users insert curves to a planar map with intersections in an incremental manner, but have some knowledge regarding the location of several curves. In such cases, special insertion functions may be called in order to speed up the construction of the map: \begin{itemize} \item If it is known in advance that the current curve is $x$-monotone and does not intersect any one of the curves currently in the map in its interior, it is possible to insert this curve using the \ccc{non_intersecting_insert()} function. A similar function is also available for a range of $x$-monotone and interior-disjoint curves, that does not induce any intersection with the existing curves in the map. \item Sometimes the exact location of the $x$-monotone curve in the map is known. It may be inserted (1) within the interior of a given face, (2) with one given vertex as one of its endpoints, or (3) between to given vertices. The \ccc{non_intersecting_insert_in_face_interior()}, \ccc{non_intersecting_insert_from_vertex()} and \ccc{non_intersecting_insert_at_vertices()} functions serve for this purpose. For more details regrading these special insertion functions, as well as for an example for their usage, see section~\ref{I1_ChapterPlanarMap}. % RWRW - refine this reference. \end{itemize} \begin{ccAdvanced} \subsection{Change Notification} %----------------------------------------------- An insertion of an intersecting curve into a planar map may add several halfedges and modify several features of the map (i.e. split halfedges, split faces, etc.). The so-called \ccc{Change Notification} class provides this kind of flexibility. The modification methods accept an additional parameter, a class which is a model of the \ccc{PlanarMapWithIntersectionsChangeNotification_2} concept. The change notification includes an associative function for each modification method. This function is called after each such modification. The change notification class is useful in many cases. For example, one may add a color (or other extra data) to any halfedge of a planar map. An insertion of a new curve can split halfedges that were previously in the map. After such a split the color of the newly created halfedges should be updated according to the original color of the split halfedge. One can do this by implementing the \ccc{split_edge} function of the change notification class. This function will be called after each split of an halfedge in the map. \subsubsection{Example of Change Notification} \label{ssecn:example2} The following example demonstrates the usage of the change notification concept during the construction of a planar map out of three segments --- $(0,1)-(1,0)$, $(0,0)-(1,1)$ and $(0,1)-(1,1)$. During the insertion we use \ccc{My_notification} instance to output the internal process of the construction of the planar map. We also count how many edges are in the map by incrementing a counter each time an edge is added (\ccc{add_edge}) or split (\ccc{split_edge}). \ccIncludeExampleCode{Pm_with_intersections/example2.C} The output of the program looks like this: \begin{verbatim} inserting 0 1 1 0 add_edge add_hole inserting 0 0 1 1 split_edge add_edge add_edge inserting 0 1 1 1 add_edge split_face Total number of edges 5 \end{verbatim} \end{ccAdvanced}