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