mirror of https://github.com/CGAL/cgal
Completed the test suite + some bug fixes.
This commit is contained in:
parent
ef0f5d103f
commit
acd8037f11
|
|
@ -1219,6 +1219,8 @@ Minkowski_sum_2/test/Minkowski_sum_2/data/mchain_part1.dat -text
|
||||||
Minkowski_sum_2/test/Minkowski_sum_2/data/mchain_part2.dat -text
|
Minkowski_sum_2/test/Minkowski_sum_2/data/mchain_part2.dat -text
|
||||||
Minkowski_sum_2/test/Minkowski_sum_2/data/random_part1.dat -text
|
Minkowski_sum_2/test/Minkowski_sum_2/data/random_part1.dat -text
|
||||||
Minkowski_sum_2/test/Minkowski_sum_2/data/random_part2.dat -text
|
Minkowski_sum_2/test/Minkowski_sum_2/data/random_part2.dat -text
|
||||||
|
Minkowski_sum_2/test/Minkowski_sum_2/data/rooms_part1.dat -text
|
||||||
|
Minkowski_sum_2/test/Minkowski_sum_2/data/rooms_part2.dat -text
|
||||||
Minkowski_sum_2/test/Minkowski_sum_2/data/wheels_part1.dat -text
|
Minkowski_sum_2/test/Minkowski_sum_2/data/wheels_part1.dat -text
|
||||||
Minkowski_sum_2/test/Minkowski_sum_2/data/wheels_part2.dat -text
|
Minkowski_sum_2/test/Minkowski_sum_2/data/wheels_part2.dat -text
|
||||||
Modifier/doc_tex/Modifier/idraw/modifier.eps -text svneol=unset#application/postscript
|
Modifier/doc_tex/Modifier/idraw/modifier.eps -text svneol=unset#application/postscript
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,9 @@ protected:
|
||||||
|
|
||||||
// Traverse the polygon vertices and edges and construct the arcs that
|
// Traverse the polygon vertices and edges and construct the arcs that
|
||||||
// constitute the single convolution cycle.
|
// constitute the single convolution cycle.
|
||||||
|
Alg_kernel alg_ker;
|
||||||
|
typename Alg_kernel::Equal_2 f_equal = alg_ker.equal_2_object();
|
||||||
|
|
||||||
Nt_traits nt_traits;
|
Nt_traits nt_traits;
|
||||||
const Rational sqr_r = CGAL::square (r);
|
const Rational sqr_r = CGAL::square (r);
|
||||||
const Algebraic alg_r = nt_traits.convert (r);
|
const Algebraic alg_r = nt_traits.convert (r);
|
||||||
|
|
@ -127,7 +130,6 @@ protected:
|
||||||
Alg_point_2 first_op; // The first offset point.
|
Alg_point_2 first_op; // The first offset point.
|
||||||
Algebraic a, b, c;
|
Algebraic a, b, c;
|
||||||
|
|
||||||
|
|
||||||
unsigned int curve_index = 0;
|
unsigned int curve_index = 0;
|
||||||
Traits_2 traits;
|
Traits_2 traits;
|
||||||
std::list<Object> xobjs;
|
std::list<Object> xobjs;
|
||||||
|
|
@ -186,6 +188,8 @@ protected:
|
||||||
first_op = op1;
|
first_op = op1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (! f_equal (op2, op1))
|
||||||
{
|
{
|
||||||
// Connect op2 (from the previous iteration) and op1 with a circular
|
// Connect op2 (from the previous iteration) and op1 with a circular
|
||||||
// arc, whose supporting circle is (x1, x2) with radius r.
|
// arc, whose supporting circle is (x1, x2) with radius r.
|
||||||
|
|
@ -211,6 +215,7 @@ protected:
|
||||||
curve_index++;
|
curve_index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Construct the second offset vertex, which corresponds to the
|
// Construct the second offset vertex, which corresponds to the
|
||||||
// target vertex of the current polygon edge.
|
// target vertex of the current polygon edge.
|
||||||
|
|
@ -240,6 +245,8 @@ protected:
|
||||||
|
|
||||||
} while (curr != first);
|
} while (curr != first);
|
||||||
|
|
||||||
|
if (! f_equal (op2, first_op))
|
||||||
|
{
|
||||||
// Close the convolution cycle by creating the final circular arc,
|
// Close the convolution cycle by creating the final circular arc,
|
||||||
// centered at the first vertex.
|
// centered at the first vertex.
|
||||||
arc = Curve_2 (Rat_circle_2 (*first, sqr_r),
|
arc = Curve_2 (Rat_circle_2 (*first, sqr_r),
|
||||||
|
|
@ -270,6 +277,7 @@ protected:
|
||||||
++oi;
|
++oi;
|
||||||
curve_index++;
|
curve_index++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (oi);
|
return (oi);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,9 @@ public:
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
out_bound.push_back (circ->source()->point());
|
out_bound.push_back (circ->source()->point());
|
||||||
++circ;
|
--circ;
|
||||||
|
|
||||||
} while (circ != first);
|
} while (circ != first);
|
||||||
|
|
||||||
++hole_it;
|
++hole_it;
|
||||||
|
|
||||||
// Locate the holes in the union: Go over all arrangement faces.
|
// Locate the holes in the union: Go over all arrangement faces.
|
||||||
|
|
@ -116,7 +115,7 @@ public:
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
pgn_hole.push_back (circ->source()->point());
|
pgn_hole.push_back (circ->source()->point());
|
||||||
++circ;
|
--circ;
|
||||||
|
|
||||||
} while (circ != first);
|
} while (circ != first);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
# This is a script for the CGAL test suite. Such a script must obey
|
||||||
|
# the following rules:
|
||||||
|
#
|
||||||
|
# - the name of the script is cgal_test
|
||||||
|
# - for every target two one line messages are written to the file 'error.txt'
|
||||||
|
# the first one indicates if the compilation was successful
|
||||||
|
# the second one indicates if the execution was successful
|
||||||
|
# if one of the two was not successful, the line should start with 'ERROR:'
|
||||||
|
# - running the script should not require any user interaction
|
||||||
|
# - the script should clean up object files and executables
|
||||||
|
|
||||||
|
ERRORFILE=error.txt
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
# compile_and_run <target>
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
|
||||||
|
compile_test()
|
||||||
|
{
|
||||||
|
local name=$1;
|
||||||
|
|
||||||
|
echo "Compiling $name ... "
|
||||||
|
if eval 'make CGAL_MAKEFILE=$CGAL_MAKEFILE $name'; then
|
||||||
|
echo " succesful compilation of $name" >> $ERRORFILE;
|
||||||
|
res=1;
|
||||||
|
else
|
||||||
|
echo " ERROR: compilation of $name" >> $ERRORFILE;
|
||||||
|
res=0;
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_test_Minkowski_sum()
|
||||||
|
{
|
||||||
|
local datafile=$1;
|
||||||
|
local flags=$2;
|
||||||
|
|
||||||
|
basedata=`basename "$datafile"`
|
||||||
|
OUTPUTFILE=ProgramOutput.$basedata.test_Minkowski_sum.$PLATFORM
|
||||||
|
first_file="$datafile"_part1.dat
|
||||||
|
second_file="$datafile"_part2.dat
|
||||||
|
|
||||||
|
rm -f $OUTPUTFILE
|
||||||
|
COMMAND="./test_Minkowski_sum"
|
||||||
|
echo "Executing $COMMAND $first_file $second_file $flags ... "
|
||||||
|
echo
|
||||||
|
if eval $COMMAND $first_file $second_file $flags > $OUTPUTFILE 2>&1 ; then
|
||||||
|
echo " succesful execution of test_Minkowski_sum $datafile" >> $ERRORFILE
|
||||||
|
else
|
||||||
|
echo " ERROR: execution of test_Minkowski_sum $datafile" >> $ERRORFILE
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_tests()
|
||||||
|
{
|
||||||
|
eval "make CGAL_MAKEFILE=$CGAL_MAKEFILE clean > /dev/null 2>&1 "
|
||||||
|
}
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
# Minkowski sum test
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
Minkowski_sum_tests()
|
||||||
|
{
|
||||||
|
compile_test test_Minkowski_sum
|
||||||
|
|
||||||
|
if [ ${res} -eq 0 ] ; then
|
||||||
|
echo " ERROR: not executed test_Minkowski_sum" >> $ERRORFILE
|
||||||
|
else
|
||||||
|
run_test_Minkowski_sum data/rooms -sohg
|
||||||
|
run_test_Minkowski_sum data/comb -sohg
|
||||||
|
run_test_Minkowski_sum data/fork -soh
|
||||||
|
run_test_Minkowski_sum data/knife -so
|
||||||
|
run_test_Minkowski_sum data/mchain -sh
|
||||||
|
run_test_Minkowski_sum data/random -sg
|
||||||
|
run_test_Minkowski_sum data/wheels -hg
|
||||||
|
fi
|
||||||
|
clean_tests
|
||||||
|
}
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
# Offset tests
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
run_offset_test()
|
||||||
|
{
|
||||||
|
local program=$1;
|
||||||
|
local datafile=$2;
|
||||||
|
local radius=$3;
|
||||||
|
local flags=$4;
|
||||||
|
|
||||||
|
basedata=`basename "$datafile"`
|
||||||
|
OUTPUTFILE=ProgramOutput.$basedata.$program.$PLATFORM
|
||||||
|
|
||||||
|
rm -f $OUTPUTFILE
|
||||||
|
COMMAND="./$program"
|
||||||
|
echo "Executing $COMMAND $datafile $radius $flags ... "
|
||||||
|
echo
|
||||||
|
if eval $COMMAND $datafile $radius $flags > $OUTPUTFILE 2>&1 ; then
|
||||||
|
echo " succesful execution of $program $datafile" >> $ERRORFILE
|
||||||
|
else
|
||||||
|
echo " ERROR: execution of $program $datafile" >> $ERRORFILE
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
offset_tests()
|
||||||
|
{
|
||||||
|
compile_test test_exact_offset
|
||||||
|
|
||||||
|
if [ ${res} -eq 0 ] ; then
|
||||||
|
echo " ERROR: not executed test_exact_offset" >> $ERRORFILE
|
||||||
|
else
|
||||||
|
run_offset_test test_exact_offset data/random_part1.dat 5/1 -sohg
|
||||||
|
run_offset_test test_exact_offset data/comb_part1.dat 1/1 -sohg
|
||||||
|
run_offset_test test_exact_offset data/wheels_part1.dat 100000/1 -sohg
|
||||||
|
fi
|
||||||
|
|
||||||
|
compile_test test_approx_offset
|
||||||
|
|
||||||
|
if [ ${res} -eq 0 ] ; then
|
||||||
|
echo " ERROR: not executed test_approx_offset" >> $ERRORFILE
|
||||||
|
else
|
||||||
|
run_offset_test test_approx_offset data/rooms_part1.dat 3/1 -sohg
|
||||||
|
run_offset_test test_approx_offset data/wheels_part1.dat 100000/1 -sohg
|
||||||
|
fi
|
||||||
|
|
||||||
|
clean_tests
|
||||||
|
}
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
# remove the previous error file
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
|
||||||
|
rm -f $ERRORFILE
|
||||||
|
touch $ERRORFILE
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
# compile and run the tests
|
||||||
|
#---------------------------------------------------------------------#
|
||||||
|
|
||||||
|
Minkowski_sum_tests
|
||||||
|
offset_tests
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
26
|
||||||
|
0/1 8/1
|
||||||
|
0/1 0/1
|
||||||
|
17/1 0/1
|
||||||
|
17/1 18/1
|
||||||
|
0/1 18/1
|
||||||
|
0/1 9/1
|
||||||
|
6/1 9/1
|
||||||
|
6/1 10/1
|
||||||
|
1/1 10/1
|
||||||
|
1/1 17/1
|
||||||
|
8/1 17/1
|
||||||
|
8/1 14/1
|
||||||
|
9/1 14/1
|
||||||
|
9/1 17/1
|
||||||
|
16/1 17/1
|
||||||
|
16/1 10/1
|
||||||
|
9/1 10/1
|
||||||
|
8/1 9/1
|
||||||
|
16/1 9/1
|
||||||
|
16/1 1/1
|
||||||
|
9/1 1/1
|
||||||
|
9/1 8/1
|
||||||
|
8/1 8/1
|
||||||
|
8/1 1/1
|
||||||
|
1/1 1/1
|
||||||
|
1/1 8/1
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
8
|
||||||
|
0/1 -3/1
|
||||||
|
1/1 -1/1
|
||||||
|
3/1 0/1
|
||||||
|
1/1 1/1
|
||||||
|
0/1 3/1
|
||||||
|
-1/1 1/1
|
||||||
|
-3/1 0/1
|
||||||
|
-1/1 -1/1
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef CGAL_READ_POLYGON_TEST_H
|
||||||
|
#define CGAL_READ_POLYGON_TEST_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)
|
||||||
|
{
|
||||||
|
// Open the input file.
|
||||||
|
std::ifstream ifile (filename);
|
||||||
|
|
||||||
|
if (! ifile.is_open())
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to open <" << filename << ">." << std::endl;
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the polygon.
|
||||||
|
int n_vertices;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -16,10 +16,9 @@
|
||||||
#include <CGAL/Small_side_angle_bisector_decomposition_2.h>
|
#include <CGAL/Small_side_angle_bisector_decomposition_2.h>
|
||||||
#include <CGAL/Polygon_convex_decomposition_2.h>
|
#include <CGAL/Polygon_convex_decomposition_2.h>
|
||||||
#include <CGAL/Boolean_set_operations_2.h>
|
#include <CGAL/Boolean_set_operations_2.h>
|
||||||
|
#include "read_polygon.h"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
typedef CGAL::Cartesian<Rational> Kernel;
|
typedef CGAL::Cartesian<Rational> Kernel;
|
||||||
typedef Kernel::Point_2 Point_2;
|
typedef Kernel::Point_2 Point_2;
|
||||||
|
|
@ -27,53 +26,6 @@ typedef Kernel::Segment_2 Segment_2;
|
||||||
typedef CGAL::Polygon_2<Kernel> Polygon_2;
|
typedef CGAL::Polygon_2<Kernel> Polygon_2;
|
||||||
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
|
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
|
||||||
|
|
||||||
/*!
|
|
||||||
* Read a polygons from an input file.
|
|
||||||
* \param filename The name of the input file.
|
|
||||||
* \param pgn Output: The polygon.
|
|
||||||
* \return Whether the polygon was successfuly read.
|
|
||||||
*/
|
|
||||||
bool read_polygon (const char *filename, Polygon_2& pgn)
|
|
||||||
{
|
|
||||||
// Open the input file.
|
|
||||||
std::ifstream ifile (filename);
|
|
||||||
|
|
||||||
if (! ifile.is_open())
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to open <" << filename << ">." << std::endl;
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the polygon.
|
|
||||||
int n_vertices;
|
|
||||||
Rational x, y;
|
|
||||||
std::list<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 (Point_2 (x, y));
|
|
||||||
}
|
|
||||||
ifile.close();
|
|
||||||
|
|
||||||
pgn = Polygon_2 (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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Check if two polygons with holes are the same. */
|
/*! Check if two polygons with holes are the same. */
|
||||||
bool are_equal (const Polygon_with_holes_2& ph1,
|
bool are_equal (const Polygon_with_holes_2& ph1,
|
||||||
const Polygon_with_holes_2& ph2)
|
const Polygon_with_holes_2& ph2)
|
||||||
|
|
@ -87,13 +39,13 @@ bool are_equal (const Polygon_with_holes_2& ph1,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! The main program. */
|
/*! The main program. */
|
||||||
int main (int argc, char **argv )
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Read the input file.
|
// Read the input file.
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
{
|
{
|
||||||
std::cerr << "Usage: " << argv[0]
|
std::cerr << "Usage: " << argv[0]
|
||||||
<< " <polygon#1> <polygon#2> ."
|
<< " <polygon#1> <polygon#2> [decomposition flags]"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
@ -113,6 +65,20 @@ int main (int argc, char **argv )
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read the decomposition flags.
|
||||||
|
bool use_ssab = true;
|
||||||
|
bool use_opt = true;
|
||||||
|
bool use_hm = true;
|
||||||
|
bool use_greene = true;
|
||||||
|
|
||||||
|
if (argc > 3)
|
||||||
|
{
|
||||||
|
use_ssab = (strchr (argv[3], 's') != NULL);
|
||||||
|
use_opt = (strchr (argv[3], 'o') != NULL);
|
||||||
|
use_hm = (strchr (argv[3], 'h') != NULL);
|
||||||
|
use_greene = (strchr (argv[3], 'g') != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// Compute the Minkowski sum using the convolution method.
|
// Compute the Minkowski sum using the convolution method.
|
||||||
Polygon_with_holes_2 sum_conv;
|
Polygon_with_holes_2 sum_conv;
|
||||||
|
|
||||||
|
|
@ -127,6 +93,8 @@ int main (int argc, char **argv )
|
||||||
CGAL::Greene_convex_decomposition_2<Kernel> greene_decomp;
|
CGAL::Greene_convex_decomposition_2<Kernel> greene_decomp;
|
||||||
Polygon_with_holes_2 sum_decomp;
|
Polygon_with_holes_2 sum_decomp;
|
||||||
|
|
||||||
|
if (use_ssab)
|
||||||
|
{
|
||||||
std::cout << "Using the small-side angle-bisector decomposition ... ";
|
std::cout << "Using the small-side angle-bisector decomposition ... ";
|
||||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, ssab_decomp);
|
sum_decomp = minkowski_sum_2 (pgn1, pgn2, ssab_decomp);
|
||||||
if (are_equal (sum_conv, sum_decomp))
|
if (are_equal (sum_conv, sum_decomp))
|
||||||
|
|
@ -137,7 +105,10 @@ int main (int argc, char **argv )
|
||||||
{
|
{
|
||||||
std::cout << "ERROR (different result)." << std::endl;
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_opt)
|
||||||
|
{
|
||||||
std::cout << "Using the optimal convex decomposition ... ";
|
std::cout << "Using the optimal convex decomposition ... ";
|
||||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, opt_decomp);
|
sum_decomp = minkowski_sum_2 (pgn1, pgn2, opt_decomp);
|
||||||
if (are_equal (sum_conv, sum_decomp))
|
if (are_equal (sum_conv, sum_decomp))
|
||||||
|
|
@ -148,7 +119,10 @@ int main (int argc, char **argv )
|
||||||
{
|
{
|
||||||
std::cout << "ERROR (different result)." << std::endl;
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_hm)
|
||||||
|
{
|
||||||
std::cout << "Using the Hertel--Mehlhorn decomposition ... ";
|
std::cout << "Using the Hertel--Mehlhorn decomposition ... ";
|
||||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, hm_approx_decomp);
|
sum_decomp = minkowski_sum_2 (pgn1, pgn2, hm_approx_decomp);
|
||||||
if (are_equal (sum_conv, sum_decomp))
|
if (are_equal (sum_conv, sum_decomp))
|
||||||
|
|
@ -159,7 +133,10 @@ int main (int argc, char **argv )
|
||||||
{
|
{
|
||||||
std::cout << "ERROR (different result)." << std::endl;
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_greene)
|
||||||
|
{
|
||||||
std::cout << "Using the Greene decomposition ... ";
|
std::cout << "Using the Greene decomposition ... ";
|
||||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, greene_decomp);
|
sum_decomp = minkowski_sum_2 (pgn1, pgn2, greene_decomp);
|
||||||
if (are_equal (sum_conv, sum_decomp))
|
if (are_equal (sum_conv, sum_decomp))
|
||||||
|
|
@ -170,6 +147,7 @@ int main (int argc, char **argv )
|
||||||
{
|
{
|
||||||
std::cout << "ERROR (different result)." << std::endl;
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,159 @@
|
||||||
|
#ifdef CGAL_USE_GMP
|
||||||
|
// GMP is installed. Use the GMP rational number-type.
|
||||||
|
#include <CGAL/Gmpq.h>
|
||||||
|
typedef CGAL::Gmpq Rational;
|
||||||
|
#else
|
||||||
|
// GMP is not installed. Use CGAL's exact rational number-type.
|
||||||
|
#include <CGAL/MP_Float.h>
|
||||||
|
#include <CGAL/Quotient.h>
|
||||||
|
typedef CGAL::Quotient<CGAL::MP_Float> Rational;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <CGAL/Cartesian.h>
|
||||||
|
#include <CGAL/Polygon_2.h>
|
||||||
|
#include <CGAL/approximated_offset_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 "read_polygon.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
typedef CGAL::Cartesian<Rational> Kernel;
|
||||||
|
|
||||||
|
typedef Kernel::Point_2 Point_2;
|
||||||
|
typedef CGAL::Polygon_2<Kernel> Polygon_2;
|
||||||
|
|
||||||
|
typedef CGAL::Gps_circle_segment_traits_2<Kernel> Gps_traits_2;
|
||||||
|
typedef Gps_traits_2::Polygon_2 Offset_polygon_2;
|
||||||
|
typedef Gps_traits_2::Polygon_with_holes_2 Offset_polygon_with_holes_2;
|
||||||
|
|
||||||
|
/*! Check if two polygons with holes are the same. */
|
||||||
|
bool are_equal (const Offset_polygon_with_holes_2& ph1,
|
||||||
|
const Offset_polygon_with_holes_2& ph2)
|
||||||
|
{
|
||||||
|
std::list<Offset_polygon_with_holes_2> sym_diff;
|
||||||
|
|
||||||
|
CGAL::symmetric_difference (ph1, ph2,
|
||||||
|
std::back_inserter(sym_diff));
|
||||||
|
|
||||||
|
return (sym_diff.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! The main program. */
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
// Read the input file.
|
||||||
|
if (argc < 3)
|
||||||
|
{
|
||||||
|
std::cerr << "Usage: <polygon> <radius> ." << std::endl;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the polygon from the input file.
|
||||||
|
Polygon_2 pgn;
|
||||||
|
|
||||||
|
if (! read_polygon (argv[1], pgn))
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to read: <" << argv[1] << ">." << std::endl;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the offset radius.
|
||||||
|
int numer, denom;
|
||||||
|
|
||||||
|
if (sscanf (argv[2], "%d/%d", &numer, &denom) != 2)
|
||||||
|
{
|
||||||
|
std::cerr << "Invalid radius: " << argv[2] << std::endl;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rational r = Rational (numer, denom);
|
||||||
|
const double eps = 0.0001;
|
||||||
|
|
||||||
|
// Read the decomposition flags.
|
||||||
|
bool use_ssab = true;
|
||||||
|
bool use_opt = true;
|
||||||
|
bool use_hm = true;
|
||||||
|
bool use_greene = true;
|
||||||
|
|
||||||
|
if (argc > 3)
|
||||||
|
{
|
||||||
|
use_ssab = (strchr (argv[3], 's') != NULL);
|
||||||
|
use_opt = (strchr (argv[3], 'o') != NULL);
|
||||||
|
use_hm = (strchr (argv[3], 'h') != NULL);
|
||||||
|
use_greene = (strchr (argv[3], 'g') != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the Minkowski sum using the convolution method.
|
||||||
|
Offset_polygon_with_holes_2 offset_conv;
|
||||||
|
|
||||||
|
std::cout << "Using the convolution method ... ";
|
||||||
|
offset_conv = approximated_offset_2 (pgn, r, eps);
|
||||||
|
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;
|
||||||
|
Offset_polygon_with_holes_2 offset_decomp;
|
||||||
|
|
||||||
|
if (use_ssab)
|
||||||
|
{
|
||||||
|
std::cout << "Using the small-side angle-bisector decomposition ... ";
|
||||||
|
offset_decomp = approximated_offset_2 (pgn, r, eps, ssab_decomp);
|
||||||
|
if (are_equal (offset_conv, offset_decomp))
|
||||||
|
{
|
||||||
|
std::cout << "OK." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_opt)
|
||||||
|
{
|
||||||
|
std::cout << "Using the optimal convex decomposition ... ";
|
||||||
|
offset_decomp = approximated_offset_2 (pgn, r, eps, opt_decomp);
|
||||||
|
if (are_equal (offset_conv, offset_decomp))
|
||||||
|
{
|
||||||
|
std::cout << "OK." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_hm)
|
||||||
|
{
|
||||||
|
std::cout << "Using the Hertel--Mehlhorn decomposition ... ";
|
||||||
|
offset_decomp = approximated_offset_2 (pgn, r, eps, hm_approx_decomp);
|
||||||
|
if (are_equal (offset_conv, offset_decomp))
|
||||||
|
{
|
||||||
|
std::cout << "OK." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_greene)
|
||||||
|
{
|
||||||
|
std::cout << "Using the Greene decomposition ... ";
|
||||||
|
offset_decomp = approximated_offset_2 (pgn, r, eps, greene_decomp);
|
||||||
|
if (are_equal (offset_conv, offset_decomp))
|
||||||
|
{
|
||||||
|
std::cout << "OK." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,172 @@
|
||||||
|
#include <CGAL/basic.h>
|
||||||
|
|
||||||
|
#ifndef CGAL_USE_CORE
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
std::cout << "Sorry, this test needs CORE ..." << std::endl;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <CGAL/Cartesian.h>
|
||||||
|
#include <CGAL/CORE_algebraic_number_traits.h>
|
||||||
|
#include <CGAL/Arr_conic_traits_2.h>
|
||||||
|
#include <CGAL/Polygon_2.h>
|
||||||
|
#include <CGAL/offset_polygon_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 "read_polygon.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
typedef CGAL::CORE_algebraic_number_traits Nt_traits;
|
||||||
|
typedef Nt_traits::Rational Rational;
|
||||||
|
typedef Nt_traits::Algebraic Algebraic;
|
||||||
|
typedef CGAL::Cartesian<Rational> Rat_kernel;
|
||||||
|
typedef CGAL::Cartesian<Algebraic> Alg_kernel;
|
||||||
|
typedef CGAL::Arr_conic_traits_2<Rat_kernel,
|
||||||
|
Alg_kernel,Nt_traits> Conic_traits_2;
|
||||||
|
|
||||||
|
typedef Rat_kernel::Point_2 Point_2;
|
||||||
|
typedef CGAL::Polygon_2<Rat_kernel> Polygon_2;
|
||||||
|
|
||||||
|
typedef CGAL::Gps_traits_2<Conic_traits_2> Gps_traits_2;
|
||||||
|
typedef Gps_traits_2::Polygon_2 Offset_polygon_2;
|
||||||
|
typedef Gps_traits_2::Polygon_with_holes_2 Offset_polygon_with_holes_2;
|
||||||
|
|
||||||
|
/*! Check if two polygons with holes are the same. */
|
||||||
|
bool are_equal (const Offset_polygon_with_holes_2& ph1,
|
||||||
|
const Offset_polygon_with_holes_2& ph2)
|
||||||
|
{
|
||||||
|
std::list<Offset_polygon_with_holes_2> sym_diff;
|
||||||
|
|
||||||
|
CGAL::symmetric_difference (ph1, ph2,
|
||||||
|
std::back_inserter(sym_diff));
|
||||||
|
|
||||||
|
return (sym_diff.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! The main program. */
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
// Read the input file.
|
||||||
|
if (argc < 3)
|
||||||
|
{
|
||||||
|
std::cerr << "Usage: <polygon> <radius> ." << std::endl;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the polygon from the input file.
|
||||||
|
Polygon_2 pgn;
|
||||||
|
|
||||||
|
if (! read_polygon (argv[1], pgn))
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to read: <" << argv[1] << ">." << std::endl;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the offset radius.
|
||||||
|
int numer, denom;
|
||||||
|
|
||||||
|
if (sscanf (argv[2], "%d/%d", &numer, &denom) != 2)
|
||||||
|
{
|
||||||
|
std::cerr << "Invalid radius: " << argv[2] << std::endl;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rational r = Rational (numer, denom);
|
||||||
|
|
||||||
|
// Read the decomposition flags.
|
||||||
|
bool use_ssab = true;
|
||||||
|
bool use_opt = true;
|
||||||
|
bool use_hm = true;
|
||||||
|
bool use_greene = true;
|
||||||
|
|
||||||
|
if (argc > 3)
|
||||||
|
{
|
||||||
|
use_ssab = (strchr (argv[3], 's') != NULL);
|
||||||
|
use_opt = (strchr (argv[3], 'o') != NULL);
|
||||||
|
use_hm = (strchr (argv[3], 'h') != NULL);
|
||||||
|
use_greene = (strchr (argv[3], 'g') != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the Minkowski sum using the convolution method.
|
||||||
|
Conic_traits_2 traits;
|
||||||
|
|
||||||
|
Offset_polygon_with_holes_2 offset_conv;
|
||||||
|
|
||||||
|
std::cout << "Using the convolution method ... ";
|
||||||
|
offset_conv = offset_polygon_2 (pgn, r, traits);
|
||||||
|
std::cout << "Done." << std::endl;
|
||||||
|
|
||||||
|
// Define auxiliary polygon-decomposition objects.
|
||||||
|
CGAL::Small_side_angle_bisector_decomposition_2<Rat_kernel> ssab_decomp;
|
||||||
|
CGAL::Optimal_convex_decomposition_2<Rat_kernel> opt_decomp;
|
||||||
|
CGAL::Hertel_Mehlhorn_convex_decomposition_2<Rat_kernel> hm_approx_decomp;
|
||||||
|
CGAL::Greene_convex_decomposition_2<Rat_kernel> greene_decomp;
|
||||||
|
Offset_polygon_with_holes_2 offset_decomp;
|
||||||
|
|
||||||
|
if (use_ssab)
|
||||||
|
{
|
||||||
|
std::cout << "Using the small-side angle-bisector decomposition ... ";
|
||||||
|
offset_decomp = offset_polygon_2 (pgn, r, ssab_decomp, traits);
|
||||||
|
if (are_equal (offset_conv, offset_decomp))
|
||||||
|
{
|
||||||
|
std::cout << "OK." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_opt)
|
||||||
|
{
|
||||||
|
std::cout << "Using the optimal convex decomposition ... ";
|
||||||
|
offset_decomp = offset_polygon_2 (pgn, r, opt_decomp, traits);
|
||||||
|
if (are_equal (offset_conv, offset_decomp))
|
||||||
|
{
|
||||||
|
std::cout << "OK." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_hm)
|
||||||
|
{
|
||||||
|
std::cout << "Using the Hertel--Mehlhorn decomposition ... ";
|
||||||
|
offset_decomp = offset_polygon_2 (pgn, r, hm_approx_decomp, traits);
|
||||||
|
if (are_equal (offset_conv, offset_decomp))
|
||||||
|
{
|
||||||
|
std::cout << "OK." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_greene)
|
||||||
|
{
|
||||||
|
std::cout << "Using the Greene decomposition ... ";
|
||||||
|
offset_decomp = offset_polygon_2 (pgn, r, greene_decomp, traits);
|
||||||
|
if (are_equal (offset_conv, offset_decomp))
|
||||||
|
{
|
||||||
|
std::cout << "OK." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR (different result)." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue