BWAPI
|
00001 // Copyright (c) 2008 INRIA Sophia-Antipolis (France). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Circular_kernel_3/include/CGAL/Circular_kernel_3/internal_functions_on_sphere_3.h $ 00015 // $Id: internal_functions_on_sphere_3.h 44381 2008-07-24 09:26:28Z pmachado $ 00016 // 00017 // Author(s) : Monique Teillaud, Sylvain Pion, Pedro Machado 00018 00019 // Partially supported by the IST Programme of the EU as a 00020 // STREP (FET Open) Project under Contract No IST-006413 00021 // (ACS -- Algorithms for Complex Shapes) 00022 00023 #ifndef CGAL_SPHERICAL_KERNEL_PREDICATES_ON_SPHERE_3_H 00024 #define CGAL_SPHERICAL_KERNEL_PREDICATES_ON_SPHERE_3_H 00025 00026 namespace CGAL { 00027 namespace SphericalFunctors { 00028 00029 template < class SK > 00030 typename SK::Algebraic_kernel::Polynomials_for_line_3 00031 get_equation( const typename SK::Line_3 & l) 00032 { 00033 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00034 return Algebraic_kernel().construct_polynomials_for_line_3_object() 00035 (l.to_vector().x(), l.point().x(), 00036 l.to_vector().y(), l.point().y(), 00037 l.to_vector().z(), l.point().z()); 00038 } 00039 00040 template < class SK > 00041 typename SK::Polynomial_1_3 00042 get_equation( const typename SK::Plane_3 & s ) 00043 { 00044 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00045 return Algebraic_kernel().construct_polynomial_1_3_object() 00046 ( s.a(), s.b(), s.c(), s.d() ); 00047 } 00048 00049 template < class SK > 00050 typename SK::Polynomial_for_spheres_2_3 00051 get_equation( const typename SK::Sphere_3 & s ) 00052 { 00053 typedef typename SK::RT RT; 00054 typedef typename SK::Point_3 Point_3; 00055 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00056 Point_3 center = s.center(); 00057 return Algebraic_kernel().construct_polynomial_for_spheres_2_3_object() 00058 ( center.x(), center.y(), center.z(), s.squared_radius() ); 00059 } 00060 00061 template < class SK > 00062 typename SK::Polynomials_for_circle_3 00063 get_equation( const typename SK::Circle_3 & c ) 00064 { 00065 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00066 return std::make_pair ( Algebraic_kernel().construct_polynomial_for_spheres_2_3_object() 00067 (c.center().x(), c.center().y(), 00068 c.center().z(), c.squared_radius()), 00069 Algebraic_kernel().construct_polynomial_1_3_object() 00070 (c.supporting_plane().a(), 00071 c.supporting_plane().b(), 00072 c.supporting_plane().c(), 00073 c.supporting_plane().d())); 00074 } 00075 00076 template < class SK > 00077 typename SK::Sphere_3 00078 construct_sphere_3(const typename SK::Polynomial_for_spheres_2_3 &eq) 00079 { 00080 typedef typename SK::Sphere_3 Sphere_3; 00081 typedef typename SK::Point_3 Point_3; 00082 return Sphere_3(Point_3(eq.a(),eq.b(),eq.c()),eq.r_sq()); 00083 } 00084 00085 00086 template < class SK > 00087 inline 00088 typename SK::Linear_kernel::Bounded_side_3::result_type 00089 bounded_side(const typename SK::Sphere_3 &s, 00090 const typename SK::Circular_arc_point_3 &p) { 00091 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00092 typedef typename SK::Polynomial_for_spheres_2_3 Equation; 00093 Equation equation = get_equation<SK>(s); 00094 Sign sign = Algebraic_kernel().sign_at_object()(equation,p.rep().coordinates()); 00095 if(sign == NEGATIVE) return ON_BOUNDED_SIDE; 00096 else if(sign == POSITIVE) return ON_UNBOUNDED_SIDE; 00097 else return ON_BOUNDARY; 00098 } 00099 00100 template < class SK > 00101 inline 00102 typename SK::Linear_kernel::Bounded_side 00103 bounded_side(const typename SK::Circle_3 &c, 00104 const typename SK::Circular_arc_point_3 &p) { 00105 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00106 typedef typename SK::Polynomial_for_spheres_2_3 Equation; 00107 CGAL_kernel_assertion(SK().has_on_3_object()(c.supporting_plane(),p)); 00108 Equation equation = get_equation<SK>(c.diametral_sphere()); 00109 Sign sign = Algebraic_kernel().sign_at_object()(equation,p.rep().coordinates()); 00110 if(sign == NEGATIVE) return ON_BOUNDED_SIDE; 00111 else if(sign == POSITIVE) return ON_UNBOUNDED_SIDE; 00112 else return ON_BOUNDARY; 00113 } 00114 00115 template < class SK > 00116 inline 00117 bool 00118 non_oriented_equal(const typename SK::Sphere_3 & s1, 00119 const typename SK::Sphere_3 & s2) 00120 { 00121 // Should we compare anyway even if they are degenerated? 00122 CGAL_kernel_assertion(!(s1.is_degenerate() || s2.is_degenerate())); 00123 return s1.center() == s2.center() && 00124 s1.squared_radius() == s2.squared_radius(); 00125 } 00126 00127 template < class SK > 00128 inline 00129 bool 00130 non_oriented_equal(const typename SK::Plane_3 & p1, 00131 const typename SK::Plane_3 & p2) 00132 { 00133 // Should we compare anyway even if they are degenerated? 00134 CGAL_kernel_assertion(!(p1.is_degenerate() || p2.is_degenerate())); 00135 if(is_zero(p1.a())) { 00136 if(!is_zero(p2.a())) return false; 00137 if(is_zero(p1.b())) { 00138 if(!is_zero(p2.b())) return false; 00139 return p1.c() * p2.d() == p1.d() * p2.c(); 00140 } 00141 return (p2.c() * p1.b() == p1.c() * p2.b()) && 00142 (p2.d() * p1.b() == p1.d() * p2.b()); 00143 } 00144 return (p2.b() * p1.a() == p1.b() * p2.a()) && 00145 (p2.c() * p1.a() == p1.c() * p2.a()) && 00146 (p2.d() * p1.a() == p1.d() * p2.a()); 00147 } 00148 00149 template < class SK > 00150 inline 00151 bool 00152 non_oriented_equal(const typename SK::Circle_3 & c1, 00153 const typename SK::Circle_3 & c2) { 00154 // We see degeneracies on the other non_oriented_equal functions 00155 if(!non_oriented_equal<SK>(c1.diametral_sphere(), c2.diametral_sphere())) return false; 00156 if(!non_oriented_equal<SK>(c1.supporting_plane(), c2.supporting_plane())) return false; 00157 return true; 00158 } 00159 00160 template< class SK> 00161 bool 00162 non_oriented_equal(const typename SK::Line_3 &l1, 00163 const typename SK::Line_3 &l2) 00164 { 00165 typedef typename SK::Vector_3 Vector_3; 00166 if(!SK().has_on_3_object()(l1, l2.point())) return false; 00167 00168 const Vector_3& v1 = l1.to_vector(); 00169 const Vector_3& v2 = l2.to_vector(); 00170 00171 if(v1.x() * v2.y() != v1.y() * v2.x()) return false; 00172 if(v1.x() * v2.z() != v1.z() * v2.x()) return false; 00173 if(v1.y() * v2.z() != v1.z() * v2.y()) return false; 00174 00175 return true; 00176 } 00177 00178 template< class SK> 00179 bool 00180 non_oriented_equal( const typename SK::Line_arc_3 &l1, 00181 const typename SK::Line_arc_3 &l2) 00182 { 00183 if(!non_oriented_equal<SK>(l1.supporting_line(), 00184 l2.supporting_line())) return false; 00185 return (l1.lower_xyz_extremity() == l2.lower_xyz_extremity()) && 00186 (l1.higher_xyz_extremity() == l2.higher_xyz_extremity()); 00187 } 00188 00189 template< class SK> 00190 bool 00191 non_oriented_equal( const typename SK::Circular_arc_3 &c1, 00192 const typename SK::Circular_arc_3 &c2) 00193 { 00194 if(!non_oriented_equal<SK>(c1.supporting_circle(), 00195 c2.supporting_circle())) return false; 00196 if(c1.rep().is_full() && c2.rep().is_full()) 00197 return true; 00198 return (c1.source() == c2.source()) && 00199 (c1.target() == c2.target()); 00200 } 00201 00202 template < class SK, class OutputIterator > 00203 OutputIterator 00204 intersect_3(const typename SK::Sphere_3 & s, 00205 const typename SK::Line_3 & l, 00206 OutputIterator res) 00207 { 00208 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00209 typedef typename SK::Polynomial_for_spheres_2_3 Equation_sphere; 00210 typedef typename SK::Polynomials_for_line_3 Equation_line; 00211 typedef typename SK::Root_for_spheres_2_3 Root_for_spheres_2_3; 00212 typedef typename SK::Circular_arc_point_3 Circular_arc_point_3; 00213 CGAL_kernel_precondition(!s.is_degenerate()); 00214 CGAL_kernel_precondition(!l.is_degenerate()); 00215 Equation_sphere e1 = get_equation<SK>(s); 00216 Equation_line e2 = get_equation<SK>(l); 00217 typedef std::vector< std::pair < Root_for_spheres_2_3, unsigned > > 00218 solutions_container; 00219 solutions_container solutions; 00220 Algebraic_kernel().solve_object()(e1, e2, std::back_inserter(solutions)); 00221 for ( typename solutions_container::iterator it = solutions.begin(); 00222 it != solutions.end(); ++it ) { 00223 *res++ = make_object(std::make_pair(Circular_arc_point_3(it->first), 00224 it->second )); 00225 } 00226 return res; 00227 } 00228 00229 namespace CGALi { 00230 00231 // It just converts when the solution is a Point_3 to Circular_arc_point_3 00232 00233 template < class SK, class OutputIterator > 00234 OutputIterator 00235 intersect_special(const typename SK::Sphere_3 & s1, 00236 const typename SK::Sphere_3 & s2, 00237 OutputIterator res) 00238 { 00239 Object obj = SK().intersect_3_object()(s1, s2); 00240 if(obj.is_empty()) return res; 00241 typename SK::Point_3 p; 00242 if(assign(p, obj)) { 00243 typename SK::Circular_arc_point_3 cp = p; 00244 *res++ = make_object(std::make_pair(cp,2u)); 00245 } else { 00246 *res++ = obj; 00247 } return res; 00248 } 00249 00250 template < class SK, class OutputIterator > 00251 OutputIterator 00252 intersect_special(const typename SK::Plane_3 & plane, 00253 const typename SK::Sphere_3 & sphere, 00254 OutputIterator res) 00255 { 00256 Object obj = SK().intersect_3_object()(plane, sphere); 00257 if(obj.is_empty()) return res; 00258 typename SK::Point_3 p; 00259 if(assign(p, obj)) { 00260 typename SK::Circular_arc_point_3 cp = p; 00261 *res++ = make_object(std::make_pair(cp,2u)); 00262 } else { 00263 *res++ = obj; 00264 } return res; 00265 } 00266 00267 template < class SK, class OutputIterator > 00268 OutputIterator 00269 intersect_special(const typename SK::Sphere_3 & sphere, 00270 const typename SK::Plane_3 & plane, 00271 OutputIterator res) 00272 { 00273 Object obj = SK().intersect_3_object()(plane, sphere); 00274 if(obj.is_empty()) return res; 00275 typename SK::Point_3 p; 00276 if(assign(p, obj)) { 00277 typename SK::Circular_arc_point_3 cp = p; 00278 *res++ = make_object(std::make_pair(cp,2u)); 00279 } else { 00280 *res++ = obj; 00281 } return res; 00282 } 00283 00284 } 00285 00286 template < class SK, class OutputIterator > 00287 OutputIterator 00288 intersect_3(const typename SK::Sphere_3 & s1, 00289 const typename SK::Sphere_3 & s2, 00290 const typename SK::Sphere_3 & s3, 00291 OutputIterator res) 00292 { 00293 typedef typename SK::Polynomial_for_spheres_2_3 Equation_sphere; 00294 typedef typename SK::Root_for_spheres_2_3 Root_for_spheres_2_3; 00295 typedef typename SK::Circular_arc_point_3 Circular_arc_point_3; 00296 typedef typename SK::Circle_3 Circle_3; 00297 typedef typename SK::Point_3 Point_3; 00298 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00299 typedef std::vector< Object > solutions_container; 00300 CGAL_kernel_precondition(!s1.is_degenerate()); 00301 CGAL_kernel_precondition(!s2.is_degenerate()); 00302 CGAL_kernel_precondition(!s3.is_degenerate()); 00303 if(non_oriented_equal<SK>(s1,s2) && non_oriented_equal<SK>(s2,s3)) { 00304 *res++ = make_object(s1); 00305 return res; 00306 } 00307 if(non_oriented_equal<SK>(s1,s2)) { 00308 return CGALi::intersect_special<SK>(s1, s3, res); 00309 } 00310 if((non_oriented_equal<SK>(s1,s3)) || 00311 (non_oriented_equal<SK>(s2,s3))) { 00312 return CGALi::intersect_special<SK>(s1, s2, res); 00313 } 00314 if(SK().collinear_3_object()(s1.center(),s2.center(),s3.center())) { 00315 Object obj = SK().intersect_3_object()(s1, s2); 00316 if(obj.is_empty()) return res; 00317 Point_3 p; 00318 if(assign(p, obj)) { 00319 if(SK().has_on_3_object()(s3, p)) { 00320 Circular_arc_point_3 cp = p; 00321 *res++ = make_object(std::make_pair(cp,2u)); 00322 return res; 00323 } else return res; 00324 } 00325 // must be a circle 00326 Circle_3 c; 00327 assign(c, obj); 00328 if(SK().has_on_3_object()(s3,c)) { 00329 *res++ = obj; 00330 return res; 00331 } 00332 return res; 00333 } 00334 Equation_sphere e1 = get_equation<SK>(s1); 00335 Equation_sphere e2 = get_equation<SK>(s2); 00336 Equation_sphere e3 = get_equation<SK>(s3); 00337 typedef std::vector< std::pair < Root_for_spheres_2_3, unsigned > > 00338 algebraic_solutions_container; 00339 algebraic_solutions_container solutions; 00340 Algebraic_kernel().solve_object()(e1, e2, e3, std::back_inserter(solutions)); 00341 for ( typename algebraic_solutions_container::iterator it = 00342 solutions.begin(); it != solutions.end(); ++it ) { 00343 *res++ = make_object(std::make_pair(Circular_arc_point_3(it->first), 00344 it->second )); 00345 } 00346 return res; 00347 } 00348 00349 template < class SK, class OutputIterator > 00350 OutputIterator 00351 intersect_3(const typename SK::Plane_3 & p, 00352 const typename SK::Sphere_3 & s1, 00353 const typename SK::Sphere_3 & s2, 00354 OutputIterator res) 00355 { 00356 typedef typename SK::Root_for_spheres_2_3 Root_for_spheres_2_3; 00357 typedef typename SK::Circular_arc_point_3 Circular_arc_point_3; 00358 typedef typename SK::Polynomial_for_spheres_2_3 Equation_sphere; 00359 typedef typename SK::Polynomial_1_3 Equation_plane; 00360 typedef typename SK::Plane_3 Plane_3; 00361 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00362 CGAL_kernel_precondition(!p.is_degenerate()); 00363 CGAL_kernel_precondition(!s1.is_degenerate()); 00364 CGAL_kernel_precondition(!s2.is_degenerate()); 00365 if(non_oriented_equal<SK>(s1,s2)) { 00366 return CGALi::intersect_special<SK>(p,s1,res); 00367 } 00368 Plane_3 radical_p = SK().construct_radical_plane_3_object()(s1,s2); 00369 if(non_oriented_equal<SK>(p,radical_p)) { 00370 return CGALi::intersect_special<SK>(p,s1,res); 00371 } 00372 Equation_sphere e1 = get_equation<SK>(s1); 00373 Equation_sphere e2 = get_equation<SK>(s2); 00374 Equation_plane e3 = get_equation<SK>(p); 00375 typedef std::vector< std::pair < Root_for_spheres_2_3, unsigned > > 00376 algebraic_solutions_container; 00377 algebraic_solutions_container solutions; 00378 Algebraic_kernel().solve_object()(e1, e2, e3, std::back_inserter(solutions)); 00379 for ( typename algebraic_solutions_container::iterator it = 00380 solutions.begin(); it != solutions.end(); ++it ) { 00381 *res++ = make_object(std::make_pair(Circular_arc_point_3(it->first), 00382 it->second )); 00383 } 00384 return res; 00385 } 00386 00387 template < class SK, class OutputIterator > 00388 OutputIterator 00389 intersect_3(const typename SK::Plane_3 & p1, 00390 const typename SK::Plane_3 & p2, 00391 const typename SK::Sphere_3 & s, 00392 OutputIterator res) 00393 { 00394 typedef typename SK::Root_for_spheres_2_3 Root_for_spheres_2_3; 00395 typedef typename SK::Circular_arc_point_3 Circular_arc_point_3; 00396 typedef typename SK::Polynomial_for_spheres_2_3 Equation_sphere; 00397 typedef typename SK::Polynomial_1_3 Equation_plane; 00398 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00399 CGAL_kernel_precondition(!p1.is_degenerate()); 00400 CGAL_kernel_precondition(!p2.is_degenerate()); 00401 CGAL_kernel_precondition(!s.is_degenerate()); 00402 if(non_oriented_equal<SK>(p1,p2)) { 00403 return CGALi::intersect_special<SK>(p1,s,res); 00404 } 00405 Equation_plane e1 = get_equation<SK>(p1); 00406 Equation_plane e2 = get_equation<SK>(p2); 00407 Equation_sphere e3 = get_equation<SK>(s); 00408 typedef std::vector< std::pair < Root_for_spheres_2_3, unsigned > > 00409 algebraic_solutions_container; 00410 algebraic_solutions_container solutions; 00411 Algebraic_kernel().solve_object()(e1, e2, e3, std::back_inserter(solutions)); 00412 for ( typename algebraic_solutions_container::iterator it = 00413 solutions.begin(); it != solutions.end(); ++it ) { 00414 *res++ = make_object(std::make_pair(Circular_arc_point_3(it->first), 00415 it->second )); 00416 } 00417 return res; 00418 } 00419 00420 template < class SK, class OutputIterator > 00421 OutputIterator 00422 intersect_3(const typename SK::Circle_3 & c, 00423 const typename SK::Plane_3 & p, 00424 OutputIterator res) 00425 { 00426 return intersect_3<SK>(p,c.supporting_plane(),c.diametral_sphere(),res); 00427 } 00428 00429 template < class SK, class OutputIterator > 00430 OutputIterator 00431 intersect_3(const typename SK::Circle_3 & c, 00432 const typename SK::Sphere_3 & s, 00433 OutputIterator res) 00434 { 00435 return intersect_3<SK>(c.supporting_plane(),s,c.diametral_sphere(),res); 00436 } 00437 00438 template < class SK, class OutputIterator > 00439 OutputIterator 00440 intersect_3(const typename SK::Circle_3 & c1, 00441 const typename SK::Circle_3 & c2, 00442 OutputIterator res) 00443 { 00444 typedef typename SK::Root_for_spheres_2_3 Root_for_spheres_2_3; 00445 typedef typename SK::Circular_arc_point_3 Circular_arc_point_3; 00446 typedef typename SK::Polynomials_for_circle_3 Equation_circle; 00447 typedef typename SK::Circle_3 Circle_3; 00448 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00449 if(non_oriented_equal<SK>(c1,c2)) { 00450 *res++ = make_object(c1); 00451 return res; 00452 } 00453 Equation_circle e1 = get_equation<SK>(c1); 00454 Equation_circle e2 = get_equation<SK>(c2); 00455 typedef std::vector< std::pair < Root_for_spheres_2_3, unsigned > > 00456 algebraic_solutions_container; 00457 algebraic_solutions_container solutions; 00458 Algebraic_kernel().solve_object()(e1, e2, std::back_inserter(solutions)); 00459 for ( typename algebraic_solutions_container::iterator it = 00460 solutions.begin(); it != solutions.end(); ++it ) { 00461 *res++ = make_object(std::make_pair(Circular_arc_point_3(it->first), 00462 it->second )); 00463 } 00464 return res; 00465 } 00466 00467 template < class SK, class OutputIterator > 00468 OutputIterator 00469 intersect_3(const typename SK::Circle_3 & c, 00470 const typename SK::Line_3 & l, 00471 OutputIterator res) 00472 { 00473 typedef typename SK::Root_for_spheres_2_3 Root_for_spheres_2_3; 00474 typedef typename SK::Circular_arc_point_3 Circular_arc_point_3; 00475 typedef typename SK::Polynomials_for_circle_3 Equation_circle; 00476 typedef typename SK::Polynomials_for_line_3 Equation_line; 00477 typedef typename SK::Circle_3 Circle_3; 00478 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00479 CGAL_kernel_precondition(!l.is_degenerate()); 00480 Equation_circle e1 = get_equation<SK>(c); 00481 Equation_line e2 = get_equation<SK>(l); 00482 typedef std::vector< std::pair < Root_for_spheres_2_3, unsigned > > 00483 algebraic_solutions_container; 00484 algebraic_solutions_container solutions; 00485 Algebraic_kernel().solve_object()(e1, e2, std::back_inserter(solutions)); 00486 for ( typename algebraic_solutions_container::iterator it = 00487 solutions.begin(); it != solutions.end(); ++it ) { 00488 *res++ = make_object(std::make_pair(Circular_arc_point_3(it->first), 00489 it->second )); 00490 } 00491 return res; 00492 } 00493 00494 // At the moment we dont need those functions 00495 // But in the future maybe (some make_x_monotone? etc..) 00496 template <class SK> 00497 typename SK::Circular_arc_point_3 00498 x_extremal_point(const typename SK::Sphere_3 & c, bool i) 00499 { 00500 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00501 return Algebraic_kernel().x_critical_points_object()(typename SK::Get_equation()(c),i); 00502 } 00503 00504 template <class SK,class OutputIterator> 00505 OutputIterator 00506 x_extremal_points(const typename SK::Sphere_3 & c, OutputIterator res) 00507 { 00508 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00509 return Algebraic_kernel().x_critical_points_object()(typename SK::Get_equation()(c),res); 00510 } 00511 00512 template <class SK> 00513 typename SK::Circular_arc_point_3 00514 y_extremal_point(const typename SK::Sphere_3 & c, bool i) 00515 { 00516 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00517 return Algebraic_kernel().y_critical_points_object()(typename SK::Get_equation()(c),i); 00518 } 00519 00520 template <class SK,class OutputIterator> 00521 OutputIterator 00522 y_extremal_points(const typename SK::Sphere_3 & c, OutputIterator res) 00523 { 00524 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00525 return Algebraic_kernel().y_critical_points_object()(typename SK::Get_equation()(c),res); 00526 } 00527 00528 template <class SK> 00529 typename SK::Circular_arc_point_3 00530 z_extremal_point(const typename SK::Sphere_3 & c, bool i) 00531 { 00532 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00533 return Algebraic_kernel().z_critical_points_object()(typename SK::Get_equation()(c),i); 00534 } 00535 00536 template <class SK,class OutputIterator> 00537 OutputIterator 00538 z_extremal_points(const typename SK::Sphere_3 & c, OutputIterator res) 00539 { 00540 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00541 return Algebraic_kernel().z_critical_points_object()(typename SK::Get_equation()(c),res); 00542 } 00543 00544 template <class SK> 00545 typename SK::Circular_arc_point_3 00546 x_extremal_point(const typename SK::Circle_3 & c, bool i) 00547 { 00548 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00549 return Algebraic_kernel().x_critical_points_object()(typename SK::Get_equation()(c),i); 00550 } 00551 00552 template <class SK,class OutputIterator> 00553 OutputIterator 00554 x_extremal_points(const typename SK::Circle_3 & c, OutputIterator res) 00555 { 00556 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00557 return Algebraic_kernel().x_critical_points_object()(typename SK::Get_equation()(c),res); 00558 } 00559 00560 template <class SK> 00561 typename SK::Circular_arc_point_3 00562 y_extremal_point(const typename SK::Circle_3 & c, bool i) 00563 { 00564 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00565 return Algebraic_kernel().y_critical_points_object()(typename SK::Get_equation()(c),i); 00566 } 00567 00568 template <class SK,class OutputIterator> 00569 OutputIterator 00570 y_extremal_points(const typename SK::Circle_3 & c, OutputIterator res) 00571 { 00572 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00573 return Algebraic_kernel().y_critical_points_object()(typename SK::Get_equation()(c),res); 00574 } 00575 00576 template <class SK> 00577 typename SK::Circular_arc_point_3 00578 z_extremal_point(const typename SK::Circle_3 & c, bool i) 00579 { 00580 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00581 return Algebraic_kernel().z_critical_points_object()(typename SK::Get_equation()(c),i); 00582 } 00583 00584 template <class SK,class OutputIterator> 00585 OutputIterator 00586 z_extremal_points(const typename SK::Circle_3 & c, OutputIterator res) 00587 { 00588 typedef typename SK::Algebraic_kernel Algebraic_kernel; 00589 return Algebraic_kernel().z_critical_points_object()(typename SK::Get_equation()(c),res); 00590 } 00591 00592 }//SphericalFunctors 00593 }//CGAL 00594 00595 #endif //CGAL_SPHERICAL_KERNEL_PREDICATES_ON_SPHERE_3_H