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