1 // Copyright (c) 2006,2007,2008,2009,2010,2011 Max-Planck-Institute Saarbruecken (Germany). 2 // All rights reserved. 3 // 4 // This file is part of CGAL (www.cgal.org) 5 // 6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Arrangement_on_surface_2/include/CGAL/Arr_algebraic_segment_traits_2.h $ 7 // $Id: Arr_algebraic_segment_traits_2.h d08f8b4 2020-07-02T19:09:51+03:00 Efi Fogel 8 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial 9 // 10 // 11 // Author(s): Michael Kerber <mkerber@mpi-inf.mpg.de> 12 // 13 // ============================================================================ 14 15 #ifndef CGAL_ARR_ALGEBRAIC_SEGMENT_TRAITS 16 #define CGAL_ARR_ALGEBRAIC_SEGMENT_TRAITS 17 18 #include <CGAL/disable_warnings.h> 19 20 #include <CGAL/config.h> 21 22 #include <CGAL/Algebraic_kernel_d/flags.h> 23 #include <CGAL/Algebraic_kernel_d_1.h> 24 #include <CGAL/Algebraic_kernel_d/Algebraic_curve_kernel_2.h> 25 26 #include <CGAL/Curved_kernel_via_analysis_2/Curved_kernel_via_analysis_2_impl.h> 27 28 #include <boost/optional.hpp> 29 #include <boost/none.hpp> 30 31 namespace CGAL { 32 33 template< class Coefficient_ > 34 class Arr_algebraic_segment_traits_2 { 35 36 public: 37 38 enum Site_of_point { 39 POINT_IN_INTERIOR = 0, 40 MIN_ENDPOINT = -1, 41 MAX_ENDPOINT = 1 }; 42 43 // Template argument 44 45 typedef Coefficient_ Coefficient; 46 47 // 'derivation' 48 typedef CGAL::Algebraic_kernel_d_1< Coefficient > Algebraic_kernel_d_1; 49 50 typedef CGAL::Algebraic_curve_kernel_2< Algebraic_kernel_d_1 > 51 Algebraic_kernel_d_2; 52 53 typedef CGAL::Curved_kernel_via_analysis_2< Algebraic_kernel_d_2 > CKvA_2; 54 55 typedef CGAL::Arr_algebraic_segment_traits_2<Coefficient> Self; 56 57 // Default constructor Arr_algebraic_segment_traits_2()58 Arr_algebraic_segment_traits_2 () {} 59 60 61 // Copy constructor Arr_algebraic_segment_traits_2(const Self &)62 Arr_algebraic_segment_traits_2 (const Self& /* s */) { /* No state...*/} 63 64 // Assignement operator 65 const Self& operator= (const Self& s) 66 {return s;} 67 68 // public types 69 70 typedef typename Algebraic_kernel_d_2::Algebraic_real_1 Algebraic_real_1; 71 typedef typename Algebraic_kernel_d_2::Bound Bound; 72 73 typedef typename Algebraic_kernel_d_2::Polynomial_2 Polynomial_2; 74 75 /// public types for ArrangementTraits_2 76 77 typedef typename Algebraic_kernel_d_2::Curve_analysis_2 Curve_2; 78 79 typedef typename CKvA_2::Arc_2 X_monotone_curve_2; 80 81 typedef typename CKvA_2::Point_2 Point_2; 82 83 84 typedef typename CKvA_2::Has_left_category Has_left_category; 85 typedef typename CKvA_2::Has_merge_category Has_merge_category; 86 typedef typename CKvA_2::Has_do_intersect_category 87 Has_do_intersect_category; 88 89 typedef typename CKvA_2::Left_side_category Left_side_category; 90 typedef typename CKvA_2::Bottom_side_category Bottom_side_category; 91 typedef typename CKvA_2::Top_side_category Top_side_category; 92 typedef typename CKvA_2::Right_side_category Right_side_category; 93 94 typedef typename CKvA_2::Multiplicity Multiplicity; 95 96 typedef typename CKvA_2::Compare_x_2 Compare_x_2; compare_x_2_object()97 Compare_x_2 compare_x_2_object() const { 98 return CKvA_2::instance().compare_x_2_object(); 99 } 100 101 typedef typename CKvA_2::Compare_xy_2 Compare_xy_2; compare_xy_2_object()102 Compare_xy_2 compare_xy_2_object() const { 103 return CKvA_2::instance().compare_xy_2_object(); 104 } 105 106 typedef typename CKvA_2::Compare_endpoints_xy_2 Compare_endpoints_xy_2; compare_endpoints_xy_2_object()107 Compare_endpoints_xy_2 compare_endpoints_xy_2_object() const { 108 return CKvA_2::instance().compare_endpoints_xy_2_object(); 109 } 110 111 typedef typename CKvA_2::Equal_2 Equal_2; equal_2_object()112 Equal_2 equal_2_object() const { 113 return CKvA_2::instance().equal_2_object(); 114 } 115 116 typedef typename CKvA_2::Parameter_space_in_y_2 Parameter_space_in_y_2; parameter_space_in_y_2_object()117 Parameter_space_in_y_2 parameter_space_in_y_2_object() const { 118 return CKvA_2::instance().parameter_space_in_y_2_object(); 119 } 120 121 typedef typename CKvA_2::Compare_y_near_boundary_2 122 Compare_y_near_boundary_2; compare_y_near_boundary_2_object()123 Compare_y_near_boundary_2 compare_y_near_boundary_2_object() const { 124 return CKvA_2::instance().compare_y_near_boundary_2_object(); 125 } 126 127 typedef typename CKvA_2::Parameter_space_in_x_2 Parameter_space_in_x_2; parameter_space_in_x_2_object()128 Parameter_space_in_x_2 parameter_space_in_x_2_object() const { 129 return CKvA_2::instance().parameter_space_in_x_2_object(); 130 } 131 132 typedef typename CKvA_2::Compare_x_at_limit_2 Compare_x_at_limit_2; compare_x_at_limit_2_object()133 Compare_x_at_limit_2 compare_x_at_limit_2_object() const { 134 return CKvA_2::instance().compare_x_at_limit_2_object(); 135 } 136 137 typedef typename CKvA_2::Compare_x_near_limit_2 Compare_x_near_limit_2; compare_x_near_limit_2_object()138 Compare_x_near_limit_2 compare_x_near_limit_2_object() const { 139 return CKvA_2::instance().compare_x_near_limit_2_object(); 140 } 141 142 typedef typename CKvA_2::Construct_min_vertex_2 Construct_min_vertex_2; construct_min_vertex_2_object()143 Construct_min_vertex_2 construct_min_vertex_2_object() const { 144 return CKvA_2::instance().construct_min_vertex_2_object(); 145 } 146 147 typedef typename CKvA_2::Construct_max_vertex_2 Construct_max_vertex_2; construct_max_vertex_2_object()148 Construct_max_vertex_2 construct_max_vertex_2_object() const { 149 return CKvA_2::instance().construct_max_vertex_2_object(); 150 } 151 152 typedef typename CKvA_2::Construct_opposite_2 Construct_opposite_2; construct_opposite_2_object()153 Construct_opposite_2 construct_opposite_2_object() const { 154 return CKvA_2::instance().construct_opposite_2_object(); 155 } 156 157 typedef typename CKvA_2::Is_vertical_2 Is_vertical_2; is_vertical_2_object()158 Is_vertical_2 is_vertical_2_object() const { 159 return CKvA_2::instance().is_vertical_2_object(); 160 } 161 162 typedef typename CKvA_2::Compare_y_at_x_2 Compare_y_at_x_2; compare_y_at_x_2_object()163 Compare_y_at_x_2 compare_y_at_x_2_object() const { 164 return CKvA_2::instance().compare_y_at_x_2_object(); 165 } 166 167 typedef typename CKvA_2::Compare_y_at_x_left_2 Compare_y_at_x_left_2; compare_y_at_x_left_2_object()168 Compare_y_at_x_left_2 compare_y_at_x_left_2_object() const { 169 return CKvA_2::instance().compare_y_at_x_left_2_object(); 170 } 171 172 typedef typename CKvA_2::Compare_y_at_x_right_2 Compare_y_at_x_right_2; compare_y_at_x_right_2_object()173 Compare_y_at_x_right_2 compare_y_at_x_right_2_object() const { 174 return CKvA_2::instance().compare_y_at_x_right_2_object(); 175 } 176 177 typedef typename CKvA_2::Intersect_2 Intersect_2; intersect_2_object()178 Intersect_2 intersect_2_object() const { 179 return CKvA_2::instance().intersect_2_object(); 180 } 181 182 typedef typename CKvA_2::Split_2 Split_2; split_2_object()183 Split_2 split_2_object() const { 184 return CKvA_2::instance().split_2_object(); 185 } 186 187 typedef typename CKvA_2::Are_mergeable_2 Are_mergeable_2; are_mergeable_2_object()188 Are_mergeable_2 are_mergeable_2_object() const { 189 return CKvA_2::instance().are_mergeable_2_object(); 190 } 191 192 typedef typename CKvA_2::Merge_2 Merge_2; merge_2_object()193 Merge_2 merge_2_object() const { 194 return CKvA_2::instance().merge_2_object(); 195 } 196 197 typedef typename CKvA_2::Make_x_monotone_2 Make_x_monotone_2; make_x_monotone_2_object()198 Make_x_monotone_2 make_x_monotone_2_object() const { 199 return Make_x_monotone_2(&CKvA_2::instance()); 200 } 201 202 typedef typename CKvA_2::Is_on_2 Is_on_2; 203 is_on_2_object()204 Is_on_2 is_on_2_object() const { 205 return Is_on_2(&CKvA_2::instance()); 206 } 207 208 typedef typename CKvA_2::Construct_point_2 Construct_point_2; 209 construct_point_2_object()210 Construct_point_2 construct_point_2_object() const { 211 return Construct_point_2(&CKvA_2::instance()); 212 } 213 214 215 class Construct_x_monotone_segment_2 : public 216 CGAL::internal::Curved_kernel_via_analysis_2_Functors:: 217 Curved_kernel_via_analysis_2_functor_base< CKvA_2 > { 218 219 public: 220 221 typedef CGAL::internal::Curved_kernel_via_analysis_2_Functors:: 222 Curved_kernel_via_analysis_2_functor_base< CKvA_2 > Base; 223 Construct_x_monotone_segment_2(CKvA_2 * kernel)224 Construct_x_monotone_segment_2(CKvA_2* kernel) : Base(kernel) {} 225 226 227 private: 228 229 // helper function, returning the number of incident branches 230 // of a point wrt to a curve 231 std::pair<std::pair<int,int>, bool> branch_numbers_and_vertical(Curve_2 cv,Point_2 p)232 branch_numbers_and_vertical(Curve_2 cv, Point_2 p) const { 233 234 Equal_2 equal = this->_ckva()->equal_2_object(); 235 236 Algebraic_real_1 x = p.x(); 237 int no; 238 bool is_event; 239 cv.x_to_index(x,no,is_event); 240 if(! is_event) { 241 return std::make_pair(std::make_pair(1,1),false); 242 } 243 typename Curve_2::Status_line_1 status_line 244 = cv.status_line_at_event(no); 245 bool vertical = status_line.covers_line(); 246 for(int i = 0; i < status_line.number_of_events(); i++) { 247 Point_2 curr_point(x,cv,i); 248 if(equal(p,curr_point)) { 249 return std::make_pair( 250 status_line.number_of_incident_branches(i), 251 vertical); 252 } 253 } 254 return std::make_pair(std::make_pair(0,0),vertical); 255 } 256 257 // abbrevation for convenience is_one_one(Curve_2 cv,Point_2 p)258 bool is_one_one(Curve_2 cv, Point_2 p) const { 259 260 std::pair<std::pair<int,int>,bool> branches 261 = branch_numbers_and_vertical(cv,p); 262 return branches.first.first==1 && branches.first.second==1 263 && !branches.second; 264 265 } 266 267 template <typename OutputIterator> OutputIterator x_monotone_segment(Curve_2 cv,Point_2 p,boost::optional<Point_2> start,boost::optional<Point_2> end,OutputIterator out)268 x_monotone_segment(Curve_2 cv, 269 Point_2 p, 270 boost::optional<Point_2> start, 271 boost::optional<Point_2> end, 272 OutputIterator out) const 273 { 274 typedef boost::variant<Point_2, X_monotone_curve_2> 275 Make_x_monotone_result; 276 //CGAL_assertion(is_one_one(cv,p)); 277 278 std::list<X_monotone_curve_2> segs; 279 280 Is_on_2 on_arc = this->_ckva()->is_on_2_object(); 281 auto left = this->_ckva()->construct_min_vertex_2_object(); 282 auto right = this->_ckva()->construct_max_vertex_2_object(); 283 Equal_2 equal = this->_ckva()->equal_2_object(); 284 285 std::vector<Make_x_monotone_result> arcs; 286 this->_ckva()->make_x_monotone_2_object()(cv, std::back_inserter(arcs)); 287 auto it = arcs.begin(); 288 auto helper = it; 289 const auto* it_seg_p = boost::get<X_monotone_curve_2>(&(*it)); 290 while (it != arcs.end()) { 291 if ( on_arc(p, *it_seg_p) ) break; 292 it++; 293 it_seg_p = boost::get<X_monotone_curve_2>(&(*it)); 294 } 295 296 bool left_on_arc = start && on_arc(start.get(), *it_seg_p); 297 bool right_on_arc = end && on_arc(end.get(), *it_seg_p); 298 299 if ( left_on_arc && right_on_arc ) { 300 segs.push_back(it_seg_p->trim(start.get(),end.get())); 301 } 302 if (left_on_arc && (!right_on_arc)) { 303 if (!it_seg_p->is_finite(CGAL::ARR_MAX_END) || 304 !equal(start.get(),right(*it_seg_p))) { 305 if (it_seg_p->is_finite(CGAL::ARR_MIN_END) && 306 equal(start.get(),left(*it_seg_p))) 307 { 308 segs.push_back(*it_seg_p); 309 } 310 else { 311 X_monotone_curve_2 split1,split2; 312 it_seg_p->split(start.get(),split1,split2); 313 segs.push_back(split2); 314 } 315 } 316 } 317 if ((!left_on_arc) && right_on_arc) { 318 if (!it_seg_p->is_finite(CGAL::ARR_MIN_END) || 319 ! equal(left(*it_seg_p), end.get())) 320 { 321 if (it_seg_p->is_finite(CGAL::ARR_MAX_END) && 322 equal(end.get(), right(*it_seg_p))) 323 { 324 segs.push_back(*it_seg_p); 325 } 326 else { 327 X_monotone_curve_2 split1,split2; 328 it_seg_p->split(end.get(), split1, split2); 329 segs.push_back(split1); 330 } 331 } 332 } 333 if ( (!left_on_arc) && (!right_on_arc)) { 334 segs.push_back(*it_seg_p); 335 } 336 helper = it; // for later usage 337 338 if (! left_on_arc) { 339 340 Point_2 point_it; 341 while (true) { 342 if (it_seg_p->is_finite(CGAL::ARR_MIN_END) && 343 is_one_one(cv, left(*it_seg_p) ) ) { 344 point_it = left(*it_seg_p); 345 } else { 346 CGAL_assertion(! start); 347 break; 348 } 349 CGAL_assertion(it != arcs.begin()); 350 it--; 351 it_seg_p = boost::get<X_monotone_curve_2>(&(*it)); 352 while (! on_arc(point_it, *it_seg_p)) { 353 CGAL_assertion(it != arcs.begin()); 354 it--; 355 it_seg_p = boost::get<X_monotone_curve_2>(&(*it)); 356 } 357 if (start && on_arc(start.get(),*it_seg_p)) { 358 segs.push_front(it_seg_p->trim(start.get(), right(*it_seg_p))); 359 break; 360 } 361 else { 362 segs.push_front(*it_seg_p); 363 } 364 } 365 } 366 if (! right_on_arc) { 367 it = helper; // reset 368 it_seg_p = boost::get<X_monotone_curve_2>(&(*it)); 369 Point_2 point_it; 370 while (true) { 371 if (it_seg_p->is_finite(CGAL::ARR_MAX_END) && 372 is_one_one(cv,right(*it_seg_p) ) ) 373 { 374 point_it=right(*it_seg_p); 375 } else { 376 CGAL_assertion(! end); 377 break; 378 } 379 it++; 380 CGAL_assertion(it != arcs.end()); 381 it_seg_p = boost::get<X_monotone_curve_2>(&(*it)); 382 while(! on_arc(point_it, *it_seg_p)) { 383 it++; 384 CGAL_assertion(it != arcs.end()); 385 it_seg_p = boost::get<X_monotone_curve_2>(&(*it)); 386 } 387 if(end && on_arc(end.get(),*it_seg_p)) { 388 segs.push_back(it_seg_p->trim(left(*it_seg_p),end.get())); 389 break; 390 } 391 else { 392 segs.push_back(*it_seg_p); 393 } 394 } 395 } 396 397 std::copy(segs.begin(), segs.end(), out); 398 return out; 399 400 } 401 402 public: 403 404 template<typename OutputIterator> OutputIterator operator()405 operator() (Curve_2 cv, 406 Point_2 p, 407 Site_of_point site_of_p, 408 OutputIterator out) const { 409 if(site_of_p==POINT_IN_INTERIOR) { 410 return x_monotone_segment(cv,p,boost::none, boost::none,out); 411 } else if(site_of_p==MIN_ENDPOINT) { 412 return x_monotone_segment(cv, 413 p, 414 boost::optional<Point_2>(p), 415 boost::none, 416 out); 417 } 418 CGAL_assertion(site_of_p==MAX_ENDPOINT); 419 return x_monotone_segment(cv, 420 p, 421 boost::none, 422 boost::optional<Point_2>(p), 423 out); 424 } 425 426 427 template<typename OutputIterator> OutputIterator operator()428 operator() (Curve_2 cv, 429 Point_2 end_left, 430 Point_2 end_right, 431 OutputIterator out) const { 432 433 434 435 CGAL_assertion((branch_numbers_and_vertical(cv,end_left). 436 first.second==1 && 437 !branch_numbers_and_vertical(cv,end_left).second)|| 438 (branch_numbers_and_vertical(cv,end_right). 439 first.first==1 && 440 !branch_numbers_and_vertical(cv,end_right).second) 441 || 442 (branch_numbers_and_vertical(cv,end_left). 443 first.second==0 && 444 branch_numbers_and_vertical(cv,end_left).second) || 445 (branch_numbers_and_vertical(cv,end_right). 446 first.first==0 && 447 branch_numbers_and_vertical(cv,end_right).second)); 448 CGAL_assertion_code( 449 if((branch_numbers_and_vertical(cv,end_left). 450 first.second==0 && 451 branch_numbers_and_vertical(cv,end_left).second) || 452 (branch_numbers_and_vertical(cv,end_right). 453 first.first==0 && 454 branch_numbers_and_vertical(cv,end_right).second)) { 455 Compare_x_2 equal_x 456 = this->_ckva()->compare_x_2_object(); ) 457 CGAL_assertion(equal_x(end_left,end_right)==CGAL::EQUAL); 458 CGAL_assertion_code(}); 459 460 461 if( (branch_numbers_and_vertical(cv,end_left). 462 first.second==0 && 463 branch_numbers_and_vertical(cv,end_left).second) || 464 (branch_numbers_and_vertical(cv,end_left). 465 first.second==1 && 466 !branch_numbers_and_vertical(cv,end_left).second)) { 467 468 return x_monotone_segment 469 (cv, 470 end_left, 471 boost::optional<Point_2>(end_left), 472 boost::optional<Point_2>(end_right), 473 out); 474 } else { 475 return x_monotone_segment 476 (cv, 477 end_right, 478 boost::optional<Point_2>(end_left), 479 boost::optional<Point_2>(end_right), 480 out); 481 } 482 } 483 484 template<typename OutputIterator> OutputIterator 485 operator() (Point_2 p, Point_2 q, OutputIterator out) { 486 bool same_x=(this->_ckva()->compare_x_2_object()(p,q)==CGAL::EQUAL); 487 if(same_x) { 488 Algebraic_real_1 x = p.x(); 489 Polynomial_2 f = Polynomial_2(x.polynomial()); 490 Curve_2 cv 491 = this->_ckva()->kernel().construct_curve_2_object() (f); 492 *out++=typename CKvA_2::Arc_2(p,q,cv); 493 return out; 494 } 495 Algebraic_real_1 px 496 =this->_ckva()->kernel().compute_x_2_object()(p.xy()), 497 py=this->_ckva()->kernel().compute_y_2_object()(p.xy()), 498 qx=this->_ckva()->kernel().compute_x_2_object()(q.xy()), 499 qy=this->_ckva()->kernel().compute_y_2_object()(q.xy()); 500 bool p_rat=px.is_rational() && py.is_rational(); 501 bool q_rat=qx.is_rational() && qy.is_rational(); 502 if(p_rat && q_rat) { 503 typedef typename Algebraic_real_1::Rational Rational; 504 Rational pxr=px.rational(), pyr=py.rational(), 505 qxr=qx.rational(), qyr=qy.rational(); 506 typedef CGAL::Fraction_traits<Rational> FT; 507 typename FT::Decompose decompose; 508 typedef typename FT::Numerator_type Numerator; 509 typedef typename FT::Denominator_type Denominator; 510 Rational term_at_y=qxr-pxr, term_at_x=-qyr+pyr, 511 term_at_1=pxr*qyr-pyr*qxr; 512 Denominator denom_curr; 513 Numerator term_at_y_int, term_at_x_int, term_at_1_int; 514 decompose(term_at_y, term_at_y_int, denom_curr); 515 term_at_x=term_at_x*denom_curr; 516 term_at_1=term_at_1*denom_curr; 517 decompose(term_at_x,term_at_x_int,denom_curr); 518 term_at_y_int=term_at_y_int*denom_curr; 519 term_at_1=term_at_1*denom_curr; 520 decompose(term_at_1,term_at_1_int,denom_curr); 521 term_at_y_int=term_at_y_int*denom_curr; 522 term_at_x_int=term_at_x_int*denom_curr; 523 typedef typename CGAL::Polynomial_traits_d<Polynomial_2> 524 ::Coefficient_type Polynomial_1; 525 Polynomial_2 pol(Polynomial_1(term_at_1_int,term_at_x_int), 526 Polynomial_1(term_at_y_int)); 527 Curve_2 curve=this->_ckva()->kernel().construct_curve_2_object() 528 (pol); 529 530 CGAL_assertion(this->_ckva()->is_on_2_object()(p,curve)); 531 CGAL_assertion(this->_ckva()->is_on_2_object()(q,curve)); 532 return this->operator()(curve,p,q,out); 533 } 534 CGAL_precondition(same_x || (p_rat && q_rat)); 535 return out; 536 } 537 }; 538 539 Construct_x_monotone_segment_2 construct_x_monotone_segment_2_object() 540 const { 541 return Construct_x_monotone_segment_2(&CKvA_2::instance()); 542 } 543 544 /* 545 546 class Construct_vertical_segment_2 : public 547 CGAL::internal::Curved_kernel_via_analysis_2_Functors:: 548 Curved_kernel_via_analysis_2_functor_base< CKvA_2 > { 549 550 public: 551 552 typedef CGAL::internal::Curved_kernel_via_analysis_2_Functors:: 553 Curved_kernel_via_analysis_2_functor_base< CKvA_2 > Base; 554 555 Construct_vertical_segment_2(CKvA_2* kernel) : Base(kernel) {} 556 557 558 public: 559 560 X_monotone_curve_2 operator() (Point_2 p, Point_2 q) { 561 Algebraic_real_1 x = p.x(); 562 Polynomial_2 f = Polynomial_2(x.polynomial()); 563 Curve_2 cv 564 = this->_ckva()->kernel().construct_curve_2_object() (f); 565 return typename CKvA_2::Arc_2(p,q,cv); 566 } 567 568 569 template<typename OutputIterator> OutputIterator 570 operator() (Point_2 p, 571 Site_of_point site_of_p) const { 572 Algebraic_real_1 x = p.x(); 573 Polynomial_2 f = Polynomial_2(x.polynomial()); 574 Curve_2 cv = this->_ckva().kernel().construct_curve_2_object() (f); 575 576 if(site_of_p==POINT_IN_INTERIOR) { 577 return typename CKvA_2::Arc_2(x,cv); 578 } else if(site_of_p==MIN_ENDPOINT) { 579 return typename CKvA_2::Arc_2(p,ARR_MIN_END,cv); 580 } 581 CGAL_assertion(site_of_p==MAX_ENDPOINT); 582 return typename CKvA_2::Arc_2(p,ARR_MAX_END,cv); 583 584 } 585 }; 586 587 Construct_vertical_segment_2 construct_vertical_segment_2_object() const { 588 return Construct_vertical_segment_2(&CKvA_2::instance()); 589 } 590 591 */ 592 593 class Construct_curve_2 : public 594 CGAL::internal::Curved_kernel_via_analysis_2_Functors:: 595 Curved_kernel_via_analysis_2_functor_base< CKvA_2 > { 596 597 public: 598 599 typedef CGAL::internal::Curved_kernel_via_analysis_2_Functors:: 600 Curved_kernel_via_analysis_2_functor_base< CKvA_2 > Base; 601 602 Construct_curve_2(CKvA_2* kernel) : Base(kernel) {} 603 604 Curve_2 operator() (Polynomial_2 p) const { 605 return this->_ckva()->kernel().construct_curve_2_object() (p); 606 } 607 }; 608 609 Construct_curve_2 construct_curve_2_object() const { 610 return Construct_curve_2(&CKvA_2::instance()); 611 } 612 613 614 615 616 617 /* 618 619 // additional functionality (for not introducing a "general" arc) 620 621 class Connect_points_2 { 622 623 624 template< class OutputIterator > 625 OutputIterator operator() (Curve_2, Point_2, Point_2, ..., 626 OutputIterator) { 627 628 629 while (false || true) { 630 *oi++ = X_monotone_curve_2(...); 631 } 632 633 return oi; 634 } 635 636 template< class OutputIterator > 637 OutputIterator operator() (Curve_2, Point_2, Point_2, int, ..., 638 OutputIterator) { 639 640 641 while (false || true) { 642 *oi++ = X_monotone_curve_2(...); 643 } 644 645 return oi; 646 } 647 648 }; 649 650 */ 651 652 }; 653 654 } //namespace CGAL 655 656 #include <CGAL/enable_warnings.h> 657 658 #endif // CGAL_ARR_ALGEBRAIC_SEGMENT_TRAITS 659