BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/ConicCPA2.h
Go to the documentation of this file.
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 ==================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines