Integrate the reduced convolution method into test_minkowski_sum_with_holes

Also, put minkowski_sum_reduced_convolution_2(pwh, pwh) into the API.
This commit is contained in:
Sebastian Morr 2014-10-18 11:23:45 +02:00
parent ba34b4fab9
commit 0c8149465f
5 changed files with 75 additions and 7 deletions

View File

@ -2,6 +2,7 @@
#define CGAL_MINKOWSKI_SUM_BY_REDUCED_CONVOLUTION_2_H
#include <CGAL/basic.h>
#include <CGAL/connect_holes.h>
#include <CGAL/Arrangement_with_history_2.h>
#include <CGAL/Arr_segment_traits_2.h>
@ -28,6 +29,7 @@ private:
// Basic types:
typedef CGAL::Polygon_2<Kernel, Container> Polygon_2;
typedef CGAL::Polygon_with_holes_2<Kernel, Container> Polygon_with_holes_2;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Vector_2 Vector_2;
typedef typename Kernel::Direction_2 Direction_2;
@ -83,6 +85,36 @@ public:
CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE);
CGAL_precondition(pgn2.orientation() == COUNTERCLOCKWISE);
common_operator(pgn1, pgn2, outer_boundary, holes);
}
template <class OutputIterator>
void operator()(const Polygon_with_holes_2 &pgn1, const Polygon_with_holes_2 &pgn2,
Polygon_2 &outer_boundary, OutputIterator holes) const
{
Polygon_2 p_pseudo_simple, q_pseudo_simple;
std::list<Point_2> points;
connect_holes(pgn1, std::back_inserter(points));
for (typename std::list<Point_2>::iterator it = points.begin(); it != points.end(); it++) {
p_pseudo_simple.push_back(*it);
}
points.clear();
connect_holes(pgn2, std::back_inserter(points));
for (typename std::list<Point_2>::iterator it = points.begin(); it != points.end(); it++) {
q_pseudo_simple.push_back(*it);
}
common_operator(p_pseudo_simple, q_pseudo_simple, outer_boundary, holes);
}
private:
template <class OutputIterator>
void common_operator(const Polygon_2 &pgn1, const Polygon_2 &pgn2,
Polygon_2 &outer_boundary, OutputIterator holes) const
{
// Initialize collision detector. It operates on pgn2 and on the inversed pgn1:
const Polygon_2 inversed_pgn1 = transform(Aff_transformation_2<Kernel>(SCALING, -1), pgn1);
AABB_collision_detector_2<Kernel, Container> collision_detector(pgn2, inversed_pgn1);
@ -106,8 +138,6 @@ public:
}
}
private:
// Builds the reduced convolution using a fiber grid approach. For each
// starting vertex, try to add two outgoing next states. If a visited
// vertex is reached, then do not explore further. This is a BFS-like

View File

@ -62,6 +62,34 @@ minkowski_sum_reduced_convolution_2(const Polygon_2<Kernel_, Container_>& pgn1,
sum_holes.end()));
}
/*!
* Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given
* polygons-with-holes.
* The function computes the reduced convolution of the two polygons and
* extracts those loops of the convolution which are part of the Minkowsi
* sum. This method works very efficiently, regardless of whether `P` and
* `Q` are convex or non-convex.
* The result is also represented as a polygon with holes.
*/
template <class Kernel_, class Container_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_reduced_convolution_2(const Polygon_with_holes_2<Kernel_, Container_>& pgn1,
const Polygon_with_holes_2<Kernel_, Container_>& pgn2)
{
typedef Kernel_ Kernel;
typedef Container_ Container;
Minkowski_sum_by_reduced_convolution_2<Kernel, Container> mink_sum;
Polygon_2<Kernel,Container> sum_bound;
std::list<Polygon_2<Kernel,Container> > sum_holes;
mink_sum (pgn1, pgn2, sum_bound, std::back_inserter(sum_holes));
return (Polygon_with_holes_2<Kernel,Container> (sum_bound,
sum_holes.begin(),
sum_holes.end()));
}
/*!
* Compute the Minkowski sum of two simple polygons using the (full)
* convolution method.

View File

@ -40,8 +40,8 @@ static const char* strategy_names[] = {
"small-side angle-bisector decomposition",
"optimal convex decomposition",
"Hertel-Mehlhorn decomposition",
"Greene decomosition",
"Vertical decomosition"
"Greene decomposition",
"vertical decomposition"
};
Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_2& p, Polygon_2& q,

View File

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

View File

@ -24,13 +24,15 @@ bool are_equal(const Polygon_with_holes_2& ph1,
}
typedef enum {
REDUCED_CONVOLUTION,
VERTICAL_DECOMP,
TRIANGULATION_DECOMP
} Strategy;
static const char* strategy_names[] = {
"Vertical decomosition",
"Constrained triangulation decomosition"
"reduced convolution",
"vertical decomposition",
"constrained triangulation decomposition"
};
Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_with_holes_2& p,
@ -38,6 +40,10 @@ Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_with_holes_2& p,
Strategy strategy)
{
switch (strategy) {
case REDUCED_CONVOLUTION:
{
return minkowski_sum_reduced_convolution_2(p, q);
}
case VERTICAL_DECOMP:
{
CGAL::Polygon_vertical_decomposition_2<Kernel> decomp;
@ -70,6 +76,10 @@ int main(int argc, char* argv[])
std::list<Strategy> strategies;
for (int i = 0; i < strlen(argv[1]); ++i) {
switch (argv[1][i]) {
case 'r':
strategies.push_back(REDUCED_CONVOLUTION);
break;
case 'v':
strategies.push_back(VERTICAL_DECOMP);
break;