BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Min_ellipse_2/Min_ellipse_2_adapterC2.h
Go to the documentation of this file.
00001 // Copyright (c) 1997-2001  Freie Universitaet Berlin (Germany).
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/Min_ellipse_2/include/CGAL/Min_ellipse_2/Min_ellipse_2_adapterC2.h $
00015 // $Id: Min_ellipse_2_adapterC2.h 41695 2008-01-20 14:48:37Z spion $
00016 // 
00017 //
00018 // Author(s)     : Sven Schoenherr <sven@inf.ethz.ch>, Bernd Gaertner
00019 
00020 #ifndef CGAL_MIN_ELLIPSE_2_ADAPTERC2_H
00021 #define CGAL_MIN_ELLIPSE_2_ADAPTERC2_H
00022 
00023 // includes
00024 #  include <CGAL/ConicCPA2.h>
00025 #  include <CGAL/Optimisation/assertions.h>
00026 
00027 CGAL_BEGIN_NAMESPACE
00028 
00029 // Class declarations
00030 // ==================
00031 template < class Traits_ >
00032 class Min_ellipse_2;
00033 
00034 template < class PT_, class DA_ >
00035 class Min_ellipse_2_adapterC2;
00036 
00037 template < class PT_, class DA_ >
00038 class _Min_ellipse_2_adapterC2__Ellipse;
00039 
00040 // Class interface and implementation
00041 // ==================================
00042 template < class PT, class DA >
00043 bool
00044 are_ordered_along_lineC2( const PT& p, const PT& q, const PT& r,
00045                           const DA& da)
00046 {
00047     typedef  typename DA::FT  FT;
00048 
00049     FT  px;
00050     FT  py;
00051     FT  qx;
00052     FT  qy;
00053     FT  rx;
00054     FT  ry;
00055 
00056     da.get( p, px, py);
00057     da.get( q, qx, qy);
00058     da.get( r, rx, ry);
00059 
00060     // p,q,r collinear?
00061     if ( ! CGAL_NTS is_zero( ( px-rx) * ( qy-ry) - ( py-ry) * ( qx-rx)))
00062         return( false);
00063 
00064     // p,q,r vertical?
00065     if ( px != rx)
00066         return(    ( ( px < qx) && ( qx < rx))
00067                 || ( ( rx < qx) && ( qx < px)));
00068     else
00069         return(    ( ( py < qy) && ( qy < ry))
00070                 || ( ( ry < qy) && ( qy < py)));
00071 }
00072 
00073 template < class PT_, class DA_ >
00074 class Min_ellipse_2_adapterC2 {
00075   public:
00076     // types
00077     typedef  PT_  PT;
00078     typedef  DA_  DA;
00079 
00080     // nested types
00081     typedef  PT                                             Point;
00082     typedef  _Min_ellipse_2_adapterC2__Ellipse<PT,DA>  Ellipse;
00083 
00084   private:
00085     DA      dao;                                    // data accessor object
00086     Ellipse ellipse;                                // current ellipse
00087     friend class Min_ellipse_2< Min_ellipse_2_adapterC2<PT,DA> >;
00088 
00089   public:
00090     // creation
00091     Min_ellipse_2_adapterC2( const DA& da = DA())
00092         : dao( da), ellipse( da)
00093     { }
00094 
00095     // operations
00096     CGAL::Orientation
00097     orientation( const Point& p, const Point& q, const Point& r) const
00098     {
00099         typedef  typename DA_::FT  FT;
00100     
00101         FT  px;
00102         FT  py;
00103         FT  qx;
00104         FT  qy;
00105         FT  rx;
00106         FT  ry;
00107     
00108         dao.get( p, px, py);
00109         dao.get( q, qx, qy);
00110         dao.get( r, rx, ry);
00111     
00112         return( static_cast< CGAL::Orientation>(
00113                    CGAL_NTS sign( ( px-rx) * ( qy-ry) - ( py-ry) * ( qx-rx))));
00114     }
00115 };
00116 
00117 // Nested type `Ellipse'
00118 template < class PT_, class DA_ >
00119 std::ostream&  operator << ( std::ostream& os,
00120     const _Min_ellipse_2_adapterC2__Ellipse<PT_,DA_>& c);
00121 
00122 template < class PT_, class DA_ >
00123 std::istream&  operator >> ( std::istream& is,
00124     _Min_ellipse_2_adapterC2__Ellipse<PT_,DA_>& c);
00125 
00126 template < class PT_, class DA_ >
00127 class _Min_ellipse_2_adapterC2__Ellipse {
00128   public:
00129     // typedefs
00130     typedef  PT_  PT;
00131     typedef  DA_  DA;
00132 
00133     typedef           ConicCPA2< PT, DA>  CT;
00134     typedef  typename DA_::FT                  FT;
00135 
00136   private:
00137     // data members
00138     int  n_boundary_points;                 // number of boundary points
00139     PT   boundary_point1, boundary_point2;  // two boundary points
00140     CT   conic1, conic2;                    // two conics
00141     FT   dr, ds, dt, du, dv, dw;            // the gradient vector
00142 
00143     friend
00144     std::ostream&  operator << <> ( std::ostream& os,
00145         const _Min_ellipse_2_adapterC2__Ellipse<PT_,DA_>& c);
00146 
00147     friend
00148     std::istream&  operator >> <> ( std::istream& is,
00149         _Min_ellipse_2_adapterC2__Ellipse<PT_,DA_>& c);
00150 
00151   public:
00152     // types
00153     typedef  PT  Point;
00154 
00155     // creation
00156     _Min_ellipse_2_adapterC2__Ellipse( const DA& da)
00157         : conic1( da), conic2( da)
00158     { }
00159 
00160     void
00161     set( )
00162     {
00163         n_boundary_points = 0;
00164     }
00165 
00166     void
00167     set( const Point& p)
00168     {
00169         n_boundary_points = 1;
00170         boundary_point1   = p;
00171     }
00172 
00173     void
00174     set( const Point& p, const Point& q)
00175     {
00176         n_boundary_points = 2;
00177         boundary_point1   = p;
00178         boundary_point2   = q;
00179     }
00180 
00181     void
00182     set( const Point& p1, const Point& p2, const Point& p3)
00183     {
00184         n_boundary_points = 3;
00185         conic1.set_ellipse( p1, p2, p3);
00186     }
00187 
00188     void
00189     set( const Point& p1, const Point& p2,
00190          const Point& p3, const Point& p4)
00191     {
00192         n_boundary_points = 4;
00193         CT::set_two_linepairs( p1, p2, p3, p4, conic1, conic2);
00194         dr = FT( 0);
00195         ds = conic1.r() * conic2.s() - conic2.r() * conic1.s(),
00196         dt = conic1.r() * conic2.t() - conic2.r() * conic1.t(),
00197         du = conic1.r() * conic2.u() - conic2.r() * conic1.u(),
00198         dv = conic1.r() * conic2.v() - conic2.r() * conic1.v(),
00199         dw = conic1.r() * conic2.w() - conic2.r() * conic1.w();
00200     }
00201 
00202     void
00203     set( const Point&, const Point&,
00204          const Point&, const Point&, const Point& p5)
00205     {
00206         n_boundary_points = 5;
00207         conic1.set( conic1, conic2, p5);
00208         conic1.analyse();
00209     }
00210 
00211     // predicates
00212     CGAL::Bounded_side
00213     bounded_side( const Point& p) const
00214     {
00215         switch ( n_boundary_points) {
00216           case 0:
00217             return( CGAL::ON_UNBOUNDED_SIDE);
00218           case 1:
00219             return( ( p == boundary_point1) ?
00220                            CGAL::ON_BOUNDARY : CGAL::ON_UNBOUNDED_SIDE);
00221           case 2:
00222             return(    ( p == boundary_point1)
00223                     || ( p == boundary_point2)
00224                     || ( CGAL::are_ordered_along_lineC2( boundary_point1, p,
00225                                            boundary_point2, conic1.da())) ?
00226                                 CGAL::ON_BOUNDARY : CGAL::ON_UNBOUNDED_SIDE);
00227           case 3:
00228           case 5:
00229             return( conic1.convex_side( p));
00230           case 4: {
00231             CT c( conic1.da());
00232             c.set( conic1, conic2, p);
00233             c.analyse();
00234             if ( ! c.is_ellipse()) {
00235                 c.set_ellipse( conic1, conic2);
00236                 c.analyse();
00237                 return( c.convex_side( p)); }
00238             else {
00239                 int tau_star = c.vol_derivative( dr, ds, dt, du, dv, dw);
00240                 return( CGAL::Bounded_side( CGAL_NTS sign( tau_star))); } }
00241           default:
00242             CGAL_optimisation_assertion( ( n_boundary_points >= 0) &&
00243                                          ( n_boundary_points <= 5) ); }
00244         // keeps g++ happy
00245         return( CGAL::Bounded_side( 0));
00246     }
00247 
00248     bool
00249     has_on_bounded_side( const Point& p) const
00250     {
00251         return( bounded_side( p) == CGAL::ON_BOUNDED_SIDE);
00252     }
00253 
00254     bool
00255     has_on_boundary( const Point& p) const
00256     {
00257         return( bounded_side( p) == CGAL::ON_BOUNDARY);
00258     }
00259 
00260     bool
00261     has_on_unbounded_side( const Point& p) const
00262     {
00263         return( bounded_side( p) == CGAL::ON_UNBOUNDED_SIDE);
00264     }
00265 
00266     bool
00267     is_empty( ) const
00268     {
00269         return( n_boundary_points == 0);
00270     }
00271 
00272     bool
00273     is_degenerate( ) const
00274     {
00275         return( n_boundary_points < 3);
00276     }
00277 
00278     // additional operations for checking
00279     bool
00280     operator == (
00281         const CGAL::_Min_ellipse_2_adapterC2__Ellipse<PT_,DA_>& e) const
00282     {
00283         if ( n_boundary_points != e.n_boundary_points)
00284             return( false);
00285 
00286         switch ( n_boundary_points) {
00287           case 0:
00288             return( true);
00289           case 1:
00290             return( boundary_point1 == e.boundary_point1);
00291           case 2:
00292             return(    (    ( boundary_point1 == e.boundary_point1)
00293                          && ( boundary_point2 == e.boundary_point2))
00294                     || (    ( boundary_point1 == e.boundary_point2)
00295                          && ( boundary_point2 == e.boundary_point1)));
00296           case 3:
00297           case 5:
00298             return( conic1 == e.conic1);
00299           case 4:
00300             return(    (    ( conic1 == e.conic1)
00301                          && ( conic2 == e.conic2))
00302                     || (    ( conic1 == e.conic2)
00303                          && ( conic2 == e.conic1)));
00304           default:
00305             CGAL_optimisation_assertion(    ( n_boundary_points >= 0)
00306                                          && ( n_boundary_points <= 5)); }
00307         // keeps g++ happy
00308         return( false);
00309     }
00310 
00311     bool
00312     operator != (
00313         const CGAL::_Min_ellipse_2_adapterC2__Ellipse<PT_,DA_>& e) const
00314     {
00315         return( ! ( *this == e));
00316     }
00317 };
00318 
00319 // I/O
00320 template < class PT_, class DA_ >
00321 std::ostream&
00322 operator << ( std::ostream& os,
00323               const CGAL::_Min_ellipse_2_adapterC2__Ellipse<PT_,DA_>& e)
00324 {
00325     const char* const  empty       = "";
00326     const char* const  pretty_head =
00327                              "CGAL::Min_ellipse_2_adapterC2::Ellipse( ";
00328     const char* const  pretty_sep  = ", ";
00329     const char* const  pretty_tail = ")";
00330     const char* const  ascii_sep   = " ";
00331 
00332     const char*  head = empty;
00333     const char*  sep  = empty;
00334     const char*  tail = empty;
00335 
00336     switch ( CGAL::get_mode( os)) {
00337       case CGAL::IO::PRETTY:
00338         head = pretty_head;
00339         sep  = pretty_sep;
00340         tail = pretty_tail;
00341         break;
00342       case CGAL::IO::ASCII:
00343         sep  = ascii_sep;
00344         break;
00345       case CGAL::IO::BINARY:
00346         break;
00347       default:
00348         CGAL_optimisation_assertion_msg( false,
00349                                         "CGAL::get_mode( os) invalid!");
00350         break; }
00351 
00352     os << head << e.n_boundary_points;
00353     switch ( e.n_boundary_points) {
00354       case 0:
00355         break;
00356       case 1:
00357         os << sep << e.boundary_point1;
00358         break;
00359       case 2:
00360         os << sep << e.boundary_point1
00361            << sep << e.boundary_point2;
00362         break;
00363       case 3:
00364       case 5:
00365         os << sep << e.conic1;
00366         break;
00367       case 4:
00368         os << sep << e.conic1
00369            << sep << e.conic2;
00370         break; }
00371     os << tail;
00372 
00373     return( os);
00374 }
00375 
00376 template < class PT_, class DA_ >
00377 std::istream&
00378 operator >> ( std::istream& is,
00379               CGAL::_Min_ellipse_2_adapterC2__Ellipse<PT_,DA_>& e)
00380 {
00381     switch ( CGAL::get_mode( is)) {
00382 
00383       case CGAL::IO::PRETTY:
00384         std::cerr << std::endl;
00385         std::cerr << "Stream must be in ascii or binary mode" << std::endl;
00386         break;
00387 
00388       case CGAL::IO::ASCII:
00389       case CGAL::IO::BINARY:
00390         CGAL::read( is, e.n_boundary_points);
00391         switch ( e.n_boundary_points) {
00392           case 0:
00393             break;
00394           case 1:
00395             is >> e.boundary_point1;
00396             break;
00397           case 2:
00398             is >> e.boundary_point1
00399                >> e.boundary_point2;
00400             break;
00401           case 3:
00402           case 5:
00403             is >> e.conic1;
00404             break;
00405           case 4:
00406             is >> e.conic1
00407                >> e.conic2;
00408             break; }
00409         break;
00410 
00411       default:
00412         CGAL_optimisation_assertion_msg( false,
00413                                          "CGAL::IO::mode invalid!");
00414         break; }
00415 
00416     return( is);
00417 }
00418 
00419 CGAL_END_NAMESPACE
00420 
00421 #endif // CGAL_MIN_ELLIPSE_2_ADAPTERC2_H
00422 
00423 // ===== EOF ==================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines