mirror of https://github.com/CGAL/cgal
Bug fixes in the conic traits.
Removed the circle_traits and the segment_circle_traits (use the conic_traits instead).
This commit is contained in:
parent
fd6ce96510
commit
2be792ff76
|
|
@ -10,7 +10,7 @@
|
|||
#include <CGAL/Cartesian.h>
|
||||
#include <fstream>
|
||||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/Arr_circles_real_traits.h>
|
||||
#include <CGAL/Arr_conic_traits_2.h>
|
||||
#include <CGAL/Arr_2_bases.h>
|
||||
#include <CGAL/Arr_2_default_dcel.h>
|
||||
#include <CGAL/Arrangement_2.h>
|
||||
|
|
@ -29,16 +29,18 @@ int main()
|
|||
|
||||
#include <CGAL/leda_real.h>
|
||||
#include <CGAL/IO/Window_stream.h>
|
||||
#include <CGAL/IO/Arr_circle_traits_Window_stream.h>
|
||||
#include <CGAL/IO/Conic_arc_2_Window_stream.h>
|
||||
#include <CGAL/Draw_preferences.h>
|
||||
|
||||
typedef CGAL::Arr_circles_real_traits<leda_real> Traits;
|
||||
typedef leda_real NT;
|
||||
typedef CGAL::Cartesian<NT> Kernel;
|
||||
typedef CGAL::Arr_conic_traits_2<Kernel> Traits;
|
||||
|
||||
typedef Traits::Point Point;
|
||||
typedef Traits::Curve Curve;
|
||||
typedef Traits::X_curve X_curve;
|
||||
typedef Traits::Point_2 Point_2;
|
||||
typedef Traits::Curve_2 Curve_2;
|
||||
typedef Traits::Circle_2 Circle_2;
|
||||
|
||||
typedef CGAL::Arr_base_node<Curve> Base_node;
|
||||
typedef CGAL::Arr_base_node<Curve_2> Base_node;
|
||||
typedef CGAL::Arr_2_default_dcel<Traits> Dcel;
|
||||
typedef CGAL::Arrangement_2<Dcel,Traits,Base_node > Arr_2;
|
||||
|
||||
|
|
@ -59,10 +61,12 @@ Window_stream& operator<<(Window_stream& os, Arr_2 &A)
|
|||
return os;
|
||||
}
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
// redraw function for the LEDA window. used automatically when window
|
||||
// reappears
|
||||
void redraw(CGAL::Window_stream * wp)
|
||||
{ wp->start_buffering();
|
||||
{
|
||||
wp->start_buffering();
|
||||
wp->clear();
|
||||
// draw arragnement
|
||||
*wp << arr;
|
||||
|
|
@ -84,13 +88,16 @@ int main(int argc, char* argv[])
|
|||
std::ifstream f(argv[1]);
|
||||
f >> circles_num;
|
||||
|
||||
std::vector<Curve> circles;
|
||||
std::vector<Circle_2> circles;
|
||||
|
||||
double max_r2=1,max_x=1,min_x=-1,min_y=-1; //for adjusting the window size
|
||||
while (circles_num--) {
|
||||
while (circles_num--)
|
||||
{
|
||||
leda_real x,y,r2;
|
||||
f >> x >> y >> r2;
|
||||
circles.push_back(Curve(x,y,r2));
|
||||
|
||||
Point_2 center (x,y);
|
||||
circles.push_back(Circle_2(center, r2, CGAL::CLOCKWISE));
|
||||
|
||||
double dx=CGAL::to_double(x);
|
||||
double dy=CGAL::to_double(y);
|
||||
|
|
@ -110,10 +117,11 @@ int main(int argc, char* argv[])
|
|||
W.open_status_window();
|
||||
W.display();
|
||||
|
||||
for (unsigned int i=0; i<circles.size(); ++i) {
|
||||
for (unsigned int i=0; i<circles.size(); ++i)
|
||||
{
|
||||
std::cout << "inserting circle " << i+1 << std::endl;
|
||||
insrt_t.start();
|
||||
arr.insert(circles[i]);
|
||||
arr.insert(Curve_2(circles[i]));
|
||||
insrt_t.stop();
|
||||
}
|
||||
|
||||
|
|
@ -122,16 +130,17 @@ int main(int argc, char* argv[])
|
|||
|
||||
//POINT LOCATION
|
||||
W.set_status_string( "Enter a query point with left mouse button" );
|
||||
Point p;
|
||||
Point_2 p;
|
||||
|
||||
Arr_2::Halfedge_handle e;
|
||||
|
||||
for (;;) {
|
||||
for (;;)
|
||||
{
|
||||
double x,y;
|
||||
int b=W.read_mouse(x,y);
|
||||
if (b==10) break;
|
||||
else
|
||||
p=Point(x,y);
|
||||
p=Point_2(x,y);
|
||||
|
||||
W << arr;
|
||||
|
||||
|
|
@ -139,7 +148,6 @@ int main(int argc, char* argv[])
|
|||
e = arr.locate(p,lt);
|
||||
|
||||
Arr_2::Face_handle fh=e->face();
|
||||
//Arr_2::Ccb_halfedge_circulator cc(e);
|
||||
Arr_2::Ccb_halfedge_circulator cc;
|
||||
|
||||
if (fh != arr.unbounded_face()) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/leda_real.h>
|
||||
#include <CGAL/Arr_conic_traits_2.h>
|
||||
#include <CGAL/Timer.h>
|
||||
|
||||
#include <CGAL/Pm_default_dcel.h>
|
||||
#include <CGAL/Planar_map_2.h>
|
||||
|
|
@ -19,6 +20,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
|
||||
#include <CGAL/Draw_preferences.h>
|
||||
|
|
@ -100,8 +102,7 @@ public:
|
|||
char one_line[128];
|
||||
|
||||
skip_comments (is, one_line);
|
||||
std::string stringvalues(one_line);
|
||||
std::istringstream str_line (stringvalues, std::istringstream::in);
|
||||
std::istringstream str_line (one_line);
|
||||
|
||||
// Get the arc type.
|
||||
char type;
|
||||
|
|
@ -324,14 +325,17 @@ int main(int argc, char * argv[])
|
|||
Naive_point_location strategy;
|
||||
Pmwx pm(&strategy);
|
||||
|
||||
#if 1
|
||||
pm.insert(curveList.begin(), curveList.end());
|
||||
#else
|
||||
CGAL::Timer t;
|
||||
t.start();
|
||||
|
||||
CurveList::const_iterator i;
|
||||
for (i = curveList.begin(); i != curveList.end(); i++)
|
||||
pm.insert(*i);
|
||||
#endif
|
||||
|
||||
for (i = curveList.begin(); i != curveList.end(); i++)
|
||||
pm.insert(*i);
|
||||
|
||||
t.stop();
|
||||
std::cout << "Construction took "
|
||||
<< t.time() << " seconds." << std::endl;
|
||||
|
||||
curveList.clear();
|
||||
|
||||
// if map is empty
|
||||
|
|
@ -357,7 +361,8 @@ int main(int argc, char * argv[])
|
|||
|
||||
CGAL::Window_stream * myWindow =
|
||||
new CGAL::Window_stream(static_cast<int>(width),
|
||||
static_cast<int>(height));
|
||||
static_cast<int>(height),
|
||||
"CGAL - Conic Arcs Arrangement Demo");
|
||||
if (!myWindow) return -1;
|
||||
|
||||
float min_range = (x_range < y_range) ? x_range : y_range;
|
||||
|
|
@ -383,8 +388,6 @@ int main(int argc, char * argv[])
|
|||
myWindow->set_flush(1);
|
||||
myWindow->flush();
|
||||
|
||||
// (*myWindow) << pm;
|
||||
|
||||
// Point Location Queries
|
||||
myWindow->set_status_string("Enter a query point with left mouse button. "
|
||||
"Finish button - exit." );
|
||||
|
|
|
|||
|
|
@ -22,47 +22,49 @@ int main()
|
|||
#else
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <fstream>
|
||||
#include <CGAL/Timer.h>
|
||||
|
||||
#include <CGAL/Arr_segment_circle_traits.h>
|
||||
#include <CGAL/IO/Segment_circle_Window_stream.h>
|
||||
|
||||
#include <CGAL/Arr_2_bases.h>
|
||||
#include <CGAL/Arr_2_default_dcel.h>
|
||||
#include <CGAL/Arrangement_2.h>
|
||||
|
||||
#include <CGAL/Arr_conic_traits_2.h>
|
||||
#include <CGAL/IO/Conic_arc_2_Window_stream.h>
|
||||
#include <CGAL/IO/Window_stream.h>
|
||||
|
||||
#include <CGAL/leda_real.h>
|
||||
#include <CGAL/Draw_preferences.h>
|
||||
|
||||
typedef CGAL::Arr_segment_circle_traits<leda_real> Traits;
|
||||
#include <fstream>
|
||||
|
||||
typedef Traits::Point Point;
|
||||
typedef Traits::Segment Segment;
|
||||
typedef Traits::Circle Circle;
|
||||
typedef Traits::Conic Conic;
|
||||
typedef Traits::Curve Curve;
|
||||
typedef Traits::X_curve X_curve;
|
||||
typedef leda_real NT;
|
||||
typedef CGAL::Cartesian<NT> Kernel;
|
||||
typedef CGAL::Arr_conic_traits_2<Kernel> Traits;
|
||||
typedef CGAL::Pm_default_dcel<Traits> Dcel;
|
||||
typedef CGAL::Planar_map_2<Dcel,Traits> Pm_2;
|
||||
typedef CGAL::Planar_map_with_intersections_2<Pm_2> Pmwx_2;
|
||||
|
||||
typedef CGAL::Arr_base_node<Curve> Base_node;
|
||||
typedef CGAL::Arr_2_default_dcel<Traits> Dcel;
|
||||
typedef CGAL::Arrangement_2<Dcel,Traits,Base_node > Arr_2;
|
||||
typedef Traits::Point_2 Point_2;
|
||||
typedef Traits::Curve_2 Curve_2;
|
||||
typedef Traits::Circle_2 Circle_2;
|
||||
typedef Traits::Segment_2 Segment_2;
|
||||
typedef std::list<Curve_2> CurveList;
|
||||
|
||||
// global variables are used so that the redraw function for the LEDA window
|
||||
// can be defined to draw information found in these variables.
|
||||
static Arr_2 arr;
|
||||
static Pmwx_2 arr;
|
||||
static CGAL::Window_stream W(400, 400,
|
||||
"CGAL - Segments and Circular Arcs Arrangement Demo");
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
Window_stream& operator<<(Window_stream& os, Arr_2 &A)
|
||||
Window_stream& operator<<(Window_stream& os, Pmwx_2 &A)
|
||||
{
|
||||
My_Arr_drawer< Arr_2,
|
||||
Arr_2::Ccb_halfedge_circulator,
|
||||
Arr_2::Holes_iterator> drawer(os);
|
||||
My_Arr_drawer< Pmwx_2,
|
||||
Pmwx_2::Ccb_halfedge_circulator,
|
||||
Pmwx_2::Holes_iterator> drawer(os);
|
||||
|
||||
draw_pm(arr, drawer, os);
|
||||
|
||||
|
||||
return os;
|
||||
}
|
||||
CGAL_END_NAMESPACE
|
||||
|
|
@ -105,21 +107,33 @@ int main(int argc, char* argv[])
|
|||
std::cout << "Inserting arc no. " << i_arc + 1;
|
||||
|
||||
// A full circle (c) or a circular arc (a):
|
||||
if (type == 'c' || type == 'C' || type == 'a' || type == 'A')
|
||||
if (type == 'c' || type == 'C' || type == 'a' || type == 'A' ||
|
||||
type == 'f' || type == 'F' || type == 'e' || type == 'E')
|
||||
{
|
||||
// Read the circle, using the format "x0 y0 r^2"
|
||||
leda_real x0, y0, r2;
|
||||
|
||||
f >> x0 >> y0 >> r2;
|
||||
|
||||
Circle circle (Point (x0, y0), r2, CGAL::CLOCKWISE);
|
||||
if (type == 'c' || type == 'C' || type == 'a' || type == 'A')
|
||||
{
|
||||
f >> x0 >> y0 >> r2;
|
||||
}
|
||||
else
|
||||
{
|
||||
leda_real r, r_;
|
||||
|
||||
if (type == 'c' || type == 'C')
|
||||
f >> r >> r_ >> x0 >> y0;
|
||||
CGAL_assertion(r == r_);
|
||||
r2 = r*r;
|
||||
}
|
||||
|
||||
Circle_2 circle (Point_2 (x0, y0), r2, CGAL::CLOCKWISE);
|
||||
|
||||
if (type == 'c' || type == 'C' || type == 'f' || type == 'F')
|
||||
{
|
||||
std::cout << " (full circle)." << std::endl;
|
||||
|
||||
insrt_t.start();
|
||||
arr.insert (Curve(circle));
|
||||
arr.insert (Curve_2(circle));
|
||||
insrt_t.stop();
|
||||
|
||||
}
|
||||
|
|
@ -132,11 +146,11 @@ int main(int argc, char* argv[])
|
|||
|
||||
f >> x1 >> y1 >> x2 >> y2;
|
||||
|
||||
Point source (x1, y1);
|
||||
Point target (x2, y2);
|
||||
Point_2 source (x1, y1);
|
||||
Point_2 target (x2, y2);
|
||||
|
||||
insrt_t.start();
|
||||
arr.insert (Curve (circle, source, target));
|
||||
arr.insert (Curve_2 (circle, source, target));
|
||||
insrt_t.stop();
|
||||
}
|
||||
|
||||
|
|
@ -158,16 +172,17 @@ int main(int argc, char* argv[])
|
|||
else if (type == 's' || type == 'S')
|
||||
{
|
||||
std::cout << " (segment)." << std::endl;
|
||||
|
||||
// Read the end points.
|
||||
leda_real x1, y1, x2, y2;
|
||||
|
||||
f >> x1 >> y1 >> x2 >> y2;
|
||||
|
||||
Point source (x1, y1);
|
||||
Point target (x2, y2);
|
||||
Point_2 source (x1, y1);
|
||||
Point_2 target (x2, y2);
|
||||
|
||||
insrt_t.start();
|
||||
arr.insert (Curve (Segment (source, target)));
|
||||
arr.insert (Curve_2 (Segment_2 (source, target)));
|
||||
insrt_t.stop();
|
||||
|
||||
// Check whether we need to resize the screen.
|
||||
|
|
@ -216,25 +231,25 @@ int main(int argc, char* argv[])
|
|||
|
||||
//POINT LOCATION
|
||||
W.set_status_string( "Left mouse button - query point." );
|
||||
Point p;
|
||||
Point_2 p;
|
||||
|
||||
Arr_2::Halfedge_handle e;
|
||||
Pmwx_2::Halfedge_handle e;
|
||||
|
||||
for (;;) {
|
||||
double x,y;
|
||||
int b=W.read_mouse(x,y);
|
||||
if (b==10) break;
|
||||
else
|
||||
p=Point(x,y);
|
||||
p=Point_2(x,y);
|
||||
|
||||
W << arr;
|
||||
|
||||
Arr_2::Locate_type lt;
|
||||
Pmwx_2::Locate_type lt;
|
||||
e = arr.locate(p,lt);
|
||||
|
||||
Arr_2::Face_handle fh=e->face();
|
||||
//Arr_2::Ccb_halfedge_circulator cc(e);
|
||||
Arr_2::Ccb_halfedge_circulator cc;
|
||||
Pmwx_2::Face_handle fh=e->face();
|
||||
//Pmwx_2::Ccb_halfedge_circulator cc(e);
|
||||
Pmwx_2::Ccb_halfedge_circulator cc;
|
||||
|
||||
if (fh != arr.unbounded_face()) {
|
||||
cc=fh->halfedge_on_outer_ccb();
|
||||
|
|
@ -243,7 +258,7 @@ int main(int argc, char* argv[])
|
|||
} while (++cc != fh->halfedge_on_outer_ccb());
|
||||
}
|
||||
|
||||
Arr_2::Holes_iterator hit=fh->holes_begin(), eit=fh->holes_end();
|
||||
Pmwx_2::Holes_iterator hit=fh->holes_begin(), eit=fh->holes_end();
|
||||
for (;hit!=eit;++hit) {
|
||||
cc=*hit;
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@ include $(CGAL_MAKEFILE)
|
|||
#---------------------------------------------------------------------#
|
||||
|
||||
CXXFLAGS = \
|
||||
-Iinclude \
|
||||
-Iinclude \
|
||||
-I../../include \
|
||||
-I../../../Planar_map/include \
|
||||
-I../../../Sweep_line_2/include \
|
||||
-I../../../Trapezoidal_decomposition/include \
|
||||
$(CGAL_CXXFLAGS) \
|
||||
$(LONG_NAME_PROBLEM_CXXFLAGS) \
|
||||
$(DEBUG_OPT)
|
||||
|
|
|
|||
|
|
@ -1,913 +0,0 @@
|
|||
// ======================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
// This software and related documentation is part of an INTERNAL release
|
||||
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
||||
// intended for general use.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// release :
|
||||
// release_date : 1999, October 13
|
||||
//
|
||||
// file : include/CGAL/Arr_circles_real_traits.h
|
||||
// package : arr (1.03)
|
||||
// author(s) : Iddo Hanniel
|
||||
// coordinator : Tel-Aviv University (Dan Halperin <halperin@math.tau.ac.il>)
|
||||
//
|
||||
// ======================================================================
|
||||
#ifndef CGAL_ARR_CIRCLES_REAL_TRAITS_H
|
||||
#define CGAL_ARR_CIRCLES_REAL_TRAITS_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <list>
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/tags.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class NT> class Arr_circles_real_traits;
|
||||
|
||||
template <class NT>
|
||||
class Circ_Curve {
|
||||
|
||||
public:
|
||||
typedef Cartesian<NT> Kernel;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Circle_2 Circle_2;
|
||||
|
||||
// Obsolete, for backward compatibility
|
||||
typedef Kernel R;
|
||||
typedef Point_2 Point;
|
||||
typedef Circle_2 Circle;
|
||||
|
||||
Circ_Curve(const NT& x, const NT& y, const NT& r2) :
|
||||
c(Point_2(x,y),r2), s(x-CGAL::sqrt(r2),y), t(x-CGAL::sqrt(r2),y)
|
||||
{}
|
||||
Circ_Curve(const NT& x, const NT& y, const NT& r2,
|
||||
const Point_2& src , const Point_2& trgt) :
|
||||
c(Point_2(x,y),r2), s(src), t(trgt)
|
||||
{
|
||||
CGAL_precondition(c.has_on_boundary(src));
|
||||
CGAL_precondition(c.has_on_boundary(trgt));
|
||||
}
|
||||
|
||||
//a ctr with cgal_circle
|
||||
Circ_Curve(const Circle& _c) : c(_c),
|
||||
s(_c.center().x()-CGAL::sqrt(c.squared_radius()), _c.center().y()),
|
||||
t(_c.center().x()-CGAL::sqrt(c.squared_radius()), _c.center().y()) {}
|
||||
|
||||
Circ_Curve(const Circle& _c, const Point_2& src, const Point_2& trgt) :
|
||||
c(_c), s(src), t(trgt)
|
||||
{
|
||||
CGAL_precondition(c.has_on_boundary(src));
|
||||
CGAL_precondition(c.has_on_boundary(trgt));
|
||||
}
|
||||
|
||||
Circ_Curve () {}
|
||||
Circ_Curve (const Circ_Curve& cv) : c(cv.c),s(cv.s),t(cv.t)
|
||||
{}
|
||||
Circ_Curve& operator=(const Circ_Curve& cv) {
|
||||
c=cv.c; s=cv.s; t=cv.t;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//Public member functions for the users
|
||||
const Circle& circle() const {return c;}
|
||||
const Point_2& source() const {return s;}
|
||||
const Point_2& target() const {return t;}
|
||||
|
||||
bool is_x_monotone() const {
|
||||
if (s==t)
|
||||
return false; //closed circle
|
||||
int point_position = (CGAL_NTS compare(s.y(),c.center().y())) *
|
||||
(CGAL_NTS compare(t.y(),c.center().y()));
|
||||
if (point_position < 0)
|
||||
return false; //one above and one below
|
||||
if (orientation(s,c.center(),t)!=(c.orientation()) )
|
||||
return true; //if the same orientation or on diameter (==COLLINEAR)
|
||||
return false;
|
||||
}
|
||||
|
||||
friend class Arr_circles_real_traits<NT>;
|
||||
|
||||
private:
|
||||
Circle c;
|
||||
Point_2 s,t; //source, target
|
||||
};
|
||||
|
||||
// DEBUG
|
||||
// template <class NT>
|
||||
// ::std::ostream& operator <<
|
||||
// (::std::ostream& os,const Circ_Curve<NT>& cv) {
|
||||
// os << "Curve:\n" ;
|
||||
// os << "s: " << cv.source() << std::endl;
|
||||
// os << "t: " << cv.target() << std::endl;
|
||||
// os << "circle: " << cv.circle() << std::endl;
|
||||
// return os;
|
||||
// }
|
||||
// DEBUG
|
||||
|
||||
template <class _NT>
|
||||
class Arr_circles_real_traits {
|
||||
public:
|
||||
// Categories:
|
||||
typedef Tag_false Has_left_category;
|
||||
|
||||
typedef _NT NT;
|
||||
|
||||
//the difference between Curve and X_curve is semantical only,
|
||||
// NOT syntactical
|
||||
typedef Circ_Curve<NT> Curve_2;
|
||||
typedef Curve_2 X_monotone_curve_2;
|
||||
|
||||
// using typename to please compiler (e.g., CC with IRIX64 on mips)
|
||||
typedef typename Curve_2::Kernel Kernel;
|
||||
typedef typename Curve_2::Point_2 Point_2;
|
||||
typedef typename Curve_2::Circle_2 Circle_2;
|
||||
typedef typename Kernel::Vector_2 Vector_2;
|
||||
|
||||
// Obsolete, for backward compatibility
|
||||
typedef Kernel R;
|
||||
typedef Point_2 Point;
|
||||
typedef Curve_2 Curve;
|
||||
typedef X_monotone_curve_2 X_curve;
|
||||
typedef Circle_2 Circle;
|
||||
typedef Vector_2 Vector;
|
||||
|
||||
Arr_circles_real_traits() {}
|
||||
|
||||
Comparison_result compare_x(const Point_2& p0, const Point_2& p1) const {
|
||||
return _compare_value(p0.x(),p1.x());
|
||||
}
|
||||
|
||||
Comparison_result compare_xy(const Point_2& p0, const Point_2& p1) const {
|
||||
Comparison_result x_res = _compare_value(p0.x(),p1.x());
|
||||
|
||||
if (x_res != EQUAL)
|
||||
return (x_res);
|
||||
|
||||
return _compare_value(p0.y(),p1.y());
|
||||
}
|
||||
|
||||
//no vertical segments :
|
||||
bool curve_is_vertical(const X_monotone_curve_2&) const {return false;}
|
||||
|
||||
bool point_in_x_range(const X_monotone_curve_2& cv, const Point_2& p) const {
|
||||
CGAL_precondition(is_x_monotone(cv));
|
||||
|
||||
return (compare_x(p,cv.s) * compare_x(p,cv.t)) <=0 ;
|
||||
}
|
||||
|
||||
Comparison_result curves_compare_y_at_x(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
const Point_2& p) const {
|
||||
CGAL_assertion(is_x_monotone(cv1));
|
||||
CGAL_assertion(is_x_monotone(cv2));
|
||||
|
||||
CGAL_precondition(point_in_x_range(cv1, p));
|
||||
CGAL_precondition(point_in_x_range(cv2, p));
|
||||
|
||||
Point_2 p1 = curve_calc_point(cv1,p);
|
||||
Point_2 p2 = curve_calc_point(cv2,p);
|
||||
|
||||
return _compare_value(p1.y(),p2.y());
|
||||
}
|
||||
|
||||
|
||||
Comparison_result curves_compare_y_at_x_left(const X_monotone_curve_2& cva,
|
||||
const X_monotone_curve_2& cvb,
|
||||
const Point_2& p) const {
|
||||
|
||||
CGAL_assertion(is_x_monotone(cva));
|
||||
CGAL_assertion(is_x_monotone(cvb));
|
||||
|
||||
// Both curves is must be defined at p and to its left.
|
||||
CGAL_precondition(point_in_x_range(cva, p));
|
||||
CGAL_precondition ((compare_x(curve_source(cva),p) == SMALLER) ||
|
||||
(compare_x(curve_target(cva),p) == SMALLER));
|
||||
|
||||
CGAL_precondition(point_in_x_range(cvb, p));
|
||||
CGAL_precondition ((compare_x(curve_source(cvb),p) == SMALLER) ||
|
||||
(compare_x(curve_target(cvb),p) == SMALLER));
|
||||
|
||||
// Compare the two curves at x(p).
|
||||
CGAL_precondition (curves_compare_y_at_x(cva, cvb, p) == EQUAL);
|
||||
|
||||
//otherwise
|
||||
// <cv1> and <cv2> meet at a point with the same x-coordinate as p
|
||||
// compare their derivatives
|
||||
Point_2 q=curve_calc_point(cva,p);
|
||||
|
||||
X_monotone_curve_2 cv1(cva),cv2(cvb);
|
||||
if (compare_x(curve_source(cv1),q) == SMALLER)
|
||||
cv1 = curve_opposite(cva);
|
||||
if (compare_x(curve_source(cv2),q) == SMALLER)
|
||||
cv2 = curve_opposite(cvb);
|
||||
|
||||
Vector d1=derivative_vec(cv1,q);
|
||||
Vector d2=derivative_vec(cv2,q);
|
||||
|
||||
if ((_compare_value(d1[0],0)==EQUAL)||
|
||||
(_compare_value(d2[0],0)==EQUAL) ) { //one or both are infinite
|
||||
if (CGAL_NTS is_negative(d1[1]*d2[1])) {
|
||||
return _compare_value(d1[1],d2[1]) ;
|
||||
}
|
||||
else {
|
||||
if (_compare_value(d1[0],0)!=EQUAL) //d2 is vertical
|
||||
return _compare_value(0,d2[1]);
|
||||
if (_compare_value(d2[0],0)!=EQUAL) //d1 is vertical
|
||||
return _compare_value(d1[1],0);
|
||||
|
||||
//otherwise both are vertical
|
||||
//and they share a tangent at q
|
||||
//compare the norm of tangent vector (==second derivative)
|
||||
if (CGAL_NTS is_negative(compare_x(cv1.s,cv1.t) *
|
||||
cv1.c.orientation()) ) {
|
||||
//curves are on lower part of circle (if d2 has greater value then
|
||||
//it is below d1 and return LARGER)
|
||||
return
|
||||
_compare_value(d2[0]*d2[0]+d2[1]*d2[1], d1[0]*d1[0]+d1[1]*d1[1]);
|
||||
}
|
||||
else { //upper part of circle(if d1 has greater value then
|
||||
//it is above d2 and return LARGER)
|
||||
return
|
||||
_compare_value(d1[0]*d1[0]+d1[1]*d1[1], d2[0]*d2[0]+d2[1]*d2[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//in any other case both derivatives are finite and to the left of q
|
||||
// return _compare_value(derivative(cv2,q), derivative(cv1,q));
|
||||
Comparison_result ccr=_compare_value(d2[1]/d2[0], d1[1]/d1[0] );
|
||||
|
||||
if (ccr!=EQUAL)
|
||||
return ccr;
|
||||
else {
|
||||
//they share a common tangent
|
||||
//compare the second derivative (norm of vectors) - needs checking
|
||||
//check if we are above or below
|
||||
|
||||
bool cv1_is_on_lower=(compare_x(cv1.s,cv1.t) * cv1.c.orientation() < 0);
|
||||
bool cv2_is_on_lower=(compare_x(cv2.s,cv2.t) * cv2.c.orientation() < 0);
|
||||
|
||||
if (cv1_is_on_lower != cv2_is_on_lower) {
|
||||
//one is from above one from below
|
||||
if (cv1_is_on_lower) return LARGER;
|
||||
else
|
||||
return SMALLER;
|
||||
}
|
||||
|
||||
//otherwise both are on upper or both on lower
|
||||
if (cv1_is_on_lower) {
|
||||
//curves are on lower part of circle (if |d2| has greater value then
|
||||
//it is below d1 and return LARGER)
|
||||
return
|
||||
_compare_value(d2[0]*d2[0]+d2[1]*d2[1], d1[0]*d1[0]+d1[1]*d1[1]);
|
||||
}
|
||||
else { //upper part of circle(if |d1| has greater value then
|
||||
//it is above d2 and return LARGER)
|
||||
return
|
||||
_compare_value(d1[0]*d1[0]+d1[1]*d1[1], d2[0]*d2[0]+d2[1]*d2[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Comparison_result curves_compare_y_at_x_right(const X_monotone_curve_2& cva,
|
||||
const X_monotone_curve_2& cvb,
|
||||
const Point_2& p) const {
|
||||
CGAL_assertion(is_x_monotone(cva));
|
||||
CGAL_assertion(is_x_monotone(cvb));
|
||||
|
||||
// Both curves is must be defined at p and to its right.
|
||||
CGAL_precondition(point_in_x_range(cva, p));
|
||||
CGAL_precondition ((compare_x(curve_source(cva),p) == LARGER) ||
|
||||
(compare_x(curve_target(cva),p) == LARGER));
|
||||
|
||||
CGAL_precondition(point_in_x_range(cvb, p));
|
||||
CGAL_precondition ((compare_x(curve_source(cvb),p) == LARGER) ||
|
||||
(compare_x(curve_target(cvb),p) == LARGER));
|
||||
|
||||
// Compare the two curves at x(p).
|
||||
CGAL_precondition (curves_compare_y_at_x(cva, cvb, p) == EQUAL);
|
||||
|
||||
// <cv1> and <cv2> meet at a point with the same x-coordinate as p
|
||||
// compare their derivatives
|
||||
|
||||
//make both curves compared - left to right
|
||||
Point_2 q=curve_calc_point(cva,p);
|
||||
|
||||
X_monotone_curve_2 cv1(cva),cv2(cvb);
|
||||
if (compare_x(curve_source(cv1),q) == LARGER)
|
||||
cv1 = curve_opposite(cva);
|
||||
if (compare_x(curve_source(cv2),q) == LARGER)
|
||||
cv2 = curve_opposite(cvb);
|
||||
|
||||
Vector d1=derivative_vec(cv1,q);
|
||||
Vector d2=derivative_vec(cv2,q);
|
||||
|
||||
if ((_compare_value(d1[0],0)==EQUAL)||
|
||||
(_compare_value(d2[0],0)==EQUAL) ) { //one or both are vertical
|
||||
if (CGAL_NTS is_negative(d1[1]*d2[1]) ) {
|
||||
return _compare_value(d1[1],d2[1]) ;
|
||||
}
|
||||
else {
|
||||
if (_compare_value(d1[0],0)!=EQUAL) //d2 is vertical
|
||||
return _compare_value(0,d2[1]);
|
||||
if (_compare_value(d2[0],0)!=EQUAL ) //d1 is vertical
|
||||
return _compare_value(d1[1],0);
|
||||
|
||||
//otherwise they share a tangent at q
|
||||
//compare the norm of tangent vector (==second derivative)
|
||||
if (compare_x(cv1.s,cv1.t) * cv1.c.orientation() < 0) {
|
||||
//curves are on lower part of circle (if |d2| has greater value then
|
||||
//it is below d1 and return LARGER)
|
||||
return
|
||||
_compare_value(d2[0]*d2[0]+d2[1]*d2[1], d1[0]*d1[0]+d1[1]*d1[1]);
|
||||
}
|
||||
else { //upper part of circle(if |d1| has greater value then
|
||||
//it is above d2 and return LARGER)
|
||||
return
|
||||
_compare_value(d1[0]*d1[0]+d1[1]*d1[1], d2[0]*d2[0]+d2[1]*d2[1]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//in other case both derivatives are finite and to the right of q
|
||||
//return _compare_value(derivative(cv1,q), derivative(cv2,q));
|
||||
Comparison_result ccr=_compare_value(d1[1]/d1[0], d2[1]/d2[0] );
|
||||
if (ccr!=EQUAL)
|
||||
return ccr;
|
||||
else {
|
||||
//they share a common tangent
|
||||
//compare the second derivative (norm of vectors) - needs checking
|
||||
//check if we are above or below
|
||||
|
||||
bool cv1_is_on_lower=(compare_x(cv1.s,cv1.t) * cv1.c.orientation() < 0);
|
||||
bool cv2_is_on_lower=(compare_x(cv2.s,cv2.t) * cv2.c.orientation() < 0);
|
||||
|
||||
if (cv1_is_on_lower != cv2_is_on_lower) {
|
||||
//one is from above one from below
|
||||
if (cv1_is_on_lower) return LARGER;
|
||||
else
|
||||
return SMALLER;
|
||||
}
|
||||
|
||||
//otherwise both are on upper or on lower
|
||||
if (cv1_is_on_lower) {
|
||||
//curves are on lower part of circle (if |d2| has greater value then
|
||||
//it is below d1 and return LARGER)
|
||||
return
|
||||
_compare_value(d2[0]*d2[0]+d2[1]*d2[1], d1[0]*d1[0]+d1[1]*d1[1]);
|
||||
}
|
||||
else { //upper part of circle(if |d1| has greater value then
|
||||
//it is above d2 and return LARGER)
|
||||
return
|
||||
_compare_value(d1[0]*d1[0]+d1[1]*d1[1], d2[0]*d2[0]+d2[1]*d2[1]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Comparison_result curve_compare_y_at_x (const Point_2& p,
|
||||
const X_monotone_curve_2 &cv) const
|
||||
{
|
||||
CGAL_precondition(is_x_monotone(cv));
|
||||
CGAL_precondition(point_in_x_range(cv, p));
|
||||
|
||||
return (_compare_value(p.y(), curve_calc_point(cv, p).y()));
|
||||
}
|
||||
|
||||
bool point_equal(const Point_2 & p, const Point_2 & q) const
|
||||
{
|
||||
return is_same(p, q);
|
||||
}
|
||||
|
||||
bool curve_equal(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2) const {
|
||||
CGAL_precondition(is_x_monotone(cv1));
|
||||
CGAL_precondition(is_x_monotone(cv2));
|
||||
|
||||
return (is_same( cv1.s,cv2.s) && is_same( cv1.t,cv2.t) &&
|
||||
( cv1.c.orientation()==cv2.c.orientation()) &&
|
||||
is_same( cv1.c.center(), cv2.c.center()) &&
|
||||
_compare_value( cv1.c.squared_radius(),
|
||||
cv2.c.squared_radius()) == EQUAL);
|
||||
}
|
||||
|
||||
Point_2 curve_source(const X_monotone_curve_2& cv) const {
|
||||
return cv.s;
|
||||
}
|
||||
Point_2 curve_target(const X_monotone_curve_2& cv) const {
|
||||
return cv.t;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// ARRANGEMENT FUNCS
|
||||
|
||||
|
||||
|
||||
X_monotone_curve_2 curve_opposite(const X_monotone_curve_2& cv) const {
|
||||
X_monotone_curve_2 xc(cv.c.center().x(),cv.c.center().y(),
|
||||
cv.c.squared_radius(),cv.t, cv.s);
|
||||
xc.c=cv.c.opposite();
|
||||
return xc;
|
||||
}
|
||||
|
||||
bool is_x_monotone(const Curve_2& cv) const {
|
||||
return cv.is_x_monotone();
|
||||
}
|
||||
|
||||
/*! Cut the given curve into x-monotone subcurves and inserts them to the
|
||||
* given output iterator. The order in which they are inserted defines their
|
||||
* order in the hierarchy tree.
|
||||
* \param cv the input curve
|
||||
* \param o the output iterator
|
||||
* \return the past-the-end iterator
|
||||
*/
|
||||
template<class OutputIterator>
|
||||
OutputIterator curve_make_x_monotone(const Curve_2 & cv,
|
||||
OutputIterator o) const
|
||||
{
|
||||
if (is_x_monotone(cv)) {
|
||||
*o++ = cv;
|
||||
return o;
|
||||
}
|
||||
|
||||
bool switch_orientation = false;
|
||||
|
||||
// is cv a closed circle ?
|
||||
if (cv.s==cv.t) {
|
||||
// for arrangements of circles this is all that is needed
|
||||
Point_2 src(cv.c.center().x()-CGAL::sqrt(cv.c.squared_radius()),
|
||||
cv.c.center().y());
|
||||
Point_2 trg(cv.c.center().x()+CGAL::sqrt(cv.c.squared_radius()),
|
||||
cv.c.center().y());
|
||||
|
||||
// bug fix, Shai, 12 Feb. 2001
|
||||
// x-monotone curves did not respect the original orintation
|
||||
typename Curve_2::Circle circ(cv.circle().center(),
|
||||
cv.circle().squared_radius(),
|
||||
cv.circle().orientation());
|
||||
|
||||
Curve_2 top_arc(circ, src, trg);
|
||||
*o++ = top_arc;
|
||||
|
||||
Curve_2 bottom_arc(circ, trg, src);
|
||||
*o++ = bottom_arc;
|
||||
}
|
||||
else {
|
||||
//if we get a curve that is not a closed circle - for completeness
|
||||
// bug fix, Shai, 12 Feb. 2001
|
||||
// curves that are split to 3 x-monotone sub curves were not handled
|
||||
|
||||
// MSVC doesn't like the copy constructor:
|
||||
// const Point_2 ¢er(cv.circle().center());
|
||||
const Point_2 & center = cv.circle().center();
|
||||
Point_2 mid1, mid2;
|
||||
NT sq_radius(cv.c.squared_radius());
|
||||
Curve_2 work_cv;
|
||||
bool two_cuts = false,
|
||||
left_cut_is_first = false;
|
||||
|
||||
// for simplicity work on CCW curve
|
||||
if (cv.c.orientation() == CLOCKWISE) {
|
||||
work_cv = curve_opposite(cv);
|
||||
switch_orientation = true;
|
||||
}
|
||||
else {
|
||||
work_cv = Curve_2(cv);
|
||||
}
|
||||
|
||||
CGAL_assertion(work_cv.circle().orientation() == COUNTERCLOCKWISE);
|
||||
|
||||
// MSVC doesn't like the copy constructor:
|
||||
// const Point_2 &src(work_cv.source()), &trg(work_cv.target());
|
||||
const Point_2 & src = work_cv.source();
|
||||
const Point_2 & trg = work_cv.target();
|
||||
|
||||
// now we work on a CCW circular curve which is, by precondition
|
||||
// NOT x-monotone.
|
||||
// There are four cases, denote the quadrants: II I
|
||||
// denote s - source, t - target III IV
|
||||
// In two of them there is ONE spliting point, in the other two
|
||||
// there are TWO split points.
|
||||
|
||||
// First, we check in which scenario we are
|
||||
if ( _compare_value(src.y(), center.y()) == LARGER ) {
|
||||
left_cut_is_first = true;
|
||||
if ( _compare_value(trg.y(), center.y()) == LARGER ) {
|
||||
// s is in II, t is in I
|
||||
two_cuts = true;
|
||||
}
|
||||
else {
|
||||
// s is in II, t is in III or IV
|
||||
}
|
||||
}
|
||||
else {
|
||||
// source is lower then center
|
||||
if ( _compare_value(trg.y(), center.y()) == SMALLER ) {
|
||||
// s is in IV, t is in III
|
||||
two_cuts = true;
|
||||
}
|
||||
else {
|
||||
// s is in IV, t is in I or II
|
||||
}
|
||||
}
|
||||
|
||||
// Second, we calculate the two or three split points
|
||||
if ( left_cut_is_first ){
|
||||
mid1 = Point_2(center.x() - CGAL::sqrt(sq_radius), center.y());
|
||||
if ( two_cuts ) {
|
||||
mid2 = Point_2(center.x() + CGAL::sqrt(sq_radius), center.y());;
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
else {
|
||||
mid1 = Point_2(center.x() + CGAL::sqrt(sq_radius), center.y());
|
||||
if ( two_cuts ) {
|
||||
mid2 = Point_2(center.x() - CGAL::sqrt(sq_radius), center.y());
|
||||
}
|
||||
}
|
||||
|
||||
// Third, we build the split curves
|
||||
*o++ = (switch_orientation) ?
|
||||
curve_opposite(Curve_2(work_cv.circle(), src, mid1)) :
|
||||
Curve_2(work_cv.circle(), src, mid1);
|
||||
if ( two_cuts ) {
|
||||
if (switch_orientation) {
|
||||
*o++ = curve_opposite(Curve_2(work_cv.circle(), mid1, mid2));
|
||||
*o++ = curve_opposite(Curve_2(work_cv.circle(), mid2, trg));
|
||||
} else {
|
||||
*o++ = Curve_2(work_cv.circle(), mid1, mid2);
|
||||
*o++ = Curve_2(work_cv.circle(), mid2, trg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
*o++ = (switch_orientation) ?
|
||||
curve_opposite(Curve_2(work_cv.circle(), mid1, trg)) :
|
||||
Curve_2(work_cv.circle(), mid1, trg);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure:
|
||||
// There are indeed 2 or 3 split points
|
||||
// CGAL_postcondition(l.size() >= 2 && l.size() <= 3);
|
||||
// The orientations of the split curves are the same as of cv
|
||||
// CGAL_postcondition_code(
|
||||
// if ( switch_orientation ) l.reverse();
|
||||
// Orientation cv_or = cv.circle().orientation();
|
||||
// typename std::list<Curve_2>::iterator lit;
|
||||
// typename std::list<Curve_2>::iterator next_it; );
|
||||
// Check consistency of end points
|
||||
// CGAL_postcondition( l.begin()->source() == cv.source() );
|
||||
// CGAL_postcondition_code( lit = l.end(); lit--; );
|
||||
// CGAL_postcondition( lit->target() == cv.target() );
|
||||
|
||||
// CGAL_postcondition_code(//for all x-monotone parts
|
||||
// for(lit = l.begin();
|
||||
// lit != l.end();
|
||||
// lit++) {
|
||||
// next_it = lit; next_it++; );
|
||||
|
||||
// CGAL_postcondition( lit->circle().orientation() == cv_or );
|
||||
// Consistency of split points
|
||||
// CGAL_postcondition( next_it == l.end() ||
|
||||
// lit->target() == next_it->source() );
|
||||
// Split points are on circle
|
||||
// CGAL_postcondition( cv.circle().has_on_boundary(lit->target()) );
|
||||
// parts are indeed x-monotone
|
||||
// CGAL_postcondition( is_x_monotone(*lit) );
|
||||
// CGAL_postcondition_code( } ); // end of for
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void curve_split(const X_monotone_curve_2& cv,
|
||||
X_monotone_curve_2& c1, X_monotone_curve_2& c2,
|
||||
const Point_2& split_pt) const
|
||||
{
|
||||
CGAL_precondition(is_x_monotone(cv));
|
||||
|
||||
//split curve at split point (x coordinate) into c1 and c2
|
||||
CGAL_precondition(curve_compare_y_at_x(split_pt, cv)==EQUAL);
|
||||
CGAL_precondition(compare_x(curve_source(cv),split_pt)!=EQUAL);
|
||||
CGAL_precondition(compare_x(curve_target(cv),split_pt)!=EQUAL);
|
||||
|
||||
c1=cv;
|
||||
c2=cv;
|
||||
c1.t=split_pt;
|
||||
c2.s=split_pt;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool nearest_intersection_to_right(const X_monotone_curve_2& c1,
|
||||
const X_monotone_curve_2& c2,
|
||||
const Point_2& pt,
|
||||
Point_2& p1,
|
||||
Point_2& p2) const {
|
||||
|
||||
CGAL_precondition(is_x_monotone(c1));
|
||||
CGAL_precondition(is_x_monotone(c2));
|
||||
|
||||
Point_2 rgt,lft;
|
||||
|
||||
//case where the arcs are from the same circle
|
||||
if ( is_same(c1.c.center(),c2.c.center()) &&
|
||||
_compare_value(c1.c.squared_radius(),c2.c.squared_radius())==EQUAL ) {
|
||||
//can intersect only at endpoints
|
||||
Point_2 rightmost1,leftmost1;
|
||||
if (compare_x(c1.s,c1.t)==LARGER) {
|
||||
rightmost1=c1.s;leftmost1=c1.t;
|
||||
}
|
||||
else {
|
||||
rightmost1=c1.t;leftmost1=c1.s;
|
||||
}
|
||||
|
||||
Point_2 rightmost2,leftmost2;
|
||||
if (compare_x(c2.s,c2.t)==LARGER) {
|
||||
rightmost2=c2.s;leftmost2=c2.t;
|
||||
}
|
||||
else {
|
||||
rightmost2=c2.t;leftmost2=c2.s;
|
||||
}
|
||||
|
||||
bool c1_is_on_lower=(compare_x(c1.s,c1.t) * c1.c.orientation() < 0);
|
||||
bool c2_is_on_lower=(compare_x(c2.s,c2.t) * c2.c.orientation() < 0);
|
||||
if (c1_is_on_lower!=c2_is_on_lower) {
|
||||
//an intersection can occure only at end points
|
||||
if (is_same(rightmost1,rightmost2)) {
|
||||
if (compare_x(rightmost1,pt)==LARGER) {
|
||||
p1=p2=rightmost1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (is_same(leftmost1,leftmost2)) {
|
||||
if (compare_x(leftmost1,pt)==LARGER) {
|
||||
p1=p2=leftmost1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//now we are dealing with two x-curves on the same side of circle
|
||||
if ( (compare_x(rightmost1,pt) != LARGER) ||
|
||||
(compare_x(rightmost2,pt) != LARGER) )
|
||||
return false; //the intersection can't be right of pt
|
||||
|
||||
//now, if there is an intersection it has a point right of pt
|
||||
if ( compare_x(rightmost1,leftmost2)==SMALLER ||
|
||||
compare_x(rightmost2,leftmost1)==SMALLER ) { //no intersection
|
||||
return false;
|
||||
}
|
||||
|
||||
//now we know there is an intersection, find p1,p2
|
||||
//p2 is the leftmost of the 2 rightmost points
|
||||
if (compare_x(rightmost1,rightmost2)==SMALLER) {
|
||||
p2=rightmost1;
|
||||
}
|
||||
else {
|
||||
p2=rightmost2;
|
||||
}
|
||||
|
||||
//p1 is the rightmost of the 2 leftmost (if it is right of pt)
|
||||
if (compare_x(leftmost1,leftmost2)==LARGER) {
|
||||
p1=leftmost1;
|
||||
}
|
||||
else {
|
||||
p1=leftmost2;
|
||||
}
|
||||
if (compare_x(p1,pt)==SMALLER) {
|
||||
//this assumes pt is on the curve, maybe we
|
||||
//need to have p1=point_on_curve (pt.x())...?
|
||||
p1=pt;
|
||||
}
|
||||
|
||||
return true;
|
||||
} //end of case where arcs come fromsame circle
|
||||
|
||||
|
||||
|
||||
Point_2 first;
|
||||
Point_2 last;
|
||||
|
||||
circle_intersection(c1.c,c2.c,&first,&last);
|
||||
|
||||
if (compare_x(first,last)==SMALLER) {
|
||||
rgt=first;
|
||||
lft=last;
|
||||
}
|
||||
else {
|
||||
rgt=last;
|
||||
lft=first;
|
||||
}
|
||||
|
||||
if (compare_x(rgt,pt)==LARGER) {
|
||||
if (point_in_x_range(c1, rgt) &&
|
||||
(curve_compare_y_at_x(rgt, c1) == EQUAL) &&
|
||||
point_in_x_range(c2, rgt) &&
|
||||
(curve_compare_y_at_x(rgt, c2) == EQUAL) )
|
||||
{
|
||||
p1=p2=rgt;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (compare_x(lft,pt)==LARGER) {
|
||||
if (point_in_x_range(c1, lft) &&
|
||||
(curve_compare_y_at_x(lft, c1) == EQUAL) &&
|
||||
point_in_x_range(c2, lft) &&
|
||||
(curve_compare_y_at_x(lft, c2) == EQUAL) )
|
||||
{
|
||||
p1=p2=lft;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//can be done differently (the check first)
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
Point_2 point_reflect_in_x_and_y (const Point_2& pt) const
|
||||
{
|
||||
// use hx(), hy(), hw() in order to support both Homogeneous and Cartesian
|
||||
Point_2 reflected_pt( -pt.hx(), -pt.hy(), pt.hw());
|
||||
return reflected_pt;
|
||||
}
|
||||
|
||||
|
||||
X_monotone_curve_2
|
||||
curve_reflect_in_x_and_y (const X_monotone_curve_2& cv) const
|
||||
{
|
||||
Circle circ( point_reflect_in_x_and_y (cv.circle().center()),
|
||||
cv.circle().squared_radius(),
|
||||
//reflection in two axes means no change in orientation
|
||||
cv.circle().orientation());
|
||||
// CGAL::opposite( cv.circle().orientation()));
|
||||
X_monotone_curve_2 reflected_cv( circ,
|
||||
point_reflect_in_x_and_y (cv.source()),
|
||||
point_reflect_in_x_and_y (cv.target()));
|
||||
return reflected_cv;
|
||||
}
|
||||
|
||||
|
||||
//currently we assume that no two circles overlap (might change in future)
|
||||
bool curves_overlap(const X_monotone_curve_2& c1,
|
||||
const X_monotone_curve_2& c2) const
|
||||
{
|
||||
CGAL_precondition(is_x_monotone(c1));
|
||||
CGAL_precondition(is_x_monotone(c2));
|
||||
|
||||
//case where the arcs are from the same circle (otherwise return false)
|
||||
if ( is_same(c1.c.center(),c2.c.center()) &&
|
||||
_compare_value(c1.c.squared_radius(),c2.c.squared_radius())==EQUAL ) {
|
||||
|
||||
bool c1_is_on_lower=(compare_x(c1.s,c1.t) * c1.c.orientation() < 0);
|
||||
bool c2_is_on_lower=(compare_x(c2.s,c2.t) * c2.c.orientation() < 0);
|
||||
if (c1_is_on_lower!=c2_is_on_lower)
|
||||
return false;
|
||||
|
||||
//check overlaps of x-monotone curves
|
||||
Point_2 leftmost1,rightmost1;
|
||||
if (compare_x(c1.s,c1.t)==SMALLER) {
|
||||
leftmost1=c1.s; rightmost1=c1.t;
|
||||
}
|
||||
else {
|
||||
leftmost1=c1.t; rightmost1=c1.s;
|
||||
}
|
||||
|
||||
Point_2 leftmost2,rightmost2;
|
||||
if (compare_x(c2.s,c2.t)==SMALLER) {
|
||||
leftmost2=c2.s; rightmost2=c2.t;
|
||||
}
|
||||
else {
|
||||
leftmost2=c2.t; rightmost2=c2.s;
|
||||
}
|
||||
|
||||
if ( compare_x(rightmost1,leftmost2)!=LARGER ||
|
||||
compare_x(rightmost2,leftmost1)!=LARGER ) { //no overlap
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false; //circles don't overlap
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// PRIVATE FUNCS
|
||||
private:
|
||||
Comparison_result _compare_value (const NT& a, const NT& b) const {
|
||||
return CGAL_NTS compare(a,b);
|
||||
}
|
||||
|
||||
|
||||
//calculates the point on the X_monotone_curve_2 with the same x coordinate
|
||||
// as p
|
||||
Point_2 curve_calc_point(const X_monotone_curve_2& cv,
|
||||
const Point_2& p) const
|
||||
{
|
||||
//simple cases
|
||||
if (compare_x(cv.s,p)==EQUAL)
|
||||
return cv.s;
|
||||
if (compare_x(cv.t,p)==EQUAL)
|
||||
return cv.t;
|
||||
|
||||
NT px(p.x());
|
||||
NT sqr = (CGAL::sqrt(cv.c.squared_radius() -
|
||||
(px-cv.c.center().x())*(px-cv.c.center().x()) ));
|
||||
|
||||
Point_2 lst1_first(px,cv.c.center().y() + sqr);
|
||||
Point_2 lst1_last(px,cv.c.center().y() - sqr);
|
||||
|
||||
|
||||
Point_2 p1;
|
||||
if (compare_x(cv.s,cv.t) * cv.c.orientation() < 0) { //lower part of circle
|
||||
if (_compare_value(lst1_first.y(),lst1_last.y()) == LARGER)
|
||||
p1=lst1_last;
|
||||
else
|
||||
p1=lst1_first;
|
||||
}
|
||||
else { //upper part of circle
|
||||
if (_compare_value(lst1_first.y(),lst1_last.y()) == LARGER)
|
||||
p1=lst1_first;
|
||||
else
|
||||
p1=lst1_last;
|
||||
}
|
||||
|
||||
return p1;
|
||||
}
|
||||
|
||||
|
||||
Vector derivative_vec(const X_monotone_curve_2& cv, const Point_2& p) const
|
||||
{
|
||||
if (cv.c.orientation()==COUNTERCLOCKWISE) { //ccw - (-y,x)
|
||||
return Vector((cv.c.center().y()-p.y()), (p.x()-cv.c.center().x()));
|
||||
}
|
||||
else
|
||||
return Vector((p.y()-cv.c.center().y()), (cv.c.center().x())-p.x());
|
||||
}
|
||||
|
||||
bool is_same(const Point_2 &p1, const Point_2 &p2) const
|
||||
{
|
||||
return (compare_xy(p1, p2) == EQUAL);
|
||||
}
|
||||
|
||||
|
||||
bool circle_intersection(const Circle& ca, const Circle& cb,
|
||||
Point_2* p1, Point_2* p2) const {
|
||||
//function checks if the circles ca,cb intersect,
|
||||
//if they don't - returns false
|
||||
//if they do p1,p2 will hold the intersection points
|
||||
|
||||
NT l2=squared_distance(ca.center(),cb.center());
|
||||
NT l=CGAL::sqrt(l2);
|
||||
|
||||
NT ra=CGAL::sqrt(ca.squared_radius());
|
||||
NT rb=CGAL::sqrt(cb.squared_radius());
|
||||
|
||||
if ( (_compare_value(l, ra+rb) == LARGER) ||
|
||||
(_compare_value(ra, l+rb) == LARGER) ||
|
||||
(_compare_value(rb, l+ra) == LARGER) )
|
||||
return false;
|
||||
|
||||
//x is the distance on the segment-of-centers from ca.center()
|
||||
//y is the distance from the segment-of-centers to the intersection point
|
||||
NT x = (ca.squared_radius()-cb.squared_radius()+l2) / NT(2*l);
|
||||
NT y = CGAL::sqrt(ca.squared_radius() - x*x);
|
||||
|
||||
//debug
|
||||
Vector v_ab=cb.center()-ca.center();
|
||||
//Vector_2<Cartesian<NT> > v_ab=cb.center()-ca.center();
|
||||
|
||||
v_ab = v_ab/(CGAL::sqrt(v_ab.x()*v_ab.x()+v_ab.y()*v_ab.y())); //normalize
|
||||
|
||||
Vector v_ab_perp(-v_ab.y(),v_ab.x());
|
||||
|
||||
*p1 = ca.center() + x*v_ab + y*v_ab_perp;
|
||||
*p2 = ca.center() + x*v_ab - y*v_ab_perp;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/tags.h>
|
||||
#include "CGAL/Arrangement_2/Conic_arc_2.h"
|
||||
#include <CGAL/Arrangement_2/Conic_arc_2.h>
|
||||
#include <list>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
|
@ -451,16 +451,29 @@ class Arr_conic_traits_2
|
|||
return (EQUAL);
|
||||
|
||||
// Get the points on the arc with the same x co-ordinate as p.
|
||||
int n;
|
||||
int n;
|
||||
Point_2 ps[2];
|
||||
|
||||
n = curve.get_points_at_x (p, ps);
|
||||
if (compare_x(p, curve.source()) == EQUAL)
|
||||
{
|
||||
ps[0] = curve.source();
|
||||
n = 1;
|
||||
}
|
||||
else if (compare_x(p, curve.target()) == EQUAL)
|
||||
{
|
||||
ps[0] = curve.target();
|
||||
n = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = curve.get_points_at_x (p, ps);
|
||||
}
|
||||
|
||||
// Make sure there is exactly one point.
|
||||
CGAL_assertion(n == 1);
|
||||
|
||||
// Compare p with the a point of the curve with the same x co-ordinate.
|
||||
return (_compare_y(ps[0], p));
|
||||
return (_compare_y(p, ps[0]));
|
||||
}
|
||||
|
||||
// Cehck whether the two points are identical.
|
||||
|
|
@ -572,12 +585,17 @@ class Arr_conic_traits_2
|
|||
OutputIterator o) const
|
||||
{
|
||||
// Find the points of vertical tangency and act accordingly.
|
||||
int n;
|
||||
int n;
|
||||
Point_2 ps[2];
|
||||
|
||||
n = curve.vertical_tangency_points (ps);
|
||||
|
||||
CGAL_assertion (n > 0);
|
||||
if (n == 0)
|
||||
{
|
||||
// In case the given curve is already x-monotone:
|
||||
*o++ = curve;
|
||||
return (o);
|
||||
}
|
||||
|
||||
// Split the conic arc into x-monotone sub-curves.
|
||||
if (curve.is_full_conic())
|
||||
|
|
@ -652,7 +670,7 @@ class Arr_conic_traits_2
|
|||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
return (o);
|
||||
}
|
||||
|
||||
// Split the given curve into two sub-curves at the given point.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -56,12 +56,12 @@ enum
|
|||
//
|
||||
|
||||
static int _conics_count = 0;
|
||||
template <class _NT> class Arr_conic_traits_2;
|
||||
template <class K> class Arr_conic_traits_2;
|
||||
|
||||
template <class Kernel_>
|
||||
class Conic_arc_2
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
typedef Conic_arc_2<Kernel_> Self;
|
||||
|
||||
public:
|
||||
|
|
@ -78,7 +78,7 @@ public:
|
|||
|
||||
typedef Point_2_ex<Kernel> My_point_2;
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -157,7 +157,7 @@ public:
|
|||
return (REFLECTION_FACTOR * _conics_count);
|
||||
}
|
||||
|
||||
// Private constructor.
|
||||
// Protected constructor.
|
||||
Conic_arc_2 (const Self & arc,
|
||||
const My_point_2& source, const My_point_2 & target,
|
||||
const bool& is_full) :
|
||||
|
|
@ -638,14 +638,12 @@ public:
|
|||
return ((_info & FULL_CONIC) != 0);
|
||||
}
|
||||
|
||||
// shai begin
|
||||
bool is_circle() const
|
||||
// Check whether the arc is a circular arc.
|
||||
bool is_circular() const
|
||||
{
|
||||
// WARNING: This is not true
|
||||
return _conic.is_ellipse();
|
||||
return ((_info & IS_CIRCLE) != 0);
|
||||
}
|
||||
// shai end
|
||||
|
||||
|
||||
// Check whether the curve is a sgement.
|
||||
bool is_segment () const
|
||||
{
|
||||
|
|
@ -1533,7 +1531,7 @@ public:
|
|||
return (SMALLER);
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
// Set the properties of a conic arc (for the usage of the constructors).
|
||||
// The source and the target are assumed be on the conic boundary.
|
||||
|
|
@ -2769,17 +2767,26 @@ public:
|
|||
My_point_2* ipts) const
|
||||
{
|
||||
// Calculate the minimal number of intersection points.
|
||||
int x_total = 0, y_total = 0;
|
||||
int min_points;
|
||||
const bool all_approx = (n_xs == n_approx_xs) && (n_ys == n_approx_ys);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n_xs; i++)
|
||||
x_total += x_mults[i];
|
||||
if (all_approx)
|
||||
{
|
||||
min_points = (n_xs < n_ys) ? n_xs : n_ys;
|
||||
}
|
||||
else
|
||||
{
|
||||
int x_total = 0, y_total = 0;
|
||||
|
||||
for (j = 0; j < n_ys; j++)
|
||||
y_total += y_mults[j];
|
||||
for (i = 0; i < n_xs; i++)
|
||||
x_total += x_mults[i];
|
||||
|
||||
min_points = (x_total < y_total) ? x_total : y_total;
|
||||
for (j = 0; j < n_ys; j++)
|
||||
y_total += y_mults[j];
|
||||
|
||||
min_points = (x_total < y_total) ? x_total : y_total;
|
||||
}
|
||||
|
||||
// Go over all x coordinates.
|
||||
const APNT r1 = TO_APNT(_conic.r());
|
||||
|
|
@ -2843,8 +2850,10 @@ public:
|
|||
k = 0;
|
||||
while (k < n_xs*n_ys && n_ipts < 4)
|
||||
{
|
||||
if (n_ipts >= min_points &&
|
||||
eps_compare<APNT>(results[k]*results[k], 0) != EQUAL)
|
||||
if (results[k] > 1 ||
|
||||
(all_approx && n_ipts == min_points) ||
|
||||
(n_ipts >= min_points &&
|
||||
eps_compare<APNT>(results[k]*results[k], 0) != EQUAL))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -2864,7 +2873,6 @@ public:
|
|||
return (n_ipts);
|
||||
}
|
||||
|
||||
// shai begin
|
||||
public:
|
||||
|
||||
// Get a segment if the arc is indeed one.
|
||||
|
|
@ -2904,8 +2912,6 @@ public:
|
|||
|
||||
return (Circle_2 (Point_2(x0, y0), r2));
|
||||
}
|
||||
|
||||
// shai end
|
||||
};
|
||||
|
||||
#ifndef NO_OSTREAM_INSERT_CONIC_ARC_2
|
||||
|
|
|
|||
|
|
@ -1,133 +0,0 @@
|
|||
// ======================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
// This software and related documentation is part of an INTERNAL release
|
||||
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
||||
// intended for general use.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// release :
|
||||
// release_date : 1999, October 13
|
||||
//
|
||||
// file : include/CGAL/IO/Arr_circle_traits_Window_stream.h
|
||||
// package : arr (1.03)
|
||||
// author(s) : Iddo Hanniel
|
||||
// coordinator : Tel-Aviv University (Dan Halperin <halperin@math.tau.ac.il>)
|
||||
//
|
||||
// ======================================================================
|
||||
#ifdef CGAL_ARR_CIRCLES_REAL_TRAITS_H
|
||||
#ifndef CGAL_ARR_CIRCLES_TRAITS_WINDOW_STREAM_H
|
||||
#define CGAL_ARR_CIRCLES_TRAITS_WINDOW_STREAM_H
|
||||
|
||||
#include <CGAL/IO/Window_stream.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef ARR_IDDO_DEBUG
|
||||
//a simple version of the windowstream operator (sufficient for X_curve)
|
||||
template <class NT>
|
||||
Window_stream& operator<<(Window_stream& os,
|
||||
//const typename
|
||||
//Arr_circles_real_traits<NT>::Curve &cv)
|
||||
const Circ_Curve<NT>& cv)
|
||||
{
|
||||
//This is not good enough - it assumes s and t have different x coord,
|
||||
//but for x-monotone arcs it is sufficient (and that's all I need).
|
||||
//runs faster than above
|
||||
double px= CGAL::to_double((cv.source().x()+cv.target().x())/2);
|
||||
double R2= CGAL::to_double(cv.circle().squared_radius());
|
||||
double sqr = CGAL::sqrt(R2 -
|
||||
(CGAL::to_double(px-cv.circle().center().x())*
|
||||
CGAL::to_double(px-cv.circle().center().x())));
|
||||
|
||||
double py;
|
||||
if ((cv.source().x()-cv.target().x()) * cv.circle().orientation() < 0)
|
||||
//underpart
|
||||
py= CGAL::to_double(cv.circle().center().y())-sqr;
|
||||
else
|
||||
py= CGAL::to_double(cv.circle().center().y())+sqr;
|
||||
|
||||
|
||||
os.draw_arc(leda_point(CGAL::to_double(cv.source().x()),
|
||||
CGAL::to_double(cv.source().y())),
|
||||
leda_point(px,py),
|
||||
leda_point(CGAL::to_double(cv.target().x()),
|
||||
CGAL::to_double(cv.target().y())));
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
#else //ARR_IDDO_DEBUG defined - use the complicated version for general Curves
|
||||
template <class NT>
|
||||
Window_stream& operator<<(Window_stream& os,
|
||||
//const Arr_circles_real_traits<NT>::Curve &cv)
|
||||
const Circ_Curve<NT>& cv)
|
||||
{
|
||||
double px,py; //middle point coordinates
|
||||
double R2= CGAL::to_double(cv.circle().squared_radius());
|
||||
|
||||
//checking for X-monotone case
|
||||
//the folowing is equivelent to "if (curve is x-monotone)"
|
||||
if (cv.is_x_monotone()) {
|
||||
px= CGAL::to_double((cv.source().x()+cv.target().x()))/2;
|
||||
double sqr = CGAL::sqrt(R2 -
|
||||
(CGAL::to_double(px-cv.circle().center().x())*
|
||||
CGAL::to_double(px-cv.circle().center().x())));
|
||||
if (CGAL::sign(cv.source().x()-cv.target().x()) *
|
||||
cv.circle().orientation() < 0) //under part
|
||||
py= CGAL::to_double(cv.circle().center().y())-sqr;
|
||||
else
|
||||
py= CGAL::to_double(cv.circle().center().y())+sqr;
|
||||
}
|
||||
else { //if not x-monotone the above is not good enough
|
||||
if (cv.source()==cv.target()) { //closed circle
|
||||
return os << cv.circle() ;
|
||||
}
|
||||
|
||||
py=CGAL::to_double(cv.circle().center().y());
|
||||
if (CGAL::compare_y(cv.source(),cv.circle().center()) *
|
||||
cv.circle().orientation() > 0) {
|
||||
//either s is under center and orient is cw or
|
||||
//s is above and orient is ccw
|
||||
px=CGAL::to_double(cv.circle().center().x())-CGAL::sqrt(R2);
|
||||
}
|
||||
else
|
||||
if (CGAL::compare_y(cv.source(), cv.circle().center()) *
|
||||
cv.circle().orientation() < 0) {
|
||||
//either s is under center and orient is ccw or
|
||||
//s is above and orient is cw
|
||||
px=CGAL::to_double(cv.circle().center().x())+CGAL::sqrt(R2);
|
||||
}
|
||||
else
|
||||
{ //s is one of the endpoints of the circle choos other endpoint
|
||||
if (CGAL::compare_x(cv.source(),cv.circle().center())==SMALLER)
|
||||
px=CGAL::to_double(cv.circle().center().x())+CGAL::sqrt(R2);
|
||||
else
|
||||
px=CGAL::to_double(cv.circle().center().x())-CGAL::sqrt(R2);
|
||||
}
|
||||
}
|
||||
|
||||
os.draw_arc(leda_point(CGAL::to_double(cv.source().x()),
|
||||
CGAL::to_double(cv.source().y())),
|
||||
leda_point(px,py),
|
||||
leda_point(CGAL::to_double(cv.target().x()),
|
||||
CGAL::to_double(cv.target().y())));
|
||||
|
||||
|
||||
return os;
|
||||
}
|
||||
#endif //ARR_IDDO_DEBUG
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //CGAL_ARR_CIRCLES_TRAITS_WINDOW_STREAM_H
|
||||
#endif //CGAL_ARR_CIRCLES_REAL_TRAITS_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -18,8 +18,8 @@
|
|||
// coordinator : Tel-Aviv University (Dan Halperin <halperin@math.tau.ac.il>)
|
||||
//
|
||||
// ======================================================================
|
||||
#ifndef CONIC_ARC_2_WINDOW_STREAM_H
|
||||
#define CONIC_ARC_2_WINDOW_STREAM_H
|
||||
#ifndef CGAL_CONIC_ARC_2_WINDOW_STREAM_H
|
||||
#define CGAL_CONIC_ARC_2_WINDOW_STREAM_H
|
||||
|
||||
#include <CGAL/IO/Window_stream.h>
|
||||
#include <CGAL/Arrangement_2/Conic_arc_2.h>
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
// ======================================================================
|
||||
//
|
||||
// Copyright (c) 2001 The CGAL Consortium
|
||||
//
|
||||
// This software and related documentation is part of an INTERNAL release
|
||||
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
||||
// intended for general use.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// release : $CGAL_Revision: CGAL-2.4-I-5 $
|
||||
// release_date : $CGAL_Date: 2001/08/31 $
|
||||
//
|
||||
// file : include/CGAL/IO/Segment_circle_Window_stream.h
|
||||
// package : Arrangement (2.19)
|
||||
// maintainer : Eyal Flato <flato@math.tau.ac.il>
|
||||
// author(s) : Ron Wein <wein@post.tau.ac.il>
|
||||
// coordinator : Tel-Aviv University (Dan Halperin <halperin@math.tau.ac.il>)
|
||||
//
|
||||
// ======================================================================
|
||||
#ifndef SEGMENT_CIRCLE_WINDOW_STREAM_H
|
||||
#define SEGMENT_CIRCLE_WINDOW_STREAM_H
|
||||
|
||||
#include <CGAL/IO/Window_stream.h>
|
||||
#include <CGAL/Segment_circle_2.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class NT>
|
||||
Window_stream& operator<<(Window_stream& os,
|
||||
const Segment_circle_2<NT>& cv)
|
||||
{
|
||||
double sx = CGAL::to_double(cv.source().x()),
|
||||
sy = CGAL::to_double(cv.source().y()),
|
||||
tx = CGAL::to_double(cv.target().x()),
|
||||
ty = CGAL::to_double(cv.target().y());
|
||||
|
||||
if (cv.is_segment())
|
||||
{
|
||||
os << leda_segment(sx, sy, tx, ty);
|
||||
}
|
||||
// The arc is circular
|
||||
else
|
||||
{
|
||||
// We need a middle point on the curve for the leda draw_arc
|
||||
// function which draws a circular arc given three points on it.
|
||||
|
||||
double px,py; // middle point coordinates
|
||||
if (cv.is_x_monotone())
|
||||
{
|
||||
// an x-monotone circular arc
|
||||
// the middle point is the one with average x value of endpoints.
|
||||
typename Segment_circle_2<NT>::Point ps[2];
|
||||
NT middle_x = (sx+tx)/2;
|
||||
cv.get_points_at_x(middle_x, ps);
|
||||
px = CGAL::to_double(middle_x);
|
||||
py = CGAL::to_double(ps[0].y());
|
||||
}
|
||||
else
|
||||
{
|
||||
// a non x-monotone circular arc
|
||||
// we use the rightmost or leftmost point as a middle point
|
||||
typename Segment_circle_2<NT>::Point ps[2];
|
||||
// there might be two tangency points but we care for one only
|
||||
cv.horizontal_tangency_points (ps);
|
||||
px = CGAL::to_double(ps[0].x());
|
||||
py = CGAL::to_double(ps[0].y());
|
||||
}
|
||||
|
||||
os.draw_arc(leda_point(sx,sy), leda_point(px,py), leda_point(tx,ty));
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -1,995 +0,0 @@
|
|||
// ======================================================================
|
||||
//
|
||||
// Copyright (c) 2001 The CGAL Consortium
|
||||
//
|
||||
// This software and related documentation is part of an INTERNAL release
|
||||
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
||||
// intended for general use.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// release : $CGAL_Revision: CGAL-2.4-I-5 $
|
||||
// release_date : $CGAL_Date: 2001/08/31 $
|
||||
//
|
||||
// file : include/CGAL/Segment_circle_2.h
|
||||
// package : Arrangement (2.19)
|
||||
// maintainer : Eyal Flato <flato@math.tau.ac.il>
|
||||
// author(s) : Ron Wein <wein@post.tau.ac.il>
|
||||
// coordinator : Tel-Aviv University (Dan Halperin <halperin@math.tau.ac.il>)
|
||||
//
|
||||
// ======================================================================
|
||||
#ifndef CGAL_SEGMENT_CIRCLE_2_H
|
||||
#define CGAL_SEGMENT_CIRCLE_2_H
|
||||
|
||||
// Segment_circle_2.h
|
||||
//
|
||||
// A modified version that specializes in segments and circular arcs.
|
||||
// This class does NOT support general conic arcs
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Conic_2.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Solve a quadratic equation.
|
||||
// The function returns the number of distinct solutions.
|
||||
// The roots area must be at least of size 2.
|
||||
//
|
||||
template <class NT>
|
||||
int _solve_quadratic_eq (const NT& a, const NT& b, const NT& c, NT* roots)
|
||||
{
|
||||
static const NT _zero = NT(0);
|
||||
static const NT _two = NT(2);
|
||||
static const NT _four = NT(4);
|
||||
|
||||
|
||||
if (a == _zero)
|
||||
{
|
||||
// We have a linear equation.
|
||||
if (b != _zero)
|
||||
{
|
||||
roots[0] = -c / b;
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
const NT disc = b*b - _four*a*c;
|
||||
|
||||
if (disc < _zero)
|
||||
{
|
||||
// Negative discriminant - no real solution.
|
||||
return (0);
|
||||
}
|
||||
else if (disc == _zero)
|
||||
{
|
||||
// Zero discriminant - one real solution (with multiplicty 2).
|
||||
roots[0] = roots[1] = -b / (_two * a);
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Positive discriminant - two distinct real solutions.
|
||||
const NT sqrt_disc = CGAL::sqrt(disc);
|
||||
|
||||
roots[0] = (sqrt_disc - b) / (_two * a);
|
||||
roots[1] = -(sqrt_disc + b) / (_two * a);
|
||||
return (2);
|
||||
}
|
||||
}
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Representation of a conic arc which is either a segment (a curve of
|
||||
// degree 1), or a circular arc (of degree 2).
|
||||
//
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class NT>
|
||||
class Segment_circle_2
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
typedef Cartesian<NT> R;
|
||||
typedef Point_2<R> Point;
|
||||
typedef Conic_2<R> Conic;
|
||||
typedef Circle_2<R> Circle;
|
||||
typedef Segment_2<R> Segment;
|
||||
|
||||
private:
|
||||
|
||||
Conic _conic; // The conic that contains the arc.
|
||||
int _deg; // The degree of the conic (either 1 or 2).
|
||||
Point _source; // The source of the arc.
|
||||
Point _target; // The target of the arc.
|
||||
bool _is_full; // Indicated whether the arc is a full conic.
|
||||
|
||||
public:
|
||||
|
||||
// Default constructor.
|
||||
Segment_circle_2 () :
|
||||
_deg(0),
|
||||
_is_full(false)
|
||||
{}
|
||||
|
||||
// Copy constructor.
|
||||
Segment_circle_2 (const Segment_circle_2<NT>& arc) :
|
||||
_conic(arc._conic),
|
||||
_deg(arc._deg),
|
||||
_source(arc._source),
|
||||
_target(arc._target),
|
||||
_is_full(arc._is_full)
|
||||
{}
|
||||
|
||||
// Constuct a segment arc from a segment.
|
||||
Segment_circle_2 (const Segment& segment) :
|
||||
_deg(1),
|
||||
_source(segment.source()),
|
||||
_target(segment.target()),
|
||||
_is_full(false)
|
||||
{
|
||||
static const NT _zero = 0;
|
||||
static const NT _one = 1;
|
||||
|
||||
// The supporting conic is r=s=t=0, and u*x + v*y + w = 0 should hold
|
||||
// for both the source (x1,y1) and the target (x2, y2).
|
||||
if (_source.x() == _target.x())
|
||||
{
|
||||
// The supporting conic is a vertical line, of the form x = CONST.
|
||||
_conic.set (_zero, _zero, _zero, // r = s = t = 0
|
||||
_one, // u = 1
|
||||
_zero, // v = 0
|
||||
-_source.x()); // w = -CONST
|
||||
}
|
||||
else
|
||||
{
|
||||
// The supporting line is y = A*x + B, where:
|
||||
//
|
||||
// y2 - y1 x2*y1 - x1*y2
|
||||
// A = --------- B = ---------------
|
||||
// x2 - x1 x2 - x1
|
||||
//
|
||||
const NT A = (_target.y() - _source.y()) /
|
||||
(_target.x() - _source.x());
|
||||
const NT B = (_target.x()*_source.y() - _source.x()*_target.y()) /
|
||||
(_target.x() - _source.x());
|
||||
|
||||
// Now we can set:
|
||||
_conic.set (_zero, _zero, _zero, // r = s = t = 0
|
||||
A, // u = A
|
||||
-_one, // v = -1
|
||||
B); // w = B
|
||||
}
|
||||
}
|
||||
|
||||
// Construct a circular arc from a circle and two points on that circle
|
||||
// (the orientation of the arc preserves the orientation of the circle).
|
||||
// The source and the target must be on the conic boundary and must
|
||||
// not be the same.
|
||||
Segment_circle_2 (const Circle& circle,
|
||||
const Point& source, const Point& target) :
|
||||
_deg(2),
|
||||
_source(source),
|
||||
_target(target),
|
||||
_is_full(false)
|
||||
{
|
||||
// Make sure the circle contains the two endpoints on its boundary.
|
||||
CGAL_precondition(circle.has_on_boundary(_source));
|
||||
CGAL_precondition(circle.has_on_boundary(_target));
|
||||
|
||||
// Make sure that the source and the taget are not the same.
|
||||
CGAL_precondition(_source != _target);
|
||||
|
||||
// Produce the correponding conic: if the circle centre is (x0,y0)
|
||||
// and it radius is r, that its equation is:
|
||||
// x^2 + y^2 - 2*x0*x - 2*y0*y + (x0^2 + y0^2 - r^2) = 0
|
||||
// Since this equation describes a curve with a negative orientation,
|
||||
// we multiply it by -1 if necessary to preserve the original orientation
|
||||
// of the input circle.
|
||||
static const NT _zero = 0;
|
||||
static const NT _one = 1;
|
||||
static const NT _minus_one = -1;
|
||||
static const NT _two = 2;
|
||||
static const NT _minus_two = -2;
|
||||
const NT x0 = circle.center().x();
|
||||
const NT y0 = circle.center().y();
|
||||
const NT r_squared = circle.squared_radius();
|
||||
|
||||
if (circle.orientation() == CGAL::COUNTERCLOCKWISE)
|
||||
{
|
||||
_conic.set (_minus_one, _minus_one, // r = s = -1
|
||||
_zero, // t = 0
|
||||
_two*x0,
|
||||
_two*y0,
|
||||
r_squared - x0*x0 - y0*y0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_conic.set (_one, _one, // r = s = 1
|
||||
_zero, // t = 0
|
||||
_minus_two*x0,
|
||||
_minus_two*y0,
|
||||
x0*x0 + y0*y0 - r_squared);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct an arc which is basically a full circle
|
||||
// (the orientation of the arc preserves the orientation of the circle).
|
||||
Segment_circle_2 (const Circle& circle) :
|
||||
_deg(2),
|
||||
_is_full(true)
|
||||
{
|
||||
// Produce the correponding conic: if the circle centre is (x0,y0)
|
||||
// and it radius is r, that its equation is:
|
||||
// x^2 + y^2 - 2*x0*x - 2*y0*y + (x0^2 + y0^2 - r^2) = 0
|
||||
// Since this equation describes a curve with a negative orientation,
|
||||
// we multiply it by -1 if necessary to preserve the original orientation
|
||||
// of the input circle.
|
||||
static const NT _zero = 0;
|
||||
static const NT _one = 1;
|
||||
static const NT _minus_one = -1;
|
||||
static const NT _two = 2;
|
||||
static const NT _minus_two = -2;
|
||||
const NT x0 = circle.center().x();
|
||||
const NT y0 = circle.center().y();
|
||||
const NT r_squared = circle.squared_radius();
|
||||
|
||||
if (circle.orientation() == CGAL::COUNTERCLOCKWISE)
|
||||
{
|
||||
_conic.set (_minus_one, _minus_one, // r = s = -1
|
||||
_zero, // t = 0
|
||||
_two*x0,
|
||||
_two*y0,
|
||||
r_squared - x0*x0 - y0*y0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_conic.set (_one, _one, // r = s = 1
|
||||
_zero, // t = 0
|
||||
_minus_two*x0,
|
||||
_minus_two*y0,
|
||||
x0*x0 + y0*y0 - r_squared);
|
||||
}
|
||||
|
||||
// Set a fictitious source and destination.
|
||||
_source = Point(x0 + CGAL::sqrt(r_squared), y0);
|
||||
_target = _source;
|
||||
}
|
||||
|
||||
// Construct a conic arc.
|
||||
// The conic must either be a circle or a line.
|
||||
// The source and the target must be on the conic boundary and must
|
||||
// not be the same.
|
||||
Segment_circle_2 (const Conic& conic,
|
||||
const Point& source, const Point& target) :
|
||||
_conic(conic),
|
||||
_source(source),
|
||||
_target(target),
|
||||
_is_full(false)
|
||||
{
|
||||
// Make sure the conic contains the two endpoints on its boundary.
|
||||
CGAL_precondition(_conic.has_on_boundary(_source));
|
||||
CGAL_precondition(_conic.has_on_boundary(_target));
|
||||
|
||||
// Make sure that the source and the taget are not the same.
|
||||
CGAL_precondition(_source != _target);
|
||||
|
||||
// Check whether we have a segment.
|
||||
static const NT _zero = 0;
|
||||
|
||||
if (conic.r() == _zero && conic.s() == _zero && conic.t() == _zero &&
|
||||
(conic.u() != _zero || conic.v() != _zero))
|
||||
{
|
||||
_deg = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the conic is of degree 2, it must be a circle.
|
||||
CGAL_precondition(_conic.is_ellipse());
|
||||
CGAL_precondition(_conic.r() != NT(0));
|
||||
CGAL_precondition(_conic.r() == _conic.s());
|
||||
CGAL_precondition(_conic.t() == NT(0));
|
||||
_deg = 2;
|
||||
}
|
||||
|
||||
// Destructor.
|
||||
virtual ~Segment_circle_2 ()
|
||||
{}
|
||||
|
||||
// Get the arc's base conic.
|
||||
const Conic& conic () const
|
||||
{
|
||||
return (_conic);
|
||||
}
|
||||
|
||||
// Get the arc's source.
|
||||
const Point& source () const
|
||||
{
|
||||
return (_source);
|
||||
}
|
||||
|
||||
// Get the arc's target.
|
||||
const Point& target () const
|
||||
{
|
||||
return (_target);
|
||||
}
|
||||
|
||||
// Check whether the curve is a segment.
|
||||
bool is_segment() const
|
||||
{
|
||||
return (_deg == 1);
|
||||
}
|
||||
|
||||
// Check whether the curve is a circle.
|
||||
bool is_circle() const
|
||||
{
|
||||
return (_deg == 2);
|
||||
}
|
||||
|
||||
// Get a segment if the arc is indeed one.
|
||||
Segment segment() const
|
||||
{
|
||||
CGAL_precondition(is_segment());
|
||||
|
||||
return (Segment (_source, _target));
|
||||
}
|
||||
|
||||
// Get a circle if the arc is indeed a circular arc.
|
||||
Circle circle() const
|
||||
{
|
||||
CGAL_precondition(is_circle());
|
||||
|
||||
// Create the appropriate circle.
|
||||
static const NT _zero = 0;
|
||||
static const NT _two = 2;
|
||||
NT x0, y0, r2;
|
||||
|
||||
if (_conic.r() > _zero)
|
||||
{
|
||||
// Positive orientation. The conic has the form:
|
||||
// x^2 + y^2 - (2*x0)*x - (2*y0)*y + (x0^2 + y0^2 - r^2) = 0
|
||||
x0 = -(_conic.u() / _two);
|
||||
y0 = -(_conic.v() / _two);
|
||||
r2 = x0*x0 + y0*y0 - _conic.w();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Negative orientation:
|
||||
// - x^2 - y^2 + (2*x0)*x + (2*y0)*y + (r^2 - x0^2 - y0^2) = 0
|
||||
x0 = _conic.u() / _two;
|
||||
y0 = _conic.v() / _two;
|
||||
r2 = x0*x0 + y0*y0 + _conic.w();
|
||||
}
|
||||
|
||||
return (Circle (Point(x0, y0), r2));
|
||||
}
|
||||
|
||||
// Check whether the arc is a full conic (i.e. a full circle).
|
||||
bool is_full_conic () const
|
||||
{
|
||||
return (_is_full);
|
||||
}
|
||||
|
||||
// Check whether the curve is a vertical segment.
|
||||
bool is_vertical_segment () const
|
||||
{
|
||||
// A vertical segment is contained in the degenerate conic: u*x + w = 0.
|
||||
static const NT _zero = 0;
|
||||
|
||||
return (_deg == 1 && _conic.v() == _zero);
|
||||
}
|
||||
|
||||
// Check whether the curve is a horizontal segment.
|
||||
bool is_horizontal_segment () const
|
||||
{
|
||||
// A vertical segment is contained in the degenerate conic: v*y + w = 0.
|
||||
static const NT _zero = 0;
|
||||
|
||||
return (_deg == 1 && _conic.u() == _zero);
|
||||
}
|
||||
|
||||
// Check whether the given point is on the arc.
|
||||
bool contains_point (const Point& p) const
|
||||
{
|
||||
// Check whether the conic contains the point (x,y).
|
||||
if (! _conic.has_on_boundary(p))
|
||||
return (false);
|
||||
|
||||
// If the point is on the conic, make sure it is between the two endpoints.
|
||||
else
|
||||
return (is_full_conic() || _is_between_endpoints(p));
|
||||
}
|
||||
|
||||
// Calculate the vertical tangency points of the arc (ps should be allocated
|
||||
// to the size of 2).
|
||||
// The function returns the number of vertical tangency points.
|
||||
int vertical_tangency_points (Point* vpts) const
|
||||
{
|
||||
// No vertical tangency points for segments:
|
||||
if (_deg < 2)
|
||||
return (0);
|
||||
|
||||
// Calculate the vertical tangency points of the conic.
|
||||
Point ps[2];
|
||||
int n;
|
||||
|
||||
n = _conic_vertical_tangency_points (ps);
|
||||
|
||||
// Return only the points that are contained in the arc interior.
|
||||
int m = 0;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
if (is_full_conic() || _is_strictly_between_endpoints(ps[i]))
|
||||
{
|
||||
vpts[m] = ps[i];
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the number of vertical tangency points found.
|
||||
return (m);
|
||||
}
|
||||
|
||||
// Calculate the horizontal tangency points of the arc (ps should be
|
||||
// allocated to the size of 2).
|
||||
// The function return the number of vertical tangency points.
|
||||
int horizontal_tangency_points (Point* hpts) const
|
||||
{
|
||||
// No vertical tangency points for segments:
|
||||
if (_deg < 2)
|
||||
return (0);
|
||||
|
||||
// Calculate the vertical tangency points of the conic.
|
||||
Point ps[2];
|
||||
int n;
|
||||
|
||||
n = _conic_horizontal_tangency_points (ps);
|
||||
|
||||
// Return only the points that are contained in the arc interior.
|
||||
int m = 0;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
if (is_full_conic() || _is_strictly_between_endpoints(ps[i]))
|
||||
{
|
||||
hpts[m] = ps[i];
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the number of vertical tangency points found.
|
||||
return (m);
|
||||
}
|
||||
|
||||
// Check whether the arc is x-monotone.
|
||||
bool is_x_monotone() const
|
||||
{
|
||||
// Any segment (including vertical segments) is considered x-monotone:
|
||||
if (_deg < 2)
|
||||
return (true);
|
||||
|
||||
// Check the number of vertical tangency points.
|
||||
Point ps[2];
|
||||
|
||||
return (vertical_tangency_points (ps) == 0);
|
||||
}
|
||||
|
||||
// Find all points on the arc with a given x-coordinate: ps should be
|
||||
// allocated to the size of 2.
|
||||
// The function return the number of points found.
|
||||
int get_points_at_x (const NT& x,
|
||||
Point *ps) const
|
||||
{
|
||||
// Make sure the conic is not a vertical segment.
|
||||
CGAL_precondition(!is_vertical_segment());
|
||||
|
||||
// Get the y co-ordinates of the points on the conic.
|
||||
NT ys[2];
|
||||
int n;
|
||||
|
||||
n = _conic_get_y_coordinates (x, ys);
|
||||
|
||||
// Find all the points that are contained in the arc.
|
||||
int m = 0;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
ps[m] = Point (x, ys[i]);
|
||||
|
||||
if (is_full_conic() || _is_between_endpoints(ps[m]))
|
||||
m++;
|
||||
}
|
||||
|
||||
// Return the number of points on the arc.
|
||||
return (m);
|
||||
}
|
||||
|
||||
// Find all points on the arc with a given y-coordinate: ps should be
|
||||
// allocated to the size of 2.
|
||||
// The function return the number of points found.
|
||||
int get_points_at_y (const NT& y,
|
||||
Point *ps) const
|
||||
{
|
||||
// Make sure the conic is not a horizontal segment.
|
||||
CGAL_precondition(!is_horizontal_segment());
|
||||
|
||||
// Get the x co-ordinates of the points on the conic.
|
||||
NT xs[2];
|
||||
int n;
|
||||
|
||||
n = _conic_get_x_coordinates (y, xs);
|
||||
|
||||
// Find all the points that are contained in the arc.
|
||||
int m = 0;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
ps[m] = Point (xs[i], y);
|
||||
|
||||
if (is_full_conic() || _is_between_endpoints(ps[m]))
|
||||
m++;
|
||||
}
|
||||
|
||||
// Return the number of points on the arc.
|
||||
return (m);
|
||||
}
|
||||
|
||||
// Return a flipped conic arc: exchange the arc's source and destination.
|
||||
Segment_circle_2 flip () const
|
||||
{
|
||||
Conic opp_conic (-_conic.r(), -_conic.s(), -_conic.t(),
|
||||
-_conic.u(), -_conic.v(), -_conic.w());
|
||||
|
||||
return (Segment_circle_2<NT> (opp_conic, _target, _source));
|
||||
}
|
||||
|
||||
// Get the partial derivatives of the arc at a given point.
|
||||
void partial_derivatives (const Point& p,
|
||||
NT& dC_dx, NT& dC_dy) const
|
||||
{
|
||||
// Make sure p is contained in the arc.
|
||||
CGAL_precondition(contains_point(p));
|
||||
|
||||
// Calulate the partial derivatives of the conic C at p=(x,y), which are:
|
||||
//
|
||||
// dC dC
|
||||
// ---- = 2rx + ty + u ---- = 2sy + tx + v
|
||||
// dx dy
|
||||
//
|
||||
static const NT _two = 2;
|
||||
|
||||
dC_dx = _two*_conic.r()*p.x() + _conic.t()*p.y() + _conic.u();
|
||||
dC_dy = _two*_conic.s()*p.y() + _conic.t()*p.x() + _conic.v();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the intersection points between the arc and the given arc.
|
||||
// ps must be allocated at the size of 4.
|
||||
// The function returns the number of actual intersection point.
|
||||
int intersections_with (const Segment_circle_2<NT>& arc,
|
||||
Point* ps) const
|
||||
{
|
||||
// For simplicity, assume that (*this) has the higher degree.
|
||||
if (_deg == 1 && arc._deg == 2)
|
||||
{
|
||||
return (arc.intersections_with (*this,
|
||||
ps));
|
||||
}
|
||||
|
||||
// Check the case when one of the two arcs is a vertical segment.
|
||||
const Segment_circle_2<NT>* vertical_P = NULL;
|
||||
const Segment_circle_2<NT>* other_P = NULL;
|
||||
|
||||
if (is_vertical_segment())
|
||||
{
|
||||
vertical_P = this;
|
||||
other_P = &arc;
|
||||
}
|
||||
if (arc.is_vertical_segment())
|
||||
{
|
||||
// Both arcs are vertical segments: there should be no intersections.
|
||||
if (vertical_P != NULL)
|
||||
return (0);
|
||||
|
||||
vertical_P = &arc;
|
||||
other_P = this;
|
||||
}
|
||||
|
||||
if (vertical_P != NULL)
|
||||
{
|
||||
// Find all points on the other arc that have the segment's x value.
|
||||
Point xps[2];
|
||||
int n_ys;
|
||||
|
||||
n_ys = other_P->get_points_at_x (vertical_P->source().x(), xps);
|
||||
|
||||
// Make sure those points are on the vertical segment.
|
||||
int n = 0;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < n_ys; j++)
|
||||
{
|
||||
// Store this point only if it is contained on the other arc.
|
||||
if (vertical_P->contains_point(xps[j]))
|
||||
{
|
||||
ps[n] = xps[j];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return (n);
|
||||
}
|
||||
|
||||
// Solve a quadratic equation to find the x co-ordinates of the potential
|
||||
// intersection points:
|
||||
//
|
||||
// (r*E^2 + s*B^2)*x^2 + (u*E^2 + 2*s*B*C - v*B*E)*x +
|
||||
// + (w*E^2 + s*C^2 - v*C*E) = 0
|
||||
//
|
||||
NT B, C, E;
|
||||
NT xs[2];
|
||||
int n_roots;
|
||||
|
||||
if (arc._deg == 1)
|
||||
{
|
||||
B = arc._conic.u();
|
||||
C = arc._conic.w();
|
||||
E = arc._conic.v();
|
||||
}
|
||||
else if (_conic.s() == arc._conic.s())
|
||||
{
|
||||
// Both conics have the same orientation.
|
||||
B = _conic.u() - arc._conic.u();
|
||||
C = _conic.w() - arc._conic.w();
|
||||
E = _conic.v() - arc._conic.v();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The two conics have opposite orientations.
|
||||
B = _conic.u() + arc._conic.u();
|
||||
C = _conic.w() + arc._conic.w();
|
||||
E = _conic.v() + arc._conic.v();
|
||||
}
|
||||
|
||||
n_roots = _solve_quadratic_eq
|
||||
(_conic.r()*E*E + _conic.s()*B*B,
|
||||
_conic.u()*E*E + 2*_conic.s()*B*C - _conic.v()*B*E,
|
||||
_conic.w()*E*E + _conic.s()*C*C - _conic.v()*C*E,
|
||||
xs);
|
||||
|
||||
// Go over all roots, and return only those located on both arcs.
|
||||
int n_ys;
|
||||
Point xps[2];
|
||||
int n = 0;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n_roots; i++)
|
||||
{
|
||||
// Find all points on our arc that have xs[i] as their x co-ordinate.
|
||||
n_ys = get_points_at_x (xs[i], xps);
|
||||
|
||||
for (j = 0; j < n_ys; j++)
|
||||
{
|
||||
// Store this point only if it is contained on the other arc.
|
||||
if (arc.contains_point(xps[j]))
|
||||
{
|
||||
ps[n] = xps[j];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the number of intersection points.
|
||||
return (n);
|
||||
}
|
||||
|
||||
// Check whether the two arcs overlap.
|
||||
// The function computes the number of overlapping arcs (2 at most), and
|
||||
// returns their number (0 means there is not overlap).
|
||||
int overlaps (const Segment_circle_2<NT>& arc,
|
||||
Segment_circle_2<NT>* ovlp_arcs) const
|
||||
{
|
||||
// Two arcs can overlap only if their base conics are identical.
|
||||
if (_conic != arc._conic)
|
||||
return (0);
|
||||
|
||||
// If the two arcs are completely equal, return one of them as the
|
||||
// overlapping arc.
|
||||
int orient1 = _conic.orientation();
|
||||
int orient2 = arc._conic.orientation();
|
||||
bool same_or = (orient1 == orient2);
|
||||
bool identical = false;
|
||||
|
||||
if (orient1 == 0)
|
||||
{
|
||||
// That mean both arcs are really segments, so they are identical
|
||||
// if their endpoints are the same.
|
||||
if ((_source == arc._source && _target == arc._target) ||
|
||||
(_source == arc._target && _target == arc._source))
|
||||
identical = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If those are really curves of degree 2, than the points curves
|
||||
// are identical only if their source and target are the same and the
|
||||
// orientation is the same, or vice-versa if the orientation is opposite.
|
||||
if ((same_or && _source == arc._source && _target == arc._target) ||
|
||||
(!same_or && _source == arc._target && _target == arc._source))
|
||||
identical = true;
|
||||
}
|
||||
|
||||
if (identical)
|
||||
{
|
||||
ovlp_arcs[0] = arc;
|
||||
return (1);
|
||||
}
|
||||
|
||||
// In case one of the arcs is a full conic, return the whole other conic.
|
||||
if (arc.is_full_conic())
|
||||
{
|
||||
ovlp_arcs[0] = *this;
|
||||
return (1);
|
||||
}
|
||||
else if (is_full_conic())
|
||||
{
|
||||
ovlp_arcs[0] = arc;
|
||||
return (1);
|
||||
}
|
||||
|
||||
// In case the other arc has an opposite orientation, switch its source
|
||||
// and target.
|
||||
const Point *arc_sourceP;
|
||||
const Point *arc_targetP;
|
||||
|
||||
if (orient1 == 0)
|
||||
orient1 = (compare_lexicographically_xy (_source, _target)
|
||||
== LARGER) ? 1 : -1;
|
||||
if (orient2 == 0)
|
||||
orient2 = (compare_lexicographically_xy (arc._source, arc._target)
|
||||
== LARGER) ? 1 : -1;
|
||||
|
||||
if (orient1 == orient2)
|
||||
{
|
||||
arc_sourceP = &(arc._source);
|
||||
arc_targetP = &(arc._target);
|
||||
}
|
||||
else
|
||||
{
|
||||
arc_sourceP = &(arc._target);
|
||||
arc_targetP = &(arc._source);
|
||||
}
|
||||
|
||||
if (_is_strictly_between_endpoints(*arc_sourceP))
|
||||
{
|
||||
if (_is_strictly_between_endpoints(*arc_targetP))
|
||||
{
|
||||
// Check the next special case (when there are 2 overlapping arcs):
|
||||
if (arc._is_strictly_between_endpoints(_source) &&
|
||||
arc._is_strictly_between_endpoints(_target))
|
||||
{
|
||||
ovlp_arcs[0] = Segment_circle_2<NT>(_conic, _source, *arc_targetP);
|
||||
ovlp_arcs[1] = Segment_circle_2<NT>(_conic, *arc_sourceP, _target);
|
||||
return (2);
|
||||
}
|
||||
|
||||
// Case 1 - *this: +----------->
|
||||
// arc: +=====>
|
||||
ovlp_arcs[0] = Segment_circle_2<NT>(_conic, *arc_sourceP,*arc_targetP);
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 2 - *this: +----------->
|
||||
// arc: +=====>
|
||||
ovlp_arcs[0] = Segment_circle_2<NT>(_conic, *arc_sourceP, _target);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
else if (_is_strictly_between_endpoints(*arc_targetP))
|
||||
{
|
||||
// Case 3 - *this: +----------->
|
||||
// arc: +=====>
|
||||
ovlp_arcs[0] = Segment_circle_2<NT>(_conic, _source, *arc_targetP);
|
||||
return (1);
|
||||
|
||||
}
|
||||
else if (arc._is_between_endpoints(_source) &&
|
||||
arc._is_between_endpoints(_target) &&
|
||||
(arc._is_strictly_between_endpoints(_source) ||
|
||||
arc._is_strictly_between_endpoints(_target)))
|
||||
{
|
||||
// Case 4 - *this: +----------->
|
||||
// arc: +================>
|
||||
// Notice the end-points of *this may be strictly contained in the other
|
||||
// arc, or one of them can be an end-point in arc - but not both (this
|
||||
// implies that there is no overlap since the two curves have opposite
|
||||
// orientations).
|
||||
ovlp_arcs[0] = *this;
|
||||
return (1);
|
||||
}
|
||||
|
||||
// If we reached here, there are no overlaps:
|
||||
return (0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Check whether the given point is between the source and the target.
|
||||
// The point is assumed to be on the conic's boundary.
|
||||
bool _is_between_endpoints (const Point& p) const
|
||||
{
|
||||
if (p == _source || p == _target)
|
||||
return (true);
|
||||
else
|
||||
return (_is_strictly_between_endpoints(p));
|
||||
}
|
||||
|
||||
// Check whether the given point is strictly between the source and the
|
||||
// target (but not any of them).
|
||||
// The point is assumed to be on the conic's boundary.
|
||||
bool _is_strictly_between_endpoints (const Point& p) const
|
||||
{
|
||||
// In case this is a full conic, any point on its boundary is between
|
||||
// its end points.
|
||||
if (is_full_conic())
|
||||
return (true);
|
||||
|
||||
// In case the conic is a line segment (i.e. of the form ux + vy + w = 0),
|
||||
// make sure that p = (x,y) satisfies the segment equation (where (x1,y1)
|
||||
// is the source, (x2,y2) is the target and 0 < lambda < 1:
|
||||
// (x,y) = (x1,y1) + lambda*(x2-x1,y2-y1)
|
||||
static const NT _zero = 0;
|
||||
static const NT _one = 1;
|
||||
|
||||
if (_deg == 1)
|
||||
{
|
||||
NT lambda;
|
||||
|
||||
if (_source.x() != _target.x())
|
||||
lambda = (p.x() - _source.x()) / (_target.x() - _source.x());
|
||||
else
|
||||
lambda = (p.y() - _source.y()) / (_target.y() - _source.y());
|
||||
|
||||
return (lambda > _zero && lambda < _one);
|
||||
}
|
||||
|
||||
// Otherwise, make a decision based on the conic's orientation and whether
|
||||
// (source,p,target) is a right or a left turn.
|
||||
if (_conic.orientation() == 1)
|
||||
return (left_turn<R>(_source, p, _target));
|
||||
else
|
||||
return (right_turn<R>(_source, p, _target));
|
||||
}
|
||||
|
||||
// Find the y-coordinates of the conic at a given x-coordinate.
|
||||
int _conic_get_y_coordinates (const NT& x,
|
||||
NT *ys) const
|
||||
{
|
||||
// Solve the quadratic equation for a given x and find the y values:
|
||||
// s*y^2 + (t*x + v)*y + (r*x^2 + u*x + w) = 0
|
||||
return (_solve_quadratic_eq (_conic.s(),
|
||||
x*_conic.t() + _conic.v(),
|
||||
x*(x*_conic.r() + _conic.u()) + _conic.w(),
|
||||
ys));
|
||||
}
|
||||
|
||||
// Find the x-coordinates of the conic at a given y-coordinate.
|
||||
int _conic_get_x_coordinates (const NT& y,
|
||||
NT *xs) const
|
||||
{
|
||||
// Solve the quadratic equation for a given y and find the x values:
|
||||
// r*x^2 + (t*y + u)*x + (s*y^2 + v*y + w) = 0
|
||||
return (_solve_quadratic_eq (_conic.r(),
|
||||
y*_conic.t() + _conic.u(),
|
||||
y*(y*_conic.s() + _conic.v()) + _conic.w(),
|
||||
xs));
|
||||
}
|
||||
|
||||
// Find the vertical tangency points of the conic.
|
||||
int _conic_vertical_tangency_points (Point* ps) const
|
||||
{
|
||||
// In case the base conic is of degree 1 (and not 2), the arc has no
|
||||
// vertical tangency points.
|
||||
static const NT _zero = 0;
|
||||
static const NT _two = 2;
|
||||
|
||||
if (_deg == 1)
|
||||
return (0);
|
||||
|
||||
// Find the vertical tangency points of the circle:
|
||||
NT x0, y0, r;
|
||||
|
||||
if (_conic.r() > _zero)
|
||||
{
|
||||
// Positive orientation:
|
||||
x0 = -(_conic.u() / _two);
|
||||
y0 = -(_conic.v() / _two);
|
||||
r = CGAL::sqrt(x0*x0 + y0*y0 - _conic.w());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Negative orientation:
|
||||
x0 = _conic.u() / _two;
|
||||
y0 = _conic.v() / _two;
|
||||
r = CGAL::sqrt(x0*x0 + y0*y0 + _conic.w());
|
||||
}
|
||||
|
||||
ps[0] = Point (x0 - r, y0);
|
||||
ps[1] = Point (x0 + r, y0);
|
||||
|
||||
return (2);
|
||||
}
|
||||
|
||||
// Find the horizontal tangency points of the conic.
|
||||
int _conic_horizontal_tangency_points (Point* ps) const
|
||||
{
|
||||
// In case the base conic is of degree 1 (and not 2), the arc has no
|
||||
// horizontal tangency points.
|
||||
static const NT _zero = 0;
|
||||
static const NT _two = 2;
|
||||
|
||||
if (_deg == 1)
|
||||
return (0);
|
||||
|
||||
// Find the horizontal tangency points of the circle:
|
||||
NT x0, y0, r;
|
||||
|
||||
if (_conic.r() > _zero)
|
||||
{
|
||||
// Positive orientation:
|
||||
x0 = -(_conic.u() / _two);
|
||||
y0 = -(_conic.v() / _two);
|
||||
r = CGAL::sqrt(x0*x0 + y0*y0 - _conic.w());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Negative orientation:
|
||||
x0 = _conic.u() / _two;
|
||||
y0 = _conic.v() / _two;
|
||||
r = CGAL::sqrt(x0*x0 + y0*y0 + _conic.w());
|
||||
}
|
||||
|
||||
ps[0] = Point (x0, y0 - r);
|
||||
ps[1] = Point (x0, y0 + r);
|
||||
|
||||
return (2);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifndef NO_OSTREAM_INSERT_CONIC_ARC_2
|
||||
template <class NT>
|
||||
std::ostream& operator<< (std::ostream& os, const Segment_circle_2<NT>& arc)
|
||||
{
|
||||
typename Segment_circle_2<NT>::Conic conic = arc.conic();
|
||||
typename Segment_circle_2<NT>::Point source =
|
||||
arc.source(), target = arc.target();
|
||||
|
||||
os << "{" << CGAL::to_double(conic.r()) << "*x^2 + "
|
||||
<< CGAL::to_double(conic.s()) << "*y^2 + "
|
||||
<< CGAL::to_double(conic.t()) << "*xy + "
|
||||
<< CGAL::to_double(conic.u()) << "*x + "
|
||||
<< CGAL::to_double(conic.v()) << "*y + "
|
||||
<< CGAL::to_double(conic.w()) << "}: "
|
||||
<< "(" << CGAL::to_double(source.x()) << ","
|
||||
<< CGAL::to_double(source.y()) << ") -> "
|
||||
<< "(" << CGAL::to_double(target.x()) << ","
|
||||
<< CGAL::to_double(target.y()) << ")";
|
||||
|
||||
return (os);
|
||||
}
|
||||
#endif // NO_OSTREAM_INSERT_CONIC_ARC_2
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#endif // CGAL_SEGMENT_CIRCLE_2_H
|
||||
|
|
@ -45,8 +45,8 @@ compile_and_run()
|
|||
echo " ERROR: compilation of $1 failed" >> $ERRORFILE
|
||||
fi
|
||||
|
||||
# running io test (not for segment_circle_traits).
|
||||
if [ $3 -ne $CGAL_SEGMENT_CIRCLE_TRAITS ]; then
|
||||
# running io test (not for conic_traits).
|
||||
if [ $3 -ne $CGAL_CONIC_TRAITS ]; then
|
||||
if compile test_io $2 $3 ; then
|
||||
echo " compilation of $1_io succeeded" >> $ERRORFILE
|
||||
run_io test_io $2 $3
|
||||
|
|
@ -70,7 +70,7 @@ run()
|
|||
datafiles="DATA/segments/*"
|
||||
elif [ $3 -eq $CGAL_POLYLINE_TRAITS -o $3 -eq $CGAL_POLYLINE_LEDA_TRAITS ]; then
|
||||
datafiles="DATA/polylines/*"
|
||||
elif [ $3 -eq $CGAL_SEGMENT_CIRCLE_TRAITS ]; then
|
||||
elif [ $3 -eq $CGAL_CONIC_TRAITS ]; then
|
||||
datafiles="DATA/segment_circles/*"
|
||||
fi
|
||||
|
||||
|
|
@ -132,8 +132,8 @@ run_io()
|
|||
SUFFIO="leda_io"
|
||||
# Avoid running test_io with leda_polyline_traits
|
||||
return
|
||||
elif [ $3 -eq $CGAL_SEGMENT_CIRCLE_TRAITS ]; then
|
||||
# Avoid running test_io with segment_circle_traits
|
||||
elif [ $3 -eq $CGAL_CONIC_TRAITS ]; then
|
||||
# Avoid running test_io with conic_traits
|
||||
return
|
||||
fi
|
||||
|
||||
|
|
@ -194,7 +194,7 @@ else
|
|||
CGAL_SEGMENT_LEDA_TRAITS=2
|
||||
CGAL_POLYLINE_TRAITS=11
|
||||
CGAL_POLYLINE_LEDA_TRAITS=12
|
||||
CGAL_SEGMENT_CIRCLE_TRAITS=21
|
||||
CGAL_CONIC_TRAITS=21
|
||||
|
||||
TRAP=1 # Trapezoidal decomposition
|
||||
NAIVE=2
|
||||
|
|
@ -224,7 +224,7 @@ else
|
|||
(compile_and_run test $WALK $CGAL_POLYLINE_LEDA_TRAITS)
|
||||
(compile_and_run test $SIMPLE $CGAL_POLYLINE_LEDA_TRAITS)
|
||||
|
||||
# run test with segment circle traits
|
||||
(compile_and_run test $WALK $CGAL_SEGMENT_CIRCLE_TRAITS)
|
||||
# run test with segment conic traits
|
||||
(compile_and_run test $WALK $CGAL_CONIC_TRAITS)
|
||||
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#define CGAL_SEGMENT_TRAITS 1
|
||||
#define CGAL_SEGMENT_LEDA_TRAITS 2
|
||||
#define CGAL_POLYLINE_TRAITS 11
|
||||
#define CGAL_POLYLINE_LEDA_TRAITS 12
|
||||
#define CGAL_SEGMENT_CIRCLE_TRAITS 21
|
||||
#define CGAL_POLYLINE_TRAITS 11
|
||||
#define CGAL_POLYLINE_LEDA_TRAITS 12
|
||||
#define CGAL_CONIC_TRAITS 21
|
||||
|
||||
// Picking a default Traits class (this, with the
|
||||
// PL flag enables the running of the test independently of cgal_make.)
|
||||
|
|
@ -18,14 +18,14 @@
|
|||
#define CGAL_ARR_TEST_TRAITS CGAL_SEGMENT_LEDA_TRAITS
|
||||
//#define CGAL_ARR_TEST_TRAITS CGAL_POLYLINE_TRAITS
|
||||
//#define CGAL_ARR_TEST_TRAITS CGAL_POLYLINE_LEDA_TRAITS
|
||||
//#define CGAL_ARR_TEST_TRAITS CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
//#define CGAL_ARR_TEST_TRAITS CGAL_CONIC_TRAITS
|
||||
#endif
|
||||
|
||||
// Making sure test doesn't fail if LEDA is not installed
|
||||
#if ! defined(CGAL_USE_LEDA) && \
|
||||
(CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_LEDA_TRAITS || \
|
||||
CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_LEDA_TRAITS || \
|
||||
CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS)
|
||||
CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS)
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
@ -52,9 +52,9 @@ int main()
|
|||
#include <CGAL/leda_rational.h>
|
||||
#include <CGAL/Arr_leda_polyline_traits.h>
|
||||
#include <CGAL/Pm_segment_traits_leda_kernel_2.h>
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
#include <CGAL/leda_real.h>
|
||||
#include <CGAL/Arr_segment_circle_traits.h>
|
||||
#include <CGAL/Arr_conic_traits_2.h>
|
||||
#else
|
||||
#error No traits defined for test
|
||||
#endif
|
||||
|
|
@ -111,16 +111,17 @@ int main()
|
|||
typedef CGAL::Pm_segment_traits_leda_kernel_2 Kernel;
|
||||
typedef CGAL::Arr_leda_polyline_traits<Kernel> Traits;
|
||||
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
typedef leda_real NT;
|
||||
typedef CGAL::Arr_segment_circle_traits<NT> Traits;
|
||||
typedef CGAL::Cartesian<NT> K;
|
||||
typedef CGAL::Arr_conic_traits_2<K> Traits;
|
||||
typedef Traits::Segment_2 Segment;
|
||||
typedef Traits::Circle Circle;
|
||||
|
||||
#endif
|
||||
|
||||
typedef Traits::Point_2 Point;
|
||||
typedef Traits::X_monotone_curve_2 X_curve;
|
||||
typedef Traits::X_monotone_curve_2 X_curve;
|
||||
typedef Traits::Curve_2 Curve;
|
||||
|
||||
typedef CGAL::Arr_base_node<X_curve> Base_node;
|
||||
|
|
@ -320,7 +321,7 @@ private:
|
|||
else
|
||||
{
|
||||
file.putback(c);
|
||||
#if CGAL_ARR_TEST_TRAITS != CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS
|
||||
file >> num;
|
||||
result = NT(num.numerator(), num.denominator());
|
||||
#else
|
||||
|
|
@ -344,7 +345,7 @@ private:
|
|||
// The to_long precondition is that number is indeed long
|
||||
// is supplied here since input numbers are small.
|
||||
return get_next_num(file).numerator().to_long();
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
return (int) CGAL::to_double(get_next_num(file));
|
||||
#else
|
||||
return get_next_num(file).numerator();
|
||||
|
|
@ -409,7 +410,7 @@ private:
|
|||
return polyline;
|
||||
}
|
||||
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
|
||||
Curve read_seg_circ_curve(std::ifstream& file, bool reverse_order)
|
||||
{
|
||||
|
|
@ -516,7 +517,7 @@ private:
|
|||
|
||||
curr_curve = read_polyline_curve(file, reverse_order);
|
||||
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
|
||||
curr_curve = read_seg_circ_curve(file, reverse_order);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#define CGAL_SEGMENT_TRAITS 1
|
||||
#define CGAL_SEGMENT_LEDA_TRAITS 2
|
||||
#define CGAL_POLYLINE_TRAITS 11
|
||||
#define CGAL_POLYLINE_LEDA_TRAITS 12
|
||||
#define CGAL_SEGMENT_CIRCLE_TRAITS 21
|
||||
#define CGAL_POLYLINE_TRAITS 11
|
||||
#define CGAL_POLYLINE_LEDA_TRAITS 12
|
||||
#define CGAL_CONIC_TRAITS 21
|
||||
|
||||
// Picking a default Traits class (this, with the
|
||||
// PL flag enables the running of the test independently of cgal_make.)
|
||||
|
|
@ -18,14 +18,14 @@
|
|||
//#define CGAL_ARR_TEST_TRAITS CGAL_SEGMENT_LEDA_TRAITS
|
||||
#define CGAL_ARR_TEST_TRAITS CGAL_POLYLINE_TRAITS
|
||||
//#define CGAL_ARR_TEST_TRAITS CGAL_POLYLINE_LEDA_TRAITS
|
||||
//#define CGAL_ARR_TEST_TRAITS CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
//#define CGAL_ARR_TEST_TRAITS CGAL_CONIC_TRAITS
|
||||
#endif
|
||||
|
||||
// Making sure test doesn't fail if LEDA is not installed
|
||||
#if ! defined(CGAL_USE_LEDA) && \
|
||||
(CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_LEDA_TRAITS || \
|
||||
CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_LEDA_TRAITS || \
|
||||
CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS)
|
||||
CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
|
@ -53,9 +53,9 @@ int main(int argc, char* argv[])
|
|||
#include <CGAL/leda_rational.h>
|
||||
#include <CGAL/Pm_segment_traits_leda_kernel_2.h>
|
||||
#include <CGAL/Arr_leda_polyline_traits.h>
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
#include <CGAL/leda_real.h>
|
||||
#include <CGAL/Arr_segment_circle_traits.h>
|
||||
#include <CGAL/Arr_conic_traits_2.h>
|
||||
#else
|
||||
#error No traits defined for test
|
||||
#endif
|
||||
|
|
@ -112,9 +112,9 @@ int main(int argc, char* argv[])
|
|||
typedef CGAL::Pm_segment_traits_leda_kernel_2 Kernel;
|
||||
typedef CGAL::Arr_leda_polyline_traits<Kernel> Traits;
|
||||
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
typedef leda_real NT;
|
||||
typedef CGAL::Arr_segment_circle_traits<NT> Traits;
|
||||
typedef CGAL::Arr_conic_traits_2<NT> Traits;
|
||||
typedef Traits::Segment Segment;
|
||||
typedef Traits::Circle Circle;
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ private:
|
|||
else
|
||||
{
|
||||
file.putback(c);
|
||||
#if CGAL_ARR_TEST_TRAITS != CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS
|
||||
file >> num;
|
||||
result = NT(num.numerator(), num.denominator());
|
||||
#else
|
||||
|
|
@ -243,7 +243,7 @@ private:
|
|||
// The to_long precondition is that number is indeed long
|
||||
// is supplied here since input numbers are small.
|
||||
return get_next_num(file).numerator().to_long();
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
return (int) CGAL::to_double(get_next_num(file));
|
||||
#else
|
||||
return get_next_num(file).numerator();
|
||||
|
|
@ -308,7 +308,7 @@ Curve read_polyline_curve(std::ifstream& file, bool reverse_order)
|
|||
return polyline;
|
||||
}
|
||||
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
|
||||
Curve read_seg_circ_curve(std::ifstream& file, bool reverse_order)
|
||||
{
|
||||
|
|
@ -415,7 +415,7 @@ Curve read_seg_circ_curve(std::ifstream& file, bool reverse_order)
|
|||
|
||||
curr_curve = read_polyline_curve(file, reverse_order);
|
||||
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS
|
||||
#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS
|
||||
|
||||
curr_curve = read_seg_circ_curve(file, reverse_order);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,173 +0,0 @@
|
|||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <fstream>
|
||||
|
||||
// Making sure test doesn't fail if LEDA is not installed
|
||||
#if ! defined(CGAL_USE_LEDA) && \
|
||||
(CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_LEDA_TRAITS || \
|
||||
CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_LEDA_TRAITS)
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "A try to run test with LEDA traits but LEDA is not installed.";
|
||||
std::cout << std::endl;
|
||||
std::cout << "Test is not performed.";
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
#include <CGAL/Circle_2.h>
|
||||
#include <CGAL/Arr_circles_real_traits.h>
|
||||
#include <CGAL/leda_real.h>
|
||||
|
||||
#include "include/Circles_traits_test_base.h"
|
||||
|
||||
typedef leda_real NT;
|
||||
typedef CGAL::Arr_circles_real_traits<NT> Traits;
|
||||
|
||||
typedef Traits::Point_2 Point;
|
||||
typedef Traits::X_monotone_curve_2 X_curve;
|
||||
typedef Traits::Curve_2 Curve;
|
||||
|
||||
class Arr_circles_real_traits_test : public Arr_traits_test<Traits> {
|
||||
|
||||
typedef Arr_traits_test<Traits>::Traits Traits;
|
||||
|
||||
void build_curve_list(std::list<Curve_with_info>& curve_list)
|
||||
{
|
||||
// Require:
|
||||
CGAL_precondition_msg(curve_list.empty(), \
|
||||
"list is not empty.");
|
||||
|
||||
const Point CENTER(NT(0), NT(0));
|
||||
const NT RADIUS = NT(100);
|
||||
const NT SQUARED_RADIUS = RADIUS * RADIUS;
|
||||
const NT sin45 = CGAL::sqrt( NT(2) ) / NT(2);
|
||||
const NT cos45 = sin45;
|
||||
|
||||
// Defining four points p1, p2, p3, p4 in quadrant I, II, III, IV
|
||||
// resepectively.
|
||||
Point p1( RADIUS * cos45, RADIUS * sin45);
|
||||
Point p2( RADIUS * -cos45, RADIUS * sin45);
|
||||
Point p3( RADIUS * -cos45, RADIUS * -sin45);
|
||||
Point p4( RADIUS * cos45, RADIUS * -sin45);
|
||||
|
||||
CGAL::Circle_2<Curve::R> my_circle(CENTER, SQUARED_RADIUS,
|
||||
CGAL::COUNTERCLOCKWISE);
|
||||
|
||||
// Check that points are indeed on boundry of circle
|
||||
CGAL_assertion( my_circle.has_on_boundary(p1) );
|
||||
CGAL_assertion( my_circle.has_on_boundary(p2) );
|
||||
CGAL_assertion( my_circle.has_on_boundary(p3) );
|
||||
CGAL_assertion( my_circle.has_on_boundary(p4) );
|
||||
|
||||
Curve_with_info cv;
|
||||
|
||||
// Defining curves and inserting into container
|
||||
// Curves are oriented counterclockwise.
|
||||
|
||||
// X-monotone curves
|
||||
cv = Curve_with_info(Curve(my_circle, p1, p2),
|
||||
true,
|
||||
1,
|
||||
"arc of quadrants I - II");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p3, p4),
|
||||
true,
|
||||
1,
|
||||
"arc of quadrants III - IV");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
// Non x-monotone circular curves with 2 x-monotone parts
|
||||
cv = Curve_with_info(Curve(my_circle),
|
||||
false,
|
||||
2,
|
||||
"a whole circle");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p4, p1),
|
||||
false,
|
||||
2,
|
||||
"arc of quadrants IV - I");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p3, p1),
|
||||
false,
|
||||
2,
|
||||
"arc of quadrants III - IV - I");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p4, p2),
|
||||
false,
|
||||
2,
|
||||
"arc of quadrants IV - I - II");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p3, p2),
|
||||
false,
|
||||
2,
|
||||
"arc of quadrants III - IV - I - II");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p4, p2),
|
||||
false,
|
||||
2,
|
||||
"arc of quadrants IV - I - II");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p2, p3),
|
||||
false,
|
||||
2,
|
||||
"arc of quadrants II - III");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p1, p3),
|
||||
false,
|
||||
2,
|
||||
"arc of quadrants I - II - III");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p2, p4),
|
||||
false,
|
||||
2,
|
||||
"arc of quadrants II - III - IV");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p1, p4),
|
||||
false,
|
||||
2,
|
||||
"arc of quadrants I - II - III - IV");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
// Non x-monotone circular curves with 3 x-monotone parts
|
||||
cv = Curve_with_info(Curve(my_circle, p2, p1),
|
||||
false,
|
||||
3,
|
||||
"arc of quadrants II - III - IV - I");
|
||||
curve_list.push_back(cv);
|
||||
|
||||
cv = Curve_with_info(Curve(my_circle, p4, p3),
|
||||
false,
|
||||
3,
|
||||
"arc of quadrants II - III");
|
||||
curve_list.push_back(cv);
|
||||
}
|
||||
|
||||
}; // Arr_traits_test
|
||||
|
||||
int main()
|
||||
{
|
||||
Arr_circles_real_traits_test test;
|
||||
|
||||
if ( test.start() )
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // ! defined(CGAL_USE_LEDA) ...
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
#include <CGAL/basic.h>
|
||||
#include <iostream>
|
||||
|
||||
// Making sure test doesn't fail if LEDA is not installed
|
||||
#if ! defined(CGAL_USE_LEDA)
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "A try to run test with LEDA traits but LEDA is not installed.";
|
||||
std::cout << std::endl;
|
||||
std::cout << "Test is not performed.";
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
#include <CGAL/leda_real.h>
|
||||
#include "include/Segment_circle_traits_test.h"
|
||||
#include <CGAL/Arr_segment_circle_traits.h>
|
||||
|
||||
typedef leda_real NT;
|
||||
typedef CGAL::Arr_segment_circle_traits<NT> Traits;
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
Segment_circle_traits_test<Traits, NT> test_obj (argc, argv);
|
||||
|
||||
if (test_obj.start())
|
||||
return (0); // SUCCESS
|
||||
else
|
||||
return (1); // FAILURE
|
||||
}
|
||||
|
||||
#endif // ! defined(CGAL_USE_LEDA) ...
|
||||
|
|
@ -82,7 +82,5 @@ else
|
|||
compile_and_run Arr_leda_segment_exact_traits_test segments
|
||||
compile_and_run Arr_polyline_traits_test polylines
|
||||
compile_and_run Arr_leda_polyline_traits_test polylines
|
||||
compile_and_run Arr_segment_circle_traits_test segment_circles
|
||||
compile_and_run Arr_circles_real_traits_test circular_arcs
|
||||
compile_and_run Arr_conic_traits_test conic_arcs
|
||||
fi
|
||||
|
|
|
|||
Loading…
Reference in New Issue