From a8b5dfcdcfd96ca5d4d1bd515a9af5f40af85ca6 Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Wed, 28 Nov 2007 00:07:41 +0000 Subject: [PATCH] Simplified API documentation --- .../Straight_skeleton_user.tex | 60 ++++++++++++++----- .../Create_offset_polygons_2.cpp | 4 -- .../Create_skeleton_and_offset_polygons_2.cpp | 7 --- ...leton_and_offset_polygons_with_holes_2.cpp | 4 -- .../Create_straight_skeleton_2.cpp | 2 +- 5 files changed, 45 insertions(+), 32 deletions(-) diff --git a/Straight_skeleton_2/doc_tex/Straight_skeleton_2/Straight_skeleton_user.tex b/Straight_skeleton_2/doc_tex/Straight_skeleton_2/Straight_skeleton_user.tex index 1a229697b1b..792efceb98a 100644 --- a/Straight_skeleton_2/doc_tex/Straight_skeleton_2/Straight_skeleton_user.tex +++ b/Straight_skeleton_2/doc_tex/Straight_skeleton_2/Straight_skeleton_user.tex @@ -365,16 +365,53 @@ The simplest way to construct a straight skeleton is via the free functions \ccc \ccIncludeExampleCode{Straight_skeleton_2/Create_straight_skeleton_2.cpp} -The input to these functions is the polygon, which can be given as an iterator pair or directly as a \ccc{Polygon_2} object. In the case of the exterior skeleton, a maximum offset must be specfied as well (see the ref manual details on this max offset parameter). +The input to these functions is the polygon, which can be given as an iterator pair or directly as a \ccc{Polygon_2} object. In the case of the exterior skeleton, a maximum offset must be specfied as well (see the ref manual for details on this max offset parameter). -If \ccc{Polygon_with_holes_2} is used, you can pass an instance of that directly to the function creating the interior skeleton, as shown below. Notice that a different header must be included in this case. +If \ccc{Polygon_with_holes_2} is used, you can pass an instance of it directly to the function creating the interior skeleton, as shown below. Notice that a different header must be included in this case. -\ccIncludeExampleCode{Straight_skeleton_2/Create_straight_skeleton_2.cpp} +\ccIncludeExampleCode{Straight_skeleton_2/Create_straight_skeleton_from_polygon_with_holes_2.cpp} + +If you already have a straight skeleton instance, the simpler way to generate offset polygons is to call \ccc{create_offset_polygons_2} as shown in the next example, passing the desired offset and the straight skeleton. You can reuse the same skeleton to generate offsets at a different distance, which is recommended because producing the straight skeleton is much slower then generating offset polygons. + +\ccIncludeExampleCode{Straight_skeleton_2/Create_offset_polygons_2.cpp} + +If you need offset polygons at just one single distance, you can hide away the construction of the straight skeleton by calling directly the functions \ccc{create_interior_skeleton_and_offset_polygons_2} and \ccc{create_exterior_skeleton_and_offset_polygons_2} as shown in the following examples: + +\ccIncludeExampleCode{Straight_skeleton_2/Create_skeleton_and_offset_polygons_2.cpp} + +... and using a \ccc{Polygon_with_holes_2} directly when available: + +\ccIncludeExampleCode{Straight_skeleton_2/Create_skeleton_and_offset_polygons_from_polygon_with_holes_2.cpp} + +If the input polygon has holes, there can be holes in the offset polygons. +However, the polygons generated by all the offseting functions shown before +do not have any parent-hole reationship computed; that is, they just instances +of \ccc{Polygon_2} instead of \ccc{Polygon_with_holes_2}. +If \ccc{Polygon_with_holes_2} are available and you need the offseting to produce them, you can call the function \ccc{arrange_offset_polygons_2} passing the result of any of the offseting functions described so far. That function arranges the offset polygons detecting and distributing holes within parents. +As a shortcut, you can use the function \ccc{create_interior_skeleton_and_offset_polygon_with_holes_2} as shown below: + +\ccIncludeExampleCode{Straight_skeleton_2/Create_skeleton_and_offset_polygons_with_holes_2.cpp} + +\begin{ccAdvanced} +Consider an input polygon with parallel edges separated a distance $2*t$. If you produce an offset polygon at distance $t$, these parallel edges will just collapse each other and vanish from the result, keeping the output as a {\em simple polygon}, just like the input. However, if you request an offset poygon at a distance $t-epsilon$, the result will still be a simple polygon but with edges that are so close to each other that will almost intersect. +If a kernel with exact constructions is used, the offseting algorithm can guarantee that the output contains only simple polygons. However, if inexact constructions are used the roundoff in the coordinates of the output points will cause parallel edges that {\em almost} collapse-but not so-to become really collinear or even cross each other. + +Thus, it is neccesary to use a kernel with exact constructions if offset polygons must be simple, yet computing a straight skeleton using that kernel is very slow, much more than computing the offset polygons. To help with this, it is possible to construct the straight skeleton using the recommended kernel \ccc{Exact_predicates_inexact_constructions_kernel}, then convert the skeleton to a different kernel via the function \ccc{convert_straight_skeleton_2} and input the converted skeleton to the offsetting functions. + +All the offsetting functions that take polygons as input (and create the straight skeleton under the hood) apply that optimization automatically: that is, the output polygons are defined over the same kernel of the input polygons, whatever that is, yet the straight skeleton is constructed with the faster recommended kernel and converted if neccessary. + +Notice how some of the examples above use \ccc{Exact_predicates_exact_constructions_kernel}. In all cases, the straight skeleton is constructed using \ccc{Exact_predicates_inexact_constructions_kernel}. + +\end{ccAdvanced} \subsection{Low level API} +All the high level functions described above are just wrappers around the low level +API described here. This low level API is richer and provides options and configurations +not covered by any of those functions. + The straight skeleton construction algorithm is encapsulated in the -class \ccc{Straight_skeleton_builder_2} which is +class \ccc{Straight_skeleton_builder_2} which is parameterized on a geometric traits (class \ccc{Straight_skeleton_builder_traits}) and the Straight Skeleton class (Ss). @@ -426,7 +463,7 @@ indication whatsoever of the parental relationship between inner and outer conto On the other hand, each outer contour is counter-clockwise oriented while each hole is clockwise-oriented. And since offset contours do form simple polygons with holes, it is guaranteed that no hole will be inside another hole, no outer contour will be inside any other contour, and each hole will be inside exactly 1 outer contour. -Parental relationships are {\em not} automatically reconstructed by this algorithm because this relation is not directly given by the input polygon with holes and doing it \textit{robustly} is a time-consuming operation. +Parental relationships are {\em not} automatically reconstructed by this algorithm because this relation is not directly given by the input polygon with holes and must be done as a post processing step. The function \ccc{arrange_offset_polygons_2} can be used to do that efficiently. A user can reconstruct the parental relationships as a post processing operation by testing each inner contour (which is identified by being clockwise) against each outer contour (identified as being counter-clockwise) for insideness. @@ -434,6 +471,8 @@ by testing each inner contour (which is identified by being clockwise) against e This algorithm requires exact predicates but not exact constructions Therefore, the \ccc{Exact_predicates_inexact_constructions_kernel} should be used. +\ccIncludeExampleCode{Straight_skeleton_2/Low_level_API.cpp} + \subsection{Exterior Skeletons and Exterior Offset contours} This \cgal\ package can only construct the straight skeleton and offset contours in the \textit{interior} of a polygon with holes. However, constructing exterior skeletons and exterior offsets is possible: @@ -482,17 +521,6 @@ If you use this function to place the outer frame you are guaranteed to obtain a \label{Exterior}} \end{figure} -\subsection{Example} - -\ccIncludeExampleCode{Straight_skeleton_2/Low_level_API.cpp} - -The offset polygon builder outputs only simple polygons provided exact constructions are used. However, if inexact constructions are used there is no guarantee that offset polygons will be simple. You can use \ccc{Exact_predicates_exact_constructions_kernel} to instantiate \ccc{Polygon_offset_builder_2}, but this kernel is significantly slower compared to -\ccc{Exact_predicates_inexact_constructions_kernel}. -To improve the overall running time, you can use inexact constructions to create the straight skeleton itself (the algorithm doesn't need exact constructions), then convert the straight skeleton \ccc{Straight_skeleton_converter_2} to the types corresponding the exact constructions kernel, then pass it to the offset builder. - -The following example illustrates how to do that: - -%%\ccIncludeExampleCode{Straight_skeleton_2/Straight_skeleton_converter_2.cpp} \section{Straight Skeletons, Medial Axis and Voronoi Diagrams} diff --git a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_offset_polygons_2.cpp b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_offset_polygons_2.cpp index f1633eed516..61d4af57960 100644 --- a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_offset_polygons_2.cpp +++ b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_offset_polygons_2.cpp @@ -1,8 +1,4 @@ #include -#include -#include -#include -#include #include diff --git a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_2.cpp b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_2.cpp index 3743f34a7bf..38376509dc4 100644 --- a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_2.cpp +++ b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_2.cpp @@ -1,8 +1,4 @@ #include -#include -#include -#include -#include #include @@ -40,9 +36,6 @@ int main() FT lOffset = 1 ; - // While the input and output polygons are defined over a kernel with exact constructions, - // the straight skeleton is constructed using inexact constructions, which is much faster. - PolygonPtrVector inner_offset_polygons = CGAL::create_interior_skeleton_and_offset_polygons_2(lOffset,poly); PolygonPtrVector outer_offset_polygons = CGAL::create_exterior_skeleton_and_offset_polygons_2(lOffset,poly); diff --git a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_with_holes_2.cpp b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_with_holes_2.cpp index d56a00e7df4..6d5df7161b2 100644 --- a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_with_holes_2.cpp +++ b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_with_holes_2.cpp @@ -1,8 +1,4 @@ #include -#include -#include -#include -#include #include diff --git a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_straight_skeleton_2.cpp b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_straight_skeleton_2.cpp index 7458c7593da..ed2c6cac0f5 100644 --- a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_straight_skeleton_2.cpp +++ b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_straight_skeleton_2.cpp @@ -27,7 +27,7 @@ int main() poly.push_back( Point(-1,1) ) ; poly.push_back( Point(-12,0) ) ; - // You can pass the polygon via a pointer-iterator pair + // You can pass the polygon via an iterator pair SsPtr iss = CGAL::create_interior_straight_skeleton_2(poly.vertices_begin(), poly.vertices_end()); // Or you can pass the polygon directly, as below.