Merge branch 'MS_2-decomposition_optimization-efif-old' into MS_2-decomposition_optimization-efif

Conflicts:
	Documentation/biblio/cgal_manual.bib
	Documentation/biblio/geom.bib
	Minkowski_sum_2/doc/Minkowski_sum_2/Minkowski_sum_2.txt
	Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum_with_holes.cpp
This commit is contained in:
Efi Fogel 2016-02-24 18:25:07 +02:00
commit bbc514714c
13 changed files with 1232 additions and 222 deletions

View File

@ -0,0 +1,24 @@
namespace CGAL {
/*!
\ingroup PkgMinkowskiSum2
\anchor mink_refnop_decomp
The `Polygon_nop_decomposition_2` class implements a convex
decompistion of a polygon, which merely passes the input polygon into
the list of output convex polygons. It should be used when it is known
that the input polygon is convex to start with.
\cgalModels `PolygonConvexDecomposition_2`
*/
template <typename Kernel, typename Container>
class Polygon_nop_decomposition_2 {
public:
/// @{
/// @}
}; /* end Polygon_nop_decomposition_2 */
} /* end namespace CGAL */

View File

@ -64,19 +64,98 @@ minkowski_sum_by_full_convolution_2(const Polygon_2<Kernel, Container>& P,
\ingroup PkgMinkowskiSum2 \ingroup PkgMinkowskiSum2
Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given polygons. Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given polygons.
If the input polygons `P` and `Q` are not convex, the function The function decomposes the summand `P` into convex sub-polygons
decomposes them into convex sub-polygons \f$ P_1, \ldots, P_k\f$ and \f$ P_1, \ldots, P_k\f$ using the given decomposition method `decomp_P`.
\f$ Q_1, \ldots, Q_{\ell}\f$ and computes the union of pairwise sub-sums If the summand `P` is of type `Polygon_2`, then `decomp_P` must be an
(namely \f$ \bigcup_{i,j}{(P_i \oplus Q_j)}\f$). instance of a class template that models the concept
The decomposition is performed using the given decomposition method `PolygonConvexDecomposition_2`. If `P` is of type `Polygon_with_holes_2`,
`decomp`, which must be an instance of a class template that models then `decomp_P` must be an instance of a class template that models the
the concept `PolygonConvexDecomposition_2`. concept `PolygonWithHolesConvexDecomposition_2`.
Similarly, the function decomposes the summand `Q` into convex sub-polygons
\f$ Q_1, \ldots, Q_k\f$ using the given decomposition method `decomp_Q`.
If the summand `Q` is of type `Polygon_2`, then `decomp_Q` must be an
instance of a class template that models the concept
`PolygonConvexDecomposition_2`. If `Q` is of type `Polygon_with_holes_2`,
then `decomp_Q` must be an instance of a class template that models the
concept `PolygonWithHolesConvexDecomposition_2`.
Then, the function computes the union of pairwise sub-sums (namely
\f$ \bigcup_{i,j}{(P_i \oplus Q_j)}\f$).
*/ */
template <typename Kernel, typename Container, typename PolygonConvexDecomposition_2> template <typename Kernel, typename Container,
typename PolygonConvexDecompositionP_2_,
typename PolygonConvexDecompositionQ_2_>
Polygon_with_holes_2<Kernel, Container> Polygon_with_holes_2<Kernel, Container>
minkowski_sum_2(const PolygonType1<Kernel, Container>& P, minkowski_sum_2(const PolygonType1<Kernel, Container>& P,
const PolygonType2<Kernel, Container>& Q, const PolygonType2<Kernel, Container>& Q,
const PolygonConvexDecomposition_2& decomp, const PolygonConvexDecompositionP_2_& decomp_P,
const PolygonConvexDecompositionQ_2_& decomp_Q,
const Gps_segment_traits_2& traits = Gps_segment_traits_2<Kernel,Container, Arr_segment_traits>());
/*!
\ingroup PkgMinkowskiSum2
Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given polygons.
The function decomposes the summands `P` and `Q` into convex sub-polygons
\f$ P_1, \ldots, P_k\f$ and \f$ Q_1, \ldots, Q_{\ell}\f$, respectively.
Then, it computes the union of pairwise sub-sums (namely
\f$ \bigcup_{i,j}{(P_i \oplus Q_j)}\f$). The decomposition is performed
using the given decomposition method `decomp`. If both summands
\f$ P \oplus Q\f$ are of type `Polygon_2`, then `decomp` must be instance
of a class template that models the concept `PolygonConvexDecomposition_2`.
If both summands are of type `Polygon_with_holes_2`, then `decomp` must be
a model of the concept `PolygonWithHolesConvexDecomposition_2`.
*/
template <typename Kernel, typename Container,
typename PolygonConvexDecomposition_2_>
Polygon_with_holes_2<Kernel, Container>
minkowski_sum_2(const PolygonType1<Kernel, Container>& P,
const PolygonType2<Kernel, Container>& Q,
const PolygonConvexDecomposition_2_& decomp,
const Gps_segment_traits_2& traits = Gps_segment_traits_2<Kernel,Container, Arr_segment_traits>());
/*!
\ingroup PkgMinkowskiSum2
Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given polygons
using the decomposition strategy. It decomposes the summands `P` and `Q`
into convex sub-polygons \f$ P_1, \ldots, P_k\f$ and
\f$ Q_1, \ldots, Q_{\ell}\f$, respectively. Then, it computes the union
of pairwise sub-sums (namely \f$ \bigcup_{i,j}{(P_i \oplus Q_j)}\f$).
If the summand `P` is of type `Polygon_with_holes_2`, then the function
first applies the hole filteration on `P`. If the summand `P` remains a
polygon with holes, then the function decomposes the summand `P` using
the given decomposition method `with_holes_decomp`. If, however, `P`
turns into a polygon without holes, then the function decomposes the
summand `P` using the given decomposition method `no_holes_decomp`,
unless the result is a convex polygon, in which case the nop strategy is
applied; namely, an instance of the class template
`Polygon_nop_decomposition_2` is used. If `P` is a polygon without holes
to start with, then only convexity is checked (checking whether the
result is convex inccurs a small overhead though). Then depending on
the result either `no_holes_decomp` or the nop strategy is applied.
Similarly, if the summand `Q` is of type `Polygon_with_holes_2`, then
the function first applies the hole filteration on `Q`. If the summand
`Q` remains a polygon with holes, then the function decomposes the
summand `Q` using the given decomposition method `with_holes_decomp`.
If, however, `Q` turns into a polygon without holes, then the function
decomposes the summand `Q` using the given decomposition method
`no_holes_decomp`, unless the result is a convex polygon, in which case
the nop strategy is applied. If `Q` is a polygon without holes to start
with, then only convexity is checked and the decomposition strategy is
chosen accordingly.
\tparam PolygonNoHolesConvexDecomposition_2_ a model of the concept `PolygonConvexDecomposition_2`.
\tparam PolygonWithHolesConvexDecomposition_2_ a model of the concept `PolygonWithHolesConvexDecomposition_2`.
*/
template <typename Kernel, typename Container,
typename PolygonNoHolesConvexDecomposition_2_,
typename PolygonWithHolesConvexDecomposition_2_>
Polygon_with_holes_2<Kernel, Container>
minkowski_sum_by_decomposition_2(const PolygonType1<Kernel, Container>& P,
const PolygonType2<Kernel, Container>& Q,
const PolygonNoHolesConvexDecomposition_2_& no_holes_decomp,
const PolygonWithHolesConvexDecomposition_2_& with_holes_decomp,
const Gps_segment_traits_2& traits = Gps_segment_traits_2<Kernel,Container, Arr_segment_traits>()); const Gps_segment_traits_2& traits = Gps_segment_traits_2<Kernel,Container, Arr_segment_traits>());
} /* namespace CGAL */ } /* namespace CGAL */

View File

@ -10,6 +10,7 @@ decomposing an input polygon \f$ P\f$ into a set of convex sub-polygons
\cgalHasModel `CGAL::Optimal_convex_decomposition_2<Kernel,Container>` \cgalHasModel `CGAL::Optimal_convex_decomposition_2<Kernel,Container>`
\cgalHasModel `CGAL::Hertel_Mehlhorn_convex_decomposition_2<Kernel,Container>` \cgalHasModel `CGAL::Hertel_Mehlhorn_convex_decomposition_2<Kernel,Container>`
\cgalHasModel `CGAL::Greene_convex_decomposition_2<Kernel,Container>` \cgalHasModel `CGAL::Greene_convex_decomposition_2<Kernel,Container>`
\cgalHasModel `CGAL::Polygon_nop_decomposition_2<Kernel,Container>`
*/ */

View File

@ -13,16 +13,16 @@ namespace CGAL {
Given two sets \f$ A,B \in \mathbb{R}^d\f$, their <I>Minkowski sum</I>, Given two sets \f$ A,B \in \mathbb{R}^d\f$, their <I>Minkowski sum</I>,
denoted by \f$ A \oplus B\f$, is their point-wise sum, namely the set denoted by \f$ A \oplus B\f$, is their point-wise sum, namely the set
\f$ \left\{ a + b ~|~ a \in A, b \in B \right\}\f$. \f$ \left\{ a + b ~|~ a \in A, b \in B \right\}\f$. Minkowski sums are
Minkowski sums are used in many applications, such as motion planning and used in many applications, such as motion planning and computer-aided
computer-aided design and manufacturing. This package contains functions design and manufacturing. This package contains functions that compute
that compute the planar Minkowski sums of two simple polygons; namely, the planar Minkowski sums of two polygons. (Here, \f$ A\f$ and \f$ B\f$
\f$ A\f$ and \f$ B\f$ are two closed polygons in \f$ \mathbb{R}^2\f$) are two closed polygons in \f$ \mathbb{R}^2\f$, which may have holes; see
(see Chapter \ref Chapter_2D_Regularized_Boolean_Set-Operations Chapter \ref Chapter_2D_Regularized_Boolean_Set-Operations
"2D Regularized Boolean Set-Operations" for the precise definition of a "2D Regularized Boolean Set-Operations" for the precise definition of valid
simple polygon), and the planar Minkowski sum of a simple polygon and a polygons), and the planar Minkowski sum of a simple polygon and a
disc---an operation also referred to as <I>offsetting</I> or <I>dilating</I> disc---an operation also referred to as <I>offsetting</I> or <I>dilating</I>
a polygon).\cgalFootnote{The family of valid types of summands is slightly a polygon.\cgalFootnote{The family of valid types of summands is slightly
broader for certain operations, e.g., a degenerate polygon consisting of broader for certain operations, e.g., a degenerate polygon consisting of
line segments is a valid operand for the approximate-offsetting operation.} line segments is a valid operand for the approximate-offsetting operation.}
This package, like the \ref Chapter_2D_Regularized_Boolean_Set-Operations This package, like the \ref Chapter_2D_Regularized_Boolean_Set-Operations
@ -54,24 +54,22 @@ The Minkowski sum can therefore be computed using an operation similar to the
merge step of the merge-sort algorithm\cgalFootnote{See, for example, merge step of the merge-sort algorithm\cgalFootnote{See, for example,
<a href="http://en.wikipedia.org/wiki/Merge_sort"> <a href="http://en.wikipedia.org/wiki/Merge_sort">
http://en.wikipedia.org/wiki/Merge_sort</a>.} in \f$ O(m + n)\f$ time, http://en.wikipedia.org/wiki/Merge_sort</a>.} in \f$ O(m + n)\f$ time,
starting from two bottommost vertices in \f$ P\f$ and in \f$ Q\f$ and merging starting from the two bottommost vertices in \f$ P\f$ and in \f$ Q\f$ and
the ordered list of edges. merging the ordered list of edges.
\cgalFigureBegin{mink_figonecyc,ms_convex_polygon.png,ms_concave_polygon.png,ms_convolution.png} \cgalFigureBegin{mink_figonecyc,ms_convex_polygon.png,ms_concave_polygon.png,ms_convolution.png}
The convolution of a convex polygon and a non-convex polygon. The convolution The convolution of a convex polygon and a non-convex polygon. The convolution
consists of a single self-intersecting cycle, drawn as a sequence of directed consists of a single self-intersecting cycle, drawn as a sequence of directed
line segments. Each face of the arrangement induced by the segments forming line segments. Each face of the arrangement induced by the segments forming
the cycle contains its winding number. The Minkowski sum of the two polygons the cycle contains its winding number. The Minkowski sum of the two polygons
is shaded. is shaded. Dotted edges are not part of the reduced convolution.
\cgalFigureEnd \cgalFigureEnd
If the polygons are not convex, you can utilize either the If the polygons are not convex, you can utilize either the
<I>Decomposition</I> or the <I>Convolution</I> approaches described below. <I>Decomposition</I> or the <I>Convolution</I> approaches described
Regarding the implementation of the two approaches, applications of below. Applications of some of the operations in this package are
Minkowski sum operations are restricted to polygons that are simple. restricted to polygons that do not contain holes. (Resulting sums may
Applications of some of the variant operations are also restricted to contain holes though.)
polygons that do not contain holes. (Resulting sums may contain holes
though.)
<DL> <DL>
<DT><B>Decomposition:</B><DD> <DT><B>Decomposition:</B><DD>
@ -84,92 +82,135 @@ simple procedure described above, and finally compute the union
\f$ P \oplus Q = \bigcup_{ij}{S_{ij}}\f$; \f$ P \oplus Q = \bigcup_{ij}{S_{ij}}\f$;
see \ref ref_bso_union "Union Functions". see \ref ref_bso_union "Union Functions".
This approach relies on a successful decomposition of the input polygons This approach relies on a successful decomposition of the input
into convex pieces, and its performance depends on the quality and performance polygons into convex pieces, and its performance depends on the
of the decomposition. The supplied decomposition methods do not handle point quality and performance of the decomposition. Some of the supplied
sets that are not simple. decomposition methods do not handle polygons that contain holes.
<DT><B>Convolution:</B><DD> <DT><B>Convolution:</B><DD>
Let us denote the vertices of the input polygons by Let \f$ P = \left( p_0, \ldots, p_{m-1} \right)\f$ and
\f$ P = \left( p_0, \ldots, p_{m-1} \right)\f$ and \f$ Q = \left(q_0, \ldots, q_{n-1} \right)\f$ denote the vertices of
\f$ Q = \left( q_0, \ldots, q_{n-1} \right)\f$. We assume that both \f$ P\f$ and \f$ Q\f$ the input polygons. We assume that both \f$ P\f$ and \f$ Q\f$ have
have positive orientations (i.e.\ their boundaries wind in a counterclockwise positive orientations (i.e., their boundaries wind in a
order around their interiors) and compute the convolution of the two polygon counterclockwise order around their interiors). The
boundaries. The <I>convolution</I> of these two polygons \cgalCite{grs-kfcg-83}, <I>convolution</I> of these two polygons \cgalCite{grs-kfcg-83},
denoted \f$ P * Q\f$, is a collection of line segments of the form denoted \f$ P * Q\f$, is a collection of line segments of the form
\f$ [p_i + q_j, p_{i+1} + q_j]\f$, \cgalFootnote{Throughout this chapter, we increment \f$ [p_i + q_j, p_{i+1} + q_j]\f$,\cgalFootnote{Throughout this
or decrement an index of a vertex modulo the size of the polygon.} chapter, we increment or decrement an index of a vertex modulo the
where the vector \f$ {\mathbf{p_i p_{i+1}}}\f$ size of the polygon.} where the vector \f$ {\mathbf{p_i p_{i+1}}}\f$
lies between \f$ {\mathbf{q_{j-1} q_j}}\f$ and \f$ {\mathbf{q_j lies between \f$ {\mathbf{q_{j-1} q_j}}\f$ and
q_{j+1}}}\f$, \cgalFootnote{We say that a vector \f$ {\mathbf v}\f$ lies between \f$ {\mathbf{q_j q_{j+1}}}\f$,\cgalFootnote{We say that a vector
two vectors \f$ {\mathbf u}\f$ and \f$ {\mathbf w}\f$ if we reach \f$ {\mathbf v}\f$ strictly before reaching \f$ {\mathbf w}\f$ if we move all three vectors to the origin and rotate \f$ {\mathbf u}\f$ counterclockwise. Note that this also covers the case where \f$ {\mathbf u}\f$ has the same direction as \f$ {\mathbf v}\f$.} and, symmetrically, of segments of the form \f$ [p_i + q_j, p_i + q_{j+1}]\f$, \f$ {\mathbf v}\f$ lies between two vectors \f$ {\mathbf u}\f$ and
where the vector \f$ {\mathbf{q_j q_{j+1}}}\f$ lies between \f$ {\mathbf w}\f$ if we reach \f$ {\mathbf v}\f$ strictly before
\f$ {\mathbf{p_{i-1} p_i}}\f$ and \f$ {\mathbf{p_i p_{i+1}}}\f$. reaching \f$ {\mathbf w}\f$ if we move all three vectors to the
origin and rotate \f$ {\mathbf u}\f$ counterclockwise. Note that this
also covers the case where \f$ {\mathbf u}\f$ has the same direction
as \f$ {\mathbf v}\f$.} and, symmetrically, of segments of the form
\f$ [p_i + q_j, p_i + q_{j+1}]\f$, where the vector \f$ {\mathbf{q_j
q_{j+1}}}\f$ lies between \f$ {\mathbf{p_{i-1} p_i}}\f$ and \f$
{\mathbf{p_i p_{i+1}}}\f$.
The segments of the convolution form a number of closed (not The segments of the convolution form a number of closed (not
necessarily simple) polygonal curves called <I>convolution necessarily simple) polygonal curves called <I>convolution cycles</I>.
cycles</I>. The Minkowski sum \f$ P \oplus Q\f$ is the set of points The Minkowski sum \f$ P \oplus Q\f$ is the set of points
having a non-zero winding number with respect to the cycles having a non-zero winding number with respect to the cycles of
of \f$ P * Q\f$. \cgalFootnote{Informally speaking, the winding number of a point \f$ p \in\mathbb{R}^2\f$ with respect to some planar curve \f$ \gamma\f$ is an integer number counting how many times does \f$ \gamma\f$ wind in a counterclockwise direction around \f$ p\f$.} See \cgalFigureRef{mink_figonecyc} \f$ P * Q\f$.\cgalFootnote{Informally speaking, the winding number
for an illustration. of a point \f$ p \in\mathbb{R}^2\f$ with respect to some planar curve
\f$ \gamma\f$ is an integer number counting how many times does
\f$ \gamma\f$ wind in a counterclockwise direction around \f$ p\f$.}
See \cgalFigureRef{mink_figonecyc} for an illustration.
The number of segments in the convolution of two polygons is usually We construct the arrangement induced by the convolution cycles of
smaller than the number of segments that constitute the boundaries of the \f$P \f$ and \f$Q \f$, then compute the winding numbers of the cells
sub-sums \f$ S_{ij}\f$ when using the decomposition approach. As both approaches of the arrangement. Finally, we extract the Minkowski sum from the
construct the arrangement of these segments and extract the sum from this arrangement. This variant is referred to as the full-convolution method.
arrangement, computing Minkowski sum using the convolution approach usually
generates a smaller intermediate arrangement, hence it is faster and
consumes less space.
<DT><B>Reduced Convolution:</B><DD>
We can reduce the number of segments in the arrangement even further by
noticing that only convolution segments created by a convex vertex can be part
of the Minkowski sum. In segments of the form \f$ [p_i + q_j, p_{i+1} + q_j]\f$,
the vertex \f$q_j\f$ has to be convex, and in segments of the form \f$
[p_i + q_j, p_i + q_{j+1}]\f$, the vertex \f$p_i\f$ has to be convex. The
collection of the remaining segments is called the <I>reduced convolution</I>
\cgalCite{cgal:bl-frmsurc-11}.
The winding number property can no longer be used here. Instead we define two A segment \f$[p_i + q_j, p_{i+1} + q_j] \f$ (resp.
different filters to identify holes in the Minkowski sum: \f$[p_i + q_j, p_i + q_{j+1}] \f$) cannot possibly contribute to the
boundary of the Minkowski sum if \f$q_j \f$ (resp. \f$p_i \f$) is a
reflex vertex (see dotted edges in \cgalFigureRef{mink_figonecyc}).
The remaining subset of convolution segments is called the
<I>reduced convolution</I> \cgalCite{cgal:bl-frmsurc-11}. This subset
is still a superset of the Minkowski sum boundary, but the winding
number property does not apply any longer as there are no closed
cycles anymore. We apply two different filters, which identify holes in
the Minkowski sum:
<OL> <OL>
<LI>Loops that are on the Minkowski sum's boundary have to be orientable, that <LI>A loop that is on the Minkowski sum boundary has to be orientable;
is, all normal directions of its edges have to point either inward or that is, all normal directions of its edges have to point either
outward.</LI> inward or outward.</LI>
<LI>For any point \f$x\f$ inside of a hole of the Minkowski sum, the following <LI>For any point \f$x\f$ inside of a hole of the Minkowski sum, the
condition holds: \f$(-P + x) \cap Q = \emptyset\f$. If, on the other hand, the following condition holds: \f$(-P + x) \cap Q = \emptyset\f$. If, on
inversed version of \f$P\f$, translated by \f$x\f$, overlaps \f$Q\f$, the loop the other hand, the inversed version of \f$P\f$, translated by
is a <I>false</I> hole and is in the Minkowski sum's interior.</LI> \f$x\f$, overlaps \f$Q\f$, the loop is a <I>false</I> hole and is in
the interior of the Minkowski sum.</LI>
</OL> </OL>
After applying these two filters, only those segments which constitute the After applying these two filters, only those segments which constitute
Minkowski sum's boundary remain. In most cases, the reduced convolution the Minkowski sum boundary remain. This variant is referred to as the
approach is even faster than the full convolution approach, as the induced reduced-convolution method.
arrangement is usually much smaller. However, in degenerated cases with many
holes in the Minkowski sum, the full convolution approach can be preferable to
avoid the costly intersection tests.
</DL> </DL>
\subsection mink_ssecsum_conv Computing Minkowski Sum using Convolutions The number of segments in the convolution of two polygons is usually
smaller than the number of segments that constitute the boundaries of
the sub-sums \f$ S_{ij}\f$ when using the decomposition approach. As
both approaches construct the arrangement of these segments and
extract the sum from this arrangement, computing Minkowski sum using
the convolution approach usually generates a smaller intermediate
arrangement; hence it is faster and consumes less space. In most cases,
the reduced convolution method is faster than the full convolution
method, as the respective induced arrangement is usually much smaller.
However, in degenerate cases with many holes in the Minkowski sum, the
full convolution method can be preferable, as it avoids costly
intersection tests.
The function template \link minkowski_sum_2() `minkowski_sum_2(P, Q)`\endlink \subsection mink_ssec_hole_filter Filtering Out Holes
accepts two simple polygons \f$ P\f$ and \f$ Q\f$ and computes their
Minkowski sum \f$ S = P \oplus Q\f$ using the convolution method. If a hole in one polygon is relatively small compared to the other
\link minkowski_sum_2() `minkowski_sum_2(P, Q)`\endlink defaults to calling the polygon, the hole is irrelevant for the computation of
function \link minkowski_sum_by_reduced_convolution_2() `minkowski_sum_by_reduced_convolution_2(P, Q)`\endlink, \f$P\oplus Q \f$ \cgalCite{bfhhm-epsph-15}; It implies that the hole
which applies the reduced convolution aforementioned. can be removed (that is, filled up) before the main computation starts.
Explicitly call the function \link minkowski_sum_by_full_convolution_2() Theoretically, we can always fill up all the holes of at least one
polygon, transforming it into a simple polygon, and still obtain
exactly the same Minkowski sum. Practically, we remove all holes in one
polygon whose bounding boxes are, in \f$x \f$- or \f$y \f$-direction,
smaller than, or as large as, the bounding box of the other polygon.
Obliterating holes in the input summands speeds up the computation of
Minkowski sums, regardless of the approach used to compute the
Minkowski sum.
\subsection mink_ssec_conv Computing Minkowski Sum using Convolutions
The function template \link minkowski_sum_2()
`minkowski_sum_2(P, Q)`\endlink accepts two polygons
\f$ P\f$ and \f$ Q\f$ and computes their Minkowski sum
\f$ S = P \oplus Q\f$ using the convolution approach.
The call \link minkowski_sum_2() `minkowski_sum_2(P, Q)`\endlink
defaults to the call \link minkowski_sum_by_reduced_convolution_2()
`minkowski_sum_by_reduced_convolution_2(P, Q)`\endlink, which applies
the reduced convolution aforementioned method. Explicitly call
\link minkowski_sum_by_full_convolution_2()
`minkowski_sum_by_full_convolution_2(P, Q)`\endlink to apply `minkowski_sum_by_full_convolution_2(P, Q)`\endlink to apply
the full convolution approach. the full convolution method. The types of the operands accepted by
The types of the operands are instances of the the function \link minkowski_sum_by_full_convolution_2()
\link Polygon_2 `Polygon_2`\endlink class template. As the input polygons `minkowski_sum_by_full_convolution_2(P, Q)`\endlink are instances of
may not be convex, their Minkowski sum may not be simply connected and the \link Polygon_2 `Polygon_2`\endlink class template. The types of
contain polygonal holes; see for example \cgalFigureRef{mink_figonecyc}. operands accepted by the function \link
The type of the returned object \f$ S \f$ is therefore an instance of the minkowski_sum_by_reduced_convolution_2()
\link Polygon_with_holes_2 `Polygon_with_holes_2`\endlink class template. `minkowski_sum_by_reduced_convolution_2(P, Q)`\endlink (and by the
The outer boundary of \f$ S \f$ is a polygon that can be accessed using function \link minkowski_sum_2() `minkowski_sum_2(P, Q)`\endlink)
`S.outer_boundary()`, and its polygonal holes are given by the range are instances of either the \link Polygon_2 `Polygon_2`\endlink or
[`S.holes_begin()`, `S.holes_end()`) (where \f$ S \f$ contains \link Polygon_with_holes_2 `Polygon_with_holes_2`\endlink class templates.
`S.number_of_holes()` holes in its interior). Even when the input polygons are restricted to be simple polygons, they
still may not be convex; thus, their Minkowski sum may not be simply
connected and may contain polygonal holes; see for example
\cgalFigureRef{mink_figonecyc}. The type of the returned object \f$ S \f$
is therefore an instance of the
\link Polygon_with_holes_2 `Polygon_with_holes_2`\endlink class template
in all cases. Recall that the outer boundary of \f$S \f$ is a polygon
that can be accessed using `S.outer_boundary()`, and its polygonal
holes are given by the range [`S.holes_begin()`, `S.holes_end()`) (where
\f$ S \f$ contains `S.number_of_holes()` holes in its interior).
\cgalFigureBegin{mink_figsum_tri_sqr,ms_sum_triangle_square.png} \cgalFigureBegin{mink_figsum_tri_sqr,ms_sum_triangle_square.png}
The Minkowski sum of a triangle and a square, as computed by the example The Minkowski sum of a triangle and a square, as computed by the example
@ -204,27 +245,48 @@ in both summands is large, the decomposition approach runs faster. In
the following we describe how to employ the decomposition-based the following we describe how to employ the decomposition-based
Minkowski sum procedure. Minkowski sum procedure.
\subsection mink_ssecdecomp Decomposition Strategies \subsection mink_ssec_decomp_strategies Decomposition Strategies
In order to compute Minkowski sums of two polygon \f$ P \f$ and In order to compute Minkowski sums of two polygon \f$ P \f$ and
\f$ Q \f$ using the decomposition method, issue the call \f$ Q \f$ using the decomposition method, issue the call
`minkowski_sum_2(P, Q, decomp)`, where `decomp` is an object of a type \link minkowski_sum_2()
that models the concept `PolygonConvexDecomposition`, which in turn `minkowski_sum_2(P, Q, decompP, decompQ)`\endlink, where each of \f$P \f$
refines a `Functor` concept variant. Namely, it requires the provision and \f$Q \f$ is either a simple polygon or a polygon with holes.
of a function operator (`operator()`) that accepts a planar polygon and If \f$P \f$ is a simple polygon, `decompP` must be an object of
returns a range of convex polygons that represents its convex decomposition. a type that models the concept `PolygonConvexDecomposition_2`.
If at least one of \f$ P \f$ or \f$ Q \f$ is a polygon with holes, If \f$P \f$ is a polygon with holes, them `decompP` is an object
`decomp` is an object of a type that models the concept of a type that models the concept
`PolygonWithHolesConvexDecomposition_2`, which refines the concept `PolygonWithHolesConvexDecomposition_2`, which refines the concept
`PolygonConvexDecomposition` and adds a requirement for the provision `PolygonConvexDecomposition_2`. The same holds for \f$Q \f$.
of a function operator (`operator()`) that accepts a planar polygon with The two concepts `PolygonConvexDecomposition_2` and
holes. `PolygonWithHolesConvexDecomposition_2` refine a `Functor` concept
variant. Namely, they both require the provision of a function
operator (`operator()`). The function operator of the model of the
concept `PolygonConvexDecomposition_2` accepts a planar simple
polygon, while the function operator of the model of the concept
`PolygonWithHolesConvexDecomposition_2` accepts a planar polygon
with holes. Both return a range of convex polygons that represents
the convex decomposition of the input polygon. If the decomposition
strategy that decomposes \f$P \f$ is the same as the strategy that
decomposes \f$Q \f$, you can omit the forth argument, and issue the call
\link minkowski_sum_2() `minkowski_sum_2(P, Q, decomp)`\endlink,
where `decomp` is an object that represents the common strategy.
The class template `Polygon_nop_decomposition_2`, which models the
concept `PolygonConvexDecomposition_2`, is a trivial convex
decomposition strategy referred to as the <I>nop</I> strategy; it merely
passes the input polygon to the next stage intact; use it in cases you
know that the corresponding input polygon is convex to start with. If
both \f$P \f$ and \f$Q \f$ are known to be convex, you can issue the call
\link minkowski_sum_2() `minkowski_sum_2(P, Q, nop)`\endlink, where `nop`
is an object that represents the nop strategy.
The Minkowski-sum package includes four models of the concept The Minkowski-sum package includes four models of the concept
`PolygonConvexDecomposition_2` and two models of the refined concept `PolygonConvexDecomposition_2` (besides the trivial model
`Polygon_nop_decomposition_2`) and two models of the refined concept
`PolygonWithHolesConvexDecomposition_2` as described below. The first `PolygonWithHolesConvexDecomposition_2` as described below. The first
three are class templates that wrap the decomposition functions included three are class templates that wrap the corresponding decomposition
in the \ref Chapter_2D_Polygon "Planar Polygon Partitioning" package. functions included in the
\ref Chapter_2D_Polygon "Planar Polygon Partitioning" package.
<UL> <UL>
<LI>The `Optimal_convex_decomposition_2<Kernel>` class template uses <LI>The `Optimal_convex_decomposition_2<Kernel>` class template uses
@ -274,12 +336,9 @@ diagonal that is closest to the angle bisector emanating from this
vertex and having rational-coordinate endpoints on both sides. vertex and having rational-coordinate endpoints on both sides.
</UL> </UL>
The following two models the refined concept The following are two models of the refined concept
`PolygonWithHolesConvexDecomposition_2`. An instance of any one these `PolygonWithHolesConvexDecomposition_2`. An instance of any one these
two types can be used to decompose a polygon with holes. You can pass two types can be used to decompose a polygon with holes.
the instance as the third argument to call
`minkowski_sum_2(P, Q, decomp)` to compute the Minkowski sum of two
polygons with holes, \f$P \f$ and \f$Q \f$.
<UL> <UL>
<LI>The `Polygon_vertical_decomposition_2<Kernel>` class template <LI>The `Polygon_vertical_decomposition_2<Kernel>` class template
uses vertical decomposition to decompose the underlying arrangement; uses vertical decomposition to decompose the underlying arrangement;
@ -298,6 +357,29 @@ angle-bisector decomposition strategy.
\cgalExample{Minkowski_sum_2/sum_by_decomposition.cpp} \cgalExample{Minkowski_sum_2/sum_by_decomposition.cpp}
\subsection mink_ssec_optimal_decomp Optimal Decomposition
Decomposition methods that handle polygons with holes are typically
more costly than decomposition methods that handle only simple
polygons. The hole filtration (see \ref mink_ssec_hole_filter) is
applied before the actual construction starts (be it convolution
based or decomposition based). The filteration may result with a
polygon that does not have holes, or even a convex polygon, but this
is unkown at the time of the call. To this end, we introduce the
overloaded function template \link minkowski_sum_by_decomposition_2()
`minkowski_sum_by_decomposition_2(P, Q, no_holes_decomp, with_holes_decomp)`\endlink,
where `no_holes_decomp` and `with_holes_decomp` are objects that model
the concepts `PolygonConvexDecomposition_2` and
`PolygonWithHolesConvexDecomposition_2`, respectively. If after the
application of the hole filtration \f$P\f$ remains a polygon with holes,
then the strategy represented by the object `with_holes_decomp` is
applied to it. If, however, \f$P\f$ turns into a polygon without holes,
then the strategy represented by the object `no_holes_decomp` is applied
to it, unless the result is a convex polygon, in which case the nop
strategy is applied. If \f$P\f$ is a polygon without holes to start with,
then only convexity is checked. (Checking whether the result is convex
inccurs a small overhead though.) The same holds for \f$Q\f$.
\section mink_secoffset Offsetting a Polygon \section mink_secoffset Offsetting a Polygon
The operation of computing the Minkowski sum \f$ P \oplus B_r\f$ of a The operation of computing the Minkowski sum \f$ P \oplus B_r\f$ of a
@ -365,7 +447,7 @@ the last step consists of computing the winding numbers of the faces
of the arrangement induced by the convolution cycle and discarding the of the arrangement induced by the convolution cycle and discarding the
faces with zero winding numbers. faces with zero winding numbers.
\subsection mink_ssecapprox_offset Approximating the Offset with a Guaranteed Error Bound \subsection mink_ssec_approx_offset Approximating the Offset with a Guaranteed Error Bound
Let \f$ P \f$ be a counterclockwise-oriented simple polygon all Let \f$ P \f$ be a counterclockwise-oriented simple polygon all
vertices of which \f$ p_0, \ldots, p_{n-1} \f$ have rational coordinates, vertices of which \f$ p_0, \ldots, p_{n-1} \f$ have rational coordinates,
@ -395,7 +477,7 @@ is supported by the line \f$ Ax + By + C' = 0 \f$, where
rational number. Therefore, the line segments that compose the offset rational number. Therefore, the line segments that compose the offset
boundaries cannot be represented as segments of lines with rational boundaries cannot be represented as segments of lines with rational
coefficients. coefficients.
In Section \ref mink_ssecexact_offset we use the line-pair representation In Section \ref mink_ssec_exact_offset we use the line-pair representation
to construct the offset polygonin an exact manner using the traits class to construct the offset polygonin an exact manner using the traits class
for conic arcs. for conic arcs.
</UL> </UL>
@ -470,7 +552,7 @@ the header file `bops_circular.h`, which defines the polygon types.
\cgalExample{Minkowski_sum_2/approx_offset.cpp} \cgalExample{Minkowski_sum_2/approx_offset.cpp}
\subsection mink_ssecexact_offset Computing the Exact Offset \subsection mink_ssec_exact_offset Computing the Exact Offset
As mentioned in the previous section, it is possible to represent As mentioned in the previous section, it is possible to represent
offset polygons in an exact manner if the edges of the polygons are offset polygons in an exact manner if the edges of the polygons are
@ -514,7 +596,7 @@ handles polygons with holes, such as the
`Polygon_vertical_decomposition_2<Kernel>` class template. `Polygon_vertical_decomposition_2<Kernel>` class template.
\cgalAdvancedEnd \cgalAdvancedEnd
\subsection mink_ssecinner_offset Computing Inner Offsets \subsection mink_ssec_inner_offset Computing Inner Offsets
An operation closely related to the (outer) offset computation, is An operation closely related to the (outer) offset computation, is
computing the <I>inner offset</I> of a polygon, or <I>insetting</I> it computing the <I>inner offset</I> of a polygon, or <I>insetting</I> it

View File

@ -36,6 +36,9 @@ bounds, in order to speed up the computation time.
## Functions ## ## Functions ##
- `CGAL::minkowski_sum_2()` - `CGAL::minkowski_sum_2()`
- `CGAL::minkowski_sum_by_decomposition_2()`
- `CGAL::minkowski_sum_full_convolution_2()`
- `CGAL::minkowski_sum_reduced_convolution_2()`
- `CGAL::approximated_offset_2()` - `CGAL::approximated_offset_2()`
- `CGAL::approximated_inset_2()` - `CGAL::approximated_inset_2()`
- `CGAL::offset_polygon_2()` - `CGAL::offset_polygon_2()`
@ -52,5 +55,6 @@ bounds, in order to speed up the computation time.
- `CGAL::Greene_convex_decomposition_2<Kernel,Container>` - `CGAL::Greene_convex_decomposition_2<Kernel,Container>`
- `CGAL::Polygon_vertical_decomposition_2<Kernel,Container>` - `CGAL::Polygon_vertical_decomposition_2<Kernel,Container>`
- `CGAL::Polygon_triangulation_decomposition_2<Kernel,Container>` - `CGAL::Polygon_triangulation_decomposition_2<Kernel,Container>`
- `CGAL::Polygon_nop_decomposition_2<Kernel,Container>`
*/ */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -28,20 +28,22 @@
namespace CGAL { namespace CGAL {
/*! \class /*! \class
* A class for computing the Minkowski sum of two simple polygons based on * A class for computing the Minkowski sum of two polygons based on their
* their decomposition two convex sub-polygons, taking the pairwise sums and * decomposition to convex sub-polygons, taking the pairwise sums and
* computing the union of the sub-sums. * computing the union of the sub-sums.
*/ */
template <class DecompStrategy_, class Container_> template <typename DecompStrategy1_, typename DecompStrategy2_,
typename Container_>
class Minkowski_sum_by_decomposition_2 { class Minkowski_sum_by_decomposition_2 {
public: public:
typedef DecompStrategy_ Decomposition_strategy; typedef DecompStrategy1_ Decomposition_strategy1;
typedef DecompStrategy2_ Decomposition_strategy2;
typedef Container_ Container; typedef Container_ Container;
typedef typename Decomposition_strategy::Polygon_2 Polygon_2; typedef typename Decomposition_strategy1::Polygon_2 Polygon_2;
typedef typename Decomposition_strategy::Kernel Kernel; typedef typename Decomposition_strategy1::Kernel Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Arr_segment_traits; typedef CGAL::Arr_segment_traits_2<Kernel> Arr_segment_traits;
typedef CGAL::Gps_segment_traits_2<Kernel, Container, Arr_segment_traits> typedef CGAL::Gps_segment_traits_2<Kernel, Container, Arr_segment_traits>
Traits_2; Traits_2;
@ -73,8 +75,10 @@ private:
Polygon_with_holes_list; Polygon_with_holes_list;
// Data members: // Data members:
const Decomposition_strategy* m_decomposition_strategy; const Decomposition_strategy1* m_decomposition_strategy1;
bool m_own_strategy; // inidicates whether the stategy should be freed up. const Decomposition_strategy2* m_decomposition_strategy2;
bool m_own_strategy1; // inidicates whether the stategy should be freed up.
bool m_own_strategy2; // inidicates whether the stategy should be freed up.
const Traits_2* m_traits; const Traits_2* m_traits;
bool m_own_traits; // inidicates whether the kernel should be freed up. bool m_own_traits; // inidicates whether the kernel should be freed up.
@ -90,33 +94,43 @@ private:
public: public:
//! Default constructor. //! Default constructor.
Minkowski_sum_by_decomposition_2() : Minkowski_sum_by_decomposition_2() :
m_decomposition_strategy(NULL), m_decomposition_strategy1(NULL),
m_own_strategy(false), m_decomposition_strategy2(NULL),
m_own_strategy1(false),
m_own_strategy2(false),
m_traits(NULL), m_traits(NULL),
m_own_traits(false) m_own_traits(false)
{ init(); } { init(); }
//! Constructor. //! Constructor.
Minkowski_sum_by_decomposition_2(const Decomposition_strategy& strategy, Minkowski_sum_by_decomposition_2(const Decomposition_strategy1& strategy1,
const Decomposition_strategy2& strategy2,
const Traits_2& traits) : const Traits_2& traits) :
m_decomposition_strategy(&strategy), m_decomposition_strategy1(&strategy1),
m_own_strategy(false), m_decomposition_strategy2(&strategy2),
m_own_strategy1(false),
m_own_strategy2(false),
m_traits(&traits), m_traits(&traits),
m_own_traits(false) m_own_traits(false)
{ init(); } { init(); }
//! Constructor. //! Constructor.
Minkowski_sum_by_decomposition_2(const Decomposition_strategy& strategy) : Minkowski_sum_by_decomposition_2(const Decomposition_strategy1& strategy1,
m_decomposition_strategy(&strategy), const Decomposition_strategy2& strategy2) :
m_own_strategy(false), m_decomposition_strategy1(&strategy1),
m_decomposition_strategy2(&strategy2),
m_own_strategy1(false),
m_own_strategy2(false),
m_traits(NULL), m_traits(NULL),
m_own_traits(false) m_own_traits(false)
{ init(); } { init(); }
//! Constructor. //! Constructor.
Minkowski_sum_by_decomposition_2(const Traits_2& traits) : Minkowski_sum_by_decomposition_2(const Traits_2& traits) :
m_decomposition_strategy(NULL), m_decomposition_strategy1(NULL),
m_own_strategy(false), m_decomposition_strategy2(NULL),
m_own_strategy1(false),
m_own_strategy2(false),
m_traits(&traits), m_traits(&traits),
m_own_traits(false) m_own_traits(false)
{ init(); } { init(); }
@ -132,12 +146,20 @@ public:
m_own_traits = false; m_own_traits = false;
} }
if (m_own_strategy) { if (m_own_strategy1) {
if (m_decomposition_strategy != NULL) { if (m_decomposition_strategy1 != NULL) {
delete m_decomposition_strategy; delete m_decomposition_strategy1;
m_decomposition_strategy = NULL; m_decomposition_strategy1 = NULL;
} }
m_own_strategy = false; m_own_strategy1 = false;
}
if (m_own_strategy2) {
if (m_decomposition_strategy2 != NULL) {
delete m_decomposition_strategy2;
m_decomposition_strategy2 = NULL;
}
m_own_strategy2 = false;
} }
} }
@ -150,10 +172,15 @@ public:
m_own_traits = true; m_own_traits = true;
} }
// Allocate the strategy if not provided. // Allocate the strategy if not provided.
if (m_decomposition_strategy == NULL) { if (m_decomposition_strategy1 == NULL) {
m_decomposition_strategy = new Decomposition_strategy; m_decomposition_strategy1 = new Decomposition_strategy1;
m_own_strategy = true; m_own_strategy1 = true;
} }
if (m_decomposition_strategy2 == NULL) {
m_decomposition_strategy2 = new Decomposition_strategy2;
m_own_strategy2 = true;
}
// Obtain kernel functors. // Obtain kernel functors.
const Kernel* kernel = m_traits; const Kernel* kernel = m_traits;
f_compare_angle = kernel->compare_angle_with_x_axis_2_object(); f_compare_angle = kernel->compare_angle_with_x_axis_2_object();
@ -175,8 +202,11 @@ public:
* Obtain the decomposition strategy * Obtain the decomposition strategy
* \return the decomposition strategy * \return the decomposition strategy
*/ */
const Decomposition_strategy* decomposition_strategy() const const Decomposition_strategy1* decomposition_strategy1() const
{ return m_decomposition_strategy; } { return m_decomposition_strategy1; }
const Decomposition_strategy2* decomposition_strategy2() const
{ return m_decomposition_strategy2; }
/*! /*!
* Compute the Minkowski sum of two simple polygons. * Compute the Minkowski sum of two simple polygons.
@ -195,8 +225,8 @@ public:
Polygons_list sub_pgns1; Polygons_list sub_pgns1;
Polygons_list sub_pgns2; Polygons_list sub_pgns2;
(*m_decomposition_strategy)(pgn1, std::back_inserter(sub_pgns1)); (*m_decomposition_strategy1)(pgn1, std::back_inserter(sub_pgns1));
(*m_decomposition_strategy)(pgn2, std::back_inserter(sub_pgns2)); (*m_decomposition_strategy2)(pgn2, std::back_inserter(sub_pgns2));
return operator()(sub_pgns1.begin(), sub_pgns1.end(), return operator()(sub_pgns1.begin(), sub_pgns1.end(),
sub_pgns2.begin(), sub_pgns2.end()); sub_pgns2.begin(), sub_pgns2.end());
@ -217,8 +247,8 @@ public:
Polygons_list sub_pgns1; Polygons_list sub_pgns1;
Polygons_list sub_pgns2; Polygons_list sub_pgns2;
(*m_decomposition_strategy)(pgn1, std::back_inserter(sub_pgns1)); (*m_decomposition_strategy1)(pgn1, std::back_inserter(sub_pgns1));
(*m_decomposition_strategy)(pgn2, std::back_inserter(sub_pgns2)); (*m_decomposition_strategy2)(pgn2, std::back_inserter(sub_pgns2));
return operator()(sub_pgns1.begin(), sub_pgns1.end(), return operator()(sub_pgns1.begin(), sub_pgns1.end(),
sub_pgns2.begin(), sub_pgns2.end()); sub_pgns2.begin(), sub_pgns2.end());
@ -240,8 +270,8 @@ public:
Polygons_list sub_pgns1; Polygons_list sub_pgns1;
Polygons_list sub_pgns2; Polygons_list sub_pgns2;
(*m_decomposition_strategy)(pgn1, std::back_inserter(sub_pgns1)); (*m_decomposition_strategy1)(pgn1, std::back_inserter(sub_pgns1));
(*m_decomposition_strategy)(pgn2, std::back_inserter(sub_pgns2)); (*m_decomposition_strategy2)(pgn2, std::back_inserter(sub_pgns2));
return operator()(sub_pgns1.begin(), sub_pgns1.end(), return operator()(sub_pgns1.begin(), sub_pgns1.end(),
sub_pgns2.begin(), sub_pgns2.end()); sub_pgns2.begin(), sub_pgns2.end());

View File

@ -0,0 +1,43 @@
// Copyright (c) 2013 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Author(s) : Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_POLYGON_NOP_DECOMPOSITION_2_H
#define CGAL_POLYGON_NOP_DECOMPOSITION_2_H
#include <CGAL/Polygon_2.h>
namespace CGAL {
/*! \class
* Nop decomposition strategy.
* Used for polygons that are already convex.
*/
template <typename Kernel_,
typename Container_ = std::vector<typename Kernel_::Point_2> >
class Polygon_nop_decomposition_2 {
public:
typedef Kernel_ Kernel;
typedef Container_ Container;
typedef CGAL::Polygon_2<Kernel, Container> Polygon_2;
template <typename OutputIterator_>
OutputIterator_ operator()(const Polygon_2& pgn, OutputIterator_ oi) const
{ *oi++ = pgn; return oi; }
};
} //namespace CGAL
#endif

View File

@ -20,11 +20,12 @@
#include <CGAL/basic.h> #include <CGAL/basic.h>
#include <CGAL/Polygon_with_holes_2.h> #include <CGAL/Polygon_with_holes_2.h>
#include <CGAL/Minkowski_sum_2/Hole_filter_2.h> #include <CGAL/Minkowski_sum_2/Hole_filter_2.h>
#include <CGAL/Minkowski_sum_2/Minkowski_sum_by_reduced_convolution_2.h> #include <CGAL/Minkowski_sum_2/Minkowski_sum_by_reduced_convolution_2.h>
#include <CGAL/Minkowski_sum_2/Minkowski_sum_conv_2.h> #include <CGAL/Minkowski_sum_2/Minkowski_sum_conv_2.h>
#include <CGAL/Minkowski_sum_2/Minkowski_sum_decomp_2.h> #include <CGAL/Minkowski_sum_2/Minkowski_sum_decomp_2.h>
#include <CGAL/Polygon_nop_decomposition_2.h>
#include <list> #include <list>
namespace CGAL { namespace CGAL {
@ -263,7 +264,11 @@ minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
{ return minkowski_sum_by_reduced_convolution_2(pgn1, pgn2); } { return minkowski_sum_by_reduced_convolution_2(pgn1, pgn2); }
/*! /*!
* Compute the Minkowski sum of two simple polygons by decomposing each * \defgroup Minkowski sum by decomposition
* @{
*/
/*! Compute the Minkowski sum of two simple polygons by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise * polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons. * Minkowski sums of the sub-polygons.
* Note that as the input polygons may not be convex, their Minkowski sum may * Note that as the input polygons may not be convex, their Minkowski sum may
@ -275,19 +280,22 @@ minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
* \return The resulting polygon with holes, representing the sum. * \return The resulting polygon with holes, representing the sum.
*/ */
template <typename Kernel_, typename Container_, template <typename Kernel_, typename Container_,
typename DecompositionStrategy_> typename DecompositionStrategy1_, typename DecompositionStrategy2_>
Polygon_with_holes_2<Kernel_, Container_> Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1, minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2, const Polygon_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy_& decomposition_strategy) const DecompositionStrategy1_& decomposition_strategy1,
const DecompositionStrategy2_& decomposition_strategy2)
{ {
typename Minkowski_sum_by_decomposition_2<DecompositionStrategy_, typename Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy2_,
Container_>::Traits_2 traits; Container_>::Traits_2 traits;
return minkowski_sum_2(pgn1, pgn2, decomposition_strategy, traits); return minkowski_sum_2(pgn1, pgn2,
decomposition_strategy1, decomposition_strategy2,
traits);
} }
/*! /*! Compute the Minkowski sum of two simple polygons by decomposing each
* Compute the Minkowski sum of two simple polygons by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise * polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons. * Minkowski sums of the sub-polygons.
* Note that as the input polygons may not be convex, their Minkowski sum may * Note that as the input polygons may not be convex, their Minkowski sum may
@ -300,20 +308,24 @@ minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
* \return The resulting polygon with holes, representing the sum. * \return The resulting polygon with holes, representing the sum.
*/ */
template <typename Kernel_, typename Container_, template <typename Kernel_, typename Container_,
typename DecompositionStrategy_> typename DecompositionStrategy1_, typename DecompositionStrategy2_>
Polygon_with_holes_2<Kernel_, Container_> Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1, minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2, const Polygon_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy_& decomposition_strategy, const DecompositionStrategy1_& decomposition_strategy1,
const DecompositionStrategy2_& decomposition_strategy2,
const typename const typename
Minkowski_sum_by_decomposition_2<DecompositionStrategy_, Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy2_,
Container_>::Traits_2& traits) Container_>::Traits_2& traits)
{ {
typedef Container_ Container; typedef Container_ Container;
typedef DecompositionStrategy_ Decomposition_strategy; typedef DecompositionStrategy1_ Decomposition_strategy1;
typedef DecompositionStrategy2_ Decomposition_strategy2;
Minkowski_sum_by_decomposition_2<Decomposition_strategy, Container> Minkowski_sum_by_decomposition_2<Decomposition_strategy1,
mink_sum(decomposition_strategy, traits); Decomposition_strategy2, Container>
mink_sum(decomposition_strategy1, decomposition_strategy2, traits);
return mink_sum(pgn1, pgn2); return mink_sum(pgn1, pgn2);
} }
@ -328,19 +340,22 @@ minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
* \return The resulting polygon with holes, representing the sum. * \return The resulting polygon with holes, representing the sum.
*/ */
template <typename Kernel_, typename Container_, template <typename Kernel_, typename Container_,
typename DecompositionStrategy_> typename DecompositionStrategy1_, typename DecompositionStrategy2_>
Polygon_with_holes_2<Kernel_, Container_> Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1, minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2, const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy_& decomposition_strategy) const DecompositionStrategy1_& decomposition_strategy1,
const DecompositionStrategy2_& decomposition_strategy2)
{ {
typename Minkowski_sum_by_decomposition_2<DecompositionStrategy_, typename Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy2_,
Container_>::Traits_2 traits; Container_>::Traits_2 traits;
return minkowski_sum_2(pgn1, pgn2, decomposition_strategy, traits); return minkowski_sum_2(pgn1, pgn2,
decomposition_strategy1, decomposition_strategy2,
traits);
} }
/*! /*! Compute the Minkowski sum of two polygon with holes by decomposing each
* Compute the Minkowski sum of two polygon with holes by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise * polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons. * Minkowski sums of the sub-polygons.
* The result is also represented as a polygon with holes. * The result is also represented as a polygon with holes.
@ -351,21 +366,25 @@ minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
* \return The resulting polygon with holes, representing the sum. * \return The resulting polygon with holes, representing the sum.
*/ */
template <typename Kernel_, typename Container_, template <typename Kernel_, typename Container_,
typename DecompositionStrategy_> typename DecompositionStrategy1_, typename DecompositionStrategy2_>
Polygon_with_holes_2<Kernel_, Container_> Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1, minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2, const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy_& decomposition_strategy, const DecompositionStrategy1_& decomposition_strategy1,
const DecompositionStrategy2_& decomposition_strategy2,
const typename const typename
Minkowski_sum_by_decomposition_2<DecompositionStrategy_, Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy2_,
Container_>::Traits_2& traits) Container_>::Traits_2& traits)
{ {
typedef Kernel_ Kernel; typedef Kernel_ Kernel;
typedef Container_ Container; typedef Container_ Container;
typedef DecompositionStrategy_ Decomposition_strategy; typedef DecompositionStrategy1_ Decomposition_strategy1;
typedef DecompositionStrategy2_ Decomposition_strategy2;
Minkowski_sum_by_decomposition_2<Decomposition_strategy, Container> Minkowski_sum_by_decomposition_2<Decomposition_strategy1,
mink_sum(decomposition_strategy, traits); Decomposition_strategy2, Container>
mink_sum(decomposition_strategy1, decomposition_strategy2, traits);
Hole_filter_2<Kernel, Container> hole_filter; Hole_filter_2<Kernel, Container> hole_filter;
Polygon_with_holes_2<Kernel,Container> filtered_pgn1; Polygon_with_holes_2<Kernel,Container> filtered_pgn1;
Polygon_with_holes_2<Kernel,Container> filtered_pgn2; Polygon_with_holes_2<Kernel,Container> filtered_pgn2;
@ -374,8 +393,7 @@ minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
return mink_sum(filtered_pgn1, filtered_pgn2); return mink_sum(filtered_pgn1, filtered_pgn2);
} }
/*! /*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union * by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also * of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes. * represented as a polygon with holes.
@ -385,19 +403,22 @@ minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
* \return The resulting polygon with holes, representing the sum. * \return The resulting polygon with holes, representing the sum.
*/ */
template <typename Kernel_, typename Container_, template <typename Kernel_, typename Container_,
typename DecompositionStrategy_> typename DecompositionStrategy1_, typename DecompositionStrategy2_>
Polygon_with_holes_2<Kernel_, Container_> Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1, minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2, const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy_& decomposition_strategy) const DecompositionStrategy1_& decomposition_strategy1,
const DecompositionStrategy2_& decomposition_strategy2)
{ {
typename Minkowski_sum_by_decomposition_2<DecompositionStrategy_, typename Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy2_,
Container_>::Traits_2 traits; Container_>::Traits_2 traits;
return minkowski_sum_2(pgn1, pgn2, decomposition_strategy, traits); return minkowski_sum_2(pgn1, pgn2,
decomposition_strategy1, decomposition_strategy2,
traits);
} }
/*! /*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union * by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also * of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes. * represented as a polygon with holes.
@ -408,29 +429,32 @@ minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
* \return The resulting polygon with holes, representing the sum. * \return The resulting polygon with holes, representing the sum.
*/ */
template <typename Kernel_, typename Container_, template <typename Kernel_, typename Container_,
typename DecompositionStrategy_> typename DecompositionStrategy1_, typename DecompositionStrategy2_>
Polygon_with_holes_2<Kernel_, Container_> Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1, minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2, const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy_& decomposition_strategy, const DecompositionStrategy1_& decomposition_strategy1,
const DecompositionStrategy2_& decomposition_strategy2,
const typename const typename
Minkowski_sum_by_decomposition_2<DecompositionStrategy_, Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy2_,
Container_>::Traits_2& traits) Container_>::Traits_2& traits)
{ {
typedef Kernel_ Kernel; typedef Kernel_ Kernel;
typedef Container_ Container; typedef Container_ Container;
typedef DecompositionStrategy_ Decomposition_strategy; typedef DecompositionStrategy1_ Decomposition_strategy1;
typedef DecompositionStrategy2_ Decomposition_strategy2;
Minkowski_sum_by_decomposition_2<Decomposition_strategy, Container> Minkowski_sum_by_decomposition_2<Decomposition_strategy1,
mink_sum(decomposition_strategy, traits); Decomposition_strategy2, Container>
mink_sum(decomposition_strategy1, decomposition_strategy2, traits);
Hole_filter_2<Kernel, Container> hole_filter; Hole_filter_2<Kernel, Container> hole_filter;
Polygon_with_holes_2<Kernel,Container> filtered_pgn2; Polygon_with_holes_2<Kernel,Container> filtered_pgn2;
hole_filter(pgn2, pgn1, filtered_pgn2); hole_filter(pgn2, pgn1, filtered_pgn2);
return mink_sum(pgn1, filtered_pgn2); return mink_sum(pgn1, filtered_pgn2);
} }
/*! /*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union * by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also * of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes. * represented as a polygon with holes.
@ -440,19 +464,22 @@ minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
* \return The resulting polygon with holes, representing the sum. * \return The resulting polygon with holes, representing the sum.
*/ */
template <typename Kernel_, typename Container_, template <typename Kernel_, typename Container_,
typename DecompositionStrategy_> typename DecompositionStrategy1_, typename DecompositionStrategy2_>
Polygon_with_holes_2<Kernel_, Container_> Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1, minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2, const Polygon_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy_& decomposition_strategy) const DecompositionStrategy1_& decomposition_strategy1,
const DecompositionStrategy2_& decomposition_strategy2)
{ {
typename Minkowski_sum_by_decomposition_2<DecompositionStrategy_, typename Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy2_,
Container_>::Traits_2 traits; Container_>::Traits_2 traits;
return minkowski_sum_2(pgn1, pgn2, decomposition_strategy, traits); return minkowski_sum_2(pgn1, pgn2,
decomposition_strategy1, decomposition_strategy2,
traits);
} }
/*! /*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union * by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also * of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes. * represented as a polygon with holes.
@ -463,15 +490,632 @@ minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
* \return The resulting polygon with holes, representing the sum. * \return The resulting polygon with holes, representing the sum.
*/ */
template <typename Kernel_, typename Container_, template <typename Kernel_, typename Container_,
typename DecompositionStrategy_> typename DecompositionStrategy1_, typename DecompositionStrategy2_>
Polygon_with_holes_2<Kernel_, Container_> Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1, minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2, const Polygon_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy_& decomposition_strategy, const DecompositionStrategy1_& decomposition_strategy1,
const DecompositionStrategy2_& decomposition_strategy2,
const typename const typename
Minkowski_sum_by_decomposition_2<DecompositionStrategy_, Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy2_,
Container_>::Traits_2& traits) Container_>::Traits_2& traits)
{ return minkowski_sum_2(pgn2, pgn1, decomposition_strategy, traits); } {
return minkowski_sum_2(pgn2, pgn1,
decomposition_strategy2, decomposition_strategy1,
traits);
}
/*! Compute the Minkowski sum of two simple polygons by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons.
* Note that as the input polygons may not be convex, their Minkowski sum may
* not be a simple polygon. The result is therefore represented as a polygon
* with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition_strategy A functor for decomposing polygons.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename DecompositionStrategy1_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy1_& decomposition_strategy1)
{
typename Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy1_,
Container_>::Traits_2 traits;
return minkowski_sum_2(pgn1, pgn2,
decomposition_strategy1, decomposition_strategy1,
traits);
}
/*! Compute the Minkowski sum of two simple polygons by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons.
* Note that as the input polygons may not be convex, their Minkowski sum may
* not be a simple polygon. The result is therefore represented as a polygon
* with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition_strategy A functor for decomposing polygons.
* \param[in] traits The traits.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename DecompositionStrategy1_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy1_& decomposition_strategy1,
const typename
Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy1_,
Container_>::Traits_2& traits)
{
typedef Container_ Container;
typedef DecompositionStrategy1_ Decomposition_strategy1;
Minkowski_sum_by_decomposition_2<Decomposition_strategy1,
Decomposition_strategy1, Container>
mink_sum(decomposition_strategy1, decomposition_strategy1, traits);
return mink_sum(pgn1, pgn2);
}
/*!
* Compute the Minkowski sum of two polygon with holes by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons.
* The result is also represented as a polygon with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition_strategy A functor for decomposing polygons.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename DecompositionStrategy1_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy1_& decomposition_strategy1)
{
typename Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy1_,
Container_>::Traits_2 traits;
return minkowski_sum_2(pgn1, pgn2,
decomposition_strategy1, decomposition_strategy1,
traits);
}
/*! Compute the Minkowski sum of two polygon with holes by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons.
* The result is also represented as a polygon with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition_strategy A functor for decomposing polygons.
* \param[in] traits The traits.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename DecompositionStrategy1_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy1_& decomposition_strategy1,
const typename
Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy1_,
Container_>::Traits_2& traits)
{
typedef Kernel_ Kernel;
typedef Container_ Container;
typedef DecompositionStrategy1_ Decomposition_strategy1;
Minkowski_sum_by_decomposition_2<Decomposition_strategy1,
Decomposition_strategy1, Container>
mink_sum(decomposition_strategy1, decomposition_strategy1, traits);
Hole_filter_2<Kernel, Container> hole_filter;
Polygon_with_holes_2<Kernel,Container> filtered_pgn1;
Polygon_with_holes_2<Kernel,Container> filtered_pgn2;
hole_filter(pgn1, pgn2, filtered_pgn1);
hole_filter(pgn2, pgn1, filtered_pgn2);
return mink_sum(filtered_pgn1, filtered_pgn2);
}
/*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition_strategy A functor for decomposing polygons.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename DecompositionStrategy1_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy1_& decomposition_strategy1)
{
typename Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy1_,
Container_>::Traits_2 traits;
return minkowski_sum_2(pgn1, pgn2,
decomposition_strategy1, decomposition_strategy1,
traits);
}
/*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes.
* \param[in] pgn1 The simple polygon.
* \param[in] pgn2 The polygon with holes.
* \param[in] decomposition_strategy A functor for decomposing polygons.
* \param[in] traits The traits.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename DecompositionStrategy1_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy1_& decomposition_strategy1,
const typename
Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy1_,
Container_>::Traits_2& traits)
{
typedef Kernel_ Kernel;
typedef Container_ Container;
typedef DecompositionStrategy1_ Decomposition_strategy1;
Minkowski_sum_by_decomposition_2<Decomposition_strategy1,
Decomposition_strategy1, Container>
mink_sum(decomposition_strategy1, decomposition_strategy1, traits);
Hole_filter_2<Kernel, Container> hole_filter;
Polygon_with_holes_2<Kernel,Container> filtered_pgn2;
hole_filter(pgn2, pgn1, filtered_pgn2);
return mink_sum(pgn1, filtered_pgn2);
}
/*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes.
* \param[in] pgn1 The second polygon.
* \param[in] pgn2 The first polygon.
* \param[in] decomposition_strategy A functor for decomposing polygons.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename DecompositionStrategy1_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy1_& decomposition_strategy1)
{
typename Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy1_,
Container_>::Traits_2 traits;
return minkowski_sum_2(pgn1, pgn2,
decomposition_strategy1, decomposition_strategy1,
traits);
}
/*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes.
* \param[in] pgn1 The polygon with holes.
* \param[in] pgn2 The simple polygon.
* \param[in] decomposition_strategy A functor for decomposing polygons.
* \param[in] traits The traits.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename DecompositionStrategy1_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const DecompositionStrategy1_& decomposition_strategy1,
const typename
Minkowski_sum_by_decomposition_2<DecompositionStrategy1_,
DecompositionStrategy1_,
Container_>::Traits_2& traits)
{
return minkowski_sum_2(pgn2, pgn1,
decomposition_strategy1, decomposition_strategy1,
traits);
}
/*! Compute the Minkowski sum of two simple polygons by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons.
* Note that as the input polygons may not be convex, their Minkowski sum may
* not be a simple polygon. The result is therefore represented as a polygon
* with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition_strategy A functor for decomposing polygons.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_, typename Decomposition_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_by_decomposition_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const Decomposition_& decomp)
{
typename Minkowski_sum_by_decomposition_2<Decomposition_, Decomposition_,
Container_>::Traits_2 traits;
return minkowski_sum_by_decomposition_2(pgn1, pgn2, decomp, traits);
}
/*! Compute the Minkowski sum of two simple polygons by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons.
* Note that as the input polygons may not be convex, their Minkowski sum may
* not be a simple polygon. The result is therefore represented as a polygon
* with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition A functor for decomposing polygons.
* \param[in] traits The traits.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_, typename Decomposition_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_by_decomposition_2
(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const Decomposition_& decomp,
const typename Minkowski_sum_by_decomposition_2<Decomposition_, Decomposition_,
Container_>::Traits_2& traits)
{
typedef Kernel_ Kernel;
typedef Container_ Container;
typedef Decomposition_ Decomposition;
typedef Polygon_nop_decomposition_2<Kernel> Nop_decomposition;
if (pgn1.is_convex()) {
Nop_decomposition decomp_nop;
if (pgn2.is_convex()) {
Minkowski_sum_by_decomposition_2<Nop_decomposition, Nop_decomposition,
Container>
mink_sum(decomp_nop, decomp_nop, traits);
return mink_sum(pgn1, pgn2);
}
Minkowski_sum_by_decomposition_2<Nop_decomposition, Decomposition,
Container>
mink_sum(decomp_nop, decomp, traits);
return mink_sum(pgn1, pgn2);
}
if (pgn2.is_convex()) {
Nop_decomposition decomp_nop;
Minkowski_sum_by_decomposition_2<Decomposition, Nop_decomposition,
Container>
mink_sum(decomp, decomp_nop, traits);
return mink_sum(pgn1, pgn2);
}
Minkowski_sum_by_decomposition_2<Decomposition, Decomposition, Container>
mink_sum(decomp, decomp, traits);
return mink_sum(pgn1, pgn2);
}
/*! Compute the Minkowski sum of two polygon with holes by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons.
* The result is also represented as a polygon with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition A functor for decomposing polygons.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename NoHolesDecomposition_, typename WithHolesDecomposition_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_by_decomposition_2
(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const NoHolesDecomposition_& decomp_no_holes,
const WithHolesDecomposition_& decomp_with_holes)
{
typename Minkowski_sum_by_decomposition_2<NoHolesDecomposition_,
WithHolesDecomposition_,
Container_>::Traits_2 traits;
return minkowski_sum_by_decomposition_2(pgn1, pgn2,
decomp_no_holes, decomp_with_holes,
traits);
}
/*! Compute the Minkowski sum of two polygon with holes by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise
* Minkowski sums of the sub-polygons.
* The result is also represented as a polygon with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition A functor for decomposing polygons.
* \param[in] traits The traits.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename NoHolesDecomposition_, typename WithHolesDecomposition_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_by_decomposition_2
(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const NoHolesDecomposition_& decomp_no_holes,
const WithHolesDecomposition_& decomp_with_holes,
const typename Minkowski_sum_by_decomposition_2<NoHolesDecomposition_,
WithHolesDecomposition_,
Container_>::Traits_2& traits)
{
typedef Kernel_ Kernel;
typedef Container_ Container;
typedef NoHolesDecomposition_ No_holes_decomposition;
typedef WithHolesDecomposition_ With_holes_decomposition;
typedef Polygon_nop_decomposition_2<Kernel> Nop_decomposition;
Hole_filter_2<Kernel, Container> hole_filter;
Polygon_with_holes_2<Kernel, Container> filtered_pgn1;
Polygon_with_holes_2<Kernel, Container> filtered_pgn2;
hole_filter(pgn1, pgn2, filtered_pgn1);
hole_filter(pgn2, pgn1, filtered_pgn2);
if (0 == filtered_pgn1.number_of_holes()) {
const Polygon_2<Kernel, Container>& pnh1 = filtered_pgn1.outer_boundary();
if (pnh1.is_convex()) {
// pnh1 is convex
Nop_decomposition decomp_nop;
if (0 == filtered_pgn2.number_of_holes()) {
const Polygon_2<Kernel, Container>& pnh2 =
filtered_pgn2.outer_boundary();
if (pnh2.is_convex()) {
// pnh2 is convex
Minkowski_sum_by_decomposition_2<Nop_decomposition, Nop_decomposition,
Container>
mink_sum(decomp_nop, decomp_nop, traits);
return mink_sum(pnh1, pnh2);
}
// pnh2 is concave
Minkowski_sum_by_decomposition_2<Nop_decomposition,
No_holes_decomposition,
Container>
mink_sum(decomp_nop, decomp_no_holes, traits);
return mink_sum(pnh1, pnh2);
}
// pnh2 has holes
Minkowski_sum_by_decomposition_2<Nop_decomposition,
With_holes_decomposition,
Container>
mink_sum(decomp_nop, decomp_with_holes, traits);
return mink_sum(pnh1, filtered_pgn2);
}
// pnh1 is concave
if (0 == filtered_pgn2.number_of_holes()) {
const Polygon_2<Kernel, Container>& pnh2 =
filtered_pgn2.outer_boundary();
if (pnh2.is_convex()) {
// pnh2 is convex
Nop_decomposition decomp_nop;
Minkowski_sum_by_decomposition_2<No_holes_decomposition,
Nop_decomposition,
Container>
mink_sum(decomp_no_holes, decomp_nop, traits);
return mink_sum(pnh1, pnh2);
}
// pnh2 is concave
Minkowski_sum_by_decomposition_2<No_holes_decomposition,
No_holes_decomposition,
Container>
mink_sum(decomp_no_holes, decomp_no_holes, traits);
return mink_sum(pnh1, pnh2);
}
// pnh2 has holes
Minkowski_sum_by_decomposition_2<No_holes_decomposition,
With_holes_decomposition,
Container>
mink_sum(decomp_no_holes, decomp_with_holes, traits);
return mink_sum(pnh1, filtered_pgn2);
}
// filtered_pgn1 has holes
if (0 == filtered_pgn2.number_of_holes()) {
const Polygon_2<Kernel, Container>& pnh2 =
filtered_pgn2.outer_boundary();
if (pnh2.is_convex()) {
// pnh2 is convex
Nop_decomposition decomp_nop;
Minkowski_sum_by_decomposition_2<Nop_decomposition,
With_holes_decomposition,
Container>
mink_sum(decomp_nop, decomp_with_holes, traits);
return mink_sum(pnh2, filtered_pgn1);
}
// pnh2 is concave
Minkowski_sum_by_decomposition_2<No_holes_decomposition,
With_holes_decomposition,
Container>
mink_sum(decomp_no_holes, decomp_with_holes, traits);
return mink_sum(pnh2, filtered_pgn1);
}
// pnh2 has holes
Minkowski_sum_by_decomposition_2<With_holes_decomposition,
With_holes_decomposition,
Container>
mink_sum(decomp_with_holes, decomp_with_holes, traits);
return mink_sum(filtered_pgn1, filtered_pgn2);
}
/*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes.
* \param[in] pgn1 The first polygon.
* \param[in] pgn2 The second polygon.
* \param[in] decomposition A functor for decomposing polygons.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename NoHolesDecomposition_, typename WithHolesDecomposition_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_by_decomposition_2
(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const NoHolesDecomposition_& decomp_no_holes,
const WithHolesDecomposition_& decomp_with_holes)
{
typename Minkowski_sum_by_decomposition_2<NoHolesDecomposition_,
WithHolesDecomposition_,
Container_>::Traits_2 traits;
return minkowski_sum_by_decomposition_2(pgn1, pgn2,
decomp_no_holes, decomp_with_holes,
traits);
}
/*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes.
* \param[in] pgn1 The simple polygon.
* \param[in] pgn2 The polygon with holes.
* \param[in] decomposition A functor for decomposing polygons.
* \param[in] traits The traits.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename NoHolesDecomposition_, typename WithHolesDecomposition_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_by_decomposition_2
(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2,
const NoHolesDecomposition_& decomp_no_holes,
const WithHolesDecomposition_& decomp_with_holes,
const typename Minkowski_sum_by_decomposition_2<NoHolesDecomposition_,
WithHolesDecomposition_,
Container_>::Traits_2& traits)
{
typedef Kernel_ Kernel;
typedef Container_ Container;
typedef NoHolesDecomposition_ No_holes_decomposition;
typedef WithHolesDecomposition_ With_holes_decomposition;
typedef Polygon_nop_decomposition_2<Kernel> Nop_decomposition;
Hole_filter_2<Kernel, Container> hole_filter;
Polygon_with_holes_2<Kernel,Container> filtered_pgn2;
hole_filter(pgn2, pgn1, filtered_pgn2);
if (pgn1.is_convex()) {
Nop_decomposition decomp_nop;
if (0 == filtered_pgn2.number_of_holes()) {
const Polygon_2<Kernel, Container>& pnh2 = filtered_pgn2.outer_boundary();
if (pnh2.is_convex()) {
Minkowski_sum_by_decomposition_2<Nop_decomposition, Nop_decomposition,
Container>
mink_sum(decomp_nop, decomp_nop, traits);
return mink_sum(pgn1, pnh2);
}
// pnh2 is concave
Minkowski_sum_by_decomposition_2<Nop_decomposition,
No_holes_decomposition,
Container>
mink_sum(decomp_nop, decomp_no_holes, traits);
return mink_sum(pgn1, pnh2);
}
// pnh2 has holes
Minkowski_sum_by_decomposition_2<Nop_decomposition,
With_holes_decomposition,
Container>
mink_sum(decomp_nop, decomp_with_holes, traits);
return mink_sum(pgn1, filtered_pgn2);
}
// pgn1 is concave
if (0 == filtered_pgn2.number_of_holes()) {
const Polygon_2<Kernel, Container>& pnh2 = filtered_pgn2.outer_boundary();
if (pnh2.is_convex()) {
// pnh2 is convex
Nop_decomposition decomp_nop;
Minkowski_sum_by_decomposition_2<No_holes_decomposition,
Nop_decomposition,
Container>
mink_sum(decomp_no_holes, decomp_nop, traits);
return mink_sum(pgn1, pnh2);
}
// pnh2 is concave
Minkowski_sum_by_decomposition_2<No_holes_decomposition,
No_holes_decomposition,
Container>
mink_sum(decomp_no_holes, decomp_no_holes, traits);
return mink_sum(pgn1, pnh2);
}
// pnh2 has holes
Minkowski_sum_by_decomposition_2<No_holes_decomposition,
With_holes_decomposition,
Container>
mink_sum(decomp_no_holes, decomp_with_holes, traits);
return mink_sum(pgn1, filtered_pgn2);
}
/*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes.
* \param[in] pgn1 The second polygon.
* \param[in] pgn2 The first polygon.
* \param[in] decomposition A functor for decomposing polygons.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename NoHolesDecomposition_, typename WithHolesDecomposition_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_by_decomposition_2
(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const NoHolesDecomposition_& decomp_no_holes,
const WithHolesDecomposition_& decomp_with_holes)
{
typename Minkowski_sum_by_decomposition_2<NoHolesDecomposition_,
WithHolesDecomposition_,
Container_>::Traits_2 traits;
return minkowski_sum_by_decomposition_2(pgn1, pgn2,
decomp_no_holes, decomp_with_holes,
traits);
}
/*! Compute the Minkowski sum of a simple polygon and a polygon with holes
* by decomposing each polygon to convex sub-polygons and computing the union
* of the pairwise Minkowski sums of the sub-polygons. The result is also
* represented as a polygon with holes.
* \param[in] pgn1 The polygon with holes.
* \param[in] pgn2 The simple polygon.
* \param[in] decomposition A functor for decomposing polygons.
* \param[in] traits The traits.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_,
typename NoHoleDecomposition_, typename WithHolesDecomposition_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_by_decomposition_2
(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const NoHoleDecomposition_& decomp_no_holes,
const WithHolesDecomposition_& decomp_with_holes,
const typename Minkowski_sum_by_decomposition_2<NoHoleDecomposition_,
WithHolesDecomposition_,
Container_>::Traits_2& traits)
{
return minkowski_sum_by_decomposition_2(pgn2, pgn1,
decomp_no_holes, decomp_with_holes,
traits);
}
/*!@}*/
} //namespace CGAL } //namespace CGAL

View File

@ -1,4 +1,4 @@
rvt rvtwud
data/pwh1.dat data/pwh1.dat data/pwh1.dat data/pwh1.dat
data/pwh2.dat data/pwh2.dat data/pwh2.dat data/pwh2.dat
data/pwh1.dat data/pwh2.dat data/pwh1.dat data/pwh2.dat

View File

@ -4,6 +4,7 @@
#include <CGAL/Polygon_vertical_decomposition_2.h> #include <CGAL/Polygon_vertical_decomposition_2.h>
#include <CGAL/Polygon_triangulation_decomposition_2.h> #include <CGAL/Polygon_triangulation_decomposition_2.h>
#include <CGAL/Boolean_set_operations_2.h> #include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/Small_side_angle_bisector_decomposition_2.h>
#include "read_polygon.h" #include "read_polygon.h"
@ -25,14 +26,20 @@ bool are_equal(const Polygon_with_holes_2& ph1,
typedef enum { typedef enum {
REDUCED_CONVOLUTION, REDUCED_CONVOLUTION,
VERTICAL_DECOMP, VERTICAL_DECOMPOSITION,
TRIANGULATION_DECOMP TRIANGULATION_DECOMPOSITION,
VERTICAL_AND_ANGLE_BISECTOR_DECOMPOSITION,
TRIANGULATION_AND_ANGLE_BISECTOR_DECOMPOSITION,
OPTIMAL_DECOMPOSITION,
} Strategy; } Strategy;
static const char* strategy_names[] = { static const char* strategy_names[] = {
"reduced convolution", "reduced convolution",
"vertical decomposition", "vertical decomposition",
"constrained triangulation decomposition" "constrained triangulation decomposition",
"vertical and angle bisector decomposition",
"constrained triangulation and angle bisector decomposition",
"optimal decomposition"
}; };
Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_with_holes_2& p, Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_with_holes_2& p,
@ -42,18 +49,102 @@ Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_with_holes_2& p,
switch (strategy) { switch (strategy) {
case REDUCED_CONVOLUTION: case REDUCED_CONVOLUTION:
{ {
return minkowski_sum_by_reduced_convolution_2(p, q); return CGAL::minkowski_sum_by_reduced_convolution_2(p, q);
} }
case VERTICAL_DECOMP: case VERTICAL_DECOMPOSITION:
{ {
CGAL::Polygon_vertical_decomposition_2<Kernel> decomp; CGAL::Polygon_vertical_decomposition_2<Kernel> decomp;
return minkowski_sum_2(p, q, decomp); return CGAL::minkowski_sum_2(p, q, decomp);
} }
default: // TRIANGULATION_DECOMP case TRIANGULATION_DECOMPOSITION:
{ {
CGAL::Polygon_triangulation_decomposition_2<Kernel> decomp; CGAL::Polygon_triangulation_decomposition_2<Kernel> decomp;
return minkowski_sum_2(p, q, decomp); return CGAL::minkowski_sum_2(p, q, decomp);
} }
case VERTICAL_AND_ANGLE_BISECTOR_DECOMPOSITION:
{
typedef CGAL::Small_side_angle_bisector_decomposition_2<Kernel>
No_holes_decomposition;
typedef CGAL::Polygon_vertical_decomposition_2<Kernel>
With_holes_decomposition;
if (0 == p.number_of_holes()) {
const Polygon_2& pnh = p.outer_boundary();
No_holes_decomposition decomp_no_holes;
if (0 == q.number_of_holes()) {
const Polygon_2& qnh = q.outer_boundary();
return CGAL::minkowski_sum_2(pnh, qnh,
decomp_no_holes, decomp_no_holes);
}
else {
With_holes_decomposition decomp_with_holes;
return
CGAL::minkowski_sum_2(pnh, q, decomp_no_holes, decomp_with_holes);
}
}
else {
With_holes_decomposition decomp_with_holes;
if (0 == q.number_of_holes()) {
const Polygon_2& qnh = q.outer_boundary();
No_holes_decomposition decomp_no_holes;
return
CGAL::minkowski_sum_2(p, qnh, decomp_with_holes, decomp_no_holes);
}
else {
return
CGAL::minkowski_sum_2(p, q, decomp_with_holes, decomp_with_holes);
}
}
}
case TRIANGULATION_AND_ANGLE_BISECTOR_DECOMPOSITION:
{
typedef CGAL::Small_side_angle_bisector_decomposition_2<Kernel>
No_holes_decomposition;
typedef CGAL::Polygon_triangulation_decomposition_2<Kernel>
With_holes_decomposition;
if (0 == p.number_of_holes()) {
const Polygon_2& pnh = p.outer_boundary();
No_holes_decomposition decomp_no_holes;
if (0 == q.number_of_holes()) {
const Polygon_2& qnh = q.outer_boundary();
return CGAL::minkowski_sum_2(pnh, qnh,
decomp_no_holes, decomp_no_holes);
}
else {
With_holes_decomposition decomp_with_holes;
return
CGAL::minkowski_sum_2(pnh, q, decomp_no_holes, decomp_with_holes);
}
}
else {
With_holes_decomposition decomp_with_holes;
if (0 == q.number_of_holes()) {
const Polygon_2& qnh = q.outer_boundary();
No_holes_decomposition decomp_no_holes;
return
CGAL::minkowski_sum_2(p, qnh, decomp_with_holes, decomp_no_holes);
}
else {
return
CGAL::minkowski_sum_2(p, q, decomp_with_holes, decomp_with_holes);
}
}
}
case OPTIMAL_DECOMPOSITION:
{
CGAL::Small_side_angle_bisector_decomposition_2<Kernel> decomp_no_holes;
CGAL::Polygon_triangulation_decomposition_2<Kernel> decomp_with_holes;
return CGAL::minkowski_sum_by_decomposition_2(p, q,
decomp_no_holes,
decomp_with_holes);
}
default:
std::cerr << "Invalid strategy" << std::endl;
return Polygon_with_holes_2();
} }
} }
@ -81,11 +172,23 @@ int main(int argc, char* argv[])
break; break;
case 'v': case 'v':
strategies.push_back(VERTICAL_DECOMP); strategies.push_back(VERTICAL_DECOMPOSITION);
break; break;
case 't': case 't':
strategies.push_back(TRIANGULATION_DECOMP); strategies.push_back(TRIANGULATION_DECOMPOSITION);
break;
case 'w':
strategies.push_back(VERTICAL_AND_ANGLE_BISECTOR_DECOMPOSITION);
break;
case 'u':
strategies.push_back(TRIANGULATION_AND_ANGLE_BISECTOR_DECOMPOSITION);
break;
case 'd':
strategies.push_back(OPTIMAL_DECOMPOSITION);
break; break;
default: default: