mirror of https://github.com/CGAL/cgal
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:
parent
ba34b4fab9
commit
0c8149465f
|
|
@ -2,6 +2,7 @@
|
||||||
#define CGAL_MINKOWSKI_SUM_BY_REDUCED_CONVOLUTION_2_H
|
#define CGAL_MINKOWSKI_SUM_BY_REDUCED_CONVOLUTION_2_H
|
||||||
|
|
||||||
#include <CGAL/basic.h>
|
#include <CGAL/basic.h>
|
||||||
|
#include <CGAL/connect_holes.h>
|
||||||
#include <CGAL/Arrangement_with_history_2.h>
|
#include <CGAL/Arrangement_with_history_2.h>
|
||||||
#include <CGAL/Arr_segment_traits_2.h>
|
#include <CGAL/Arr_segment_traits_2.h>
|
||||||
|
|
||||||
|
|
@ -28,6 +29,7 @@ private:
|
||||||
|
|
||||||
// Basic types:
|
// Basic types:
|
||||||
typedef CGAL::Polygon_2<Kernel, Container> Polygon_2;
|
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::Point_2 Point_2;
|
||||||
typedef typename Kernel::Vector_2 Vector_2;
|
typedef typename Kernel::Vector_2 Vector_2;
|
||||||
typedef typename Kernel::Direction_2 Direction_2;
|
typedef typename Kernel::Direction_2 Direction_2;
|
||||||
|
|
@ -83,6 +85,36 @@ public:
|
||||||
CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE);
|
CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE);
|
||||||
CGAL_precondition(pgn2.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:
|
// 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);
|
const Polygon_2 inversed_pgn1 = transform(Aff_transformation_2<Kernel>(SCALING, -1), pgn1);
|
||||||
AABB_collision_detector_2<Kernel, Container> collision_detector(pgn2, inversed_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
|
// Builds the reduced convolution using a fiber grid approach. For each
|
||||||
// starting vertex, try to add two outgoing next states. If a visited
|
// 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
|
// vertex is reached, then do not explore further. This is a BFS-like
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,34 @@ minkowski_sum_reduced_convolution_2(const Polygon_2<Kernel_, Container_>& pgn1,
|
||||||
sum_holes.end()));
|
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)
|
* Compute the Minkowski sum of two simple polygons using the (full)
|
||||||
* convolution method.
|
* convolution method.
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ static const char* strategy_names[] = {
|
||||||
"small-side angle-bisector decomposition",
|
"small-side angle-bisector decomposition",
|
||||||
"optimal convex decomposition",
|
"optimal convex decomposition",
|
||||||
"Hertel-Mehlhorn decomposition",
|
"Hertel-Mehlhorn decomposition",
|
||||||
"Greene decomosition",
|
"Greene decomposition",
|
||||||
"Vertical decomosition"
|
"vertical decomposition"
|
||||||
};
|
};
|
||||||
|
|
||||||
Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_2& p, Polygon_2& q,
|
Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_2& p, Polygon_2& q,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
vt
|
rvt
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,15 @@ bool are_equal(const Polygon_with_holes_2& ph1,
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
REDUCED_CONVOLUTION,
|
||||||
VERTICAL_DECOMP,
|
VERTICAL_DECOMP,
|
||||||
TRIANGULATION_DECOMP
|
TRIANGULATION_DECOMP
|
||||||
} Strategy;
|
} Strategy;
|
||||||
|
|
||||||
static const char* strategy_names[] = {
|
static const char* strategy_names[] = {
|
||||||
"Vertical decomosition",
|
"reduced convolution",
|
||||||
"Constrained triangulation decomosition"
|
"vertical decomposition",
|
||||||
|
"constrained triangulation 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,
|
||||||
|
|
@ -38,6 +40,10 @@ Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_with_holes_2& p,
|
||||||
Strategy strategy)
|
Strategy strategy)
|
||||||
{
|
{
|
||||||
switch (strategy) {
|
switch (strategy) {
|
||||||
|
case REDUCED_CONVOLUTION:
|
||||||
|
{
|
||||||
|
return minkowski_sum_reduced_convolution_2(p, q);
|
||||||
|
}
|
||||||
case VERTICAL_DECOMP:
|
case VERTICAL_DECOMP:
|
||||||
{
|
{
|
||||||
CGAL::Polygon_vertical_decomposition_2<Kernel> decomp;
|
CGAL::Polygon_vertical_decomposition_2<Kernel> decomp;
|
||||||
|
|
@ -70,6 +76,10 @@ int main(int argc, char* argv[])
|
||||||
std::list<Strategy> strategies;
|
std::list<Strategy> strategies;
|
||||||
for (int i = 0; i < strlen(argv[1]); ++i) {
|
for (int i = 0; i < strlen(argv[1]); ++i) {
|
||||||
switch (argv[1][i]) {
|
switch (argv[1][i]) {
|
||||||
|
case 'r':
|
||||||
|
strategies.push_back(REDUCED_CONVOLUTION);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
strategies.push_back(VERTICAL_DECOMP);
|
strategies.push_back(VERTICAL_DECOMP);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue