merged with the reduced convolution branch

This commit is contained in:
Efi Fogel 2014-09-15 19:33:17 +03:00
commit 99f663b8bd
54 changed files with 24935 additions and 691 deletions

View File

@ -2384,6 +2384,14 @@ ADDRESS = "Saarbr{\"u}cken, Germany"
year={2009},
pages={1-6},
howpublished = {http://igl.ethz.ch/projects/ARAP/}
@conference {cgal:bl-frmsurc-11
,address = {San Francisco, CA}
,author = {Evan Behar and Jyh-Ming Lien}
,booktitle = {Proc. {IEEE} Int. Conf. Intel. Rob. Syst. ({IROS})}
,month = {Sep.}
,title = {Fast and Robust 2D Minkowski Sum Using Reduced Convolution}
,year = {2011}
}
% ----------------------------------------------------------------------------

View File

@ -1,53 +0,0 @@
#ifndef _PRINT_UTILS_H_
#define _PRINT_UTILS_H_
#include <CGAL/Polygon_with_holes_2.h>
#include <iostream>
//-----------------------------------------------------------------------------
// Pretty-print a CGAL polygon.
//
template<class Kernel, class Container>
void print_polygon (const CGAL::Polygon_2<Kernel, Container>& P)
{
typename CGAL::Polygon_2<Kernel, Container>::Vertex_const_iterator vit;
std::cout << "[ " << P.size() << " vertices:";
for (vit = P.vertices_begin(); vit != P.vertices_end(); ++vit)
std::cout << " (" << *vit << ')';
std::cout << " ]" << std::endl;
return;
}
//-----------------------------------------------------------------------------
// Pretty-print a polygon with holes.
//
template<class Kernel, class Container>
void print_polygon_with_holes
(const CGAL::Polygon_with_holes_2<Kernel, Container>& pwh)
{
if (! pwh.is_unbounded())
{
std::cout << "{ Outer boundary = ";
print_polygon (pwh.outer_boundary());
}
else
std::cout << "{ Unbounded polygon." << std::endl;
typename CGAL::Polygon_with_holes_2<Kernel,Container>::
Hole_const_iterator hit;
unsigned int k = 1;
std::cout << " " << pwh.number_of_holes() << " holes:" << std::endl;
for (hit = pwh.holes_begin(); hit != pwh.holes_end(); ++hit, ++k)
{
std::cout << " Hole #" << k << " = ";
print_polygon (*hit);
}
std::cout << " }" << std::endl;
return;
}
#endif

View File

@ -1,70 +0,0 @@
//! \file examples/Minkowski_sum_2/sum_by_decomposition.cpp
// Computing the Minkowski sum of two non-convex polygons read from a file
// using the small-side angle-bisector decomposition strategy.
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/minkowski_sum_2.h>
#include <CGAL/Small_side_angle_bisector_decomposition_2.h>
#include <iostream>
#include <fstream>
#include <CGAL/Timer.h>
#include "print_utils.h"
struct Kernel : public CGAL::Exact_predicates_exact_constructions_kernel {};
typedef Kernel::Point_2 Point_2;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
int main (int argc, char * argv[])
{
CGAL::Timer t_mink_sum;
if (argc < 3)
{
std::cerr << "Usage: " << argv[0]
<< " <polygon#1> <polygon#2>"
<< std::endl;
return (1);
}
std::ifstream in_file1 (argv[1]);
if (! in_file1.is_open())
{
std::cerr << "Failed to open the input file 1." << std::endl;
return (1);
}
// Read the two polygons from the files and compute their Minkowski sum.
Polygon_2 P, Q;
in_file1 >> P;
in_file1.close();
std::ifstream in_file2 (argv[2]);
if (! in_file2.is_open())
{
std::cerr << "Failed to open the input file 2." << std::endl;
return (1);
}
in_file2 >> Q;
in_file2.close();
// Compute the Minkowski sum using the decomposition approach.
CGAL::Small_side_angle_bisector_decomposition_2<Kernel> ssab_decomp;
t_mink_sum.start();
Polygon_with_holes_2 sum = minkowski_sum_2 (P, Q, ssab_decomp);
t_mink_sum.stop();
std::cout << "Done! Time:" << t_mink_sum.time() << " seconds\n P (+) Q = "; print_polygon_with_holes (sum);
return (0);
}

View File

@ -4,19 +4,81 @@ namespace CGAL {
\ingroup PkgMinkowskiSum2
Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given polygons.
The function computes the convolution cycles of the two polygons and
This method defaults to the reduced convolution method, see below.
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.
\pre Both `P` and `Q` are simple, counterclockwise-oriented polygons.
\sa `CGAL::minkowski_sum_reduced_convolution_2()`
\sa `CGAL::minkowski_sum_full_convolution_2()`
*/
template<class Kernel, class Container>
Polygon_with_holes_2<Kernel,Container>
minkowski_sum_2 (const Polygon_2<Kernel,Container>& P,
const Polygon_2<Kernel,Container>& Q);
/*!
\ingroup PkgMinkowskiSum2
Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given polygons. The
function computes the reduced convolution \cgalCite{cgal:bl-frmsurc-11} 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. It is usually faster than the full
convolution method, except in degenerate cases where the output polygon has
many holes.
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.
\pre Both `P` and `Q` are simple, counterclockwise-oriented polygons.
*/
template<class Kernel, class Container>
Polygon_with_holes_2<Kernel,Container>
minkowski_sum_reduced_convolution_2 (const Polygon_2<Kernel,Container>& P,
const Polygon_2<Kernel,Container>& Q);
/*!
\ingroup PkgMinkowskiSum2
Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given polygons.
The function computes the (full) convolution cycles of the two polygons and
extract the regions having positive winding number with respect to these
cycles. This method work very efficiently, regardless of whether `P`
and `Q` are convex or non-convex.
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.
\pre Both `P` and `Q` are simple polygons.
*/
template<class Kernel, class Container>
Polygon_with_holes_2<Kernel,Container>
minkowski_sum_2 (const Polygon_2<Kernel,Container>& P,
const Polygon_2<Kernel,Container>& Q);
minkowski_sum_full_convolution_2 (const Polygon_2<Kernel,Container>& P,
const Polygon_2<Kernel,Container>& Q);
/*!
\ingroup PkgMinkowskiSum2
Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given polygons.
The function computes the (full) convolution cycles of the two polygons and
extract the regions having positive winding number with respect to these
cycles. This method work very efficiently, regardless of whether `P`
and `Q` are convex or non-convex.
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.
\pre Both `P` and `Q` are simple polygons.
*/
template<class Kernel, class Container>
Polygon_with_holes_2<Kernel,Container>
minkowski_sum_full_convolution_2(const Polygon_2<Kernel,Container>& P,
const Polygon_2<Kernel,Container>& Q,
const Kernel& kernel);
/*!
\ingroup PkgMinkowskiSum2

View File

@ -7,7 +7,7 @@ namespace CGAL {
\anchor chapterMinkowskisum2
\cgalAutoToc
\authors Ron Wein and Efi Fogel
\authors Ron Wein, Alon Baram, Efi Fogel, Eyal Flato, Michael Hemmer, and Sebastian Morr
\section mink_secintro Introduction
@ -120,6 +120,33 @@ 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.
<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
different filters to identify holes in the Minkowski sum:
<OL>
<LI>Loops that are on the Minkowski sum's boundary have to be orientable, that
is, all normal directions of its edges have to point either inward or
outward.</LI>
<LI>For any point \f$x\f$ inside of a hole of the Minkowski sum, the following
condition holds: \f$(-P + x) \cap Q = \emptyset\f$. If, on the other hand, the
inversed version of \f$P\f$, translated by \f$x\f$, overlaps \f$Q\f$, the loop
is a <I>false</I> hole and is in the Minkowski sum's interior.</LI>
</OL>
After applying these two filters, only those segments which constitute the
Minkowski sum's boundary remain. In most cases, the reduced convolution
approach is even faster than the full convolution approach, as the induced
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>
\subsection mink_ssecsum_conv Computing Minkowski Sum using Convolutions
@ -127,6 +154,12 @@ consumes less space.
The function template \link minkowski_sum_2() `minkowski_sum_2(P, Q)`\endlink
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.
\link minkowski_sum_2() `minkowski_sum_2(P, Q)`\endlink defaults to calling the
function \link minkowski_sum_reduced_convolution_2() `minkowski_sum_reduced_convolution_2(P, Q)`\endlink,
which applies the reduced convolution aforementioned.
Explicitly call the function \link minkowski_sum_full_convolution_2()
`minkowski_sum_full_convolution_2(P, Q)`\endlink to apply
the full convolution approach.
The types of the operands are instances of the
\link Polygon_2 `Polygon_2`\endlink class template. As the input polygons
may not be convex, their Minkowski sum may not be simply connected and
@ -545,6 +578,9 @@ applying bug fixes and other improvements. In particular, Andreas Fabri and
Laurent Rineau helped tracing and solving several bugs in the approximated
offset computation. They have also suggested a few algorithmic improvements
that made their way into version 3.4, yielding a faster approximation scheme.
During the <I>Google Summer of Code</I> 2014, Sebastian Morr, mentored by
Michael Hemmer, implemented the reduced convolution approach, based on Alon
Baram's~2013 master's thesis.
*/
} /* namespace CGAL */

View File

@ -5,17 +5,16 @@
/*!
\addtogroup PkgMinkowskiSum2
\todo check generated documentation
\cgalPkgDescriptionBegin{2D Minkowski Sums,PkgMinkowskiSum2Summary}
\cgalPkgPicture{Minkowski_sum_2/fig/Minkowski_sum_2.png}
\cgalPkgSummaryBegin
\cgalPkgAuthors{Ron Wein and Efi Fogel}
\cgalPkgAuthor{Ron Wein, Alon Baram, Eyal Flato, Efi Fogel, Michael Hemmer, Sebastian Morr}
\cgalPkgDesc{This package consists of functions that compute the Minkowski sum of two simple straight-edge polygons in the plane. It also contains functions for computing the Minkowski sum of a polygon and a disc, an operation known as <I>offsetting</I> or <I>dilating</I> a polygon. The package can compute the exact representation of the offset polygon, or provide a guaranteed approximation of the offset.}
\cgalPkgManuals{Chapter_2D_Minkowski_Sums,PkgMinkowskiSum2}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{3.3}
\cgalPkgDependsOn{\ref PkgArrangement2Summary}
\cgalPkgDependsOn{\ref PkgArrangement2Summary, \ref PkgAABB_treeSummary}
\cgalPkgBib{cgal:w-rms2}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgShortInfoEnd

View File

@ -9,3 +9,4 @@ Polygon
Partition_2
Boolean_set_operations_2
Number_types
AABB_tree

View File

@ -0,0 +1,64 @@
#ifndef CGAL_AABB_COLLISION_DETECTOR_2_H
#define CGAL_AABB_COLLISION_DETECTOR_2_H
#include <CGAL/Minkowski_sum_2/AABB_tree_with_join.h>
#include <CGAL/Minkowski_sum_2/AABB_traits_2.h>
#include <CGAL/Minkowski_sum_2/AABB_segment_2_primitive.h>
namespace CGAL {
// Tests whether two polygons P and Q overlap for different translations of Q.
template <class Kernel_, class Container_>
class AABB_collision_detector_2
{
public:
typedef typename Kernel_::Point_2 Point_2;
typedef typename Kernel_::Vector_2 Vector_2;
typedef typename CGAL::Polygon_2<Kernel_> Polygon_2;
typedef typename Polygon_2::Edge_const_iterator Edge_iterator;
typedef AABB_segment_2_primitive<Kernel_, Edge_iterator, Polygon_2>
Tree_segment_2;
typedef AABB_traits_2<Kernel_, Tree_segment_2> Tree_traits;
typedef AABB_tree_with_join<Tree_traits> Tree_2;
public:
AABB_collision_detector_2(const Polygon_2 &p, const Polygon_2 &q)
: m_stationary_tree((p.edges_begin()), (p.edges_end())),
m_translating_tree((q.edges_begin()), (q.edges_end())), m_p(q), m_q(p)
{
}
// Returns true iff the polygons' boundaries intersect or one polygon is
// completely inside of the other one. Q is translated by t.
bool check_collision(const Point_2 &t)
{
if (m_stationary_tree.do_intersect(m_translating_tree, t))
{
return true;
}
// If t_q is inside of P, or t_p is inside of Q, one polygon is completely
// inside of the other.
Point_2 t_q = *m_q.vertices_begin() + Vector_2(ORIGIN, t);
Point_2 t_p = *m_p.vertices_begin() - Vector_2(ORIGIN, t);
// Use bounded_side_2() instead of on_bounded_side() because the latter
// checks vor simplicity every time.
return bounded_side_2(m_p.vertices_begin(), m_p.vertices_end(), t_q, m_p.traits_member()) == ON_BOUNDED_SIDE
|| bounded_side_2(m_q.vertices_begin(), m_q.vertices_end(), t_p, m_q.traits_member()) == ON_BOUNDED_SIDE;
}
private:
Tree_2 m_stationary_tree;
Tree_2 m_translating_tree;
const Polygon_2 &m_p;
const Polygon_2 &m_q;
};
} // namespace CGAL
#endif

View File

@ -0,0 +1,285 @@
// Copyright (c) 2008 INRIA Sophia-Antipolis (France).
// 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.
//
// $URL$
// $Id$
//
//
// Author(s) : Camille Wormser, Pierre Alliez, Stephane Tayeb
#ifndef CGAL_AABB_NODE_WITH_JOIN_H
#define CGAL_AABB_NODE_WITH_JOIN_H
#include <CGAL/Profile_counter.h>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/intersections.h>
#include <CGAL/Bbox_3.h>
#include <vector>
namespace CGAL {
/**
* @class AABB_node_with_join
*
*
*/
template<typename AABBTraits>
class AABB_node_with_join
{
public:
typedef typename AABBTraits::Bounding_box Bounding_box;
/// Constructor
AABB_node_with_join()
: m_bbox()
, m_p_left_child(NULL)
, m_p_right_child(NULL) { };
/// Non virtual Destructor
/// Do not delete children because the tree hosts and delete them
~AABB_node_with_join() { };
/// Returns the bounding box of the node
const Bounding_box& bbox() const { return m_bbox; }
/**
* @brief Builds the tree by recursive expansion.
* @param first the first primitive to insert
* @param last the last primitive to insert
* @param range the number of primitive of the range
*
* [first,last[ is the range of primitives to be added to the tree.
*/
template<typename ConstPrimitiveIterator>
void expand(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
const std::size_t range,
const AABBTraits&);
/**
* @brief General traversal query
* @param query the query
* @param traits the traversal traits that define the traversal behaviour
* @param nb_primitives the number of primitive
*
* General traversal query. The traits class allows using it for the various
* traversal methods we need: listing, counting, detecting intersections,
* drawing the boxes.
*/
template<class Traversal_traits, class Query>
void traversal(const Query& query,
Traversal_traits& traits,
const std::size_t nb_primitives) const;
/**
* @param other_node root node of a tree which we want to traverse in parallel
* @param traits the traversal traits that define the traversal behaviour
* @param nb_primitives the number of primitives in this tree
* @param nb_primitives_other the number of primitives in the other tree
* @param first_stationary if true, the other_node is the translatable tree's root
*
* General traversal query for two trees.
*/
template<class Traversal_traits>
void traversal(const AABB_node_with_join &other_node,
Traversal_traits &traits,
const std::size_t nb_primitives,
const std::size_t nb_primitives_other,
bool first_stationary) const;
private:
typedef AABBTraits AABB_traits;
typedef AABB_node_with_join<AABB_traits> Node;
typedef typename AABB_traits::Primitive Primitive;
/// Helper functions
const Node& left_child() const
{ return *static_cast<Node*>(m_p_left_child); }
const Node& right_child() const
{ return *static_cast<Node*>(m_p_right_child); }
const Primitive& left_data() const
{ return *static_cast<Primitive*>(m_p_left_child); }
const Primitive& right_data() const
{ return *static_cast<Primitive*>(m_p_right_child); }
Node& left_child() { return *static_cast<Node*>(m_p_left_child); }
Node& right_child() { return *static_cast<Node*>(m_p_right_child); }
Primitive& left_data() { return *static_cast<Primitive*>(m_p_left_child); }
Primitive& right_data() { return *static_cast<Primitive*>(m_p_right_child); }
private:
/// node bounding box
Bounding_box m_bbox;
/// children nodes, either pointing towards children (if children are not leaves),
/// or pointing toward input primitives (if children are leaves).
void *m_p_left_child;
void *m_p_right_child;
private:
// Disabled copy constructor & assignment operator
typedef AABB_node_with_join<AABBTraits> Self;
AABB_node_with_join(const Self& src);
Self& operator=(const Self& src);
}; // end class AABB_node_with_join
template<typename Tr>
template<typename ConstPrimitiveIterator>
void
AABB_node_with_join<Tr>::expand(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
const std::size_t range,
const Tr& traits)
{
m_bbox = traits.compute_bbox_object()(first, beyond);
// sort primitives along longest axis aabb
traits.sort_primitives_object()(first, beyond, m_bbox);
switch(range)
{
case 2:
m_p_left_child = &(*first);
m_p_right_child = &(*(++first));
break;
case 3:
m_p_left_child = &(*first);
m_p_right_child = static_cast<Node*>(this)+1;
right_child().expand(first+1, beyond, 2,traits);
break;
default:
const std::size_t new_range = range/2;
m_p_left_child = static_cast<Node*>(this) + 1;
m_p_right_child = static_cast<Node*>(this) + new_range;
left_child().expand(first, first + new_range, new_range,traits);
right_child().expand(first + new_range, beyond, range - new_range,traits);
}
}
template<typename Tr>
template<class Traversal_traits, class Query>
void
AABB_node_with_join<Tr>::traversal(const Query& query,
Traversal_traits& traits,
const std::size_t nb_primitives) const
{
// Recursive traversal
switch(nb_primitives)
{
case 2:
traits.intersection(query, left_data());
if( traits.go_further() )
{
traits.intersection(query, right_data());
}
break;
case 3:
traits.intersection(query, left_data());
if( traits.go_further() && traits.do_intersect(query, right_child()) )
{
right_child().traversal(query, traits, 2);
}
break;
default:
if( traits.do_intersect(query, left_child()) )
{
left_child().traversal(query, traits, nb_primitives/2);
if( traits.go_further() && traits.do_intersect(query, right_child()) )
{
right_child().traversal(query, traits, nb_primitives-nb_primitives/2);
}
}
else if( traits.do_intersect(query, right_child()) )
{
right_child().traversal(query, traits, nb_primitives-nb_primitives/2);
}
}
}
template<typename Tr>
template<class Traversal_traits>
void
AABB_node_with_join<Tr>::traversal(const AABB_node_with_join &other_node,
Traversal_traits &traits,
const std::size_t nb_primitives,
const std::size_t nb_primitives_other,
bool first_stationary) const
{
if (nb_primitives >= nb_primitives_other)
{
switch(nb_primitives)
{
case 2: // Both trees contain 2 primitives, test all pairs
traits.intersection(left_data(), other_node.left_data(), first_stationary);
if (!traits.go_further()) return;
traits.intersection(right_data(), other_node.right_data(), first_stationary);
if (!traits.go_further()) return;
traits.intersection(right_data(), other_node.left_data(), first_stationary);
if (!traits.go_further()) return;
traits.intersection(left_data(), other_node.right_data(), first_stationary);
break;
case 3: // This tree contains 3 primitives, the other 3 or 2
// Both left children are primitives:
traits.intersection(left_data(), other_node.left_data(), first_stationary);
if (!traits.go_further()) return;
// Test left child against all right leaves of the other tree
if (nb_primitives_other == 2)
{
traits.intersection(left_data(), other_node.right_data(), first_stationary);
}
else
{
if (traits.do_intersect(left_data(), other_node.right_child(), first_stationary))
{
traits.intersection(left_data(), other_node.right_child().left_data(), first_stationary);
if (!traits.go_further()) return;
traits.intersection(left_data(), other_node.right_child().right_data(), first_stationary);
}
}
if (!traits.go_further()) return;
// Test right child against the other node
if(traits.do_intersect(right_child(), other_node, first_stationary))
{
right_child().traversal(other_node, traits, 2, nb_primitives_other, first_stationary);
}
break;
default: // This tree has two node-children, test both against the other node
if( traits.do_intersect(left_child(), other_node, first_stationary) )
{
left_child().traversal(other_node, traits, nb_primitives/2, nb_primitives_other, first_stationary);
}
if (!traits.go_further()) return;
if( traits.do_intersect(right_child(), other_node, first_stationary) )
{
right_child().traversal(other_node, traits, nb_primitives-nb_primitives/2, nb_primitives_other, first_stationary);
}
}
}
else
{
// The other node contains more primitives. Call this method the other way around:
other_node.traversal(*this, traits, nb_primitives_other, nb_primitives, !first_stationary);
}
}
} // end namespace CGAL
#endif // CGAL_AABB_NODE_WITH_JOIN_H

View File

@ -0,0 +1,53 @@
#ifndef CGAL_AABB_SEGMENT_2_PRIMITIVE_H
#define CGAL_AABB_SEGMENT_2_PRIMITIVE_H
namespace CGAL {
// Wraps around a Segment_2 and provides its iterator as Id
template <class GeomTraits, class Iterator_, class ContainerType>
class AABB_segment_2_primitive
{
public:
typedef Iterator_ Id;
typedef typename GeomTraits::Segment_2 Datum;
typedef typename GeomTraits::Point_2 Point;
typedef ContainerType Container;
AABB_segment_2_primitive() {}
AABB_segment_2_primitive(Id it) : m_it(it)
{
}
AABB_segment_2_primitive(const AABB_segment_2_primitive &primitive)
{
m_it = primitive.id();
}
const Id &id() const
{
return m_it;
}
const Datum datum() const
{
return *m_it;
}
// Return a point on the primitive
Point reference_point() const
{
return m_it->source();
}
private:
Id m_it;
};
} // namespace CGAL
#endif

View File

@ -0,0 +1,205 @@
#ifndef CGAL_AABB_TRAITS_2_H
#define CGAL_AABB_TRAITS_2_H
namespace CGAL {
template<typename GeomTraits, typename AABB_primitive_>
class AABB_traits_2
{
public:
typedef AABB_primitive_ Primitive;
typedef typename Primitive::Id Id;
typedef typename Primitive::Datum Datum;
typedef typename Primitive::Container Container;
typedef typename GeomTraits::Point_2 Point;
typedef typename GeomTraits::Vector_2 Vector_2;
typedef typename CGAL::Bbox_2 Bounding_box;
typedef typename std::pair<Object, Id> Object_and_primitive_id;
typedef typename std::pair<Point, Id> Point_and_primitive_id;
// Types for AABB_tree
typedef typename GeomTraits::FT FT;
typedef typename GeomTraits::Point_2 Point_3;
typedef typename GeomTraits::Circle_2 Sphere_3;
typedef typename GeomTraits::Iso_rectangle_2 Iso_cuboid_3;
typedef typename GeomTraits::Construct_center_2 Construct_center_3;
typedef typename GeomTraits::Construct_iso_rectangle_2 Construct_iso_cuboid_3;
typedef typename GeomTraits::Construct_min_vertex_2 Construct_min_vertex_3;
typedef typename GeomTraits::Construct_max_vertex_2 Construct_max_vertex_3;
typedef typename GeomTraits::Compute_squared_radius_2 Compute_squared_radius_3;
typedef typename GeomTraits::Cartesian_const_iterator_2
Cartesian_const_iterator_3;
typedef typename GeomTraits::Construct_cartesian_const_iterator_2
Construct_cartesian_const_iterator_3;
AABB_traits_2(const Point &translation_point): m_translation_point(
translation_point)
{
m_interval_x = Interval_nt<true>(to_interval(translation_point.x()));
m_interval_y = Interval_nt<true>(to_interval(translation_point.y()));
};
AABB_traits_2()
{
m_translation_point = Point(0, 0);
m_interval_x = Interval_nt<true>(0);
m_interval_y = Interval_nt<true>(0);
};
Interval_nt<true> get_interval_x() const
{
return m_interval_x;
}
Interval_nt<true> get_interval_y() const
{
return m_interval_y;
}
Point get_translation_point() const
{
return m_translation_point;
}
// Put the n/2 smallest primitives in the front, the n/2 largest primitives
// in the back. They are compared along the bbox' longest axis.
class Sort_primitives
{
public:
template<typename PrimitiveIterator>
void operator()(PrimitiveIterator first,
PrimitiveIterator beyond,
const Bounding_box &bbox) const
{
PrimitiveIterator middle = first + (beyond - first) / 2;
if (bbox.xmax()-bbox.xmin() >= bbox.ymax()-bbox.ymin())
{
std::nth_element(first, middle, beyond, less_x); // sort along x
}
else
{
std::nth_element(first, middle, beyond, less_y); // sort along y
}
}
};
Sort_primitives sort_primitives_object() const
{
return Sort_primitives();
}
// Computes the bounding box of a set of primitives
class Compute_bbox
{
public:
template<typename ConstPrimitiveIterator>
Bounding_box operator()(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond) const
{
Bounding_box bbox = first->datum().bbox();
for (++first; first != beyond; ++first)
{
bbox = bbox + first->datum().bbox();
}
return bbox;
}
};
Compute_bbox compute_bbox_object() const
{
return Compute_bbox();
}
class Do_intersect
{
private:
AABB_traits_2 *m_traits;
public:
Do_intersect(AABB_traits_2 *_traits): m_traits(_traits) {}
bool operator()(const Bounding_box &q, const Bounding_box &bbox) const
{
Interval_nt<true> x1 = Interval_nt<true>(q.xmin(), q.xmax());
Interval_nt<true> y1 = Interval_nt<true>(q.ymin(), q.ymax());
Interval_nt<true> x2 = Interval_nt<true>(bbox.xmin(),
bbox.xmax()) + m_traits->get_interval_x();
Interval_nt<true> y2 = Interval_nt<true>(bbox.ymin(),
bbox.ymax()) + m_traits->get_interval_y();
return x1.do_overlap(x2) && y1.do_overlap(y2);
}
bool operator()(const Primitive &q, const Bounding_box &bbox) const
{
Interval_nt<true> x1 = Interval_nt<true>(q.datum().bbox().xmin(),
q.datum().bbox().xmax());
Interval_nt<true> y1 = Interval_nt<true>(q.datum().bbox().ymin(),
q.datum().bbox().ymax());
Interval_nt<true> x2 = Interval_nt<true>(bbox.xmin(),
bbox.xmax()) + m_traits->get_interval_x();
Interval_nt<true> y2 = Interval_nt<true>(bbox.ymin(),
bbox.ymax()) + m_traits->get_interval_y();
return x1.do_overlap(x2) && y1.do_overlap(y2);
}
bool operator()(const Bounding_box &q, const Primitive &pr) const
{
Datum tr_pr = pr.datum().transform(typename GeomTraits::Aff_transformation_2(
Translation(),
Vector_2(ORIGIN, m_traits->get_translation_point())));
return do_overlap(q, tr_pr.bbox());
}
bool operator()(const Primitive &q, const Primitive &pr) const
{
Datum tr_pr = pr.datum().transform(typename GeomTraits::Aff_transformation_2(
Translation(), Vector_2(ORIGIN, m_traits->get_translation_point())));
if (!do_overlap(q.datum().bbox(), tr_pr.bbox()))
{
return false;
}
return do_intersect(q.datum(), tr_pr);
}
};
Do_intersect do_intersect_object()
{
return Do_intersect(this);
}
private:
Point m_translation_point;
Interval_nt<true> m_interval_x;
Interval_nt<true> m_interval_y;
// Comparison functions
static bool less_x(const Primitive &pr1, const Primitive &pr2)
{
return pr1.reference_point().x() < pr2.reference_point().x();
}
static bool less_y(const Primitive &pr1, const Primitive &pr2)
{
return pr1.reference_point().y() < pr2.reference_point().y();
}
};
} // namespace CGAL
#endif

View File

@ -0,0 +1,428 @@
// Copyright (c) 2008-2009 INRIA Sophia-Antipolis (France).
// 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.
//
// $URL$
// $Id$
//
//
// Author(s) : Camille Wormser, Pierre Alliez, Stephane Tayeb
#ifndef CGAL_AABB_TRAVERSAL_TRAITS_WITH_JOIN_H
#define CGAL_AABB_TRAVERSAL_TRAITS_WITH_JOIN_H
#include <CGAL/Minkowski_sum_2/AABB_node_with_join.h>
#include <boost/optional.hpp>
namespace CGAL {
namespace internal { namespace AABB_tree_with_join {
template <class Value_type, typename Integral_type>
class Counting_output_iterator {
typedef Counting_output_iterator<Value_type,Integral_type> Self;
Integral_type* i;
public:
Counting_output_iterator(Integral_type* i_) : i(i_) {};
struct Proxy {
Proxy& operator=(const Value_type&) { return *this; };
};
Proxy operator*() {
return Proxy();
}
Self& operator++() {
++*i;
return *this;
}
Self& operator++(int) {
++*i;
return *this;
}
};
//-------------------------------------------------------
// Traits classes for traversal computation
//-------------------------------------------------------
/**
* @class First_intersection_traits
*/
template<typename AABBTraits, typename Query>
class First_intersection_traits
{
typedef typename AABBTraits::FT FT;
typedef typename AABBTraits::Point_3 Point;
typedef typename AABBTraits::Primitive Primitive;
typedef typename AABBTraits::Bounding_box Bounding_box;
typedef typename AABBTraits::Primitive::Id Primitive_id;
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
public:
typedef
#if CGAL_INTERSECTION_VERSION < 2
boost::optional<Object_and_primitive_id>
#else
boost::optional< typename AABBTraits::template Intersection_and_primitive_id<Query>::Type >
#endif
Result;
public:
First_intersection_traits(const AABBTraits& traits)
: m_result(), m_traits(traits)
{}
bool go_further() const {
return !m_result;
}
void intersection(const Query& query, const Primitive& primitive)
{
m_result = m_traits.intersection_object()(query, primitive);
}
bool do_intersect(const Query& query, const Node& node) const
{
return m_traits.do_intersect_object()(query, node.bbox());
}
Result result() const { return m_result; }
bool is_intersection_found() const {
return m_result;
}
private:
Result m_result;
const AABBTraits& m_traits;
};
/**
* @class Listing_intersection_traits
*/
template<typename AABBTraits, typename Query, typename Output_iterator>
class Listing_intersection_traits
{
typedef typename AABBTraits::FT FT;
typedef typename AABBTraits::Point_3 Point;
typedef typename AABBTraits::Primitive Primitive;
typedef typename AABBTraits::Bounding_box Bounding_box;
typedef typename AABBTraits::Primitive::Id Primitive_id;
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
public:
Listing_intersection_traits(Output_iterator out_it, const AABBTraits& traits)
: m_out_it(out_it), m_traits(traits) {}
bool go_further() const { return true; }
void intersection(const Query& query, const Primitive& primitive)
{
#if CGAL_INTERSECTION_VERSION < 2
boost::optional<Object_and_primitive_id>
#else
boost::optional< typename AABBTraits::template Intersection_and_primitive_id<Query>::Type >
#endif
intersection = m_traits.intersection_object()(query, primitive);
if(intersection)
{
*m_out_it++ = *intersection;
}
}
bool do_intersect(const Query& query, const Node& node) const
{
return m_traits.do_intersect_object()(query, node.bbox());
}
private:
Output_iterator m_out_it;
const AABBTraits& m_traits;
};
/**
* @class Listing_primitive_traits
*/
template<typename AABBTraits, typename Query, typename Output_iterator>
class Listing_primitive_traits
{
typedef typename AABBTraits::FT FT;
typedef typename AABBTraits::Point_3 Point;
typedef typename AABBTraits::Primitive Primitive;
typedef typename AABBTraits::Bounding_box Bounding_box;
typedef typename AABBTraits::Primitive::Id Primitive_id;
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
public:
Listing_primitive_traits(Output_iterator out_it, const AABBTraits& traits)
: m_out_it(out_it), m_traits(traits) {}
bool go_further() const { return true; }
void intersection(const Query& query, const Primitive& primitive)
{
if( m_traits.do_intersect_object()(query, primitive) )
{
*m_out_it++ = primitive.id();
}
}
bool do_intersect(const Query& query, const Node& node) const
{
return m_traits.do_intersect_object()(query, node.bbox());
}
private:
Output_iterator m_out_it;
const AABBTraits& m_traits;
};
/**
* @class First_primitive_traits
*/
template<typename AABBTraits, typename Query>
class First_primitive_traits
{
typedef typename AABBTraits::FT FT;
typedef typename AABBTraits::Point_3 Point;
typedef typename AABBTraits::Primitive Primitive;
typedef typename AABBTraits::Bounding_box Bounding_box;
typedef typename AABBTraits::Primitive::Id Primitive_id;
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
public:
First_primitive_traits(const AABBTraits& traits)
: m_is_found(false)
, m_result()
, m_traits(traits) {}
bool go_further() const { return !m_is_found; }
void intersection(const Query& query, const Primitive& primitive)
{
if( m_traits.do_intersect_object()(query, primitive) )
{
m_result = boost::optional<typename Primitive::Id>(primitive.id());
m_is_found = true;
}
}
bool do_intersect(const Query& query, const Node& node) const
{
return m_traits.do_intersect_object()(query, node.bbox());
}
boost::optional<typename Primitive::Id> result() const { return m_result; }
bool is_intersection_found() const { return m_is_found; }
private:
bool m_is_found;
boost::optional<typename Primitive::Id> m_result;
const AABBTraits& m_traits;
};
/**
* @class Do_intersect_traits
*/
template<typename AABBTraits, typename Query>
class Do_intersect_traits
{
typedef typename AABBTraits::FT FT;
typedef typename AABBTraits::Point_3 Point;
typedef typename AABBTraits::Primitive Primitive;
typedef typename AABBTraits::Bounding_box Bounding_box;
typedef typename AABBTraits::Primitive::Id Primitive_id;
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
public:
Do_intersect_traits(const AABBTraits& traits)
: m_is_found(false), m_traits(traits)
{}
bool go_further() const { return !m_is_found; }
void intersection(const Query& query, const Primitive& primitive)
{
if( m_traits.do_intersect_object()(query, primitive) )
m_is_found = true;
}
bool do_intersect(const Query& query, const Node& node) const
{
return m_traits.do_intersect_object()(query, node.bbox());
}
bool is_intersection_found() const { return m_is_found; }
private:
bool m_is_found;
const AABBTraits& m_traits;
};
/**
* @class Do_intersect_joined_traits
*/
template<typename AABBTraits>
class Do_intersect_joined_traits
{
typedef typename AABBTraits::Point_3 Point;
typedef typename AABBTraits::Primitive Primitive;
typedef AABB_node_with_join<AABBTraits> Node;
public:
Do_intersect_joined_traits(const Point &point) : m_is_found(false)
{
m_traits_ptr = new AABBTraits(point);
}
bool go_further() const { return !m_is_found; }
void intersection(const Primitive &primitive1, const Primitive &primitive2, bool first_stationary)
{
if (first_stationary)
{
if (m_traits_ptr->do_intersect_object()(primitive1, primitive2))
{
m_is_found = true;
}
}
else
{
if (m_traits_ptr->do_intersect_object()(primitive2, primitive1))
{
m_is_found = true;
}
}
}
bool do_intersect(const Node &node_1, const Node &node_2, bool first_stationary) const
{
if (first_stationary)
{
return m_traits_ptr->do_intersect_object()(node_1.bbox(), node_2.bbox());
}
else
{
return m_traits_ptr->do_intersect_object()(node_2.bbox(), node_1.bbox());
}
}
bool do_intersect(const Node &node_1, const Primitive &primitive2, bool first_stationary) const
{
if (first_stationary)
{
return m_traits_ptr->do_intersect_object()(node_1.bbox(), primitive2);
}
else
{
return m_traits_ptr->do_intersect_object()(primitive2, node_1.bbox());
}
}
bool do_intersect(const Primitive &primitive1, const Node &node_2, bool first_stationary) const
{
if (first_stationary)
{
return m_traits_ptr->do_intersect_object()(primitive1, node_2.bbox());
}
else
{
return m_traits_ptr->do_intersect_object()(node_2.bbox(), primitive1);
}
}
bool is_intersection_found() const { return m_is_found; }
~Do_intersect_joined_traits() { delete m_traits_ptr; }
private:
bool m_is_found;
AABBTraits *m_traits_ptr;
};
/**
* @class Projection_traits
*/
template <typename AABBTraits>
class Projection_traits
{
typedef typename AABBTraits::FT FT;
typedef typename AABBTraits::Point_3 Point;
typedef typename AABBTraits::Primitive Primitive;
typedef typename AABBTraits::Bounding_box Bounding_box;
typedef typename AABBTraits::Primitive::Id Primitive_id;
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
public:
Projection_traits(const Point& hint,
const typename Primitive::Id& hint_primitive,
const AABBTraits& traits)
: m_closest_point(hint),
m_closest_primitive(hint_primitive),
m_traits(traits)
{}
bool go_further() const { return true; }
void intersection(const Point& query, const Primitive& primitive)
{
Point new_closest_point = m_traits.closest_point_object()
(query, primitive, m_closest_point);
if(new_closest_point != m_closest_point)
{
m_closest_primitive = primitive.id();
m_closest_point = new_closest_point; // this effectively shrinks the sphere
}
}
bool do_intersect(const Point& query, const Node& node) const
{
return m_traits.compare_distance_object()
(query, node.bbox(), m_closest_point) == CGAL::SMALLER;
}
Point closest_point() const { return m_closest_point; }
Point_and_primitive_id closest_point_and_primitive() const
{
return Point_and_primitive_id(m_closest_point, m_closest_primitive);
}
private:
Point m_closest_point;
typename Primitive::Id m_closest_primitive;
const AABBTraits& m_traits;
};
}}} // end namespace CGAL::internal::AABB_tree_with_join
#endif // CGAL_AABB_TRAVERSAL_TRAITS_WITH_JOIN_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,383 @@
#ifndef CGAL_MINKOWSKI_SUM_BY_REDUCED_CONVOLUTION_2_H
#define CGAL_MINKOWSKI_SUM_BY_REDUCED_CONVOLUTION_2_H
#include <CGAL/basic.h>
#include <CGAL/Arrangement_with_history_2.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Minkowski_sum_2/AABB_collision_detector_2.h>
#include <queue>
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
namespace CGAL {
// This algorithm was first described by Evan Behar and Jyh-Ming Lien in "Fast
// and Robust 2D Minkowski Sum Using Reduced Convolution", IROS 2011.
// This implementation is based on Alon Baram's 2013 master's thesis "Polygonal
// Minkowski Sums via Convolution: Theory and Practice" at Tel-Aviv University.
template <class Kernel_, class Container_>
class Minkowski_sum_by_reduced_convolution_2
{
private:
typedef Kernel_ Kernel;
typedef Container_ Container;
// Basic types:
typedef CGAL::Polygon_2<Kernel, Container> Polygon_2;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Vector_2 Vector_2;
typedef typename Kernel::Direction_2 Direction_2;
typedef typename Kernel::Triangle_2 Triangle_2;
typedef typename Kernel::FT FT;
// Segment-related types:
typedef Arr_segment_traits_2<Kernel> Traits_2;
typedef typename Traits_2::X_monotone_curve_2 Segment_2;
typedef std::list<Segment_2> Segment_list;
typedef Arr_default_dcel<Traits_2> Dcel;
typedef std::pair<int, int> State;
// Arrangement-related types:
typedef Arrangement_with_history_2<Traits_2, Dcel> Arrangement_history_2;
typedef typename Arrangement_history_2::Halfedge_handle Halfedge_handle;
typedef typename Arrangement_history_2::Face_iterator Face_iterator;
typedef typename Arrangement_history_2::Face_handle Face_handle;
typedef typename Arrangement_history_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
typedef typename Arrangement_history_2::Originating_curve_iterator
Originating_curve_iterator;
// Function object types:
typename Kernel::Construct_translated_point_2 f_add;
typename Kernel::Construct_vector_2 f_vector;
typename Kernel::Construct_direction_2 f_direction;
typename Kernel::Orientation_2 f_orientation;
typename Kernel::Compare_xy_2 f_compare_xy;
typename Kernel::Counterclockwise_in_between_2 f_ccw_in_between;
public:
Minkowski_sum_by_reduced_convolution_2()
{
// Obtain kernel functors
Kernel ker;
f_add = ker.construct_translated_point_2_object();
f_vector = ker.construct_vector_2_object();
f_direction = ker.construct_direction_2_object();
f_orientation = ker.orientation_2_object();
f_compare_xy = ker.compare_xy_2_object();
f_ccw_in_between = ker.counterclockwise_in_between_2_object();
}
template <class OutputIterator>
void operator()(const Polygon_2 &pgn1, const Polygon_2 &pgn2,
Polygon_2 &outer_boundary, OutputIterator holes) const
{
CGAL_precondition(pgn1.is_simple());
CGAL_precondition(pgn2.is_simple());
CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE);
CGAL_precondition(pgn2.orientation() == COUNTERCLOCKWISE);
// 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);
// Compute the reduced convolution (see section 4.1 of Alon's master's thesis)
Segment_list reduced_convolution;
build_reduced_convolution(pgn1, pgn2, reduced_convolution);
// Insert the segments into an arrangement
Arrangement_history_2 arr;
insert(arr, reduced_convolution.begin(), reduced_convolution.end());
// Trace the outer loop and put it in 'outer_boundary'
get_outer_loop(arr, outer_boundary);
// Check for each face whether it is a hole in the M-sum. If it is, add it to 'holes'.
// See chapter 3 of of Alon's master's thesis.
for (Face_iterator face = arr.faces_begin(); face != arr.faces_end(); ++face)
{
handle_face(arr, face, holes, collision_detector);
}
}
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
// iteration beginning from each vertex in the first column of the fiber
// grid.
void build_reduced_convolution(const Polygon_2 &pgn1, const Polygon_2 &pgn2,
Segment_list &reduced_convolution) const
{
unsigned int n1 = pgn1.size();
unsigned int n2 = pgn2.size();
// Init the direcions of both polygons
std::vector<Direction_2> p1_dirs = directions_of_polygon(pgn1);
std::vector<Direction_2> p2_dirs = directions_of_polygon(pgn2);
// Contains states that were already visited
boost::unordered_set<State> visited_states;
// Init the queue with vertices from the first column
std::queue<State> state_queue;
for (int i = n1-1; i >= 0; --i)
{
state_queue.push(State(i, 0));
}
while (state_queue.size() > 0)
{
State curr_state = state_queue.front();
state_queue.pop();
int i1 = curr_state.first;
int i2 = curr_state.second;
// If this state was already visited, skip it
if (visited_states.count(curr_state) > 0)
{
continue;
}
visited_states.insert(curr_state);
int next_i1 = (i1+1) % n1;
int next_i2 = (i2+1) % n2;
int prev_i1 = (n1+i1-1) % n1;
int prev_i2 = (n2+i2-1) % n2;
// Try two transitions: From (i,j) to (i+1,j) and to (i,j+1). Add
// the respective segments, if they are in the reduced convolution.
for(int step_in_pgn1 = 0; step_in_pgn1 <= 1; step_in_pgn1++)
{
int new_i1, new_i2;
if (step_in_pgn1)
{
new_i1 = next_i1;
new_i2 = i2;
}
else
{
new_i1 = i1;
new_i2 = next_i2;
}
// If the segment's direction lies counterclockwise in between
// the other polygon's vertex' ingoing and outgoing directions,
// the segment belongs to the full convolution.
bool belongs_to_convolution;
if (step_in_pgn1)
{
belongs_to_convolution = f_ccw_in_between(p1_dirs[i1], p2_dirs[prev_i2],
p2_dirs[i2]) ||
p1_dirs[i1] == p2_dirs[i2];
}
else
{
belongs_to_convolution = f_ccw_in_between(p2_dirs[i2], p1_dirs[prev_i1],
p1_dirs[i1]) ||
p2_dirs[i2] == p1_dirs[prev_i1];
}
if (belongs_to_convolution)
{
state_queue.push(State(new_i1, new_i2));
// Only edges added to convex vertices can be on the M-sum's boundary.
// This filter only leaves the *reduced* convolution.
bool convex;
if (step_in_pgn1)
{
convex = is_convex(pgn2[prev_i2], pgn2[i2], pgn2[next_i2]);
}
else
{
convex = is_convex(pgn1[prev_i1], pgn1[i1], pgn1[next_i1]);
}
if (convex)
{
Point_2 start_point = get_point(i1, i2, pgn1, pgn2);
Point_2 end_point = get_point(new_i1, new_i2, pgn1, pgn2);
reduced_convolution.push_back(Segment_2(start_point, end_point));
}
}
}
}
}
// Returns a sorted list of the polygon's edges
std::vector<Direction_2> directions_of_polygon(const Polygon_2 &p) const
{
std::vector<Direction_2> directions;
unsigned int n = p.size();
for (int i = 0; i < n-1; ++i)
{
directions.push_back(f_direction(f_vector(p[i], p[i+1])));
}
directions.push_back(f_direction(f_vector(p[n-1], p[0])));
return directions;
}
bool is_convex(const Point_2 &prev, const Point_2 &curr,
const Point_2 &next) const
{
return f_orientation(prev, curr, next) == LEFT_TURN;
}
// Returns the point corresponding to a state (i,j).
Point_2 get_point(int i1, int i2, const Polygon_2 &pgn1,
const Polygon_2 &pgn2) const
{
return f_add(pgn1[i1], Vector_2(Point_2(ORIGIN), pgn2[i2]));
}
// Put the outer loop of the arrangement in 'outer_boundary'
void get_outer_loop(Arrangement_history_2 &arr,
Polygon_2 &outer_boundary) const
{
Ccb_halfedge_circulator circ_start = *(arr.unbounded_face()->holes_begin());
Ccb_halfedge_circulator circ = circ_start;
do
{
outer_boundary.push_back(circ->source()->point());
}
while (--circ != circ_start);
}
// Check whether the face is on the M-sum's border. Add it to 'holes' if it is.
template <class OutputIterator>
void handle_face(const Arrangement_history_2 &arr, const Face_handle face,
OutputIterator holes, AABB_collision_detector_2<Kernel, Container>
&collision_detector) const
{
// If the face contains holes, it can't be on the Minkowski sum's border
if (face->holes_begin() != face->holes_end())
{
return;
}
Ccb_halfedge_circulator start = face->outer_ccb();
Ccb_halfedge_circulator circ = start;
// The face needs to be orientable
do
{
if (!do_original_edges_have_same_direction(arr, circ))
{
return;
}
}
while (++circ != start);
// When the reversed polygon 1, translated by a point inside of this face,
// collides with polygon 2, this cannot be a hole
Point_2 inner_point = get_point_in_face(face);
if (collision_detector.check_collision(inner_point))
{
return;
}
// At this point, the face is a real hole, add it to 'holes'
Polygon_2 pgn_hole;
circ = start;
do
{
pgn_hole.push_back(circ->source()->point());
}
while (--circ != start);
*holes = pgn_hole;
++holes;
}
// Check whether the convolution's original edge(s) had the same direction as
// the arrangement's half edge
bool do_original_edges_have_same_direction(const Arrangement_history_2 &arr,
const Halfedge_handle he) const
{
Originating_curve_iterator segment_itr;
for (segment_itr = arr.originating_curves_begin(he);
segment_itr != arr.originating_curves_end(he); ++segment_itr)
{
if (f_compare_xy(segment_itr->source(),
segment_itr->target()) == (Comparison_result)he->direction())
{
return false;
}
}
return true;
}
// Return a point in the face's interior by finding a diagonal
Point_2 get_point_in_face(const Face_handle face) const
{
Ccb_halfedge_circulator current_edge = face->outer_ccb();
Ccb_halfedge_circulator next_edge = current_edge;
next_edge++;
Point_2 a, v, b;
// Move over the face's vertices until a convex corner is encountered:
do
{
a = current_edge->source()->point();
v = current_edge->target()->point();
b = next_edge->target()->point();
current_edge++;
next_edge++;
}
while (!is_convex(a, v, b));
Triangle_2 ear(a, v, b);
FT min_distance = -1;
Point_2 min_q;
// Of the remaining vertices, find the one inside of the "ear" with minimal
// distance to v:
while (++next_edge != current_edge)
{
Point_2 q = next_edge->target()->point();
if (ear.has_on_bounded_side(q))
{
FT distance = squared_distance(q, v);
if (min_distance == -1 || distance < min_distance)
{
min_distance = distance;
min_q = q;
}
}
}
// If there was no vertex inside of the ear, return it's centroid.
// Otherwise, return a point between v and min_q.
if (min_distance == -1)
{
return centroid(ear);
}
else
{
return midpoint(v, min_q);
}
}
};
} // namespace CGAL
#endif

View File

@ -121,8 +121,8 @@ private:
public:
/*! Default constructor. */
Minkowski_sum_by_convolution_2() :
m_kernel(NULL),
m_own_kernel(false)
m_kernel(new Kernel),
m_own_kernel(true)
{ init(); }
/*! Constructor. */

View File

@ -21,6 +21,7 @@
#include <CGAL/basic.h>
#include <CGAL/Polygon_with_holes_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_decomp_2.h>
#include <list>
@ -28,8 +29,42 @@
namespace CGAL {
/*!
* Compute the Minkowski sum of two simple polygons using the convolution
* method.
* Computes the Minkowski sum \f$ P \oplus Q\f$ of the two given polygons.
* 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.
* 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.
* \pre Both `P` and `Q` are simple, counterclockwise-oriented polygons.
*/
template <class Kernel_, class Container_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_reduced_convolution_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_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;
if (pgn1.size() > pgn2.size())
mink_sum (pgn1, pgn2, sum_bound, std::back_inserter(sum_holes));
else
mink_sum (pgn2, pgn1, 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.
* 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.
@ -37,18 +72,30 @@ namespace CGAL {
* \param pgn2 (in) The second polygon.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_>
template <class Kernel_, class Container_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2)
minkowski_sum_full_convolution_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2)
{
Kernel_ kernel;
return minkowski_sum_2(pgn1, pgn2, kernel);
typedef Kernel_ Kernel;
typedef Container_ Container;
Minkowski_sum_by_convolution_2<Kernel, Container> mink_sum;
Polygon_2<Kernel, Container> sum_bound;
std::list<Polygon_2<Kernel, Container> > sum_holes;
if (pgn1.size() > pgn2.size())
mink_sum(pgn1, pgn2, sum_bound, std::back_inserter(sum_holes));
else
mink_sum(pgn2, pgn1, 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 convolution
* method.
* Compute the Minkowski sum of two simple polygons using the (full)
* convolution method.
* 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.
@ -57,11 +104,11 @@ minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
* \param kernel (in) The kernel.
* \return The resulting polygon with holes, representing the sum.
*/
template <typename Kernel_, typename Container_>
template <class Kernel_, class Container_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const Kernel_& kernel)
minkowski_sum_full_convolution_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2,
const Kernel_& kernel)
{
typedef Kernel_ Kernel;
typedef Container_ Container;
@ -79,6 +126,28 @@ minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
sum_holes.end()));
}
/*!
* Compute the Minkowski sum of two simple polygons using the convolution
* method. This function defaults to calling the reduced convolution method,
* as it is more efficient in most cases.
* 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 pgn1 (in) The first polygon.
* \param pgn2 (in) The second polygon.
* \return The resulting polygon with holes, representing the sum.
*
* \sa `CGAL::minkowski_sum_reduced_convolution_2()`
* \sa `CGAL::minkowski_sum_full_convolution_2()`
*/
template <typename Kernel_, typename Container_>
Polygon_with_holes_2<Kernel_, Container_>
minkowski_sum_2(const Polygon_2<Kernel_, Container_>& pgn1,
const Polygon_2<Kernel_, Container_>& pgn2)
{
return minkowski_sum_reduced_convolution_2(pgn1, pgn2);
}
/*!
* Compute the Minkowski sum of two simple polygons by decomposing each
* polygon to convex sub-polygons and computing the union of the pairwise

View File

@ -1 +1,2 @@
Efi Fogel <efif@post.tau.ac.il>
Efi Fogel <efif@gmail.com>
Michael Hemmer <Michael.Hemmer@cgal.org>

View File

@ -0,0 +1,105 @@
104
100 0
100 50
99 1
98 50
97 1
96 50
95 1
94 50
93 1
92 50
91 1
90 50
89 1
88 50
87 1
86 50
85 1
84 50
83 1
82 50
81 1
80 50
79 1
78 50
77 1
76 50
75 1
74 50
73 1
72 50
71 1
70 50
69 1
68 50
67 1
66 50
65 1
64 50
63 1
62 50
61 1
60 50
59 1
58 50
57 1
56 50
55 1
54 50
53 1
52 50
51 1
1 1
1 51
50 52
1 53
50 54
1 55
50 56
1 57
50 58
1 59
50 60
1 61
50 62
1 63
50 64
1 65
50 66
1 67
50 68
1 69
50 70
1 71
50 72
1 73
50 74
1 75
50 76
1 77
50 78
1 79
50 80
1 81
50 82
1 83
50 84
1 85
50 86
1 87
50 88
1 89
50 90
1 91
50 92
1 93
50 94
1 95
50 96
1 97
50 98
1 99
50 100
0 100
0 0

View File

@ -0,0 +1,405 @@
404
400 0
400 200
399 1
398 200
397 1
396 200
395 1
394 200
393 1
392 200
391 1
390 200
389 1
388 200
387 1
386 200
385 1
384 200
383 1
382 200
381 1
380 200
379 1
378 200
377 1
376 200
375 1
374 200
373 1
372 200
371 1
370 200
369 1
368 200
367 1
366 200
365 1
364 200
363 1
362 200
361 1
360 200
359 1
358 200
357 1
356 200
355 1
354 200
353 1
352 200
351 1
350 200
349 1
348 200
347 1
346 200
345 1
344 200
343 1
342 200
341 1
340 200
339 1
338 200
337 1
336 200
335 1
334 200
333 1
332 200
331 1
330 200
329 1
328 200
327 1
326 200
325 1
324 200
323 1
322 200
321 1
320 200
319 1
318 200
317 1
316 200
315 1
314 200
313 1
312 200
311 1
310 200
309 1
308 200
307 1
306 200
305 1
304 200
303 1
302 200
301 1
300 200
299 1
298 200
297 1
296 200
295 1
294 200
293 1
292 200
291 1
290 200
289 1
288 200
287 1
286 200
285 1
284 200
283 1
282 200
281 1
280 200
279 1
278 200
277 1
276 200
275 1
274 200
273 1
272 200
271 1
270 200
269 1
268 200
267 1
266 200
265 1
264 200
263 1
262 200
261 1
260 200
259 1
258 200
257 1
256 200
255 1
254 200
253 1
252 200
251 1
250 200
249 1
248 200
247 1
246 200
245 1
244 200
243 1
242 200
241 1
240 200
239 1
238 200
237 1
236 200
235 1
234 200
233 1
232 200
231 1
230 200
229 1
228 200
227 1
226 200
225 1
224 200
223 1
222 200
221 1
220 200
219 1
218 200
217 1
216 200
215 1
214 200
213 1
212 200
211 1
210 200
209 1
208 200
207 1
206 200
205 1
204 200
203 1
202 200
201 1
1 1
1 201
200 202
1 203
200 204
1 205
200 206
1 207
200 208
1 209
200 210
1 211
200 212
1 213
200 214
1 215
200 216
1 217
200 218
1 219
200 220
1 221
200 222
1 223
200 224
1 225
200 226
1 227
200 228
1 229
200 230
1 231
200 232
1 233
200 234
1 235
200 236
1 237
200 238
1 239
200 240
1 241
200 242
1 243
200 244
1 245
200 246
1 247
200 248
1 249
200 250
1 251
200 252
1 253
200 254
1 255
200 256
1 257
200 258
1 259
200 260
1 261
200 262
1 263
200 264
1 265
200 266
1 267
200 268
1 269
200 270
1 271
200 272
1 273
200 274
1 275
200 276
1 277
200 278
1 279
200 280
1 281
200 282
1 283
200 284
1 285
200 286
1 287
200 288
1 289
200 290
1 291
200 292
1 293
200 294
1 295
200 296
1 297
200 298
1 299
200 300
1 301
200 302
1 303
200 304
1 305
200 306
1 307
200 308
1 309
200 310
1 311
200 312
1 313
200 314
1 315
200 316
1 317
200 318
1 319
200 320
1 321
200 322
1 323
200 324
1 325
200 326
1 327
200 328
1 329
200 330
1 331
200 332
1 333
200 334
1 335
200 336
1 337
200 338
1 339
200 340
1 341
200 342
1 343
200 344
1 345
200 346
1 347
200 348
1 349
200 350
1 351
200 352
1 353
200 354
1 355
200 356
1 357
200 358
1 359
200 360
1 361
200 362
1 363
200 364
1 365
200 366
1 367
200 368
1 369
200 370
1 371
200 372
1 373
200 374
1 375
200 376
1 377
200 378
1 379
200 380
1 381
200 382
1 383
200 384
1 385
200 386
1 387
200 388
1 389
200 390
1 391
200 392
1 393
200 394
1 395
200 396
1 397
200 398
1 399
200 400
0 400
0 0

View File

@ -1,54 +1,54 @@
53
1250/1 100/1
1250/1 50/1
0/1 50/1
0/1 100/1
25/1 250/1
50/1 100/1
75/1 250/1
100/1 100/1
125/1 250/1
150/1 100/1
175/1 250/1
200/1 100/1
225/1 250/1
250/1 100/1
275/1 250/1
300/1 100/1
325/1 250/1
350/1 100/1
375/1 250/1
400/1 100/1
425/1 250/1
450/1 100/1
475/1 250/1
500/1 100/1
525/1 250/1
550/1 100/1
575/1 250/1
600/1 100/1
625/1 250/1
650/1 100/1
675/1 250/1
700/1 100/1
725/1 250/1
750/1 100/1
775/1 250/1
800/1 100/1
825/1 250/1
850/1 100/1
875/1 250/1
900/1 100/1
925/1 250/1
950/1 100/1
975/1 250/1
1000/1 100/1
1025/1 250/1
1050/1 100/1
1075/1 250/1
1100/1 100/1
1125/1 250/1
1150/1 100/1
1175/1 250/1
1200/1 100/1
1225/1 250/1
1200/1 100/1
1175/1 250/1
1150/1 100/1
1125/1 250/1
1100/1 100/1
1075/1 250/1
1050/1 100/1
1025/1 250/1
1000/1 100/1
975/1 250/1
950/1 100/1
925/1 250/1
900/1 100/1
875/1 250/1
850/1 100/1
825/1 250/1
800/1 100/1
775/1 250/1
750/1 100/1
725/1 250/1
700/1 100/1
675/1 250/1
650/1 100/1
625/1 250/1
600/1 100/1
575/1 250/1
550/1 100/1
525/1 250/1
500/1 100/1
475/1 250/1
450/1 100/1
425/1 250/1
400/1 100/1
375/1 250/1
350/1 100/1
325/1 250/1
300/1 100/1
275/1 250/1
250/1 100/1
225/1 250/1
200/1 100/1
175/1 250/1
150/1 100/1
125/1 250/1
100/1 100/1
75/1 250/1
50/1 100/1
25/1 250/1
0/1 100/1
0/1 50/1
1250/1 50/1
1250/1 100/1

View File

@ -1,23 +1,23 @@
22
20/1 0/1
-20/1 0/1
-19/1 7/1
-17/1 9/1
-15/1 11/1
-13/1 13/1
-11/1 15/1
-9/1 17/1
-7/1 19/1
-5/1 21/1
-3/1 23/1
-1/1 25/1
1/1 27/1
3/1 29/1
5/1 31/1
7/1 33/1
9/1 35/1
11/1 37/1
13/1 39/1
15/1 41/1
17/1 43/1
19/1 45/1
17/1 43/1
15/1 41/1
13/1 39/1
11/1 37/1
9/1 35/1
7/1 33/1
5/1 31/1
3/1 29/1
1/1 27/1
-1/1 25/1
-3/1 23/1
-5/1 21/1
-7/1 19/1
-9/1 17/1
-11/1 15/1
-13/1 13/1
-15/1 11/1
-17/1 9/1
-19/1 7/1
-20/1 0/1
20/1 0/1

View File

@ -0,0 +1,13 @@
12
0 0
6 0
6 6
4 6
4 5
5 5
5 1
1 1
1 5
2 5
2 6
0 6

View File

@ -0,0 +1,5 @@
4
-1 -1
1 -1
1 1
-1 1

View File

@ -0,0 +1,13 @@
12
0 0
6 0
6 6
3.5 6
3.5 4
4 4
4 2
2 2
2 4
2.5 4
2.5 6
0 6

View File

@ -0,0 +1,5 @@
4
-1 -1
1 -1
1 1
-1 1

View File

@ -1,65 +1,65 @@
64
100/1 -10/1
100/1 500/1
500/1 498/1
110/1 495/1
110/1 450/1
500/1 448/1
110/1 445/1
110/1 400/1
500/1 398/1
110/1 395/1
110/1 350/1
500/1 348/1
110/1 345/1
110/1 300/1
500/1 298/1
110/1 295/1
110/1 250/1
500/1 248/1
110/1 245/1
110/1 200/1
500/1 198/1
110/1 195/1
110/1 150/1
500/1 148/1
110/1 145/1
110/1 100/1
500/1 98/1
110/1 95/1
110/1 50/1
500/1 48/1
110/1 45/1
110/1 0/1
600/1 0/1
602/1 500/1
605/1 0/1
610/1 0/1
612/1 500/1
615/1 0/1
620/1 0/1
622/1 500/1
625/1 0/1
630/1 0/1
632/1 500/1
635/1 0/1
640/1 0/1
642/1 500/1
645/1 0/1
650/1 0/1
652/1 500/1
655/1 0/1
660/1 0/1
662/1 500/1
665/1 0/1
670/1 0/1
672/1 500/1
675/1 0/1
680/1 0/1
682/1 500/1
685/1 0/1
690/1 0/1
692/1 500/1
695/1 0/1
700/1 0/1
700/1 -10/1
700/1 0/1
695/1 0/1
692/1 500/1
690/1 0/1
685/1 0/1
682/1 500/1
680/1 0/1
675/1 0/1
672/1 500/1
670/1 0/1
665/1 0/1
662/1 500/1
660/1 0/1
655/1 0/1
652/1 500/1
650/1 0/1
645/1 0/1
642/1 500/1
640/1 0/1
635/1 0/1
632/1 500/1
630/1 0/1
625/1 0/1
622/1 500/1
620/1 0/1
615/1 0/1
612/1 500/1
610/1 0/1
605/1 0/1
602/1 500/1
600/1 0/1
110/1 0/1
110/1 45/1
500/1 48/1
110/1 50/1
110/1 95/1
500/1 98/1
110/1 100/1
110/1 145/1
500/1 148/1
110/1 150/1
110/1 195/1
500/1 198/1
110/1 200/1
110/1 245/1
500/1 248/1
110/1 250/1
110/1 295/1
500/1 298/1
110/1 300/1
110/1 345/1
500/1 348/1
110/1 350/1
110/1 395/1
500/1 398/1
110/1 400/1
110/1 445/1
500/1 448/1
110/1 450/1
110/1 495/1
500/1 498/1
100/1 500/1
100/1 -10/1

View File

@ -1,13 +1,13 @@
12
0/1 0/1
10/1 2/1
0/1 5/1
10/1 7/1
0/1 10/1
10/1 12/1
0/1 15/1
10/1 17/1
0/1 20/1
10/1 22/1
0/1 25/1
420/1 12/1
0/1 25/1
10/1 22/1
0/1 20/1
10/1 17/1
0/1 15/1
10/1 12/1
0/1 10/1
10/1 7/1
0/1 5/1
10/1 2/1
0/1 0/1

View File

@ -0,0 +1,7 @@
6
0 0
200 0
200 0.1
0.1 0.1
0.1 200
0 200

View File

@ -1,83 +1,83 @@
82
1150840/1 3269680/1
2009089/1 622385/1
3563659/1 -1685869/1
5694160/1 -3476329/1
8235589/1 -4610310/1
10991099/1 -5000000/1
13747300/1 -4615210/1
16290799/1 -3485749/1
18424400/1 -1699079/1
19983099/1 606407/1
21100000/1 1000000/1
22000000/1 -1000000/1
23100000/1 1000000/1
24000000/1 -1000000/1
25100000/1 1000000/1
26000000/1 -1000000/1
27100000/1 1000000/1
28000000/1 -1000000/1
29100000/1 1000000/1
30000000/1 -1000000/1
31100000/1 1000000/1
32000000/1 -1000000/1
33100000/1 1000000/1
34000000/1 -1000000/1
35100000/1 1000000/1
36000000/1 -1000000/1
37100000/1 1000000/1
38000000/1 -1000000/1
39100000/1 1000000/1
40000000/1 -1000000/1
42014300/1 4388269/1
43571599/1 6694679/1
45704200/1 8482609/1
48246999/1 9613579/1
51003000/1 10000000/1
53758699/1 9611950/1
56300799/1 8479470/1
58432399/1 6690280/1
59988299/1 4382939/1
60848100/1 1736160/1
61150799/1 3269680/1
62009099/1 622385/1
63563699/1 -1685869/1
65694200/1 -3476329/1
68235600/1 -4610310/1
70991099/1 -5000000/1
73747299/1 -4615210/1
76290799/1 -3485749/1
78424399/1 -1699079/1
79983100/1 606407/1
81100000/1 1000000/1
82000000/1 -1000000/1
83100000/1 1000000/1
84000000/1 -1000000/1
85100000/1 1000000/1
86000000/1 -1000000/1
87100000/1 1000000/1
88000000/1 -1000000/1
89100000/1 1000000/1
90000000/1 -1000000/1
91100000/1 1000000/1
92000000/1 -1000000/1
93100000/1 1000000/1
94000000/1 -1000000/1
95100000/1 1000000/1
96000000/1 -1000000/1
97100000/1 1000000/1
98000000/1 -1000000/1
99100000/1 1000000/1
100000000/1 -1000000/1
102013999/1 4388269/1
103572000/1 6694679/1
105703999/1 8482609/1
108247000/1 9613579/1
111002999/1 10000000/1
113758999/1 9611950/1
116301000/1 8479470/1
118432000/1 6690280/1
119987999/1 4382939/1
120847999/1 1736160/1
121100000/1 -30000000/1
0/1 -30000000/1
121100000/1 -30000000/1
120847999/1 1736160/1
119987999/1 4382939/1
118432000/1 6690280/1
116301000/1 8479470/1
113758999/1 9611950/1
111002999/1 10000000/1
108247000/1 9613579/1
105703999/1 8482609/1
103572000/1 6694679/1
102013999/1 4388269/1
100000000/1 -1000000/1
99100000/1 1000000/1
98000000/1 -1000000/1
97100000/1 1000000/1
96000000/1 -1000000/1
95100000/1 1000000/1
94000000/1 -1000000/1
93100000/1 1000000/1
92000000/1 -1000000/1
91100000/1 1000000/1
90000000/1 -1000000/1
89100000/1 1000000/1
88000000/1 -1000000/1
87100000/1 1000000/1
86000000/1 -1000000/1
85100000/1 1000000/1
84000000/1 -1000000/1
83100000/1 1000000/1
82000000/1 -1000000/1
81100000/1 1000000/1
79983100/1 606407/1
78424399/1 -1699079/1
76290799/1 -3485749/1
73747299/1 -4615210/1
70991099/1 -5000000/1
68235600/1 -4610310/1
65694200/1 -3476329/1
63563699/1 -1685869/1
62009099/1 622385/1
61150799/1 3269680/1
60848100/1 1736160/1
59988299/1 4382939/1
58432399/1 6690280/1
56300799/1 8479470/1
53758699/1 9611950/1
51003000/1 10000000/1
48246999/1 9613579/1
45704200/1 8482609/1
43571599/1 6694679/1
42014300/1 4388269/1
40000000/1 -1000000/1
39100000/1 1000000/1
38000000/1 -1000000/1
37100000/1 1000000/1
36000000/1 -1000000/1
35100000/1 1000000/1
34000000/1 -1000000/1
33100000/1 1000000/1
32000000/1 -1000000/1
31100000/1 1000000/1
30000000/1 -1000000/1
29100000/1 1000000/1
28000000/1 -1000000/1
27100000/1 1000000/1
26000000/1 -1000000/1
25100000/1 1000000/1
24000000/1 -1000000/1
23100000/1 1000000/1
22000000/1 -1000000/1
21100000/1 1000000/1
19983099/1 606407/1
18424400/1 -1699079/1
16290799/1 -3485749/1
13747300/1 -4615210/1
10991099/1 -5000000/1
8235589/1 -4610310/1
5694160/1 -3476329/1
3563659/1 -1685869/1
2009089/1 622385/1
1150840/1 3269680/1

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
8
70/1 90/1
70/1 80/1
90/1 80/1
90/1 40/1
70/1 40/1
70/1 30/1
100/1 30/1
100/1 90/1
70 90
70 80
90 80
90 40
70 40
70 30
100 30
100 90

View File

@ -1,9 +1,9 @@
8
-70/1 90/1
-70/1 80/1
-90/1 80/1
-90/1 40/1
-70/1 40/1
-70/1 30/1
-100/1 30/1
-100/1 90/1
-100/1 30/1
-70/1 30/1
-70/1 40/1
-90/1 40/1
-90/1 80/1
-70/1 80/1
-70/1 90/1

View File

@ -1,21 +1,21 @@
20
-67/1 -56/1
-43/1 15/1
6/1 -79/1
82/1 47/1
9/1 -40/1
-9/1 -14/1
24/1 78/1
-45/1 45/1
-71/1 -21/1
-76/1 -1/1
-72/1 58/1
18/1 96/1
84/1 56/1
92/1 -54/1
95/1 -89/1
85/1 -5/1
58/1 -44/1
-2/1 -88/1
-31/1 -74/1
-78/1 -85/1
-31/1 -74/1
-2/1 -88/1
58/1 -44/1
85/1 -5/1
95/1 -89/1
92/1 -54/1
84/1 56/1
18/1 96/1
-72/1 58/1
-76/1 -1/1
-71/1 -21/1
-45/1 45/1
24/1 78/1
-9/1 -14/1
9/1 -40/1
82/1 47/1
6/1 -79/1
-43/1 15/1
-67/1 -56/1

View File

@ -0,0 +1,5 @@
4
0.00 -0.03
0.03 0.00
0.00 0.03
-0.03 0.00

View File

@ -0,0 +1,9 @@
8
0.00 -0.03
0.01 -0.01
0.03 0.00
0.01 0.01
0.00 0.03
-0.01 0.01
-0.03 0.00
-0.01 -0.01

View File

@ -0,0 +1,2 @@
100
98.992745 -222.742388 54.990231 -222.873098 38.684214 -218.445967 -5.083750 -223.088689 24.219973 -216.651977 169.853938 -159.707226 53.474768 -199.608325 83.185543 -187.717021 59.443502 -195.669803 112.839860 -173.015995 74.990144 -183.841870 147.519217 -138.978260 35.251631 -198.381845 102.614236 -145.980554 66.579430 -149.269879 -2.907098 -216.950834 83.760248 -125.485961 27.980232 -177.551082 -3.205769 -203.075411 17.207667 -134.023654 29.571287 -92.839361 -0.565308 -68.285561 -5.856002 -58.051733 -8.277534 -138.017251 -10.958793 -123.004551 -14.059751 -97.064905 -23.301102 -78.607151 -19.783424 -141.578616 -19.770107 -152.665962 -31.791053 -162.761532 -60.858715 -146.138641 -100.067914 -126.139023 -103.725504 -133.913764 -63.170556 -180.023962 -102.800331 -151.115855 -155.276971 -135.712958 -41.231057 -206.094104 -63.533945 -196.905411 -19.155725 -219.978471 -165.181637 -185.030017 -168.544207 -202.465507 -89.649244 -216.516819 -73.808965 -219.058748 -208.960812 -220.050917 -120.966794 -226.714898 -12.985003 -224.299592 -178.681835 -257.621995 -125.591539 -252.277132 -174.157722 -278.600754 -157.857148 -273.741973 -29.859021 -230.827832 -83.761175 -252.289381 -190.890377 -299.463047 -103.138638 -267.979473 -81.093232 -258.449272 -110.127325 -274.184846 -171.923498 -334.439037 -80.633255 -279.775831 -145.690882 -331.317215 -31.607233 -243.342376 -23.693907 -238.576588 -56.093321 -276.682120 -19.654333 -235.480150 -79.737742 -307.771400 -107.614483 -391.652655 -36.596687 -274.414445 -17.290758 -239.357241 -22.194284 -251.409842 -22.282084 -254.629241 -49.380345 -324.564350 -32.565113 -315.251387 -22.057227 -276.636710 -36.846731 -356.303640 -13.664373 -248.729989 -8.486353 -274.977533 1.984348 -341.389844 -2.422839 -294.594523 2.298796 -328.277225 1.109183 -291.086407 -9.020225 -228.903064 12.272199 -301.877783 21.446902 -319.979646 3.798654 -246.036269 55.647199 -328.016563 111.574003 -373.895837 2.904471 -236.548890 39.770981 -260.970927 80.585057 -279.048592 68.477319 -268.060304 155.013443 -314.080873 118.506500 -291.164570 121.567852 -291.778318 105.807424 -278.521926 -2.322573 -226.248802 116.468020 -249.433049 53.658477 -230.602898 10.909648 -225.945920 6.963465 -225.113938 170.809246 -232.307612 40.952257 -226.206252

View File

@ -0,0 +1,2 @@
100
-309.050798 -963.735832 -309.627893 -943.846502 -330.935653 -943.265591 -381.641997 -949.238997 -420.559599 -953.412598 -432.367515 -955.589256 -395.296211 -947.239279 -486.115492 -967.330201 -408.343097 -938.338951 -365.212523 -892.772110 -417.718036 -923.847474 -390.132522 -896.845543 -392.827425 -896.563448 -331.353023 -850.196245 -444.693127 -932.496272 -481.066412 -962.261938 -373.111050 -835.994208 -384.106009 -823.466134 -460.010614 -898.418434 -480.627244 -938.920067 -480.117484 -934.926356 -481.925477 -935.563906 -468.380974 -849.614639 -470.280782 -797.920521 -487.319743 -959.025745 -485.693783 -849.022349 -490.727485 -918.074447 -491.622005 -924.149332 -500.392177 -822.526862 -491.163951 -931.135526 -491.161305 -946.228318 -506.763392 -878.955432 -498.244329 -930.369511 -517.272184 -898.948286 -502.541801 -933.977419 -561.185869 -805.741476 -517.359884 -936.583488 -570.460755 -896.717295 -514.421384 -946.601157 -565.129888 -921.621337 -639.407538 -902.419841 -575.275890 -930.477753 -654.121135 -909.864222 -615.273910 -932.994975 -596.561320 -950.267551 -591.515681 -957.974845 -573.714521 -960.998513 -650.078844 -985.304575 -614.963648 -990.830511 -524.040925 -976.369693 -681.170327 -1019.819153 -582.381408 -994.384652 -582.505475 -1006.375971 -624.596938 -1036.922249 -608.499632 -1028.867386 -617.177954 -1036.037169 -525.045296 -993.546938 -550.031658 -1013.618783 -535.154798 -1019.734177 -578.318556 -1110.841025 -587.908475 -1136.624721 -516.502119 -1017.362225 -585.729134 -1137.897076 -539.594043 -1077.448868 -502.897547 -1002.958019 -522.426511 -1054.393376 -495.795989 -991.753369 -528.213695 -1102.100182 -504.923432 -1119.054948 -494.741735 -1063.762983 -494.070965 -1104.865421 -488.287827 -1111.999712 -487.331298 -1010.994800 -485.574303 -996.898374 -478.053700 -1064.488710 -465.647345 -1166.746972 -460.697984 -1142.881674 -486.073033 -975.764457 -432.941630 -1149.847672 -421.767121 -1134.295537 -472.053935 -1007.933983 -402.416746 -1145.438740 -460.825160 -1011.157016 -417.896287 -1072.697037 -426.611073 -1051.948792 -421.779154 -1041.592116 -453.690411 -1004.371034 -478.415186 -976.782445 -462.157192 -990.094100 -380.143637 -1045.820338 -358.357937 -1025.939068 -324.659404 -1021.887381 -436.360197 -983.790209 -483.158707 -969.249754 -378.160271 -989.891414 -448.654860 -975.208324 -305.910329 -1000.685650 -432.229351 -973.063077 -442.018984 -969.321431 -384.001518 -968.561925

View File

@ -0,0 +1,2 @@
120
663.872821 407.793015 636.520633 429.192598 560.950640 409.865143 647.618009 446.816024 601.923372 429.124197 613.805641 434.432037 643.383414 446.651260 694.543585 469.495060 554.128772 411.290719 714.507149 478.779819 686.820558 476.930600 607.923030 448.440214 673.666537 490.428459 581.665653 433.848437 618.063295 458.587182 657.384327 486.141373 591.456726 450.927474 565.035986 444.715613 561.083445 446.307485 585.845234 505.873436 572.120488 481.443983 566.776238 485.009718 598.179174 586.489341 578.759534 553.968898 544.336311 443.192420 579.929048 585.855395 534.988016 413.622038 533.024410 406.893933 539.946121 443.241474 540.155553 460.433611 539.642814 475.604262 541.014154 572.762247 523.749711 590.819842 531.244841 414.978048 523.328304 483.540185 509.770510 590.695124 519.770932 445.306465 527.847485 411.097066 531.036897 403.752835 508.717380 439.335233 451.970182 510.720873 515.960407 423.719380 443.604531 511.850994 482.416238 460.910530 484.821179 457.706004 406.638643 548.743075 519.791944 415.227372 495.336159 438.874962 473.268329 460.648025 427.768081 496.956343 416.414953 497.603854 525.530372 406.705732 403.949851 492.841397 476.636115 434.106702 460.198983 443.636690 515.876641 410.002331 469.102137 432.722285 508.011124 412.026656 473.531526 419.390731 342.963829 421.113501 377.389339 412.979226 367.175430 394.393347 509.029740 400.830740 491.739854 394.246251 415.722563 376.690762 529.129759 401.127236 482.695905 377.625706 414.312979 340.042231 498.722398 378.050028 420.370721 320.864902 514.395710 388.805721 461.196547 346.440382 512.586884 384.704599 462.561099 324.577529 502.927363 358.886409 514.231586 375.386404 489.166830 328.581205 478.853242 303.412871 511.306481 344.617265 486.035969 261.318417 518.829764 334.268583 530.814564 393.078411 522.100666 320.599735 525.446980 337.331167 531.320788 330.003204 533.223486 391.068253 556.138132 253.954904 536.772511 386.728355 552.189669 346.561951 562.891491 323.886520 584.719879 272.305689 551.646249 360.406432 600.463337 257.387513 598.537649 264.225760 562.259078 339.988806 552.937778 359.921390 601.782228 278.329305 572.609965 330.762154 632.199745 241.747040 604.512824 292.899632 543.819830 384.642246 635.748406 284.164232 629.900733 301.922798 548.922706 387.942190 564.358824 375.224890 676.819145 283.693554 564.295825 376.741741 539.115699 396.489390 619.234634 336.646205 532.806371 401.408590 626.699338 335.007199 609.055098 355.497184 682.053798 322.100952 638.767466 349.448043 541.961488 397.334300 657.470427 344.544174 556.458218 393.179819 715.481899 356.663561 539.948995 401.098070 673.996111 400.949015

View File

@ -0,0 +1,2 @@
120
40.970801 465.021624 37.356322 472.264911 28.333218 476.924872 -26.137177 463.896797 23.834123 481.562205 130.854532 526.486445 -0.952002 476.202643 70.987796 511.202081 -17.628868 469.300584 118.258343 547.941040 134.741634 565.164952 20.771883 498.266977 8.401227 491.463102 113.587631 585.526599 88.380620 584.584498 78.855021 575.708892 40.478287 537.677758 48.965891 550.237147 46.363902 553.798030 24.646383 528.932281 72.641813 595.506384 -9.556376 488.415458 -15.893693 480.669881 31.745147 548.644773 16.469732 564.259585 -16.753125 493.643336 -19.370787 491.412643 -25.689823 475.571505 -10.071817 547.915981 -8.152779 558.756950 -28.648776 464.968919 -19.707909 515.179086 -18.083197 531.130929 -28.643368 465.978727 -12.790606 603.065183 -53.922913 631.163160 -44.289810 546.613526 -67.027297 621.502128 -77.641347 654.932330 -52.149052 546.863707 -99.717644 642.577323 -76.852258 536.852294 -53.081630 497.410393 -55.555440 494.237935 -129.915380 576.666557 -160.194014 599.048266 -159.248058 576.861510 -93.534010 513.590133 -179.746938 580.287513 -104.754560 518.652913 -151.956541 534.033014 -116.078198 510.099760 -96.889317 492.445554 -145.185133 503.373444 -152.817322 505.781663 -70.470995 474.364707 -138.762544 485.275187 -217.542046 499.275293 -205.538390 475.774848 -223.982617 465.603638 -155.509430 451.848131 -110.058045 450.606719 -115.647219 442.671215 -30.944119 462.530529 -93.712813 445.643391 -168.900538 398.627339 -140.548527 396.239787 -105.802458 416.081107 -179.735192 348.982888 -184.330779 343.466117 -105.332107 399.957083 -96.792599 405.335769 -150.783850 359.227683 -47.691364 446.397804 -135.936712 336.033313 -119.855383 343.646327 -97.909631 367.211364 -61.249000 411.221607 -85.279590 359.285933 -63.091527 353.169368 -41.065165 422.770262 -31.873671 451.349162 -39.294336 418.166679 -68.471540 268.974235 -56.509539 303.352810 -29.820290 454.037460 -34.712437 354.149791 -29.096200 410.000087 -17.829129 361.613553 -14.042908 346.959984 -27.433486 453.123460 1.986081 289.749133 -9.335988 368.014071 -20.571498 424.921655 21.494466 272.581228 22.754276 289.556940 23.361026 348.394926 5.993424 397.796777 65.933127 303.050941 76.029168 316.819037 -22.463234 454.152928 -18.027494 448.731009 3.451301 427.631750 17.231167 414.505885 101.111120 352.040113 -25.954050 460.407282 11.791162 430.749711 95.238431 388.234953 -13.565578 453.738325 120.100325 375.261222 0.961635 446.928272 51.192430 419.986348 25.721057 447.043626 78.249055 438.553318 162.647003 426.994083 0.499661 457.543811 144.641019 451.828762 68.859795 457.759726 89.941763 459.277507 -28.000268 462.976863

View File

@ -0,0 +1,2 @@
150
1087.533372 -705.496939 1181.256997 -689.187697 1105.203113 -652.890025 1111.245118 -649.348559 1150.633323 -613.815999 1159.808173 -607.744228 1050.450891 -655.657001 1099.578658 -605.790683 1053.947996 -650.676211 1082.907668 -616.116328 1003.779098 -700.939607 1081.858021 -611.130755 1026.174352 -670.147297 1019.759341 -677.826080 1020.391527 -672.103168 1094.390214 -550.846219 1073.704483 -580.374711 1061.141851 -591.532916 1084.957753 -541.849947 1053.303115 -590.744932 1009.136063 -678.229316 1035.802110 -622.254267 1029.686485 -628.233901 1004.769385 -622.013958 1013.324914 -526.316142 1002.227369 -596.530822 993.953153 -682.132404 1007.555903 -521.707729 1001.068309 -594.419615 998.715634 -559.190921 994.836122 -598.062905 991.704722 -576.001786 984.148642 -549.141449 989.071607 -671.042278 987.411398 -664.126412 981.703110 -596.363716 986.859207 -681.253092 965.688888 -584.430679 961.254999 -571.040857 985.124706 -686.601392 973.290312 -631.865368 981.290476 -673.110560 976.057265 -659.993503 952.353659 -582.521850 947.288438 -568.377016 969.014799 -647.489623 952.075156 -601.488518 978.714594 -682.227011 973.101393 -668.313387 985.925668 -705.240330 974.137733 -685.476044 908.528471 -579.060871 983.927658 -704.092114 979.857963 -699.609905 937.031208 -646.762404 989.088259 -712.688021 968.072327 -688.555307 858.138091 -569.546526 915.812208 -636.083615 854.039406 -592.126912 844.756608 -586.012131 971.911185 -698.856359 989.371510 -713.838957 988.474825 -713.380280 826.770265 -609.863926 928.781169 -676.818628 909.129939 -680.095943 909.606162 -684.274716 951.637282 -700.351573 900.521485 -686.040747 857.507197 -676.261496 904.506837 -690.121641 909.000699 -696.775988 944.124810 -711.577048 818.247987 -705.740296 802.264875 -704.997372 927.078394 -711.833254 796.038177 -711.141561 813.097446 -720.889094 826.110847 -721.047079 862.414526 -725.333240 824.853856 -731.865908 981.114629 -716.509778 873.447308 -733.503100 795.404517 -751.652518 940.681836 -728.118018 970.339724 -722.559959 945.474188 -733.121821 931.786431 -741.809574 890.513078 -764.460878 939.888184 -746.425821 873.928459 -795.363265 918.755282 -765.246400 855.192207 -817.255774 954.288873 -748.945444 875.348744 -832.685118 876.099778 -834.807926 958.147534 -755.307759 917.828226 -842.494672 927.005780 -831.592195 927.242423 -859.564765 930.793231 -853.477959 914.907134 -899.959119 934.645448 -859.392397 932.712384 -882.127358 967.778189 -782.095063 943.557483 -869.897410 942.750382 -903.936430 982.573921 -762.254642 977.431995 -798.910126 960.598644 -912.675890 974.986231 -836.953102 990.913206 -718.999058 990.137524 -906.998063 991.205137 -725.998087 1002.971656 -908.630265 998.234079 -798.687921 1007.203553 -885.230564 1022.825722 -890.131732 1008.825564 -810.348043 996.353651 -733.230151 1024.865746 -808.027476 1037.848771 -831.966631 1040.696188 -826.419428 1040.955773 -819.692028 1055.248749 -833.731202 1028.827717 -784.354623 995.013077 -721.920637 1001.096647 -729.901601 1103.284428 -879.296096 1028.954782 -751.992358 997.791487 -720.905565 1104.533664 -809.942652 1046.368902 -759.444175 1114.548020 -805.249027 1123.001956 -799.996962 996.195668 -718.000838 1131.238940 -794.082487 1153.959086 -798.266658 1166.782520 -792.230212 1164.218047 -788.071938 1155.745831 -782.400380 1149.841335 -769.712251 1165.608953 -769.778770 1100.221894 -747.658505 1163.639153 -754.047701 1033.487800 -721.617161 1148.358826 -729.219696 1074.905707 -718.978986 1117.946095 -718.699861

View File

@ -0,0 +1,2 @@
150
558.906722 -263.703439 547.507995 -258.707486 645.458738 -244.040522 646.639710 -238.223858 627.082180 -236.638475 480.056446 -261.775934 613.260320 -204.224815 513.330876 -245.200489 552.043811 -215.426843 477.901650 -257.021342 537.305486 -219.991023 508.832098 -231.442836 556.963489 -190.707816 516.211847 -223.008576 550.430483 -184.625377 583.193013 -149.406233 581.579662 -147.752814 535.347592 -187.857999 545.902232 -173.106340 501.721828 -219.468679 470.264536 -255.726479 461.814427 -265.610888 537.160229 -165.871164 518.313706 -190.485410 465.880035 -259.911416 522.964379 -176.586178 497.527063 -210.097327 462.611961 -263.736473 523.966134 -155.976191 508.047479 -169.048296 494.774125 -192.635816 513.381442 -116.107204 468.740954 -237.216957 499.133760 -122.159166 480.012266 -172.065078 475.753568 -184.472609 482.960050 -132.937659 474.839148 -69.554038 460.658366 -71.001100 453.534884 -68.104522 456.238354 -164.068051 450.546446 -135.336402 438.686690 -106.399434 453.891523 -222.407385 434.510478 -135.428192 439.257619 -166.089482 449.075301 -220.233370 431.189577 -184.849777 418.596556 -150.056137 412.550178 -143.752206 405.971367 -148.660540 379.603276 -102.493605 406.640923 -158.287608 454.148217 -257.523520 410.935531 -199.818786 401.535892 -193.120443 424.010713 -223.798516 423.682207 -226.696030 380.514912 -182.144768 385.008509 -190.280786 406.519699 -219.793596 377.889448 -194.802615 444.317372 -257.273622 411.758669 -235.801025 377.002492 -214.033216 365.632779 -207.677305 388.076824 -222.700367 370.933611 -216.268207 387.088371 -235.077449 432.637661 -255.699495 298.455173 -195.665576 394.728712 -240.059724 349.279542 -230.184922 344.983101 -241.635004 336.267579 -244.203194 340.789221 -247.268616 318.389973 -257.483332 315.208020 -260.235814 377.233483 -274.221230 422.157066 -271.451428 455.024276 -268.492112 378.952596 -280.462675 292.637320 -315.599720 293.685605 -322.447423 311.572052 -332.908738 360.323448 -314.525101 337.635622 -331.804067 342.929666 -337.213705 332.846576 -369.985326 439.239478 -285.262698 433.975313 -289.879571 353.070405 -359.907898 407.553096 -315.857312 371.900128 -358.080034 344.227579 -386.965317 424.743756 -306.222994 353.010349 -405.219585 342.624730 -418.678618 403.546539 -340.643009 425.203738 -324.082263 444.372658 -295.924652 387.639626 -414.058126 392.536743 -415.284449 403.416109 -393.866053 441.657053 -309.091803 432.851505 -329.253238 455.722090 -278.134075 447.744581 -299.714424 434.844791 -342.888019 409.887024 -439.842049 434.056474 -398.445136 451.608286 -333.464335 441.007397 -431.903267 455.374979 -316.781238 456.503343 -449.966407 459.391701 -326.996864 465.807295 -392.865028 468.875641 -429.756678 461.405889 -274.857367 496.165194 -440.244241 517.302382 -457.526877 501.409908 -391.228323 487.076071 -339.013283 534.644679 -394.637956 558.812019 -423.216574 514.473146 -351.861054 480.722991 -298.652205 517.666025 -343.495891 469.732971 -279.413557 592.225530 -395.954716 541.526049 -330.948418 501.440435 -297.726930 530.487589 -307.906137 630.529741 -356.224755 577.275403 -328.584485 597.427113 -337.496680 481.002335 -277.375602 508.435996 -289.516373 609.785245 -332.291371 600.752746 -325.381744 539.480909 -298.129474 590.257858 -313.572912 592.919910 -305.098483 495.691259 -277.753667 462.904243 -268.751914 465.824210 -269.441729 480.521242 -272.458546 628.071723 -285.688862 480.976201 -268.999506 524.926560 -271.088983

View File

@ -0,0 +1,2 @@
200
1002.993294 523.128779 1034.884438 527.416585 947.951136 523.976544 1107.702322 532.907913 908.998023 522.062849 1031.677539 530.936802 1072.389559 536.180019 990.628047 529.848939 1087.052474 540.444825 1010.097206 535.607372 1097.860544 556.669497 1028.005725 543.968752 1039.181933 549.336796 1087.639027 566.213347 995.343862 543.703680 1029.122005 560.189787 948.200230 537.262421 1012.917219 563.968764 927.262182 530.364708 961.871589 546.059341 1007.495960 566.514649 941.659618 537.363272 958.431947 546.343762 949.252819 544.521211 1002.461083 578.365804 1004.015938 579.662289 1013.062702 589.726130 908.839797 522.542900 939.281967 543.574025 980.883449 584.482020 911.012390 524.631636 975.339690 589.010194 918.825524 533.781682 942.398916 559.652551 985.388434 609.749816 928.486006 545.266361 961.492088 585.463348 1020.492881 661.234880 1001.315994 665.293843 963.894719 615.577670 954.476527 602.553910 921.949792 548.559429 952.260412 609.435782 953.781260 626.403430 933.463379 586.129684 938.835983 600.135409 919.635550 556.067785 954.595792 682.367803 938.911279 654.440526 915.667968 559.218306 932.567529 642.521519 917.671786 663.670239 908.118594 527.998828 909.572721 626.988221 908.014029 573.999998 906.722230 623.991996 896.872656 716.682260 892.060050 685.223522 886.791445 692.687425 872.798168 698.524307 894.995430 580.573724 866.447512 694.053453 894.578539 572.238077 897.808613 559.644862 897.978642 558.654773 852.577674 685.882171 878.914606 606.113256 882.035189 595.551537 850.389217 678.748198 893.155079 561.289036 827.812177 683.151832 863.792360 602.682617 891.892236 550.801735 880.326392 568.369941 852.787539 611.311725 824.900424 652.841356 864.427985 586.695282 902.899073 529.414886 793.490925 683.529167 842.235152 603.853435 800.832393 652.675568 793.583122 659.658193 817.053785 625.792032 837.287660 598.261163 847.236406 587.029114 854.083905 576.973218 902.888259 526.782269 875.805327 551.991716 894.733456 534.165476 788.887657 628.828132 845.804543 573.891474 900.271520 528.345912 857.639178 561.494147 752.971933 603.186811 737.203128 598.140846 827.974186 553.493953 743.902391 579.861687 816.472941 554.121605 730.108963 560.454893 858.053854 532.314191 803.642102 540.585725 859.000817 521.717004 740.003459 520.921990 802.107827 517.220068 838.092900 518.394820 856.258190 516.824567 874.270499 517.719723 789.501159 503.078459 747.053089 496.210627 741.173199 489.307210 742.441634 488.067311 861.062330 511.957333 809.044898 497.263633 779.180466 485.101114 889.747114 516.724382 804.346048 488.282671 850.950112 503.417475 836.385736 493.708708 809.111524 481.133518 828.795268 488.494620 865.189587 502.602358 902.535934 519.521295 902.573136 519.440871 858.447723 498.134295 784.017709 459.155816 849.242723 491.940352 777.389810 446.224158 770.051597 440.942995 898.643428 516.216009 906.348650 520.871707 793.970175 430.823254 806.273596 436.321889 817.983777 445.704001 769.903358 400.405109 886.639264 495.547798 789.058747 367.474991 882.312513 486.276716 903.332323 515.502863 881.513906 484.390336 826.669212 405.598527 873.785304 459.787826 840.051270 397.312510 856.704402 415.732594 898.887431 501.975987 857.388829 402.256485 857.427602 383.973073 851.061220 358.638513 906.457009 517.244038 901.574764 491.673175 889.942308 417.549439 904.036709 476.171054 896.001804 353.426445 905.744071 435.029253 908.453258 462.001712 910.281160 406.022432 911.216815 453.075026 917.833263 350.281315 911.431938 464.101625 915.129289 433.286003 927.342782 369.219580 929.356376 448.020914 921.746365 476.010464 938.811137 449.256108 923.786097 485.246781 945.683621 441.371564 969.282139 414.201579 933.304735 482.393556 1008.344154 378.626185 997.687503 405.530468 947.908662 471.967024 1009.904134 394.781497 965.646319 450.299917 993.351759 416.117625 944.857071 477.216562 1007.661207 413.941480 1011.616189 417.727831 1008.808976 421.992248 937.975438 492.581075 935.456968 500.294819 995.313136 460.150050 1024.832308 441.289333 908.850270 521.473653 941.291013 501.684773 1036.902921 449.281110 1082.194594 423.733814 943.652963 503.865331 949.912127 500.730924 969.074243 492.101224 933.569440 510.589315 970.141713 494.388272 1012.444414 476.312318 993.358461 485.082076 1074.393594 456.013851 930.336221 513.219724 928.490218 513.990570 981.771984 493.738818 1041.699133 480.472396 1079.354385 473.816240 917.636257 519.327445 966.400772 513.612519

View File

@ -0,0 +1,2 @@
200
208.946160 213.248025 281.897169 215.929400 124.954421 211.128779 216.580662 219.419337 176.673651 216.555271 179.390024 219.154487 255.661850 236.114156 273.888727 246.827470 248.680698 244.756660 141.359516 220.114337 295.946059 274.891874 216.193735 248.448383 199.914684 243.454131 185.169230 239.982084 126.531576 216.911596 162.125370 232.851620 178.182379 241.024636 252.773504 284.163830 113.644992 211.415632 150.834381 233.004828 225.591247 286.895034 117.365577 214.845558 235.703442 307.020883 209.035950 299.877430 218.550181 317.410235 177.720275 289.777221 222.675430 374.710650 130.278109 240.403199 155.441517 285.953615 173.326832 320.654263 173.898580 329.451951 181.295250 380.042870 179.826814 378.484034 115.668439 222.132835 153.037696 330.900092 142.304643 301.809691 126.834363 265.796711 149.728089 349.732370 134.375394 308.257778 141.171696 342.610968 146.287685 367.085261 139.211242 344.063887 115.646580 233.545898 137.086713 400.219566 119.727149 277.437652 117.521170 273.666901 121.066564 343.621347 113.223855 239.917461 112.089698 265.989397 111.731271 341.997974 102.848031 318.694735 105.648329 266.748212 74.822593 402.632280 86.003438 322.250487 78.212761 352.270858 58.305102 377.926316 69.892261 336.487762 77.100255 309.377097 93.959775 258.069021 61.737511 335.690919 39.345936 366.363983 61.755909 291.240504 10.558391 362.972165 103.384903 220.536142 53.235202 289.165827 2.512634 358.615246 52.896525 288.917591 47.808305 283.592185 73.303596 250.049733 97.942326 223.802070 16.956801 305.456151 92.624744 228.394292 95.224206 225.333765 43.789833 268.342038 20.734847 274.600326 -49.769550 316.780858 13.667651 271.248787 97.373323 218.385325 47.056611 245.217084 107.493465 211.924633 24.840539 245.007818 -68.349923 278.539077 -76.408326 267.394418 82.891438 217.135036 57.659443 223.408391 -78.148816 257.410182 -39.436331 247.335110 -8.690896 233.623916 -56.473577 232.662768 -24.222393 224.522549 -73.998116 209.165086 -83.952477 205.695172 99.003132 209.725858 105.001669 209.858509 -30.545300 198.645355 -16.527113 199.007483 17.434152 200.976025 -0.457675 198.991522 92.101363 208.040020 -50.342549 180.596224 37.360331 195.780327 -67.619507 170.199602 -52.940151 173.289962 -4.198666 180.162650 91.652279 204.933868 65.901581 193.564288 106.318693 208.243480 82.164495 198.619595 -52.149530 141.361593 90.052576 198.286528 -28.407365 109.254844 -28.891825 106.528858 -31.074013 99.478622 108.669198 208.111254 -11.099477 106.599237 82.813518 186.030807 105.709637 205.416108 86.521739 187.868242 30.264244 135.288972 0.491426 102.743974 1.760439 98.632508 63.940067 158.179514 15.684849 104.743067 68.135912 158.505632 32.622251 113.911872 53.167926 138.449660 84.646319 174.765308 59.398578 139.955063 41.963556 102.213315 23.412945 67.811717 38.444777 87.935511 93.304412 178.649304 55.658591 108.052325 38.502589 71.869173 45.279181 72.942443 91.646238 162.814919 85.803109 145.765144 64.328548 70.605683 92.950056 154.880135 85.047016 124.868087 62.517563 49.147728 57.222990 20.482103 80.460341 90.851650 103.562765 174.776605 109.246004 197.118871 99.667462 72.466100 110.876183 164.000167 112.662065 77.010386 114.240925 41.031079 118.065739 62.168761 120.869750 30.270793 114.231903 161.106700 124.427366 33.510040 112.064960 200.056869 123.842364 111.836495 130.702869 94.670919 144.046821 22.895998 134.054700 85.110125 132.712381 117.514474 117.696179 185.913465 130.085155 157.352523 164.689807 65.662186 165.317673 69.107877 112.604380 206.335854 191.578838 60.310151 197.155618 50.820198 183.210092 94.753730 115.946885 202.481468 166.894817 127.079741 191.044895 97.586412 115.688857 203.518131 143.294503 170.527667 152.406504 161.199371 133.793220 184.771661 173.338503 142.339738 240.204559 78.995489 118.085393 202.943287 154.468068 173.128235 236.634200 104.586301 248.766338 95.713360 247.629673 128.677601 115.457049 207.734009 125.349414 202.922266 278.039895 130.484760 204.315891 166.397885 119.201192 206.293190 261.209348 157.864103 249.015701 162.379980 129.937532 203.568059 261.005300 160.377323 246.715935 168.224589 186.378695 189.948756 286.914157 163.328708 136.476513 204.808924 202.804496 195.136134 215.909902 194.837134 233.480735 198.709753 121.966624 209.143750 115.991505 209.708655 133.995316 209.535831

View File

@ -0,0 +1,2 @@
50
498.970460 -793.155144 454.488983 -779.213458 387.353904 -790.239829 506.781283 -725.577134 375.604154 -787.578184 382.860885 -782.222356 496.264053 -683.758457 451.318270 -690.803771 398.937005 -699.850857 400.756840 -678.212448 400.312083 -633.454055 362.605067 -793.061651 379.556043 -692.478092 359.972229 -719.026705 358.875839 -784.413818 315.615956 -660.731672 307.053346 -649.997037 291.771187 -670.286382 347.520570 -776.859830 321.253493 -745.356914 250.061574 -662.786679 266.627868 -699.045596 327.321225 -762.812916 357.510700 -792.019274 320.859795 -762.586177 230.241492 -724.308330 284.523211 -756.422895 182.376671 -731.065727 345.824184 -790.770949 358.162933 -794.869993 239.929110 -780.910338 320.819934 -808.377486 220.942649 -849.887139 233.434056 -858.608290 290.886316 -836.827000 325.048370 -828.180382 293.252696 -876.683383 279.282017 -931.789305 318.779784 -944.852319 345.694412 -869.206064 346.596553 -882.641409 338.645853 -992.617862 384.004025 -974.650001 393.034393 -940.709594 391.784850 -829.732220 373.812772 -803.513882 378.775493 -802.525551 412.528835 -811.994899 392.625771 -800.802308 434.739640 -802.159928

View File

@ -0,0 +1,2 @@
50
45.569687 -328.063945 2.157047 -327.857532 101.922069 -306.566181 62.421225 -290.223985 -46.127100 -336.512101 39.711389 -238.805626 76.724580 -190.179605 13.741696 -257.561682 14.358070 -232.711040 16.553530 -208.898677 -44.778905 -324.191146 -43.868773 -300.132732 -40.639963 -161.114953 -64.306800 -179.950725 -74.564733 -151.031762 -66.800547 -279.303047 -114.814519 -178.932954 -141.431262 -202.915188 -159.749900 -213.807224 -119.436208 -287.030051 -142.223066 -283.956926 -207.690031 -249.434516 -159.904468 -296.348049 -48.920486 -336.441670 -100.407603 -323.861206 -74.408993 -331.277493 -188.002011 -353.805741 -55.784754 -338.956554 -128.239401 -370.825429 -165.835199 -405.170342 -138.252078 -400.198563 -75.420083 -359.097486 -61.071328 -348.224870 -75.871380 -361.707153 -102.486104 -385.962151 -139.863508 -499.312565 -79.110426 -473.267827 -48.935153 -370.944885 -36.668035 -491.655263 -20.456404 -415.641195 60.732829 -429.507500 4.193646 -380.222802 39.533399 -406.519572 109.224314 -461.875793 73.339376 -395.944334 113.154062 -414.683181 19.730358 -364.038108 36.975516 -359.740114 94.964408 -375.145862 151.548040 -350.404317

View File

@ -0,0 +1,2 @@
80
-103.022301 675.297834 51.616886 712.311539 -57.371346 686.511356 47.487463 720.039688 45.530067 729.228211 -66.176977 691.024135 -13.785327 713.482248 12.479847 799.255727 -19.501177 767.552424 -83.782162 712.400580 -15.493682 848.244391 -60.351386 773.338707 -40.997638 829.248818 -45.470529 827.814404 -97.379158 785.738082 -106.618407 760.984771 -106.233578 733.987103 -130.815535 833.916828 -146.141022 868.678642 -131.604427 773.469307 -123.114405 709.537926 -156.213378 771.219488 -136.094605 714.155147 -154.294672 736.733584 -132.245265 706.963972 -207.637817 795.122764 -171.383387 742.957678 -192.427023 712.168747 -240.101634 724.835212 -129.917843 682.423012 -288.302303 728.677422 -246.502200 714.826215 -226.167131 701.353867 -216.690577 692.152698 -150.632600 680.802222 -282.293579 690.842568 -207.871458 680.144234 -188.846309 669.920982 -257.382492 641.599760 -241.393544 643.427842 -287.747196 596.231590 -212.570614 624.112250 -133.396469 660.247354 -128.776246 662.205856 -135.410032 657.672855 -116.723653 667.347814 -164.605998 627.849974 -215.830655 579.960187 -159.661967 619.357665 -110.429917 669.124968 -106.276709 673.460515 -161.243031 555.581737 -169.066126 538.264739 -110.839509 662.276002 -129.606108 611.608049 -139.765562 581.237770 -105.163192 612.000211 -99.135087 540.127457 -97.675997 513.165643 -81.479546 541.049307 -66.406670 492.025808 -78.290058 549.817817 -68.334791 566.001548 -6.024675 502.359087 -99.311073 665.585325 -95.635564 659.627709 -2.231353 511.636585 -48.995190 615.104580 -9.187331 575.682668 -39.894262 625.147789 54.785444 556.384605 35.965095 583.606116 -62.942267 647.960268 -33.409269 631.059503 -40.014949 639.603063 37.583477 604.636997 -98.528023 672.332883 43.091232 614.427835 -98.260779 673.107144 -101.023272 674.569144

View File

@ -0,0 +1,2 @@
80
-162.405748 -689.690570 -142.320755 -680.659634 -80.026541 -665.043679 -221.054510 -688.889113 -146.372551 -670.042986 -125.889732 -654.061695 -109.882532 -636.369086 -145.274049 -644.991768 -97.104015 -609.067968 -268.143492 -698.483866 -256.007421 -689.662287 -179.678063 -628.165040 -219.022253 -652.888995 -181.144896 -614.350838 -251.461863 -681.183891 -187.748377 -614.814646 -190.269729 -543.830594 -257.334120 -674.650313 -242.256483 -631.075157 -263.579031 -681.835703 -259.452793 -663.252960 -250.051679 -577.468271 -245.155972 -514.534658 -252.086096 -551.969663 -269.072926 -697.001330 -276.857482 -608.339866 -280.945754 -588.644670 -283.678527 -627.490974 -270.577799 -693.211170 -312.944509 -571.352516 -337.312504 -581.401523 -308.353219 -633.982125 -321.708971 -629.784652 -333.868672 -613.905609 -277.813624 -692.418205 -307.838203 -672.531265 -344.874489 -658.514671 -297.692191 -694.785957 -466.675583 -687.670224 -438.222352 -715.241786 -450.683836 -738.836964 -434.302973 -756.444992 -342.319196 -728.415906 -337.079262 -732.781861 -274.188900 -702.012527 -402.270490 -778.145288 -329.225761 -736.601299 -299.433448 -724.957759 -369.408232 -793.668828 -297.082100 -731.563717 -283.514269 -716.841973 -376.884851 -854.183308 -342.200020 -854.646256 -300.412899 -869.124160 -271.990233 -724.827476 -271.110115 -744.951577 -271.349005 -867.983674 -254.756617 -860.372631 -263.523262 -754.731547 -259.751656 -761.317479 -254.849980 -774.688684 -245.059243 -779.516086 -261.624684 -710.899778 -155.490198 -851.366416 -165.600641 -819.787303 -178.651758 -793.858817 -121.141462 -827.661777 -247.509336 -715.344766 -183.513279 -758.228545 -178.692819 -756.390008 -246.200994 -713.463931 -155.339265 -760.010142 -194.354763 -732.942432 -140.792658 -752.701745 -133.374756 -733.724531 -209.418774 -712.079659 -105.620112 -733.583411 -116.991605 -729.305906 -72.218520 -720.932831 -146.681171 -711.926874

View File

@ -1,56 +1,22 @@
#ifndef CGAL_READ_POLYGON_TEST_H
#define CGAL_READ_POLYGON_TEST_H
#ifndef CGAL_READ_POLYGON_H
#define CGAL_READ_POLYGON_H
#include <CGAL/Polygon_2.h>
#include <iostream>
#include <fstream>
/*!
* Read a polygon from an input file.
* \param filename The name of the input file.
* \param pgn Output: The polygon.
* \return Whether the polygon was successfuly read.
*/
template <class Kernel>
bool read_polygon (const char *filename, CGAL::Polygon_2<Kernel>& pgn)
void read_polygon (const char *filename, CGAL::Polygon_2<Kernel>& pgn)
{
// Open the input file.
std::ifstream ifile (filename);
std::ifstream file(filename);
if (! ifile.is_open())
if (!file)
{
std::cerr << "Failed to open <" << filename << ">." << std::endl;
return (false);
std::cerr << "Failed to open " << filename << std::endl;
exit(1);
}
// Read the polygon.
int n_vertices = 0;
typename Kernel::FT x, y;
std::list<typename Kernel::Point_2> vertices;
int k;
// Read the number of polygon vertices.
ifile >> n_vertices;
// Read the vertices.
for (k = 0; k < n_vertices; k++)
{
ifile >> x >> y;
vertices.push_back (typename Kernel::Point_2 (x, y));
}
ifile.close();
pgn = CGAL::Polygon_2<Kernel> (vertices.begin(), vertices.end());
// Make sure the polygon is simple.
if (! pgn.is_simple())
{
std::cerr << "Error - the polygon is not simple." << std::endl;
return (false);
}
return (true);
file >> pgn;
}
#endif

View File

@ -1,16 +0,0 @@
./data/rooms_part1.dat ./data/rooms_part2.dat -sohgv
./data/comb_part1.dat ./data/comb_part2.dat -sohgv
./data/fork_part1.dat ./data/fork_part2.dat -sohv
./data/knife_part1.dat ./data/knife_part2.dat -sov
./data/mchain_part1.dat ./data/mchain_part2.dat -shv
./data/random_part1.dat ./data/random_part2.dat -sgv
./data/wheels_part1.dat ./data/wheels_part2.dat -hgv
./data/r35975_part1.dat ./data/r35975_part2.dat -sohgv
./data/r38305_part1.dat ./data/r38305_part2.dat -sohgv
./data/D.dat ./data/E.dat -sohgv
./data/F.dat ./data/G.dat -sohgv
./data/F.dat ./data/E.dat -sohgv
./data/F.dat ./data/D.dat -sohgv
./data/F.dat ./data/A.dat -sohgv
./data/A.dat ./data/G.dat -sohgv
./data/B.dat ./data/G.dat -sohgv

View File

@ -1,207 +0,0 @@
#include <CGAL/Arithmetic_kernel.h>
// leda_rational, or Gmpq, or Quotient<MP_float>
typedef CGAL::Arithmetic_kernel::Rational Rational;
#include <CGAL/Cartesian.h>
#include <CGAL/minkowski_sum_2.h>
#include <CGAL/Small_side_angle_bisector_decomposition_2.h>
#include <CGAL/Polygon_convex_decomposition_2.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/Polygon_vertical_decomposition_2.h>
#include <CGAL/Polygon_set_2.h>
#include "read_polygon.h"
#include <cstring>
#include <list>
typedef CGAL::Cartesian<Rational> Kernel;
typedef Kernel::Point_2 Point_2;
typedef Kernel::Segment_2 Segment_2;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
typedef CGAL::Polygon_set_2<Kernel> Polygon_set_2;
typedef Polygon_set_2::Arrangement_2 Arrangement_2;
// Merge mergable edges
void simplify(Arrangement_2& arr)
{
Arrangement_2::Vertex_iterator vit;
for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) {
if (vit->degree() != 2) continue;
Arrangement_2::Halfedge_around_vertex_circulator eit =
vit->incident_halfedges();
const Arrangement_2::Geometry_traits_2* traits = arr.geometry_traits();
if (traits->are_mergeable_2_object()(eit->curve(), eit->next()->curve())) {
Arrangement_2::Geometry_traits_2::X_monotone_curve_2 c;
traits->merge_2_object()(eit->curve(), eit->next()->curve(), c);
arr.merge_edge(eit, eit->next(), c);
}
}
}
/*! Check if two polygons with holes are the same. */
bool are_equal(Polygon_set_2& ps1, const Polygon_set_2& ps2)
{
ps1.symmetric_difference(ps2);
return (ps1.is_empty());
}
/*! The main program. */
int main(int argc, char* argv[])
{
// Read the input file. Because of the structure of the *.cmd file
// (which is concatenated to the command line) we need to get all the
// inputs in one command line. This is the reason we read triplets/pairs of
// arguments. Each triplet/double is one input for the program.
if (argc < 3) {
std::cerr << "Usage: " << argv[0] << ". The input are triplets of:"
<< " <polygon#1> <polygon#2> [decomposition flags]"
<< std::endl;
return (1);
}
int i = 1;
while (i < argc) {
// Read the polygons from the input files.
Polygon_2 pgn1, pgn2;
if (! read_polygon(argv[i], pgn1)) {
std::cerr << "Failed to read: <" << argv[i] << ">." << std::endl;
return (1);
}
if (! read_polygon(argv[i+1], pgn2)) {
std::cerr << "Failed to read: <" << argv[i+1] << ">." << std::endl;
return (1);
}
std::cout << "Testing " << argv[i] << " and " << argv[i+1] << std::endl;
// Read the decomposition flags.
bool use_ssab = true;
bool use_opt = true;
bool use_hm = true;
bool use_greene = true;
bool use_vertical = true;
if (((i+2) < argc) && (argv[i+2][0] == '-')) {
use_ssab = (std::strchr(argv[i+2], 's') != NULL);
use_opt = (std::strchr(argv[i+2], 'o') != NULL);
use_hm = (std::strchr(argv[i+2], 'h') != NULL);
use_greene = (std::strchr(argv[i+2], 'g') != NULL);
use_vertical = (std::strchr(argv[i+2], 'v') != NULL);
}
// Compute the Minkowski sum using the convolution method.
std::cout << "Using the convolution method ... " << std::flush;
Polygon_with_holes_2 sum_conv = minkowski_sum_2(pgn1, pgn2);
std::cout << "simplifying ... " << std::flush;
Polygon_set_2 ps_conv;
ps_conv.insert(sum_conv);
Arrangement_2& arr = ps_conv.arrangement();
simplify(arr);
std::cout << "Done." << std::endl;
// Define auxiliary polygon-decomposition objects.
CGAL::Small_side_angle_bisector_decomposition_2<Kernel> ssab_decomp;
CGAL::Optimal_convex_decomposition_2<Kernel> opt_decomp;
CGAL::Hertel_Mehlhorn_convex_decomposition_2<Kernel> hm_approx_decomp;
CGAL::Greene_convex_decomposition_2<Kernel> greene_decomp;
CGAL::Polygon_vertical_decomposition_2<Kernel> vertical_decomp;
if (use_ssab) {
std::cout << "Using the small-side angle-bisector decomposition ... "
<< std::flush;
Polygon_with_holes_2 sum = minkowski_sum_2(pgn1, pgn2, ssab_decomp);
std::cout << "simplifying ... " << std::flush;
Polygon_set_2 ps_decomp;
ps_decomp.insert(sum);
Arrangement_2& arr = ps_decomp.arrangement();
simplify(arr);
if (are_equal(ps_decomp, ps_conv)) {
std::cout << "OK." << std::endl;
}
else {
std::cout << "ERROR (different result)." << std::endl;
return 1;
}
}
if (use_opt) {
std::cout << "Using the optimal convex decomposition ... " << std::flush;
Polygon_with_holes_2 sum = minkowski_sum_2(pgn1, pgn2, opt_decomp);
std::cout << "simplifying ... " << std::flush;
Polygon_set_2 ps_decomp;
ps_decomp.insert(sum);
Arrangement_2& arr = ps_decomp.arrangement();
simplify(arr);
if (are_equal(ps_decomp, ps_conv)) {
std::cout << "OK." << std::endl;
}
else {
std::cout << "ERROR (different result)." << std::endl;
return 1;
}
}
if (use_hm) {
std::cout << "Using the Hertel--Mehlhorn decomposition ... "
<< std::flush;
Polygon_with_holes_2 sum = minkowski_sum_2(pgn1, pgn2, hm_approx_decomp);
std::cout << "simplifying ... " << std::flush;
Polygon_set_2 ps_decomp;
ps_decomp.insert(sum);
Arrangement_2& arr = ps_decomp.arrangement();
simplify(arr);
if (are_equal(ps_decomp, ps_conv)) {
std::cout << "OK." << std::endl;
}
else {
std::cout << "ERROR (different result)." << std::endl;
return 1;
}
}
if (use_greene) {
std::cout << "Using the Greene decomposition ... " << std::flush;
Polygon_with_holes_2 sum = minkowski_sum_2(pgn1, pgn2, greene_decomp);
std::cout << "simplifying ... " << std::flush;
Polygon_set_2 ps_decomp;
ps_decomp.insert(sum);
Arrangement_2& arr = ps_decomp.arrangement();
simplify(arr);
if (are_equal(ps_decomp, ps_conv)) {
std::cout << "OK." << std::endl;
}
else {
std::cout << "ERROR (different result)." << std::endl;
return 1;
}
}
if (use_vertical) {
std::cout << "Using the vertical decomposition ... " << std::flush;
Polygon_with_holes_2 sum = minkowski_sum_2(pgn1, pgn2, vertical_decomp);
std::cout << "simplifying ... " << std::flush;
Polygon_set_2 ps_decomp;
ps_decomp.insert(sum);
Arrangement_2& arr = ps_decomp.arrangement();
simplify(arr);
if (are_equal(ps_decomp, ps_conv)) {
std::cout << "OK." << std::endl;
}
else {
std::cout << "ERROR (different result)." << std::endl;
return 1;
}
}
if (((i + 2) < argc) && (argv[i+2][0] == '-')) i += 3;
else i += 2;
}
return (0);
}

View File

@ -55,10 +55,7 @@ int main (int argc, char* argv[])
// Read the polygon from the input file.
Polygon_2 pgn;
const char* filename = argv[i];
if (! read_polygon (filename, pgn)) {
std::cerr << "Failed to read: <" << filename << ">." << std::endl;
return -1;
}
read_polygon (filename, pgn);
// Read the offset radius.
Rational r;

View File

@ -77,11 +77,7 @@ int main (int argc, char **argv)
int i = 1;
while (i < argc)
{
if (! read_polygon (argv[i], pgn))
{
std::cerr << "Failed to read: <" << argv[i] << ">." << std::endl;
return (1);
}
read_polygon (argv[i], pgn);
// Read the offset radius.
int numer, denom;

View File

@ -0,0 +1,18 @@
rfsohg
data/rooms_part1.dat data/rooms_part2.dat
data/comb_part1.dat data/comb_part2.dat
data/knife_part1.dat data/knife_part2.dat
data/mchain_part1.dat data/mchain_part2.dat
data/random_part1.dat data/random_part2.dat
data/wheels_part1.dat data/wheels_part2.dat
data/r35975_part1.dat data/r35975_part2.dat
data/r38305_part1.dat data/r38305_part2.dat
data/D.dat data/E.dat
data/F.dat data/G.dat
data/F.dat data/E.dat
data/F.dat data/D.dat
data/F.dat data/A.dat
data/A.dat data/G.dat
data/B.dat data/G.dat
data/dangling_edge_part1.dat data/dangling_edge_part2.dat
data/isolated_vertex_part1.dat data/isolated_vertex_part2.dat

View File

@ -0,0 +1,172 @@
#include <CGAL/basic.h>
#include <CGAL/minkowski_sum_2.h>
#include <CGAL/Small_side_angle_bisector_decomposition_2.h>
#include <CGAL/Polygon_convex_decomposition_2.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/Timer.h>
#include "read_polygon.h"
#include <string.h>
#include <list>
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
bool are_equal(const Polygon_with_holes_2& ph1,
const Polygon_with_holes_2& ph2)
{
std::list<Polygon_with_holes_2> sym_diff;
CGAL::symmetric_difference (ph1, ph2, std::back_inserter(sym_diff));
return sym_diff.empty();
}
typedef enum
{
REDUCED_CONVOLUTION,
FULL_CONVOLUTION,
SSAB_DECOMP,
OPT_DECOMP,
HM_DECOMP,
GREENE_DECOMP
} Strategy;
static const char *strategy_names[] =
{
"reduced convolution",
"full convolution",
"small-side angle-bisector decomposition",
"optimal convex decomposition",
"Hertel-Mehlhorn decomposition",
"Greene decomosition"
};
Polygon_with_holes_2 compute_minkowski_sum_2(Polygon_2 &p, Polygon_2 &q, Strategy strategy)
{
switch (strategy)
{
case REDUCED_CONVOLUTION:
{
return minkowski_sum_reduced_convolution_2 (p, q);
break;
}
case FULL_CONVOLUTION:
{
return minkowski_sum_full_convolution_2 (p, q);
break;
}
case SSAB_DECOMP:
{
CGAL::Small_side_angle_bisector_decomposition_2<Kernel> decomp;
return minkowski_sum_2(p, q, decomp);
break;
}
case OPT_DECOMP:
{
CGAL::Optimal_convex_decomposition_2<Kernel> decomp;
return minkowski_sum_2(p, q, decomp);
break;
}
case HM_DECOMP:
{
CGAL::Hertel_Mehlhorn_convex_decomposition_2<Kernel> decomp;
return minkowski_sum_2(p, q, decomp);
break;
}
case GREENE_DECOMP:
{
CGAL::Greene_convex_decomposition_2<Kernel> decomp;
return minkowski_sum_2(p, q, decomp);
break;
}
}
}
int main (int argc, char **argv)
{
if (argc < 2)
{
std::cerr << "Usage: " << argv[0] << " [method flag] [polygon files]..." << std::endl;
std::cerr << "For the method flag, use a subset of the letters 'rfsohg'." << std::endl;
std::cerr << "The program will compute the Minkowski sum of the first and second polygon, of the third and fourth, and so on." << std::endl;
return 1;
}
Polygon_2 p, q;
CGAL::Timer timer;
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 'f':
strategies.push_back(FULL_CONVOLUTION);
break;
case 's':
strategies.push_back(SSAB_DECOMP);
break;
case 'o':
strategies.push_back(OPT_DECOMP);
break;
case 'h':
strategies.push_back(HM_DECOMP);
break;
case 'g':
strategies.push_back(GREENE_DECOMP);
break;
default:
std::cerr << "Unknown flag '" << argv[1][i] << "'" << std::endl;
return 1;
}
}
int i = 2;
while (i+1 < argc)
{
std::cout << "Testing " << argv[i] << " + " << argv[i+1] << std::endl;
read_polygon (argv[i], p);
read_polygon (argv[i+1], q);
bool compare = false;
Polygon_with_holes_2 reference;
for (std::list<Strategy>::iterator it = strategies.begin(); it != strategies.end(); it++)
{
std::cout << "Using " << strategy_names[*it] << ": ";
timer.reset();
timer.start();
Polygon_with_holes_2 result = compute_minkowski_sum_2(p, q, *it);
timer.stop();
std::cout << timer.time() << " s " << std::flush;
if (compare)
{
if (are_equal(reference, result))
{
std::cout << "(OK)";
}
else
{
std::cout << "(ERROR: different result)";
return 1;
}
}
else
{
compare = true;
reference = result;
}
std::cout << std::endl;
}
std::cout << std::endl;
i += 2;
}
return 0;
}