BWAPI
|
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 ==================================================================