From 0c8149465ffce295b19edf05472476b81c0340ff Mon Sep 17 00:00:00 2001 From: Sebastian Morr Date: Sat, 18 Oct 2014 11:23:45 +0200 Subject: [PATCH] Integrate the reduced convolution method into test_minkowski_sum_with_holes Also, put minkowski_sum_reduced_convolution_2(pwh, pwh) into the API. --- .../Minkowski_sum_by_reduced_convolution_2.h | 34 +++++++++++++++++-- .../include/CGAL/minkowski_sum_2.h | 28 +++++++++++++++ .../Minkowski_sum_2/test_minkowski_sum.cpp | 4 +-- .../test_minkowski_sum_with_holes.cmd | 2 +- .../test_minkowski_sum_with_holes.cpp | 14 ++++++-- 5 files changed, 75 insertions(+), 7 deletions(-) diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/Minkowski_sum_by_reduced_convolution_2.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/Minkowski_sum_by_reduced_convolution_2.h index 38110ce7c13..f7b9c18fc72 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/Minkowski_sum_by_reduced_convolution_2.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/Minkowski_sum_by_reduced_convolution_2.h @@ -2,6 +2,7 @@ #define CGAL_MINKOWSKI_SUM_BY_REDUCED_CONVOLUTION_2_H #include +#include #include #include @@ -28,6 +29,7 @@ private: // Basic types: typedef CGAL::Polygon_2 Polygon_2; + typedef CGAL::Polygon_with_holes_2 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 + 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 points; + connect_holes(pgn1, std::back_inserter(points)); + for (typename std::list::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::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 + 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(SCALING, -1), pgn1); AABB_collision_detector_2 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 diff --git a/Minkowski_sum_2/include/CGAL/minkowski_sum_2.h b/Minkowski_sum_2/include/CGAL/minkowski_sum_2.h index e4287fe1716..78dcdcb715c 100644 --- a/Minkowski_sum_2/include/CGAL/minkowski_sum_2.h +++ b/Minkowski_sum_2/include/CGAL/minkowski_sum_2.h @@ -62,6 +62,34 @@ minkowski_sum_reduced_convolution_2(const Polygon_2& 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 +Polygon_with_holes_2 +minkowski_sum_reduced_convolution_2(const Polygon_with_holes_2& pgn1, + const Polygon_with_holes_2& pgn2) +{ + typedef Kernel_ Kernel; + typedef Container_ Container; + + Minkowski_sum_by_reduced_convolution_2 mink_sum; + Polygon_2 sum_bound; + std::list > sum_holes; + + mink_sum (pgn1, pgn2, sum_bound, std::back_inserter(sum_holes)); + + return (Polygon_with_holes_2 (sum_bound, + sum_holes.begin(), + sum_holes.end())); +} + /*! * Compute the Minkowski sum of two simple polygons using the (full) * convolution method. diff --git a/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum.cpp b/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum.cpp index 7bdbe23ca6a..9bc05c537fa 100644 --- a/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum.cpp +++ b/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum.cpp @@ -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, diff --git a/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum_with_holes.cmd b/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum_with_holes.cmd index 09b06b0b9e2..2fc35b88ddc 100644 --- a/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum_with_holes.cmd +++ b/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum_with_holes.cmd @@ -1,4 +1,4 @@ -vt +rvt data/pwh1.dat data/pwh1.dat data/pwh2.dat data/pwh2.dat data/pwh1.dat data/pwh2.dat diff --git a/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum_with_holes.cpp b/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum_with_holes.cpp index bb66916471e..c5aa69d0ced 100644 --- a/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum_with_holes.cpp +++ b/Minkowski_sum_2/test/Minkowski_sum_2/test_minkowski_sum_with_holes.cpp @@ -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 decomp; @@ -70,6 +76,10 @@ int main(int argc, char* argv[]) std::list 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;