mirror of https://github.com/CGAL/cgal
286 lines
7.8 KiB
C
286 lines
7.8 KiB
C
#include <CGAL/basic.h>
|
|
|
|
#if !defined(CGAL_USE_CORE)
|
|
#include <iostream>
|
|
int main()
|
|
{
|
|
std::cout << "CORE is not installed. Test aborted!" << std::endl;
|
|
return 0;
|
|
}
|
|
#else
|
|
|
|
#include <CGAL/Cartesian.h>
|
|
|
|
#include <CGAL/Sweep_line_2_algorithms.h>
|
|
#include <CGAL/Arr_conic_traits_2.h>
|
|
#include <CGAL/CORE_algebraic_number_traits.h>
|
|
|
|
#include <vector>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <fstream>
|
|
#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 Rat_kernel::Point_2 Rat_point_2;
|
|
typedef Rat_kernel::Segment_2 Rat_segment_2;
|
|
typedef Rat_kernel::Circle_2 Rat_circle_2;
|
|
typedef CGAL::Cartesian<Algebraic> Alg_kernel;
|
|
typedef CGAL::Arr_conic_traits_2<Rat_kernel,
|
|
Alg_kernel,
|
|
Nt_traits> Traits_2;
|
|
|
|
typedef Traits_2::Curve_2 Curve_2;
|
|
typedef Traits_2::X_monotone_curve_2 X_monotone_curve_2;
|
|
typedef Traits_2::Point_2 Point_2;
|
|
typedef std::list<Curve_2> CurveList;
|
|
|
|
typedef std::list<Point_2> PointList;
|
|
typedef PointList::iterator PointListIter;
|
|
|
|
|
|
/*! Conic reader */
|
|
template <class Traits>
|
|
class Conic_reader
|
|
{
|
|
public:
|
|
|
|
int ReadData(const char * filename, CurveList & curves,
|
|
CGAL::Bbox_2 & bbox)
|
|
{
|
|
Curve_2 cv;
|
|
char dummy[256];
|
|
|
|
std::ifstream inp(filename);
|
|
if (!inp.is_open()) {
|
|
std::cerr << "Cannot open file " << filename << "!" << std::endl;
|
|
return -1;
|
|
}
|
|
int count;
|
|
inp >> count;
|
|
inp.getline(dummy, sizeof(dummy));
|
|
for (int i = 0; i < count; i++) {
|
|
ReadCurve(inp, cv);
|
|
curves.push_back(cv);
|
|
CGAL::Bbox_2 curve_bbox = cv.bbox();
|
|
if (i == 0) bbox = curve_bbox;
|
|
else bbox = bbox + curve_bbox;
|
|
}
|
|
inp.close();
|
|
return 0;
|
|
}
|
|
|
|
void ReadCurve(std::ifstream & is, Curve_2 & cv)
|
|
{
|
|
// Read a line from the input file.
|
|
char one_line[128];
|
|
|
|
skip_comments (is, one_line);
|
|
std::string stringvalues(one_line);
|
|
std::istringstream str_line (stringvalues, std::istringstream::in);
|
|
|
|
// Get the arc type.
|
|
// Supported types are: 'f' - Full ellipse (or circle).
|
|
// 'e' - Elliptic arc (or circular arc).
|
|
// 's' - Line segment.
|
|
char type;
|
|
bool is_circle = false; // Is this a circle.
|
|
Rat_circle_2 circle;
|
|
Rational r, s, t, u, v, w; // The conic coefficients.
|
|
|
|
str_line >> type;
|
|
|
|
// An ellipse (full ellipse or a partial ellipse):
|
|
if (type == 'f' || type == 'F' || type == 'e' || type == 'E')
|
|
{
|
|
// Read the ellipse (using the format "a b x0 y0"):
|
|
//
|
|
// x - x0 2 y - y0 2
|
|
// ( -------- ) + ( -------- ) = 1
|
|
// a b
|
|
//
|
|
int a, b, x0, y0;
|
|
|
|
str_line >> a >> b >> x0 >> y0;
|
|
|
|
Rational a_sq = Rational(a*a);
|
|
Rational b_sq = Rational(b*b);
|
|
|
|
if (a == b)
|
|
{
|
|
is_circle = true;
|
|
circle = Rat_circle_2 (Rat_point_2 (Rational(x0), Rational(y0)),
|
|
Rational(a*b));
|
|
}
|
|
else
|
|
{
|
|
r = b_sq;
|
|
s = a_sq;
|
|
t = 0;
|
|
u = Rational(-2*x0*b_sq);
|
|
v = Rational(-2*y0*a_sq);
|
|
w = Rational(x0*x0*b_sq + y0*y0*a_sq - a_sq*b_sq);
|
|
}
|
|
|
|
if (type == 'f' || type == 'F')
|
|
{
|
|
// Create a full ellipse (or circle).
|
|
if (is_circle)
|
|
cv = Curve_2 (circle);
|
|
else
|
|
cv = Curve_2 (r, s, t, u, v, w);
|
|
}
|
|
else
|
|
{
|
|
// Read the endpointd of the arc.
|
|
int x1, y1, x2, y2;
|
|
|
|
str_line >> x1 >> y1 >> x2 >> y2;
|
|
|
|
Point_2 source = Point_2 (Algebraic(x1), Algebraic(y1));
|
|
Point_2 target = Point_2 (Algebraic(x2), Algebraic(y2));
|
|
|
|
// Create the arc. Note that it is always clockwise oriented.
|
|
if (is_circle)
|
|
cv = Curve_2 (circle,
|
|
CGAL::CLOCKWISE,
|
|
source, target);
|
|
else
|
|
cv = Curve_2 (r, s, t, u, v, w,
|
|
CGAL::CLOCKWISE,
|
|
source, target);
|
|
}
|
|
}
|
|
else if (type == 's' || type == 'S')
|
|
{
|
|
// Read a segment, given by its endpoints (x1,y1) and (x2,y2);
|
|
int x1, y1, x2, y2;
|
|
|
|
str_line >> x1 >> y1 >> x2 >> y2;
|
|
|
|
// Create the segment.
|
|
Rat_point_2 source = Rat_point_2 (Rational(x1), Rational(y1));
|
|
Rat_point_2 target = Rat_point_2 (Rational(x2), Rational(y2));
|
|
|
|
cv = Curve_2(Rat_segment_2 (source, target));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void skip_comments( std::ifstream& is, char* one_line )
|
|
{
|
|
while( !is.eof() ){
|
|
is.getline( one_line, 128 );
|
|
if( one_line[0] != '#' ){
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
// The main:
|
|
//
|
|
int main (int argc, char** argv)
|
|
{
|
|
bool verbose = false;
|
|
|
|
// Define a test objects to read the conic arcs from it.
|
|
if (argc<2)
|
|
{
|
|
std::cerr << "Usage: Conic_traits_test <filename>" << std::endl;
|
|
exit(1);
|
|
}
|
|
|
|
CGAL::Bbox_2 bbox;
|
|
CurveList curves;
|
|
|
|
Conic_reader<Traits_2> reader;
|
|
reader.ReadData(argv[1], curves, bbox);
|
|
|
|
// run the sweep
|
|
std::list<X_monotone_curve_2> mylist;
|
|
|
|
CGAL::get_subcurves(curves.begin(), curves.end(),
|
|
std::back_inserter(mylist), false);
|
|
|
|
|
|
PointList point_list_with_ends;
|
|
CGAL::get_intersection_points(curves.begin(), curves.end(),
|
|
std::back_inserter(point_list_with_ends), true);
|
|
int point_count_with_ends_calculated = point_list_with_ends.size();
|
|
|
|
// generate the string for the output
|
|
std::stringstream out1;
|
|
for ( std::list<X_monotone_curve_2>::iterator iter = mylist.begin() ;
|
|
iter != mylist.end() ; ++iter )
|
|
{
|
|
out1 << *iter << "\n";
|
|
}
|
|
|
|
// read the output from the file
|
|
std::stringstream out2;
|
|
char buf[1024];
|
|
int count = 0;
|
|
|
|
std::ifstream in_file(argv[1]);
|
|
in_file >> count;
|
|
in_file.getline(buf, 1024); // to get rid of the new line
|
|
for ( int i = 0 ; i < count ; i++ ) {
|
|
in_file.getline(buf, 1024);
|
|
}
|
|
in_file >> count;
|
|
in_file.getline(buf, 1024); // to get rid of the new line
|
|
for (int i = 0; i < count; i++) {
|
|
in_file.getline(buf, 1024);
|
|
out2 << buf << "\n";
|
|
}
|
|
int point_count_with_ends_from_file = 0;
|
|
in_file >> point_count_with_ends_from_file;
|
|
in_file.close();
|
|
|
|
if ( verbose )
|
|
{
|
|
std::cout << "Result: \n" << mylist.size() << "\n";
|
|
for ( std::list<X_monotone_curve_2>::iterator i = mylist.begin() ;
|
|
i != mylist.end() ; ++i )
|
|
{
|
|
std::cout << *i << "\n";
|
|
}
|
|
}
|
|
|
|
std::string calculated = out1.str();
|
|
std::string infile = out2.str();
|
|
|
|
if ( infile == calculated ) {
|
|
if ( point_count_with_ends_from_file !=
|
|
point_count_with_ends_calculated ) {
|
|
std::cout << "number of intersection points (with ends):"
|
|
<< point_count_with_ends_calculated << ". Should be "
|
|
<< point_count_with_ends_from_file << "\n";
|
|
std::cout << argv[1] << " Error\n";
|
|
return -1;
|
|
} else {
|
|
std::cout << argv[1] << " OK!\n";
|
|
}
|
|
} else {
|
|
std::cout << argv[1] << " Error\n";
|
|
std::cout << "\ncalculated:\n";
|
|
std::cout << calculated << std::endl;
|
|
std::cout << "\nin file:\n";
|
|
std::cout << infile << std::endl;
|
|
std::cout << "--" << std::endl;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif
|