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/random_part1.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_part2.dat -text
|
||||
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
|
||||
// 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;
|
||||
const Rational sqr_r = CGAL::square (r);
|
||||
const Algebraic alg_r = nt_traits.convert (r);
|
||||
|
|
@ -127,7 +130,6 @@ protected:
|
|||
Alg_point_2 first_op; // The first offset point.
|
||||
Algebraic a, b, c;
|
||||
|
||||
|
||||
unsigned int curve_index = 0;
|
||||
Traits_2 traits;
|
||||
std::list<Object> xobjs;
|
||||
|
|
@ -187,28 +189,31 @@ protected:
|
|||
}
|
||||
else
|
||||
{
|
||||
// Connect op2 (from the previous iteration) and op1 with a circular
|
||||
// arc, whose supporting circle is (x1, x2) with radius r.
|
||||
arc = Curve_2 (Rat_circle_2 (*curr, sqr_r),
|
||||
CGAL::COUNTERCLOCKWISE,
|
||||
op2, op1);
|
||||
|
||||
// Subdivide the arc into x-monotone subarcs and append them to the
|
||||
// convolution cycle.
|
||||
xobjs.clear();
|
||||
f_make_x_monotone (arc, std::back_inserter(xobjs));
|
||||
|
||||
for (xobj_it = xobjs.begin(); xobj_it != xobjs.end(); ++xobj_it)
|
||||
if (! f_equal (op2, op1))
|
||||
{
|
||||
assign_success = CGAL::assign (xarc, *xobj_it);
|
||||
CGAL_assertion (assign_success);
|
||||
// Connect op2 (from the previous iteration) and op1 with a circular
|
||||
// arc, whose supporting circle is (x1, x2) with radius r.
|
||||
arc = Curve_2 (Rat_circle_2 (*curr, sqr_r),
|
||||
CGAL::COUNTERCLOCKWISE,
|
||||
op2, op1);
|
||||
|
||||
// Subdivide the arc into x-monotone subarcs and append them to the
|
||||
// convolution cycle.
|
||||
xobjs.clear();
|
||||
f_make_x_monotone (arc, std::back_inserter(xobjs));
|
||||
|
||||
for (xobj_it = xobjs.begin(); xobj_it != xobjs.end(); ++xobj_it)
|
||||
{
|
||||
assign_success = CGAL::assign (xarc, *xobj_it);
|
||||
CGAL_assertion (assign_success);
|
||||
|
||||
*oi = Labeled_curve_2 (xarc,
|
||||
X_curve_label (xarc.is_directed_right(),
|
||||
cycle_id,
|
||||
curve_index));
|
||||
++oi;
|
||||
curve_index++;
|
||||
*oi = Labeled_curve_2 (xarc,
|
||||
X_curve_label (xarc.is_directed_right(),
|
||||
cycle_id,
|
||||
curve_index));
|
||||
++oi;
|
||||
curve_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,35 +245,38 @@ protected:
|
|||
|
||||
} while (curr != first);
|
||||
|
||||
// Close the convolution cycle by creating the final circular arc,
|
||||
// centered at the first vertex.
|
||||
arc = Curve_2 (Rat_circle_2 (*first, sqr_r),
|
||||
CGAL::COUNTERCLOCKWISE,
|
||||
op2, first_op);
|
||||
|
||||
// Subdivide the arc into x-monotone subarcs and append them to the
|
||||
// convolution cycle.
|
||||
bool is_last;
|
||||
|
||||
xobjs.clear();
|
||||
f_make_x_monotone (arc, std::back_inserter(xobjs));
|
||||
|
||||
xobj_it = xobjs.begin();
|
||||
while (xobj_it != xobjs.end())
|
||||
if (! f_equal (op2, first_op))
|
||||
{
|
||||
assign_success = CGAL::assign (xarc, *xobj_it);
|
||||
CGAL_assertion (assign_success);
|
||||
// Close the convolution cycle by creating the final circular arc,
|
||||
// centered at the first vertex.
|
||||
arc = Curve_2 (Rat_circle_2 (*first, sqr_r),
|
||||
CGAL::COUNTERCLOCKWISE,
|
||||
op2, first_op);
|
||||
|
||||
++xobj_it;
|
||||
is_last = (xobj_it == xobjs.end());
|
||||
|
||||
*oi = Labeled_curve_2 (xarc,
|
||||
X_curve_label (xarc.is_directed_right(),
|
||||
cycle_id,
|
||||
curve_index,
|
||||
is_last));
|
||||
++oi;
|
||||
curve_index++;
|
||||
// Subdivide the arc into x-monotone subarcs and append them to the
|
||||
// convolution cycle.
|
||||
bool is_last;
|
||||
|
||||
xobjs.clear();
|
||||
f_make_x_monotone (arc, std::back_inserter(xobjs));
|
||||
|
||||
xobj_it = xobjs.begin();
|
||||
while (xobj_it != xobjs.end())
|
||||
{
|
||||
assign_success = CGAL::assign (xarc, *xobj_it);
|
||||
CGAL_assertion (assign_success);
|
||||
|
||||
++xobj_it;
|
||||
is_last = (xobj_it == xobjs.end());
|
||||
|
||||
*oi = Labeled_curve_2 (xarc,
|
||||
X_curve_label (xarc.is_directed_right(),
|
||||
cycle_id,
|
||||
curve_index,
|
||||
is_last));
|
||||
++oi;
|
||||
curve_index++;
|
||||
}
|
||||
}
|
||||
|
||||
return (oi);
|
||||
|
|
|
|||
|
|
@ -95,10 +95,9 @@ public:
|
|||
do
|
||||
{
|
||||
out_bound.push_back (circ->source()->point());
|
||||
++circ;
|
||||
--circ;
|
||||
|
||||
} while (circ != first);
|
||||
|
||||
++hole_it;
|
||||
|
||||
// Locate the holes in the union: Go over all arrangement faces.
|
||||
|
|
@ -116,10 +115,10 @@ public:
|
|||
do
|
||||
{
|
||||
pgn_hole.push_back (circ->source()->point());
|
||||
++circ;
|
||||
--circ;
|
||||
|
||||
} while (circ != first);
|
||||
|
||||
|
||||
// Insert it to the containers of holes in the Minkowski sum.
|
||||
*holes = pgn_hole;
|
||||
++holes;
|
||||
|
|
|
|||
|
|
@ -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/Polygon_convex_decomposition_2.h>
|
||||
#include <CGAL/Boolean_set_operations_2.h>
|
||||
#include "read_polygon.h"
|
||||
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
typedef CGAL::Cartesian<Rational> Kernel;
|
||||
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_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. */
|
||||
bool are_equal (const Polygon_with_holes_2& ph1,
|
||||
const Polygon_with_holes_2& ph2)
|
||||
|
|
@ -87,13 +39,13 @@ bool are_equal (const Polygon_with_holes_2& ph1,
|
|||
}
|
||||
|
||||
/*! The main program. */
|
||||
int main (int argc, char **argv )
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
// Read the input file.
|
||||
if (argc < 3)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0]
|
||||
<< " <polygon#1> <polygon#2> ."
|
||||
<< " <polygon#1> <polygon#2> [decomposition flags]"
|
||||
<< std::endl;
|
||||
return (1);
|
||||
}
|
||||
|
|
@ -113,6 +65,20 @@ int main (int argc, char **argv )
|
|||
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.
|
||||
Polygon_with_holes_2 sum_conv;
|
||||
|
||||
|
|
@ -127,48 +93,60 @@ int main (int argc, char **argv )
|
|||
CGAL::Greene_convex_decomposition_2<Kernel> greene_decomp;
|
||||
Polygon_with_holes_2 sum_decomp;
|
||||
|
||||
std::cout << "Using the small-side angle-bisector decomposition ... ";
|
||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, ssab_decomp);
|
||||
if (are_equal (sum_conv, sum_decomp))
|
||||
if (use_ssab)
|
||||
{
|
||||
std::cout << "OK." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR (different result)." << std::endl;
|
||||
std::cout << "Using the small-side angle-bisector decomposition ... ";
|
||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, ssab_decomp);
|
||||
if (are_equal (sum_conv, sum_decomp))
|
||||
{
|
||||
std::cout << "OK." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR (different result)." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Using the optimal convex decomposition ... ";
|
||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, opt_decomp);
|
||||
if (are_equal (sum_conv, sum_decomp))
|
||||
if (use_opt)
|
||||
{
|
||||
std::cout << "OK." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR (different result)." << std::endl;
|
||||
std::cout << "Using the optimal convex decomposition ... ";
|
||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, opt_decomp);
|
||||
if (are_equal (sum_conv, sum_decomp))
|
||||
{
|
||||
std::cout << "OK." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR (different result)." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Using the Hertel--Mehlhorn decomposition ... ";
|
||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, hm_approx_decomp);
|
||||
if (are_equal (sum_conv, sum_decomp))
|
||||
if (use_hm)
|
||||
{
|
||||
std::cout << "OK." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR (different result)." << std::endl;
|
||||
std::cout << "Using the Hertel--Mehlhorn decomposition ... ";
|
||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, hm_approx_decomp);
|
||||
if (are_equal (sum_conv, sum_decomp))
|
||||
{
|
||||
std::cout << "OK." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR (different result)." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Using the Greene decomposition ... ";
|
||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, greene_decomp);
|
||||
if (are_equal (sum_conv, sum_decomp))
|
||||
if (use_greene)
|
||||
{
|
||||
std::cout << "OK." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR (different result)." << std::endl;
|
||||
std::cout << "Using the Greene decomposition ... ";
|
||||
sum_decomp = minkowski_sum_2 (pgn1, pgn2, greene_decomp);
|
||||
if (are_equal (sum_conv, sum_decomp))
|
||||
{
|
||||
std::cout << "OK." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR (different result)." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
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