BWAPI
|
00001 // Copyright (c) 2000,2001 Utrecht University (The Netherlands), 00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany), 00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg 00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria), 00005 // and Tel-Aviv University (Israel). All rights reserved. 00006 // 00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public License as 00009 // published by the Free Software Foundation; version 2.1 of the License. 00010 // See the file LICENSE.LGPL distributed with CGAL. 00011 // 00012 // Licensees holding a valid commercial license may use this file in 00013 // accordance with the commercial license agreement provided with the software. 00014 // 00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 // 00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Conic_2/include/CGAL/ConicCPA2.h $ 00019 // $Id: ConicCPA2.h 34970 2006-10-28 13:07:32Z hemmer $ 00020 // 00021 // 00022 // Author(s) : Bernd Gaertner, Sven Schoenherr <sven@inf.ethz.ch> 00023 00024 #ifndef CGAL_CONICCPA2_H 00025 #define CGAL_CONICCPA2_H 00026 00027 // includes 00028 #include <CGAL/Conic_misc.h> 00029 #include <CGAL/kernel_assertions.h> 00030 00031 CGAL_BEGIN_NAMESPACE 00032 00033 template < class PT, class DA> 00034 class ConicCPA2; 00035 00036 template < class PT, class DA> 00037 class _Min_ellipse_2_adapterC2__Ellipse; 00038 00039 00040 template < class _PT, class _DA> 00041 class ConicCPA2 00042 { 00043 public: 00044 // types 00045 typedef _PT PT; 00046 typedef _DA DA; 00047 typedef typename _DA::FT FT; 00048 00049 //private: 00050 //friend class Conic_2< CGAL::Cartesian<FT> >; 00051 friend class _Min_ellipse_2_adapterC2__Ellipse<PT,DA>; 00052 00053 DA dao; 00054 FT _r, _s, _t, _u, _v, _w; 00055 Conic_type type; 00056 CGAL::Orientation o; 00057 bool empty, trivial, degenerate; 00058 00059 00060 void 00061 set_linear_combination (const FT& a1, const ConicCPA2<PT,DA>& c1, 00062 const FT& a2, const ConicCPA2<PT,DA>& c2) 00063 { 00064 _r = a1 * c1.r() + a2 * c2.r(); 00065 _s = a1 * c1.s() + a2 * c2.s(); 00066 _t = a1 * c1.t() + a2 * c2.t(); 00067 _u = a1 * c1.u() + a2 * c2.u(); 00068 _v = a1 * c1.v() + a2 * c2.v(); 00069 _w = a1 * c1.w() + a2 * c2.w(); 00070 } 00071 00072 static void set_two_linepairs (const PT& p1, 00073 const PT& p2, 00074 const PT& p3, 00075 const PT& p4, 00076 ConicCPA2<PT,DA>& pair1, 00077 ConicCPA2<PT,DA>& pair2) 00078 { 00079 FT x1, y1, x2, y2, x3, y3, x4, y4; 00080 const DA& da = pair1.da(); 00081 da.get (p1, x1, y1); 00082 da.get (p2, x2, y2); 00083 da.get (p3, x3, y3); 00084 da.get (p4, x4, y4); 00085 00086 CGAL::Orientation side1_24 = (CGAL::Orientation)(CGAL_NTS sign 00087 (-x1*y4+x2*y4 00088 +x4*y1-x2*y1 00089 +x1*y2-x4*y2)), 00090 side3_24 = (CGAL::Orientation)(CGAL_NTS sign 00091 (-x3*y4+x2*y4 00092 +x4*y3-x2*y3 00093 +x3*y2-x4*y2)); 00094 if (side1_24 != side3_24) { 00095 // (counter)clockwise order 00096 pair1.set_linepair (p1, p2, p3, p4); 00097 pair2.set_linepair (p2, p3, p4, p1); 00098 } else { 00099 CGAL::Orientation side1_32 = (CGAL::Orientation)(CGAL_NTS sign 00100 (-x1*y2+x3*y2 00101 +x2*y1-x3*y1 00102 +x1*y3-x2*y3)); 00103 if (side1_32 != side3_24) { 00104 // p1, p2 need to be swapped 00105 pair1.set_linepair (p2, p1, p3, p4); 00106 pair2.set_linepair (p1, p3, p4, p2); 00107 } else { 00108 // p2, p3 need to be swapped 00109 pair1.set_linepair (p1, p3, p2, p4); 00110 pair2.set_linepair (p3, p2, p4, p1); 00111 } 00112 } 00113 } 00114 00115 void set_ellipse (const ConicCPA2<PT,DA>& pair1, 00116 const ConicCPA2<PT,DA>& pair2) 00117 { 00118 FT b = FT(2) * (pair1.r() * pair2.s() + pair1.s() * pair2.r()) - 00119 pair1.t() * pair2.t(); 00120 set_linear_combination (pair2.det()-b, pair1, 00121 pair1.det()-b, pair2); 00122 } 00123 00124 void set (const ConicCPA2<PT,DA>& c1, 00125 const ConicCPA2<PT,DA>& c2, 00126 const PT& p) 00127 { 00128 set_linear_combination (c2.evaluate(p), c1, -c1.evaluate(p), c2); 00129 } 00130 00131 CGAL::Sign vol_derivative (FT dr, FT ds, FT dt, 00132 FT du, FT dv, FT dw) const 00133 { 00134 FT a1 = FT(4)*r()*ds+FT(4)*dr*s()-FT(2)*t()*dt, 00135 a0 = FT(4)*r()*s()-t()*t(), 00136 b1 = (FT(4)*r()*s()-t()*t())*dw+(FT(4)*r()*ds+FT(4)*dr*s()- 00137 FT(2)*t()*dt)*w()-u()*u()*ds - 00138 FT(2)*u()*du*s()-v()*v()*dr-FT(2)*v()*dv*r()+u()*v()*dt+ 00139 (u()*dv+du*v())*t(), 00140 b0 = (FT(4)*r()*s()-t()*t())*w() 00141 -u()*u()*s()-v()*v()*r()+u()*v()*t(), 00142 c0 = -FT(2)*a0*b1 + FT(3)*a1*b0; 00143 00144 return CGAL_NTS sign ((int)-CGAL_NTS sign (c0)*o); 00145 } 00146 00147 double vol_minimum (FT dr, FT ds, FT dt, FT du, FT dv, FT dw) const 00148 { 00149 FT a2 = FT(4)*dr*ds-dt*dt, 00150 a1 = FT(4)*r()*ds+FT(4)*dr*s()-FT(2)*t()*dt, 00151 a0 = FT(4)*r()*s()-t()*t(), 00152 b3 = (FT(4)*dr*ds-dt*dt)*dw-du*du*ds-dv*dv*dr+du*dv*dt, 00153 b2 = (FT(4)*r()*ds+FT(4)*dr*s()-FT(2)*t()*dt)*dw+ 00154 (FT(4)*dr*ds-dt*dt)*w()-FT(2)*u()*du*ds-du*du*s()- 00155 FT(2)*v()*dv*dr-dv*dv*r()+(u()*dv+du*v())*dt+du*dv*t(), 00156 b1 = (FT(4)*r()*s()-t()*t())*dw+(FT(4)*r()*ds+FT(4)*dr*s()- 00157 FT(2)*t()*dt)*w()-u()*u()*ds - 00158 FT(2)*u()*du*s()-v()*v()*dr-FT(2)*v()*dv*r()+u()*v()*dt+ 00159 (u()*dv+du*v())*t(), 00160 b0 = (FT(4)*r()*s()-t()*t())*w() 00161 -u()*u()*s()-v()*v()*r()+u()*v()*t(), 00162 c3 = -FT(3)*a1*b3 + FT(2)*a2*b2, 00163 c2 = -FT(6)*a0*b3 - a1*b2 + FT(4)*a2*b1, 00164 c1 = -FT(4)*a0*b2 + a1*b1 + FT(6)*a2*b0, 00165 c0 = -FT(2)*a0*b1 + FT(3)*a1*b0; 00166 00167 double roots[3]; 00168 int nr_roots = solve_cubic 00169 (CGAL::to_double(c3), CGAL::to_double(c2), 00170 CGAL::to_double(c1), CGAL::to_double(c0), 00171 roots[0], roots[1], roots[2]); 00172 CGAL_kernel_precondition (nr_roots > 0); // minimum exists 00173 return best_value (roots, nr_roots, 00174 CGAL::to_double(a2), CGAL::to_double(a1), 00175 CGAL::to_double(a0), CGAL::to_double(b3), 00176 CGAL::to_double(b2), CGAL::to_double(b1), 00177 CGAL::to_double(b0)); 00178 } 00179 00180 00181 00182 protected: 00183 FT det () const 00184 { 00185 return FT(4)*s()*r() - t()*t(); 00186 } 00187 00188 void analyse( ) 00189 { 00190 FT d = det(); 00191 type = (Conic_type)(CGAL_NTS sign(d)); 00192 switch (type) { 00193 case HYPERBOLA: 00194 { 00195 trivial = empty = false; 00196 FT z_prime = d*w() - u()*u()*s() - v()*v()*r() + u()*v()*t(); 00197 o = (CGAL::Orientation)(CGAL_NTS sign (z_prime)); 00198 degenerate = (o == CGAL::ZERO); 00199 00200 00201 } 00202 break; 00203 case PARABOLA: 00204 { 00205 if (!CGAL_NTS is_zero (r())) { 00206 trivial = false; 00207 degenerate = (t()*u() == FT(2)*r()*v()); 00208 if (degenerate) { 00209 CGAL::Sign discr = (CGAL::Sign) 00210 CGAL_NTS sign(u()*u()-FT(4)*r()*w()); 00211 switch (discr) { 00212 case CGAL::NEGATIVE: 00213 empty = true; 00214 o = (CGAL::Orientation)(CGAL_NTS sign (w())); 00215 break; 00216 case CGAL::ZERO: 00217 empty = false; 00218 o = (CGAL::Orientation)(CGAL_NTS sign (r())); 00219 break; 00220 case CGAL::POSITIVE: 00221 empty = false; 00222 o = CGAL::ZERO; 00223 break; 00224 } 00225 } else { 00226 empty = false; 00227 o = (CGAL::Orientation)(-CGAL_NTS sign (r())); 00228 } 00229 } else if (!CGAL_NTS is_zero (s())) { 00230 trivial = false; 00231 degenerate = (t()*v() == FT(2)*s()*u()); 00232 if (degenerate) { 00233 CGAL::Sign discr = (CGAL::Sign) 00234 CGAL_NTS sign(v()*v()-FT(4)*s()*w()); 00235 switch (discr) { 00236 case CGAL::NEGATIVE: 00237 empty = true; 00238 o = (CGAL::Orientation)(CGAL_NTS sign (w())); 00239 break; 00240 case CGAL::ZERO: 00241 empty = false; 00242 o = (CGAL::Orientation)(CGAL_NTS sign (s())); 00243 break; 00244 case CGAL::POSITIVE: 00245 empty = false; 00246 o = CGAL::ZERO; 00247 break; 00248 } 00249 } else { 00250 empty = false; 00251 o = (CGAL::Orientation)(-CGAL_NTS sign (s())); 00252 } 00253 } else { // r=0, s=0 00254 degenerate = true; 00255 bool uv_zero = CGAL_NTS is_zero (u()) 00256 && CGAL_NTS is_zero (v()); 00257 trivial = uv_zero && CGAL_NTS is_zero (w()); 00258 empty = uv_zero && !trivial; 00259 if (empty) 00260 o = (CGAL::Orientation)(CGAL_NTS sign (w())); 00261 else if (trivial) 00262 o = CGAL::POSITIVE; 00263 else 00264 o = CGAL::ZERO; 00265 } 00266 00267 00268 } 00269 break; 00270 case ELLIPSE: 00271 { 00272 trivial = false; 00273 FT z_prime = d*w() - u()*u()*s() - v()*v()*r() + u()*v()*t(); 00274 if (CGAL_NTS is_positive (r())) { 00275 empty = CGAL_NTS sign (z_prime) == CGAL::POSITIVE; 00276 empty ? o = CGAL::POSITIVE : o = CGAL::NEGATIVE; 00277 } else { 00278 empty = CGAL_NTS sign (z_prime) == CGAL::NEGATIVE ; 00279 empty ? o = CGAL::NEGATIVE : o = CGAL::POSITIVE; 00280 } 00281 degenerate = empty || CGAL_NTS is_zero (z_prime); 00282 00283 00284 } 00285 break; 00286 } 00287 } 00288 00289 FT evaluate (const PT& p) const 00290 { 00291 FT x, y; 00292 dao.get (p, x, y); 00293 return r()*x*x + s()*y*y + t()*x*y + u()*x + v()*y + w(); 00294 } 00295 00296 00297 00298 public: 00299 ConicCPA2 ( const DA& da = DA()) : dao( da) { } 00300 00301 ConicCPA2 (FT r, FT s, FT t, FT u, FT v, FT w, const DA& da = DA()) 00302 : dao( da), _r(r), _s(s), _t(t), _u(u), _v(v), _w(w) 00303 { 00304 analyse(); 00305 } 00306 00307 const DA& da() const 00308 { 00309 return dao; 00310 } 00311 00312 FT r() const { return _r;} 00313 FT s() const { return _s;} 00314 FT t() const { return _t;} 00315 FT u() const { return _u;} 00316 FT v() const { return _v;} 00317 FT w() const { return _w;} 00318 00319 PT center () const 00320 { 00321 CGAL_kernel_precondition (type != PARABOLA); 00322 // PT p; 00323 // replaced previous line by following hack (no idea 00324 // why original version doesn't work) 00325 typename DA::Point p; 00326 FT two = FT(2); 00327 FT div = -det(); 00328 dao.set( p, (two*s()*u() - t()*v()) / div, 00329 (two*r()*v() - t()*u()) / div); 00330 return p; 00331 } 00332 00333 Conic_type conic_type () const 00334 { 00335 return type; 00336 } 00337 00338 bool is_hyperbola () const 00339 { 00340 return (type == HYPERBOLA); 00341 } 00342 00343 bool is_parabola () const 00344 { 00345 return (type == PARABOLA); 00346 } 00347 00348 bool is_ellipse () const 00349 { 00350 return (type == ELLIPSE); 00351 } 00352 00353 bool is_circle () const 00354 { 00355 return (type == ELLIPSE && (r()==s()) && CGAL_NTS is_zero (t())); 00356 } 00357 00358 bool is_empty () const 00359 { 00360 return empty; 00361 } 00362 00363 bool is_trivial () const 00364 { 00365 return trivial; 00366 } 00367 00368 bool is_degenerate () const 00369 { 00370 return degenerate; 00371 } 00372 00373 CGAL::Orientation orientation () const 00374 { 00375 return o; 00376 } 00377 00378 CGAL::Oriented_side oriented_side (const PT& p) const 00379 { 00380 return (CGAL::Oriented_side)(CGAL_NTS sign (evaluate (p))); 00381 } 00382 00383 bool has_on_positive_side (const PT& p) const 00384 { 00385 return (CGAL_NTS is_positive (evaluate(p))); 00386 } 00387 00388 bool has_on_negative_side (const PT& p) const 00389 { 00390 return (CGAL_NTS is_negative (evaluate(p))); 00391 } 00392 00393 bool has_on_boundary (const PT& p) const 00394 { 00395 return (CGAL_NTS is_zero (evaluate(p))); 00396 } 00397 00398 bool has_on (const PT& p) const 00399 { 00400 return (CGAL_NTS is_zero (evaluate(p))); 00401 } 00402 00403 00404 Convex_side convex_side (const PT& p) const 00405 { 00406 switch (o) { 00407 case CGAL::POSITIVE: 00408 return (Convex_side)( CGAL_NTS sign (evaluate (p))); 00409 case CGAL::NEGATIVE: 00410 return (Convex_side)(-CGAL_NTS sign (evaluate (p))); 00411 case CGAL::ZERO: 00412 return (Convex_side)( CGAL_NTS sign (CGAL_NTS abs (evaluate(p)))); 00413 } 00414 // keeps g++ happy 00415 return( Convex_side( 0)); 00416 } 00417 00418 bool has_on_convex_side (const PT& p) const 00419 { 00420 return (convex_side (p) == ON_CONVEX_SIDE); 00421 } 00422 00423 bool has_on_nonconvex_side (const PT& p) const 00424 { 00425 return (convex_side (p) == ON_NONCONVEX_SIDE); 00426 } 00427 00428 bool operator == ( const ConicCPA2<_PT,_DA>& c) const 00429 { 00430 // find coefficient != 0 00431 FT factor1(0); 00432 if ( ! CGAL_NTS is_zero( r())) factor1 = r(); else 00433 if ( ! CGAL_NTS is_zero( s())) factor1 = s(); else 00434 if ( ! CGAL_NTS is_zero( t())) factor1 = t(); else 00435 if ( ! CGAL_NTS is_zero( u())) factor1 = u(); else 00436 if ( ! CGAL_NTS is_zero( v())) factor1 = v(); else 00437 if ( ! CGAL_NTS is_zero( w())) factor1 = w(); else 00438 CGAL_kernel_assertion_msg( false, "all coefficients zero"); 00439 00440 // find coefficient != 0 00441 FT factor2(0); 00442 if ( ! CGAL_NTS is_zero( c.r())) factor2 = c.r(); else 00443 if ( ! CGAL_NTS is_zero( c.s())) factor2 = c.s(); else 00444 if ( ! CGAL_NTS is_zero( c.t())) factor2 = c.t(); else 00445 if ( ! CGAL_NTS is_zero( c.u())) factor2 = c.u(); else 00446 if ( ! CGAL_NTS is_zero( c.v())) factor2 = c.v(); else 00447 if ( ! CGAL_NTS is_zero( c.w())) factor2 = c.w(); else 00448 CGAL_kernel_assertion_msg( false, "all coefficients zero"); 00449 00450 return( ( r()*factor2 == c.r()*factor1) 00451 && ( s()*factor2 == c.s()*factor1) 00452 && ( t()*factor2 == c.t()*factor1) 00453 && ( u()*factor2 == c.u()*factor1) 00454 && ( v()*factor2 == c.v()*factor1) 00455 && ( w()*factor2 == c.w()*factor1)); 00456 } 00457 00458 void set (FT r_, FT s_, FT t_, FT u_, FT v_, FT w_) 00459 { 00460 _r = r_; _s = s_; _t = t_; _u = u_; _v = v_; _w = w_; 00461 analyse(); 00462 } 00463 00464 void set_opposite () 00465 { 00466 _r = -r(); _s = -s(); _t = -t(); _u = -u(); _v = -v(); _w = -w(); 00467 o = CGAL::opposite(orientation()); 00468 } 00469 00470 void set_circle (const PT& p1, const PT& p2, const PT& p3) 00471 { 00472 // the circle will have r = s = det, t=0 00473 FT x1, y1, x2, y2, x3, y3; 00474 dao.get (p1, x1, y1); 00475 dao.get (p2, x2, y2); 00476 dao.get (p3, x3, y3); 00477 00478 // precondition: p1, p2, p3 not collinear 00479 FT det = -x3*y2+x1*y2+x2*y3-x1*y3+x3*y1-x2*y1; 00480 CGAL_kernel_precondition (!CGAL_NTS is_zero (det)); 00481 00482 // Cramer's rule 00483 FT sqr1 = -x1*x1 - y1*y1; 00484 FT sqr2 = -x2*x2 - y2*y2; 00485 FT sqr3 = -x3*x3 - y3*y3; 00486 00487 _u = -sqr3*y2+sqr1*y2+sqr2*y3-sqr1*y3+sqr3*y1-sqr2*y1; 00488 _v = -x3*sqr2+x1*sqr2+x2*sqr3-x1*sqr3+x3*sqr1-x2*sqr1; 00489 _w = -x3*y2*sqr1+x1*y2*sqr3+x2*y3*sqr1-x1*y3*sqr2+x3*y1*sqr2-x2*y1*sqr3; 00490 _r = det; 00491 _s = det; 00492 _t = FT(0); 00493 00494 analyse(); 00495 CGAL_kernel_postcondition(is_circle()); 00496 CGAL_kernel_postcondition(has_on_boundary(p1)); 00497 CGAL_kernel_postcondition(has_on_boundary(p2)); 00498 CGAL_kernel_postcondition(has_on_boundary(p3)); 00499 } 00500 00501 void set_linepair (const PT& p1, const PT& p2, const PT& p3, const PT& p4) 00502 { 00503 FT x1, y1, x2, y2, x3, y3, x4, y4; 00504 dao.get (p1, x1, y1); 00505 dao.get (p2, x2, y2); 00506 dao.get (p3, x3, y3); 00507 dao.get (p4, x4, y4); 00508 00509 // precondition: p1 != p2, p3 != p4 00510 CGAL_kernel_precondition 00511 ( ((x1 != x2) || (y1 != y2)) && 00512 ((x3 != x4) || (y3 != y4)) ); 00513 00514 FT x2_x1 = x2-x1; 00515 FT x4_x3 = x4-x3; 00516 FT y1_y2 = y1-y2; 00517 FT y3_y4 = y3-y4; 00518 FT x1y2_y1x2 = x1*y2-y1*x2; 00519 FT x3y4_y3x4 = x3*y4-y3*x4; 00520 00521 _r = y1_y2 * y3_y4; 00522 _s = x2_x1 * x4_x3; 00523 _t = x2_x1 * y3_y4 + y1_y2 * x4_x3; 00524 _u = x1y2_y1x2 * y3_y4 + y1_y2 * x3y4_y3x4; 00525 _v = x1y2_y1x2 * x4_x3 + x2_x1 * x3y4_y3x4; 00526 _w = x1y2_y1x2 * x3y4_y3x4; 00527 00528 analyse(); 00529 } 00530 00531 void set_ellipse (const PT& p1, const PT& p2, const PT& p3) 00532 { 00533 FT x1, y1, x2, y2, x3, y3; 00534 dao.get (p1, x1, y1); 00535 dao.get (p2, x2, y2); 00536 dao.get (p3, x3, y3); 00537 00538 // precondition: p1, p2, p3 not collinear 00539 FT det = -x3*y2+x1*y2+x2*y3-x1*y3+x3*y1-x2*y1; 00540 CGAL_kernel_precondition (!CGAL_NTS is_zero (det)); 00541 00542 FT x1x1 = x1*x1, y1y1 = y1*y1, 00543 x2x2 = x2*x2, y2y2 = y2*y2, 00544 x3x3 = x3*x3, y3y3 = y3*y3, // x_i^2, y_i^2 00545 two = FT(2); 00546 00547 _r = y1y1 - y1*y2 - y1*y3 + 00548 y2y2 - y2*y3 + y3y3; 00549 00550 _s = x1x1 - x1*x2 - x1*x3 + 00551 x2x2 - x2*x3 + x3x3; 00552 00553 _t = -two*x1*y1 + x1*y2 + x1*y3 + 00554 y1*x2 -two*x2*y2 + x2*y3 + 00555 y1*x3 + y2*x3 -two*x3*y3; 00556 00557 _u = -(y2y2*x3 - x2*y2*y3 - y2*x3*y3 + 00558 x1*y3y3 + x2*y3y3 + y1y1*x2 + 00559 y1y1*x3 - x1*y1*y2 - y1*x2*y2 - 00560 x1*y1*y3 - y1*x3*y3 + x1*y2y2); 00561 00562 _v = -(x2x2*y3 - x2*y2*x3 - x2*x3*y3 + 00563 y1*x3x3 + y2*x3x3 + x1x1*y2 + 00564 x1x1*y3 - x1*y1*x2 - x1*x2*y2 - 00565 x1*y1*x3 - x1*x3*y3 + y1*x2x2); 00566 00567 _w = y1y1*x2*x3 - x1*y1*y2*x3 - y1*x2*y2*x3 + 00568 y1*y2*x3x3 - x1*y1*x2*y3 + y1*x2x2*y3 - 00569 y1*x2*x3*y3 + x1*y2y2*x3 + x1x1*y2*y3 - 00570 x1*x2*y2*y3 - x1*y2*x3*y3 + x1*x2*y3y3; 00571 00572 type = ELLIPSE; 00573 degenerate = trivial = empty = false; 00574 o = CGAL::NEGATIVE; 00575 if (CGAL_NTS is_positive (det)) set_opposite(); 00576 } 00577 00578 void set_ellipse (const PT& p1, const PT& p2, 00579 const PT& p3, const PT& p4, 00580 CGAL::Orientation _o = POSITIVE) 00581 { 00582 ConicCPA2<PT,DA> pair1, pair2; 00583 set_two_linepairs (p1, p2, p3, p4, pair1, pair2); 00584 set_ellipse (pair1, pair2); 00585 analyse(); 00586 if (o != _o) set_opposite(); 00587 } 00588 00589 void set (const PT& p1, const PT& p2, const PT& p3, const PT& p4, 00590 const PT& p5, CGAL::Orientation _o = POSITIVE) 00591 { 00592 ConicCPA2<PT,DA> c1; c1.set_linepair (p1, p2, p3, p4); 00593 ConicCPA2<PT,DA> c2; c2.set_linepair (p1, p4, p2, p3); 00594 set_linear_combination (c2.evaluate (p5), c1, 00595 -c1.evaluate (p5), c2); 00596 analyse(); 00597 // precondition: all points distinct <=> conic nontrivial 00598 CGAL_kernel_precondition (!is_trivial()); 00599 if (o != _o) set_opposite(); 00600 } 00601 00602 00603 00604 }; 00605 00606 #ifndef CGAL_NO_OSTREAM_INSERT_CONICCPA2 00607 template< class _PT, class _DA> 00608 std::ostream& operator << ( std::ostream& os, const ConicCPA2<_PT,_DA>& c) 00609 { 00610 return( os << c.r() << ' ' << c.s() << ' ' << c.t() << ' ' 00611 << c.u() << ' ' << c.v() << ' ' << c.w()); 00612 } 00613 00614 template< class _PT, class _DA> 00615 std::istream& operator >> ( std::istream& is, ConicCPA2<_PT,_DA>& c) 00616 { 00617 typedef ConicCPA2<_PT,_DA> Conic; 00618 typedef typename _DA::FT FT; 00619 00620 FT r, s, t, u, v, w; 00621 is >> r >> s >> t >> u >> v >> w; 00622 c.set( r, s, t, u, v, w); 00623 00624 return( is); 00625 } 00626 #endif // CGAL_NO_OSTREAM_INSERT_CONICCPA2 00627 00628 CGAL_END_NAMESPACE 00629 00630 #endif // CGAL_CONICCPA2_H 00631 00632 // ===== EOF ==================================================================