From 2be792ff767cf4cc55bad3199f27def2b9f0d26f Mon Sep 17 00:00:00 2001 From: Ron Wein Date: Sun, 18 May 2003 14:25:58 +0000 Subject: [PATCH] Bug fixes in the conic traits. Removed the circle_traits and the segment_circle_traits (use the conic_traits instead). --- .../demo/Arrangement_2/Circle_arr_from_file.C | 42 +- .../demo/Arrangement_2/Conics_arr_from_file.C | 27 +- .../Arrangement_2/Seg_circ_arr_from_file.C | 95 +- .../Arrangement/demo/Arrangement_2/makefile | 6 +- .../include/CGAL/Arr_circles_real_traits.h | 913 -------------- .../include/CGAL/Arr_conic_traits_2.h | 32 +- .../include/CGAL/Arr_segment_circle_traits.h | 1066 ----------------- .../include/CGAL/Arrangement_2/Conic_arc_2.h | 50 +- .../CGAL/IO/Arr_circle_traits_Window_stream.h | 133 -- .../CGAL/IO/Conic_arc_2_Window_stream.h | 4 +- .../CGAL/IO/Segment_circle_Window_stream.h | 78 -- .../include/CGAL/Segment_circle_2.h | 995 --------------- .../Arrangement/test/Arrangement_2/cgal_test | 16 +- .../Arrangement/test/Arrangement_2/test_arr.C | 29 +- .../test/Arrangement_2/test_assignment.C | 26 +- .../Arr_circles_real_traits_test.C | 173 --- .../Arr_segment_circle_traits_test.C | 35 - .../test/Arrangement_2_Traits/cgal_test | 2 - 18 files changed, 191 insertions(+), 3531 deletions(-) delete mode 100644 Packages/Arrangement/include/CGAL/Arr_circles_real_traits.h delete mode 100644 Packages/Arrangement/include/CGAL/Arr_segment_circle_traits.h delete mode 100644 Packages/Arrangement/include/CGAL/IO/Arr_circle_traits_Window_stream.h delete mode 100644 Packages/Arrangement/include/CGAL/IO/Segment_circle_Window_stream.h delete mode 100644 Packages/Arrangement/include/CGAL/Segment_circle_2.h delete mode 100644 Packages/Arrangement/test/Arrangement_2_Traits/Arr_circles_real_traits_test.C delete mode 100644 Packages/Arrangement/test/Arrangement_2_Traits/Arr_segment_circle_traits_test.C diff --git a/Packages/Arrangement/demo/Arrangement_2/Circle_arr_from_file.C b/Packages/Arrangement/demo/Arrangement_2/Circle_arr_from_file.C index bc71a0cba2e..d73527616e9 100644 --- a/Packages/Arrangement/demo/Arrangement_2/Circle_arr_from_file.C +++ b/Packages/Arrangement/demo/Arrangement_2/Circle_arr_from_file.C @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -29,16 +29,18 @@ int main() #include #include -#include +#include #include -typedef CGAL::Arr_circles_real_traits Traits; +typedef leda_real NT; +typedef CGAL::Cartesian Kernel; +typedef CGAL::Arr_conic_traits_2 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 Base_node; +typedef CGAL::Arr_base_node Base_node; typedef CGAL::Arr_2_default_dcel Dcel; typedef CGAL::Arrangement_2 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 circles; + std::vector 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; iface(); - //Arr_2::Ccb_halfedge_circulator cc(e); Arr_2::Ccb_halfedge_circulator cc; if (fh != arr.unbounded_face()) { diff --git a/Packages/Arrangement/demo/Arrangement_2/Conics_arr_from_file.C b/Packages/Arrangement/demo/Arrangement_2/Conics_arr_from_file.C index 1ec45729bf2..aee81ae1043 100644 --- a/Packages/Arrangement/demo/Arrangement_2/Conics_arr_from_file.C +++ b/Packages/Arrangement/demo/Arrangement_2/Conics_arr_from_file.C @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include @@ -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(width), - static_cast(height)); + static_cast(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." ); diff --git a/Packages/Arrangement/demo/Arrangement_2/Seg_circ_arr_from_file.C b/Packages/Arrangement/demo/Arrangement_2/Seg_circ_arr_from_file.C index a5a1f595db9..eee81134bb5 100644 --- a/Packages/Arrangement/demo/Arrangement_2/Seg_circ_arr_from_file.C +++ b/Packages/Arrangement/demo/Arrangement_2/Seg_circ_arr_from_file.C @@ -22,47 +22,49 @@ int main() #else #include -#include #include -#include -#include - #include #include #include +#include +#include +#include + #include #include -typedef CGAL::Arr_segment_circle_traits Traits; +#include -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 Kernel; +typedef CGAL::Arr_conic_traits_2 Traits; +typedef CGAL::Pm_default_dcel Dcel; +typedef CGAL::Planar_map_2 Pm_2; +typedef CGAL::Planar_map_with_intersections_2 Pmwx_2; -typedef CGAL::Arr_base_node Base_node; -typedef CGAL::Arr_2_default_dcel Dcel; -typedef CGAL::Arrangement_2 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 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 { diff --git a/Packages/Arrangement/demo/Arrangement_2/makefile b/Packages/Arrangement/demo/Arrangement_2/makefile index f3aec4d5527..54288e2b192 100644 --- a/Packages/Arrangement/demo/Arrangement_2/makefile +++ b/Packages/Arrangement/demo/Arrangement_2/makefile @@ -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) diff --git a/Packages/Arrangement/include/CGAL/Arr_circles_real_traits.h b/Packages/Arrangement/include/CGAL/Arr_circles_real_traits.h deleted file mode 100644 index dfa4fd37f27..00000000000 --- a/Packages/Arrangement/include/CGAL/Arr_circles_real_traits.h +++ /dev/null @@ -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 ) -// -// ====================================================================== -#ifndef CGAL_ARR_CIRCLES_REAL_TRAITS_H -#define CGAL_ARR_CIRCLES_REAL_TRAITS_H - -#include -#include - -#include -#include - -CGAL_BEGIN_NAMESPACE - -template class Arr_circles_real_traits; - -template -class Circ_Curve { - -public: - typedef Cartesian 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; - -private: - Circle c; - Point_2 s,t; //source, target -}; - -// DEBUG -// template -// ::std::ostream& operator << -// (::std::ostream& os,const Circ_Curve& 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 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 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 - // and 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); - - // and 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 - 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::iterator lit; - // typename std::list::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 > 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 diff --git a/Packages/Arrangement/include/CGAL/Arr_conic_traits_2.h b/Packages/Arrangement/include/CGAL/Arr_conic_traits_2.h index bcc165aebc6..5648ef2d3f5 100644 --- a/Packages/Arrangement/include/CGAL/Arr_conic_traits_2.h +++ b/Packages/Arrangement/include/CGAL/Arr_conic_traits_2.h @@ -23,7 +23,7 @@ #include #include -#include "CGAL/Arrangement_2/Conic_arc_2.h" +#include #include 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. diff --git a/Packages/Arrangement/include/CGAL/Arr_segment_circle_traits.h b/Packages/Arrangement/include/CGAL/Arr_segment_circle_traits.h deleted file mode 100644 index 0e8d4b88be6..00000000000 --- a/Packages/Arrangement/include/CGAL/Arr_segment_circle_traits.h +++ /dev/null @@ -1,1066 +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/Arr_segment_circle_traits.h -// package : Arrangement (2.19) -// maintainer : Eyal Flato -// author(s) : Ron Wein -// coordinator : Tel-Aviv University (Dan Halperin ) -// -// ====================================================================== -#ifndef CGAL_ARR_CONIC_TRAITS_2_H -#define CGAL_ARR_CONIC_TRAITS_2_H - -#include -#include -#include -#include - -CGAL_BEGIN_NAMESPACE - -// ---------------------------------------------------------------------------- -// Arrangement traits for conic arcs. -// - -template -class Arr_segment_circle_traits -{ - public: - typedef Tag_false Has_left_category; - - typedef _NT NT; - - // The difference between Curve and X_curve is semantical only, - // NOT syntactical. - typedef Segment_circle_2 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::R R; - typedef typename Curve_2::Point Point_2; - typedef typename Curve_2::Segment Segment_2; - typedef typename Curve_2::Circle Circle_2; - typedef typename Curve_2::Conic Conic_2; - - // Obsolete, for backward compatibility - typedef Point_2 Point; - typedef X_monotone_curve_2 X_curve; - typedef Curve_2 Curve; - typedef Segment_2 Segment; - typedef Circle_2 Circle; - typedef Conic_2 Conic; - - // Constructor. - Arr_segment_circle_traits() - {} - - ////////// Planar Map methods: ////////// - - // Compare the x co-ordinates of two given points. - Comparison_result compare_x(const Point_2 & p0, const Point_2 & p1) const - { - return _compare_value(p0.x(),p1.x()); - } - - // Compare the two points lexicographically (by x, then by y). - 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()); - } - - // Check whether the given curve is a vertical segment. - bool curve_is_vertical(const X_monotone_curve_2& curve) const - { - return (curve.is_vertical_segment()); - } - - // Check whether the x co-ordinate of the given point is contained in the - // x-range of the given x-monotone curve. - bool point_in_x_range (const X_monotone_curve_2& curve, - const Point_2& p) const - { - CGAL_precondition(is_x_monotone(curve)); - - if (curve.is_vertical_segment()) - { - return (compare_x (curve.source(), p) == EQUAL); - } - else - { - // Find the number of points on the arc with the same x co-ordinate as p. - // p is is the x-range of the arc only if there is at least one point. - Point_2 ps[2]; - int n = curve.get_points_at_x (p.x(), ps); - - return (n > 0); - } - } - - // Decide wether curve1 is above, below or equal to curve2 at the - // x co-ordinate of the given point. - Comparison_result curves_compare_y_at_x(const X_monotone_curve_2& curve1, - const X_monotone_curve_2& curve2, - const Point_2& p) const - { - CGAL_precondition(is_x_monotone(curve1)); - CGAL_precondition(is_x_monotone(curve2)); - CGAL_precondition(point_in_x_range(curve1, p)); - CGAL_precondition(point_in_x_range(curve2, p)); - - // Get the points on curve1 with the same x co-ordinate as p. - int n1; - Point_2 ps1[2]; - - if (curve1.is_vertical_segment()) - { - // Vertical segment. - if (compare_x (curve1.source(), p) != EQUAL) - return (EQUAL); - - n1 = 2; - if (_compare_y (curve1.source(), curve1.target()) == SMALLER) - { - ps1[0] = curve1.source(); - ps1[1] = curve1.target(); - } - else - { - ps1[0] = curve1.target(); - ps1[1] = curve1.source(); - } - } - else - { - n1 = curve1.get_points_at_x (p.x(), ps1); - - CGAL_assertion(n1 == 1); - } - - // Get the points on curve2 with the same x co-ordinate as p. - int n2; - Point_2 ps2[2]; - - if (curve2.is_vertical_segment()) - { - // Vertical segment. - if (compare_x (curve2.source(), p) != EQUAL) - return (EQUAL); - - n2 = 2; - if (_compare_y (curve2.source(), curve2.target()) == SMALLER) - { - ps2[0] = curve2.source(); - ps2[1] = curve2.target(); - } - else - { - ps2[0] = curve2.target(); - ps2[1] = curve2.source(); - } - } - else - { - n2 = curve2.get_points_at_x (p.x(), ps2); - - CGAL_assertion(n2 == 1); - } - - // Deal with vertical segments: - if (n1 == 2) - { - // Check if the vertical segment contains ps2[0]. - if (_compare_y (ps1[0], ps2[0]) != LARGER && - _compare_y (ps1[1], ps2[0]) != SMALLER) - { - return (EQUAL); - } - - if (n2 == 2) - { - if (_compare_y (ps1[0], ps2[1]) != LARGER && - _compare_y (ps1[1], ps2[1]) != SMALLER) - { - return (EQUAL); - } - } - } - else if (n2 == 2) - { - // Check if the vertical segment contains ps1[0]. - if (_compare_y (ps2[0], ps1[0]) != LARGER && - _compare_y (ps2[1], ps1[0]) != SMALLER) - { - return (EQUAL); - } - } - - // Compare the y co-ordinates of the two points. - return (_compare_y (ps1[0], ps2[0])); - } - - // Decide wether curve1 is above, below or equal to curve2 immediately to - // the left of the x co-ordinate of the given point. - Comparison_result - curves_compare_y_at_x_left(const X_monotone_curve_2& curve1, - const X_monotone_curve_2& curve2, - const Point_2& p) const - { - CGAL_precondition(is_x_monotone(curve1)); - CGAL_precondition(is_x_monotone(curve2)); - - // The two curve must not be vertical segments. - CGAL_precondition(! curve1.is_vertical_segment()); - CGAL_precondition(! curve2.is_vertical_segment()); - - // Check that both curves are defined to the left of p. - CGAL_precondition((compare_x(curve1.source(), p) == SMALLER) || - (compare_x(curve1.target(), p) == SMALLER)); - - CGAL_precondition((compare_x(curve2.source(), p) == SMALLER) || - (compare_x(curve2.target(), p) == SMALLER)); - - // Get the points on curve1 with the same x co-ordinate as p. - int n1; - Point_2 ps1[2]; - - if (curve1.contains_point(p)) - { - ps1[0] = p; - n1 = 1; - } - else - { - n1 = curve1.get_points_at_x (p.x(), ps1); - } - - // Make sure that there is exactly one point. - CGAL_assertion(n1 == 1); - - // Get the points on curve2 with the same x co-ordinate as p. - int n2; - Point_2 ps2[2]; - - if (curve2.contains_point(p)) - { - ps2[0] = p; - n2 = 1; - } - else - { - n2 = curve2.get_points_at_x (p.x(), ps2); - } - - // Make sure that there is exactly one point. - CGAL_assertion(n2 == 1); - - // Make sure the two curves intersect at x(p). - CGAL_precondition(_compare_y (ps1[0], ps2[0]) == EQUAL); - - // If the curves are the same, they are equal to the left of p: - if (curve_equal(curve1,curve2)) - return (EQUAL); - - // Otherwise, the two curves do intersect at p_int = ps1[0] = ps2[0]: - // make a decision based on their partial derivatives. - const Point_2& p_int = ps1[0]; - - // In order to simplify the process, make sure the source is always to the - // left of p. - X_monotone_curve_2 c1 = curve1; - X_monotone_curve_2 c2 = curve2; - - if (compare_x(c1.source(), p) != SMALLER) - c1 = curve1.flip(); - if (compare_x(c2.source(), p) != SMALLER) - c2 = curve2.flip(); - - // Calculate the partial derivatives at the intersection point. - NT dC1_dx, dC1_dy; - NT dC2_dx, dC2_dy; - const NT zero = 0; - - c1.partial_derivatives (p_int, dC1_dx, dC1_dy); - c2.partial_derivatives (p_int, dC2_dx, dC2_dy); - - // Try to compare the slopes of the tangents to the two arcs. - if (dC1_dy != zero && dC2_dy != zero) - { - Comparison_result slope_result = _compare_value (dC1_dx/dC1_dy, - dC2_dx/dC2_dy); - if (slope_result != EQUAL) - { - return (slope_result); - } - } - - // If we reached here, the two curves intersect at p_int, and their - // tangents at this point have the same slope. We shall therefore find - // a point with extreme y-coordinate for each curve and compare the - // y-values of these two extreme points. - Point_2 p_extr1, p_extr2; - Point_2 hpts[2]; - int n_hpts; - - n_hpts = c1.horizontal_tangency_points(hpts); - if (n_hpts == 0) - { - // No horizontal tangency points - the source must have an extreme - // y-value. - p_extr1 = c1.source(); - } - else if (n_hpts == 1) - { - // Use the vertical tangency points only if it lies between the source - // and p_int. Otherwise, use the source. - if (compare_x(c1.source(), hpts[0]) == SMALLER && - compare_x(p_int, hpts[0]) == LARGER) - { - p_extr1 = hpts[0]; - } - else - { - p_extr1 = c1.source(); - } - } - else - { - // An x-monotone curve cannot have more than 1 horizontal tangencies. - CGAL_assertion (false); - } - - n_hpts = c2.horizontal_tangency_points(hpts); - if (n_hpts == 0) - { - // No horizontal tangency points - the source must have an extreme - // y-value. - p_extr2 = c2.source(); - } - else if (n_hpts == 1) - { - // Use the vertical tangency points only if it lies between the source - // and p_int. Otherwise, use the source. - if (compare_x(c2.source(), hpts[0]) == SMALLER && - compare_x(p_int, hpts[0]) == LARGER) - { - p_extr2 = hpts[0]; - } - else - { - p_extr2 = c2.source(); - } - } - else - { - // An x-monotone curve cannot have more than 1 horizontal tangencies. - CGAL_assertion (false); - } - - // Use the x-coordinate of the point next to x. - Comparison_result result = compare_x (p_extr1, p_extr2); - - if (result == SMALLER) - { - n_hpts = c1.get_points_at_x (p_extr2.x(), hpts); - CGAL_assertion(n_hpts == 1); - p_extr1 = hpts[0]; - } - else if (result == LARGER) - { - n_hpts = c2.get_points_at_x (p_extr1.x(), hpts); - CGAL_assertion(n_hpts == 1); - p_extr2 = hpts[0]; - } - - // Compare the y-coordinates of the two extreme points. - Comparison_result extr_result = _compare_y (p_extr1, p_extr2); - - if (extr_result != EQUAL) - return (extr_result); - - // As a last resort: - NT x_mid = (p_extr1.x() + p_int.x()) / NT(2); - Point_2 p_mid1, p_mid2; - - n_hpts = c1.get_points_at_x (x_mid, hpts); - CGAL_assertion(n_hpts == 1); - p_mid1 = hpts[0]; - - n_hpts = c2.get_points_at_x (x_mid, hpts); - CGAL_assertion(n_hpts == 1); - p_mid2 = hpts[0]; - - Comparison_result mid_result = _compare_y (p_mid1, p_mid2); - - if (mid_result != EQUAL) - return (mid_result); - - // If we reached here, the two curves must be overlapping: - int n_ovlps; - X_monotone_curve_2 ovlp_arcs[2]; - - n_ovlps = curve1.overlaps (curve2, ovlp_arcs); - CGAL_assertion (n_ovlps == 1); - return (EQUAL); - } - - // Decide wether curve1 is above, below or equal to curve2 immediately to - // the right of the x co-ordinate of the given point. - Comparison_result - curves_compare_y_at_x_right(const X_monotone_curve_2& curve1, - const X_monotone_curve_2& curve2, - const Point_2& p) const - { - CGAL_precondition(is_x_monotone(curve1)); - CGAL_precondition(is_x_monotone(curve2)); - - // The two curve must not be vertical segments. - CGAL_precondition(! curve1.is_vertical_segment()); - CGAL_precondition(! curve2.is_vertical_segment()); - - // Check that both curves are defined to the right of p. - CGAL_precondition((compare_x(curve1.source(), p) == LARGER) || - (compare_x(curve1.target(), p) == LARGER)); - - CGAL_precondition((compare_x(curve2.source(), p) == LARGER) || - (compare_x(curve2.target(), p) == LARGER)); - - // Get the points on curve1 with the same x co-ordinate as p. - int n1; - Point_2 ps1[2]; - - if (curve1.contains_point(p)) - { - ps1[0] = p; - n1 = 1; - } - else - { - n1 = curve1.get_points_at_x (p.x(), ps1); - } - - // Make sure we have a single point. - CGAL_assertion(n1 == 1); - - // Get the points on curve2 with the same x co-ordinate as p. - int n2; - Point_2 ps2[2]; - - if (curve2.contains_point(p)) - { - ps2[0] = p; - n2 = 1; - } - else - { - n2 = curve2.get_points_at_x (p.x(), ps2); - } - - // Make sure we have a single point. - CGAL_assertion(n2 == 1); - - // Make sure the two curves intersect at x(p). - CGAL_precondition(_compare_y (ps1[0], ps2[0]) == EQUAL); - - // If the two curves are the same, they are equal to the right of p: - if (curve_equal(curve1,curve2)) - return (EQUAL); - - // Otherwise, the two curves do intersect at p_int = ps1[0] = ps2[0]: - // make a decision based on their partial derivatives. - const Point_2& p_int = ps1[0]; - - // In order to simplify the process, make sure the source is always to the - // right of p. - X_monotone_curve_2 c1 = curve1; - X_monotone_curve_2 c2 = curve2; - - if (compare_x(c1.source(), p) != LARGER) - c1 = curve1.flip(); - if (compare_x(c2.source(), p) != LARGER) - c2 = curve2.flip(); - - // Calculate the partial derivatives at the intersection point. - NT dC1_dx, dC1_dy; - NT dC2_dx, dC2_dy; - const NT zero = 0; - - c1.partial_derivatives (p_int, dC1_dx, dC1_dy); - c2.partial_derivatives (p_int, dC2_dx, dC2_dy); - - // Try to compare the slopes of the two arcs. - if (dC1_dy != zero && dC2_dy != zero) - { - Comparison_result slope_result = _compare_value (dC2_dx/dC2_dy, - dC1_dx/dC1_dy); - if (slope_result != EQUAL) - { - return (slope_result); - } - } - - // If we reached here, the two curves intersect at p_int, and their - // tangents at this point have the same slope. We shall therefore find - // a point with extreme y-coordinate for each curve and compare the - // y-values of these two extreme points. - Point_2 p_extr1, p_extr2; - Point_2 hpts[2]; - int n_hpts; - - n_hpts = c1.horizontal_tangency_points(hpts); - if (n_hpts == 0) - { - // No horizontal tangency points - the source must have an extreme - // y-value. - p_extr1 = c1.source(); - } - else if (n_hpts == 1) - { - // Use the vertical tangency points only if it lies between p_int - // and the source. Otherwise, use the source. - if (compare_x(c1.source(), hpts[0]) == LARGER && - compare_x(p_int, hpts[0]) == SMALLER) - { - p_extr1 = hpts[0]; - } - else - { - p_extr1 = c1.source(); - } - } - else - { - // An x-monotone curve cannot have more than 1 horizontal tangencies. - CGAL_assertion (false); - } - - n_hpts = c2.horizontal_tangency_points(hpts); - if (n_hpts == 0) - { - // No horizontal tangency points - the source must have an extreme - // y-value. - p_extr2 = c2.source(); - } - else if (n_hpts == 1) - { - // Use the vertical tangency points only if it lies between p_int - // and the source. Otherwise, use the source. - if (compare_x(c2.source(), hpts[0]) == LARGER && - compare_x(p_int, hpts[0]) == SMALLER) - { - p_extr2 = hpts[0]; - } - else - { - p_extr2 = c2.source(); - } - } - else - { - // An x-monotone curve cannot have more than 1 horizontal tangencies. - CGAL_assertion (false); - } - - // Use the x-coordinate of the point next to x. - Comparison_result result = compare_x (p_extr1, p_extr2); - - if (result == LARGER) - { - n_hpts = c1.get_points_at_x (p_extr2.x(), hpts); - CGAL_assertion(n_hpts == 1); - p_extr1 = hpts[0]; - } - else if (result == SMALLER) - { - n_hpts = c2.get_points_at_x (p_extr1.x(), hpts); - CGAL_assertion(n_hpts == 1); - p_extr2 = hpts[0]; - } - - // Compare the y-coordinates of the two extreme points. - Comparison_result extr_result = _compare_y (p_extr1, p_extr2); - - if (extr_result != EQUAL) - return (extr_result); - - // As a last resort: - NT x_mid = (p_extr1.x() + p_int.x()) / NT(2); - Point_2 p_mid1, p_mid2; - - n_hpts = c1.get_points_at_x (x_mid, hpts); - CGAL_assertion(n_hpts == 1); - p_mid1 = hpts[0]; - - n_hpts = c2.get_points_at_x (x_mid, hpts); - CGAL_assertion(n_hpts == 1); - p_mid2 = hpts[0]; - - Comparison_result mid_result = _compare_y (p_mid1, p_mid2); - - if (mid_result != EQUAL) - return (mid_result); - - // If we reached here, the two curves must be overlapping: - int n_ovlps; - X_monotone_curve_2 ovlp_arcs[2]; - - n_ovlps = curve1.overlaps (curve2, ovlp_arcs); - CGAL_assertion (n_ovlps == 1); - return (EQUAL); - } - - // Check whether the given point is above, under or on the given curve. - Comparison_result curve_compare_y_at_x(const Point_2& p, - const X_monotone_curve_2& curve) const - { - CGAL_precondition(is_x_monotone(curve)); - CGAL_precondition(point_in_x_range(curve, p)); - - // A special treatment for vertical segments: - if (curve.is_vertical_segment()) - { - Comparison_result res1 = _compare_y (p, curve.source()); - Comparison_result res2 = _compare_y (p, curve.target()); - - if (res1 == res2) - return (res1); - else - return (EQUAL); - } - - // Get the points on the arc with the same x co-ordinate as p. - int n; - Point_2 ps[2]; - - n = curve.get_points_at_x (p.x(), ps); - - // Make sure there is at most one point. - CGAL_assertion(n == 1); - - // Compare p with the a point of the curve with the same x co-ordinate. - return (_compare_y (p, ps[0])); - } - - // Check whether the two curves are identical. - bool curve_equal(const Point_2 & p, const Point_2 & q) const - { - return (p == q); - } - - // Check whether the two curves are identical. - bool curve_equal(const X_monotone_curve_2& curve1, - const X_monotone_curve_2& curve2) const - { - CGAL_precondition(is_x_monotone(curve1)); - CGAL_precondition(is_x_monotone(curve2)); - - // Check whether all arc features are the same. - if (curve1.conic().orientation() == curve2.conic().orientation()) - { - // Same orientation: - return (curve1.conic() == curve2.conic() && - curve1.source() == curve2.source() && - curve1.target() == curve2.target()); - } - else - { - // Check the flip case: - return (curve1.conic() == curve2.conic() && - curve1.source() == curve2.target() && - curve1.target() == curve2.source()); - } - } - - // Get the source and target vertex of the curve. - Point_2 curve_source(const X_monotone_curve_2& curve) const - { - return (curve.source()); - } - - Point_2 curve_target(const X_monotone_curve_2& curve) const - { - return (curve.target()); - } - - // Reflect a point in y. - Point_2 point_reflect_in_y (const Point_2& p) const - { - // Use hx(), hy(), hw() in order to support both Homogeneous and Cartesian. - return (Point_2 (-p.hx(), p.hy(), p.hw())); - } - - // Reflect a curve in y. - X_monotone_curve_2 curve_reflect_in_y(const X_monotone_curve_2& curve) const - { - Conic ref_conic (curve.conic().r(), - curve.conic().s(), - -curve.conic().t(), - -curve.conic().u(), - curve.conic().v(), - curve.conic().w()); - X_monotone_curve_2 ref_arc (ref_conic, - point_reflect_in_y (curve.source()), - point_reflect_in_y (curve.target())); - return (ref_arc); - } - - // Reflect a point in x and y. - Point_2 point_reflect_in_x_and_y (const Point_2& p) const - { - // Use hx(), hy(), hw() in order to support both Homogeneous and Cartesian. - return (Point_2 (-p.hx(), -p.hy(), p.hw())); - } - - // Reflect a curve in x and y. - X_monotone_curve_2 - curve_reflect_in_x_and_y(const X_monotone_curve_2& curve) const - { - Conic ref_conic (curve.conic().r(), - curve.conic().s(), - curve.conic().t(), - -curve.conic().u(), - -curve.conic().v(), - curve.conic().w()); - X_monotone_curve_2 ref_arc (ref_conic, - point_reflect_in_x_and_y (curve.source()), - point_reflect_in_x_and_y (curve.target())); - return (ref_arc); - } - - - ////////// Arrangement methods: ////////// - - // Change the orientation of the curve (swap the source and the target). - X_monotone_curve_2 curve_opposite (const X_monotone_curve_2& curve) const - { - CGAL_precondition(is_x_monotone(curve)); - - // Flip the arc. - return (curve.flip()); - } - - // Check whether the curve is x-monotone. - bool is_x_monotone (const Curve_2& curve) const - { - return (curve.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 - OutputIterator curve_make_x_monotone(const Curve_2 & curve, - OutputIterator o) const - { - if (is_x_monotone(curve)) { - *o++ = curve; - return o; - } - - // Find the points of vertical tangency and act accordingly. - int n; - Point_2 ps[2]; - - n = curve.vertical_tangency_points (ps); - - CGAL_assertion (n > 0); - - // Split the conic arc into x-monotone sub-curves. - if (curve.is_full_conic()) - { - // Make sure we have two vertical tangency points. - CGAL_assertion(n == 2); - - // In case the curve is a full conic, split it to two x-monotone curves, - // one going from ps[0] to ps[1], and the other from ps[1] to ps[0]. - *o++ = X_monotone_curve_2 (curve.conic(), ps[0], ps[1]); - *o++ = X_monotone_curve_2 (curve.conic(), ps[1], ps[0]); - } - else - { - X_monotone_curve_2 sub_curve1; - X_monotone_curve_2 sub_curve2; - X_monotone_curve_2 sub_curve3; - - if (n == 1) - { - // Split the arc into two x-monotone sub-curves: one going from the - // arc source to ps[0], and the other from ps[0] to the target. - _curve_split (curve, - sub_curve1, sub_curve2, - ps[0]); - - *o++ = sub_curve1; - *o++ = sub_curve2; - } - else if (n == 2) - { - // Split the arc into three x-monotone sub-curves: one going from the - // arc source to ps[0], one from ps[0] to ps[1], and the last one - // from ps[1] to the target. - // Notice that ps[0] and ps[1] might switch places. - X_monotone_curve_2 temp; - - _curve_split (curve, - sub_curve1, sub_curve2, - ps[0]); - - if (sub_curve2.contains_point(ps[1])) - { - temp = sub_curve2; - _curve_split (temp, - sub_curve2, sub_curve3, - ps[1]); - } - else if (sub_curve1.contains_point(ps[1])) - { - // Actually we switch between ps[0] and ps[1]. - temp = sub_curve1; - sub_curve3 = sub_curve2; - _curve_split (temp, - sub_curve1, sub_curve2, - ps[1]); - } - else - { - // We should never reach here: - CGAL_assertion(false); - } - - *o++ = sub_curve1; - *o++ = sub_curve2; - *o++ = sub_curve3; - } - else - { - // We should never reach here: - CGAL_assertion(false); - } - } - - return o; - } - - // Split the given curve into two sub-curves at the given point. - void curve_split (const X_monotone_curve_2& curve, - X_monotone_curve_2& sub_curve1, - X_monotone_curve_2& sub_curve2, - const Point_2& p) const - { - CGAL_precondition(is_x_monotone(curve)); - - // Make sure the point is on the curve and is not an end-point. - CGAL_precondition(curve.contains_point(p)); - CGAL_precondition(curve_source(curve) != p); - CGAL_precondition(curve_target(curve) != p); - - // Split the curve. - _curve_split (curve, - sub_curve1, sub_curve2, - p); - return; - } - - // Find the nearest intersection point between the two given curves to the - // right of the given point. - // In case of an overlap, p1 and p2 are the source and destination of the - // overlapping curve. Otherwise p1=p2 is the calculated intersection point. - bool nearest_intersection_to_right (const X_monotone_curve_2& curve1, - const X_monotone_curve_2& curve2, - const Point_2& p, - Point_2& p1, - Point_2& p2) const - { - CGAL_precondition(is_x_monotone(curve1)); - CGAL_precondition(is_x_monotone(curve2)); - - // Deal with overlapping curves: - int n_ovlps; - X_monotone_curve_2 ovlp_arcs[2]; - - n_ovlps = curve1.overlaps (curve2, ovlp_arcs); - CGAL_assertion (n_ovlps < 2); - - if (n_ovlps == 1) - { - Point_2 ovlp_source = ovlp_arcs[0].source(); - Point_2 ovlp_target = ovlp_arcs[0].target(); - - if (compare_lexicographically_xy (ovlp_source, p) == LARGER && - compare_lexicographically_xy (ovlp_target, p) == LARGER) - { - // The entire overlapping arc is to the right of p: - p1 = ovlp_source; - p2 = ovlp_target; - return (true); - } - else if (compare_lexicographically_xy (ovlp_source, p) != LARGER && - compare_lexicographically_xy (ovlp_target, p) == LARGER) - { - // The source is to the left of p, and the traget is to its right. - p1 = p; - p2 = ovlp_target; - return (true); - } - else if (compare_lexicographically_xy (ovlp_source, p) == LARGER && - compare_lexicographically_xy (ovlp_target, p) != LARGER) - { - // The source is to the right of p, and the traget is to its left. - p1 = ovlp_source; - p2 = p; - return (true); - } - else - { - // The entire overlapping arc is to the left of p: - return (false); - } - } - - // In case there are no overlaps and the base conics are the same, - // there cannot be any intersection points, unless the two x-monotone - // curves share an end point. - if (curve1.conic() == curve2.conic()) - { - const Point_2 *nearest_end_P = NULL; - - if ((curve1.source() == curve2.source() || - curve1.source() == curve2.target()) && - compare_lexicographically_xy (curve1.source(), p) == LARGER) - { - nearest_end_P = &(curve1.source()); - } - - if ((curve1.target() == curve2.source() || - curve1.target() == curve2.target()) && - compare_lexicographically_xy (curve1.target(), p) == LARGER) - { - if (nearest_end_P == NULL || - compare_lexicographically_xy (*nearest_end_P, - curve1.target()) == LARGER) - { - nearest_end_P = &(curve1.target()); - } - } - - if (nearest_end_P != NULL) - { - // A common end point was found: - p1 = p2 = *nearest_end_P; - return (true); - } - else - { - // No intersection: - return (false); - } - } - - // Find the intersection points and choose the one nearest to p. - int n; - Point_2 ps[4]; - const Point_2 *nearest_inter_P = NULL; - - n = curve1.intersections_with (curve2, ps); - - for (int i = 0; i < n; i++) - { - if (compare_lexicographically_xy (ps[i], p) == LARGER) - { - if (nearest_inter_P == NULL) - { - // The first point to the right so far: - nearest_inter_P = &(ps[i]); - } - else - { - // Compare with the nearest point so far. - if (compare_lexicographically_xy (ps[i], - *nearest_inter_P) == SMALLER) - nearest_inter_P = &(ps[i]); - } - } - } - - if (nearest_inter_P != NULL) - { - // Return the nearest intersection point. - p1 = p2 = *nearest_inter_P; - return (true); - } - - // No intersection found. - return (false); - } - - // Check whether two curves overlap. - bool curves_overlap(const X_monotone_curve_2& curve1, - const X_monotone_curve_2& curve2) const - { - CGAL_precondition(is_x_monotone(curve1)); - CGAL_precondition(is_x_monotone(curve2)); - - X_monotone_curve_2 ovlp_arcs[2]; - - return (curve1.overlaps (curve2, ovlp_arcs) > 0); - } - - // Check if the two points are the same. - bool point_equal(const Point_2 & p1, const Point_2 & p2) const - { - return (compare_xy(p1, p2) == EQUAL); - } - -private: - - ////////// Private auxiliary methods: ////////// - - // Compare two values. - Comparison_result _compare_value (const NT& a, const NT& b) const - { - return CGAL::compare(a,b); - } - - // Compare the y coordinates of the two points. - Comparison_result _compare_y(const Point_2 & p0, const Point_2 & p1) const - { - return _compare_value(p0.y(),p1.y()); - } - - // Split the given curve into two sub-curves at the given point. - // Since this is a private function, there are no preconditions. - void _curve_split (const X_monotone_curve_2& curve, - X_monotone_curve_2& sub_curve1, - X_monotone_curve_2& sub_curve2, - const Point_2 & p) const - { - // Split the curve to source->p and p->target. - sub_curve1 = X_monotone_curve_2 (curve.conic(), curve.source(), p); - sub_curve2 = X_monotone_curve_2 (curve.conic(), p, curve.target()); - - return; - } - -}; - -CGAL_END_NAMESPACE - -#endif diff --git a/Packages/Arrangement/include/CGAL/Arrangement_2/Conic_arc_2.h b/Packages/Arrangement/include/CGAL/Arrangement_2/Conic_arc_2.h index d0119db378e..7663dde648e 100644 --- a/Packages/Arrangement/include/CGAL/Arrangement_2/Conic_arc_2.h +++ b/Packages/Arrangement/include/CGAL/Arrangement_2/Conic_arc_2.h @@ -56,12 +56,12 @@ enum // static int _conics_count = 0; -template class Arr_conic_traits_2; +template class Arr_conic_traits_2; template class Conic_arc_2 { -private: +protected: typedef Conic_arc_2 Self; public: @@ -78,7 +78,7 @@ public: typedef Point_2_ex 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(results[k]*results[k], 0) != EQUAL) + if (results[k] > 1 || + (all_approx && n_ipts == min_points) || + (n_ipts >= min_points && + eps_compare(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 diff --git a/Packages/Arrangement/include/CGAL/IO/Arr_circle_traits_Window_stream.h b/Packages/Arrangement/include/CGAL/IO/Arr_circle_traits_Window_stream.h deleted file mode 100644 index f57460d366b..00000000000 --- a/Packages/Arrangement/include/CGAL/IO/Arr_circle_traits_Window_stream.h +++ /dev/null @@ -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 ) -// -// ====================================================================== -#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_BEGIN_NAMESPACE - -#ifndef ARR_IDDO_DEBUG -//a simple version of the windowstream operator (sufficient for X_curve) -template -Window_stream& operator<<(Window_stream& os, - //const typename - //Arr_circles_real_traits::Curve &cv) - const Circ_Curve& 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 -Window_stream& operator<<(Window_stream& os, - //const Arr_circles_real_traits::Curve &cv) - const Circ_Curve& 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 - - - - diff --git a/Packages/Arrangement/include/CGAL/IO/Conic_arc_2_Window_stream.h b/Packages/Arrangement/include/CGAL/IO/Conic_arc_2_Window_stream.h index 6adc0f6dcca..ce1a5f2dd5a 100644 --- a/Packages/Arrangement/include/CGAL/IO/Conic_arc_2_Window_stream.h +++ b/Packages/Arrangement/include/CGAL/IO/Conic_arc_2_Window_stream.h @@ -18,8 +18,8 @@ // coordinator : Tel-Aviv University (Dan Halperin ) // // ====================================================================== -#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 #include diff --git a/Packages/Arrangement/include/CGAL/IO/Segment_circle_Window_stream.h b/Packages/Arrangement/include/CGAL/IO/Segment_circle_Window_stream.h deleted file mode 100644 index 7677f0b88b6..00000000000 --- a/Packages/Arrangement/include/CGAL/IO/Segment_circle_Window_stream.h +++ /dev/null @@ -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 -// author(s) : Ron Wein -// coordinator : Tel-Aviv University (Dan Halperin ) -// -// ====================================================================== -#ifndef SEGMENT_CIRCLE_WINDOW_STREAM_H -#define SEGMENT_CIRCLE_WINDOW_STREAM_H - -#include -#include - -CGAL_BEGIN_NAMESPACE - -template -Window_stream& operator<<(Window_stream& os, - const Segment_circle_2& 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::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::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 diff --git a/Packages/Arrangement/include/CGAL/Segment_circle_2.h b/Packages/Arrangement/include/CGAL/Segment_circle_2.h deleted file mode 100644 index fe3db26aab7..00000000000 --- a/Packages/Arrangement/include/CGAL/Segment_circle_2.h +++ /dev/null @@ -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 -// author(s) : Ron Wein -// coordinator : Tel-Aviv University (Dan Halperin ) -// -// ====================================================================== -#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 -#include - -#include -#include - - -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 -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 Segment_circle_2 -{ - - public: - - typedef Cartesian R; - typedef Point_2 Point; - typedef Conic_2 Conic; - typedef Circle_2 Circle; - typedef Segment_2 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& 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 (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& 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* vertical_P = NULL; - const Segment_circle_2* 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& arc, - Segment_circle_2* 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(_conic, _source, *arc_targetP); - ovlp_arcs[1] = Segment_circle_2(_conic, *arc_sourceP, _target); - return (2); - } - - // Case 1 - *this: +-----------> - // arc: +=====> - ovlp_arcs[0] = Segment_circle_2(_conic, *arc_sourceP,*arc_targetP); - return (1); - } - else - { - // Case 2 - *this: +-----------> - // arc: +=====> - ovlp_arcs[0] = Segment_circle_2(_conic, *arc_sourceP, _target); - return (1); - } - } - else if (_is_strictly_between_endpoints(*arc_targetP)) - { - // Case 3 - *this: +-----------> - // arc: +=====> - ovlp_arcs[0] = Segment_circle_2(_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(_source, p, _target)); - else - return (right_turn(_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 -std::ostream& operator<< (std::ostream& os, const Segment_circle_2& arc) -{ - typename Segment_circle_2::Conic conic = arc.conic(); - typename Segment_circle_2::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 diff --git a/Packages/Arrangement/test/Arrangement_2/cgal_test b/Packages/Arrangement/test/Arrangement_2/cgal_test index 489f5fadb5a..87cad05f680 100755 --- a/Packages/Arrangement/test/Arrangement_2/cgal_test +++ b/Packages/Arrangement/test/Arrangement_2/cgal_test @@ -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 diff --git a/Packages/Arrangement/test/Arrangement_2/test_arr.C b/Packages/Arrangement/test/Arrangement_2/test_arr.C index bd60e3bb3f9..886667773af 100644 --- a/Packages/Arrangement/test/Arrangement_2/test_arr.C +++ b/Packages/Arrangement/test/Arrangement_2/test_arr.C @@ -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 #include #include -#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS +#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS #include - #include + #include #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 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 Traits; + typedef CGAL::Cartesian K; + typedef CGAL::Arr_conic_traits_2 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 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); diff --git a/Packages/Arrangement/test/Arrangement_2/test_assignment.C b/Packages/Arrangement/test/Arrangement_2/test_assignment.C index 7d6322f3031..b8c440cca58 100644 --- a/Packages/Arrangement/test/Arrangement_2/test_assignment.C +++ b/Packages/Arrangement/test/Arrangement_2/test_assignment.C @@ -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 #include #include -#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_CIRCLE_TRAITS +#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS #include - #include + #include #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 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 Traits; + typedef CGAL::Arr_conic_traits_2 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); diff --git a/Packages/Arrangement/test/Arrangement_2_Traits/Arr_circles_real_traits_test.C b/Packages/Arrangement/test/Arrangement_2_Traits/Arr_circles_real_traits_test.C deleted file mode 100644 index 40b8855e3d3..00000000000 --- a/Packages/Arrangement/test/Arrangement_2_Traits/Arr_circles_real_traits_test.C +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include -#include - -// 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 -#include -#include - -#include "include/Circles_traits_test_base.h" - -typedef leda_real NT; -typedef CGAL::Arr_circles_real_traits 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 { - - typedef Arr_traits_test::Traits Traits; - - void build_curve_list(std::list& 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 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) ... diff --git a/Packages/Arrangement/test/Arrangement_2_Traits/Arr_segment_circle_traits_test.C b/Packages/Arrangement/test/Arrangement_2_Traits/Arr_segment_circle_traits_test.C deleted file mode 100644 index 2c93a40f579..00000000000 --- a/Packages/Arrangement/test/Arrangement_2_Traits/Arr_segment_circle_traits_test.C +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -// 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 -#include "include/Segment_circle_traits_test.h" -#include - -typedef leda_real NT; -typedef CGAL::Arr_segment_circle_traits Traits; - -int main (int argc, char** argv) -{ - Segment_circle_traits_test test_obj (argc, argv); - - if (test_obj.start()) - return (0); // SUCCESS - else - return (1); // FAILURE -} - -#endif // ! defined(CGAL_USE_LEDA) ... diff --git a/Packages/Arrangement/test/Arrangement_2_Traits/cgal_test b/Packages/Arrangement/test/Arrangement_2_Traits/cgal_test index 0975b8fbf5d..1f0b9e35950 100755 --- a/Packages/Arrangement/test/Arrangement_2_Traits/cgal_test +++ b/Packages/Arrangement/test/Arrangement_2_Traits/cgal_test @@ -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