BWAPI
|
00001 // Copyright (c) 1997 INRIA Sophia-Antipolis (France). 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/Triangulation_2/include/CGAL/Triangulation_line_face_circulator_2.h $ 00015 // $Id: Triangulation_line_face_circulator_2.h 44130 2008-07-12 21:58:52Z spion $ 00016 // 00017 // 00018 // Author(s) : Mariette Yvinec 00019 00020 00021 #ifndef CGAL_TRIANGULATION_LINE_FACE_CIRCULATOR_2_H 00022 #define CGAL_TRIANGULATION_LINE_FACE_CIRCULATOR_2_H 00023 00024 // #include <CGAL/circulator.h> 00025 // #include <CGAL/Triangulation_utils_2.h> 00026 // #include <CGAL/triangulation_assertions.h> 00027 // #include <CGAL/Triangulation_face_2.h> 00028 // #include <CGAL/Triangulation_vertex_2.h> 00029 // #include <CGAL/Triangulation_handles_2.h> 00030 00031 CGAL_BEGIN_NAMESPACE 00032 00033 template < class Gt, class Tds > 00034 class Triangulation_2; 00035 00036 template < class Gt, class Tds > 00037 class Triangulation_line_face_circulator_2 00038 : public Bidirectional_circulator_base< typename Tds::Face, 00039 std::ptrdiff_t, 00040 std::size_t>, 00041 public Triangulation_cw_ccw_2 00042 { 00043 public: 00044 typedef Triangulation_line_face_circulator_2<Gt,Tds> Line_face_circulator; 00045 typedef Triangulation_2<Gt,Tds> Triangulation; 00046 00047 typedef typename Tds::Vertex Vertex; 00048 typedef typename Tds::Face Face; 00049 typedef typename Tds::Edge Edge; 00050 typedef typename Tds::Vertex_handle Vertex_handle; 00051 typedef typename Tds::Face_handle Face_handle; 00052 typedef typename Tds::Face_circulator Face_circulator; 00053 00054 typedef typename Gt::Point_2 Point; 00055 typedef typename Triangulation::Locate_type Locate_type; 00056 00057 enum State {undefined = -1, 00058 vertex_vertex, 00059 vertex_edge, 00060 edge_vertex, 00061 edge_edge}; 00062 00063 private: 00064 Face_handle pos; 00065 const Triangulation_2<Gt, Tds>* _tr; 00066 State s; 00067 int i; 00068 Point p, q; 00069 00070 public: 00071 Triangulation_line_face_circulator_2() 00072 : pos(), _tr(NULL), s(undefined), i(-1) 00073 {} 00074 00075 Triangulation_line_face_circulator_2(Vertex_handle v, 00076 const Triangulation_2<Gt,Tds>* tr, 00077 const Point& dir); 00078 00079 Triangulation_line_face_circulator_2(const Point& pp, 00080 const Point& qq, 00081 const Triangulation_2<Gt,Tds> * t); 00082 00083 Triangulation_line_face_circulator_2(const Point& pp, 00084 const Point& qq, 00085 const Face_handle& ff, 00086 const Triangulation_2<Gt,Tds>* t); 00087 00088 Line_face_circulator& operator++() ; 00089 Line_face_circulator& operator--() ; 00090 Line_face_circulator operator++(int); 00091 Line_face_circulator operator--(int); 00092 Face* operator->() {return &*pos;} 00093 Face& operator*() { return *pos;} 00094 Face_handle handle() {return pos;} 00095 operator const Face_handle() const {return pos;} 00096 bool operator==(const Line_face_circulator& lfc) const; 00097 bool operator!=(const Line_face_circulator& lfc) const; 00098 00099 bool operator==(const Face_handle& fh) const { return fh == pos; } 00100 bool operator!=(const Face_handle& fh) const { return fh != pos; } 00101 00102 bool operator==(Nullptr_t CGAL_triangulation_assertion_code(n)) const; 00103 bool operator!=(Nullptr_t n) const; 00104 bool is_empty() const; 00105 bool collinear_outside() const; 00106 bool locate(const Point& t, Locate_type <, int &li); 00107 00108 //private: 00109 Triangulation_line_face_circulator_2(const Face_handle& face, 00110 int index, 00111 State state, 00112 const Triangulation_2<Gt,Tds> * t, 00113 const Point& pp, 00114 const Point& qq); 00115 private: 00116 void increment(); 00117 void decrement(); 00118 }; 00119 00120 template < class Gt, class Tds > 00121 inline 00122 bool 00123 operator==(typename Tds::Face_handle fh, 00124 Triangulation_line_face_circulator_2<Gt,Tds> fc) 00125 { 00126 return (fc==fh); 00127 } 00128 00129 template < class Gt, class Tds > 00130 inline 00131 bool 00132 operator!=(typename Tds::Face_handle fh, 00133 Triangulation_line_face_circulator_2<Gt, Tds> fc) 00134 { 00135 return (fc!=fh); 00136 } 00137 00138 template < class Gt, class Tds > 00139 Triangulation_line_face_circulator_2<Gt,Tds>:: 00140 Triangulation_line_face_circulator_2(const Face_handle& face, 00141 int index, 00142 State state, 00143 const Triangulation_2<Gt,Tds> * t, 00144 const Point& pp, 00145 const Point& qq) 00146 : pos(face), _tr(t), s(state), i(index), 00147 p(pp), q(qq) 00148 { 00149 CGAL_triangulation_precondition(! t->xy_equal(p, q)); 00150 } 00151 00152 00153 template < class Gt, class Tds > 00154 Triangulation_line_face_circulator_2<Gt,Tds>:: 00155 Triangulation_line_face_circulator_2(Vertex_handle v, 00156 const Triangulation_2<Gt,Tds>* tr, 00157 const Point& dir) 00158 :pos(), _tr(tr), s(undefined) 00159 // begin at the face incident to v, traversed by the ray from v to 00160 // dir 00161 // or null iterator 00162 { 00163 CGAL_triangulation_precondition((!_tr->is_infinite(v)) && 00164 (_tr->dimension() == 2) && 00165 (! _tr->xy_equal(v->point(),dir))); 00166 p=v->point(); 00167 q=dir; 00168 00169 // find a finite vertex to the left of pq 00170 // if there is no, the line_face_circulator is null 00171 Face_circulator fc = _tr->incident_faces(v); 00172 Face_circulator done(fc); 00173 int ic = fc->index(v); 00174 Vertex_handle vt= fc->vertex(cw(ic)); 00175 while( _tr->is_infinite(vt) || 00176 _tr->orientation(p, q, vt->point()) != LEFT_TURN) { 00177 ++fc; 00178 ic = fc->index(v); 00179 vt= fc->vertex(cw(ic)); 00180 if (fc == done) { *this = Line_face_circulator(); return;} 00181 } 00182 00183 // now vt is finite and to the left of pq 00184 Vertex_handle vr = fc-> vertex(ccw(ic)); 00185 Orientation pqr = RIGHT_TURN; // warning "pqr might be used uninitialized" 00186 while ( (!_tr->is_infinite(vr)) && 00187 (pqr = _tr->orientation(p, q, vr->point()))== LEFT_TURN ) { 00188 --fc; 00189 ic = fc->index(v); 00190 vr = fc-> vertex(ccw(ic)); 00191 } 00192 00193 // vr can be infinite or finite. 00194 // If finite [pqr] is COLLINEAR or RIGHT_TURN 00195 // reset vt and conclude. vt is still finite and [pqt] still LEFT_TURN 00196 ic = fc->index(v); 00197 vt= fc->vertex(cw(ic)); 00198 CGAL_triangulation_assertion (_tr->orientation(p,q, vt->point())== 00199 LEFT_TURN ); 00200 if (_tr->is_infinite(vr)) { 00201 --fc; 00202 ic = fc->index(v); 00203 vr = fc->vertex(ccw(ic)); 00204 pqr = _tr->orientation(p, q, vr->point()); 00205 switch(pqr){ 00206 case RIGHT_TURN: 00207 case COLLINEAR: 00208 ++fc; 00209 ic = fc->index(_tr->infinite_vertex()); 00210 pos = fc; 00211 s = vertex_vertex; 00212 i = ic; 00213 break; 00214 case LEFT_TURN: 00215 *this = Line_face_circulator(); 00216 break; 00217 } 00218 } 00219 else if (pqr == COLLINEAR) { 00220 pos = fc; 00221 s = vertex_vertex; 00222 i = ccw(ic); 00223 } 00224 else { // pqr==RIGHT_TURN 00225 pos = fc; 00226 s = vertex_edge; 00227 i = ic ; 00228 } 00229 return; 00230 } 00231 00232 00233 00234 00235 template < class Gt, class Tds > 00236 Triangulation_line_face_circulator_2<Gt,Tds>:: 00237 Triangulation_line_face_circulator_2(const Point& pp, 00238 const Point& qq, 00239 const Triangulation_2<Gt,Tds> * t) 00240 : pos(), _tr(t), s(undefined), p(pp), q(qq) 00241 //begins at the first finite face traversed be the oriented line pq 00242 { 00243 Vertex_handle inf = _tr->infinite_vertex(); 00244 Face_circulator fc = _tr->incident_faces(inf), 00245 done(fc); 00246 00247 i = fc->index(inf); 00248 Point l = fc->vertex(cw(i))->point(); 00249 Point r = fc->vertex(ccw(i))->point(); 00250 Orientation pql = _tr->orientation(p, q, l); 00251 Orientation pqr = _tr->orientation(p, q, r); 00252 00253 do{ 00254 if( (pql == LEFT_TURN) && (pqr == RIGHT_TURN) ){ 00255 *this = ++Line_face_circulator( fc, i, vertex_edge, t, p, q); 00256 return; 00257 } 00258 else if ( (pql == LEFT_TURN) && (pqr == COLLINEAR) ){ 00259 --fc; 00260 i = fc->index(inf); 00261 Point ss = fc->vertex(ccw(i))->point(); 00262 Orientation pqs = _tr->orientation(p, q, ss); 00263 Face_handle fn; 00264 int in; 00265 switch(pqs) { 00266 case LEFT_TURN: 00267 *this = Line_face_circulator(); 00268 return; 00269 case COLLINEAR: 00270 fn = fc->neighbor(i); 00271 in = fn->index(fc); 00272 *this = Line_face_circulator( fn, cw(in),vertex_vertex,t,p,q); 00273 return; 00274 case RIGHT_TURN: 00275 fn = fc->neighbor(i); 00276 Vertex_handle vr = fc->vertex(cw(i)); // vertex corresponding to r 00277 in = fn->index(vr); 00278 ss = fn->vertex(cw(in))->point(); 00279 pqs = _tr->orientation(p, q, ss); 00280 Orientation pqss = RIGHT_TURN; 00281 while ( pqs != LEFT_TURN) { 00282 pqss = pqs; 00283 fn = fn->neighbor(ccw(in)); 00284 in = fn->index(vr); 00285 ss = fn->vertex(cw(in))->point(); 00286 pqs = _tr->orientation(p, q, ss); 00287 } 00288 if (pqss == RIGHT_TURN) 00289 *this = Line_face_circulator( fn, in ,vertex_edge,t,p,q); 00290 else // pqss = COLLINEAR 00291 *this = Line_face_circulator(fn,ccw(in),vertex_vertex,t,p,q); 00292 return; 00293 } 00294 } 00295 00296 // going CCW around convex hull is CW around infinite vertex 00297 --fc; 00298 l = r; 00299 pql = pqr; 00300 i = fc->index(inf); 00301 r = fc->vertex(ccw(i))->point(); 00302 pqr = _tr->orientation(p, q, r); 00303 }while(fc != done); 00304 00305 // if line (p,q) does not intersect the convex hull in an edge 00306 // the circulator has a singular value 00307 *this=Line_face_circulator(); 00308 return; 00309 } 00310 00311 00312 template < class Gt, class Tds > 00313 Triangulation_line_face_circulator_2<Gt,Tds>:: 00314 Triangulation_line_face_circulator_2(const Point& pp, 00315 const Point& qq, 00316 const Face_handle& ff, 00317 const Triangulation_2<Gt,Tds>* t) 00318 : pos(ff), _tr(t), s(undefined), p(pp), q(qq) 00319 // precondition : face ff contain p 00320 // the walk begins at face ff if ff is a finite face traversed by the 00321 // circulator 00322 // if ff is finite but not traversed by the circulator 00323 // (this happens when p is a vertex of ff or on an edge) : 00324 // the circulator may be empty, or the walk begins at a finite face 00325 // incident to p 00326 // if ff is infinite, the walk begin at the first finite face traversed 00327 { 00328 CGAL_triangulation_precondition(_tr->is_infinite(ff) || 00329 _tr->oriented_side(ff,p) != ON_NEGATIVE_SIDE); 00330 int j; 00331 if(_tr->is_infinite(pos)){ 00332 *this = Line_face_circulator(p, q, t); 00333 return; 00334 } 00335 00336 // Test whether p lies on a vertex 00337 for(j = 0; j < 3; j++){ 00338 if(pos->vertex(j)->point() == p){ 00339 *this = Line_face_circulator( pos->vertex(j), t, q); 00340 if( (!is_empty()) && _tr->is_infinite(pos )) --(*this); 00341 return; 00342 } 00343 } 00344 00345 // Test whether p lies on an edge 00346 for(j = 0; j < 3; j++) { 00347 if(_tr->orientation(pos->vertex(ccw(j))->point(), 00348 pos->vertex(cw(j))->point(), 00349 p) == COLLINEAR){ 00350 Orientation pqj = 00351 _tr->orientation(p, q, pos->vertex(j)->point()); 00352 Orientation pqcwj = 00353 _tr->orientation(p, q, pos->vertex(cw(j))->point()); 00354 switch(pqcwj) { 00355 case COLLINEAR : 00356 if(pqj == LEFT_TURN){ 00357 s = vertex_vertex; 00358 i = cw(j); 00359 return; 00360 } 00361 else if(! _tr->is_infinite(pos->neighbor(j))){ 00362 Face_handle n = pos->neighbor(j); 00363 i = cw(n->index(pos)); 00364 pos = n; 00365 s = vertex_vertex; 00366 return; 00367 } else { 00368 // singular value 00369 *this = Line_face_circulator(); 00370 return; 00371 } 00372 case LEFT_TURN : 00373 i = j; 00374 s = (pqj == COLLINEAR) ? vertex_edge : 00375 edge_edge; 00376 break; 00377 case RIGHT_TURN : 00378 switch(pqj){ 00379 case COLLINEAR: 00380 s = edge_vertex; 00381 i = j; 00382 return; 00383 case LEFT_TURN: 00384 s = edge_edge; 00385 i = ccw(j); 00386 return; 00387 case RIGHT_TURN: 00388 s = edge_edge; 00389 i = cw(j); 00390 return; 00391 } 00392 } 00393 } 00394 } 00395 00396 // p lies in the interior of the face 00397 Orientation orient[3]; 00398 for(j=0; j<3; j++) { 00399 orient[j] = 00400 _tr->orientation(p,q,pos->vertex(j)->point()); 00401 } 00402 for(j=0; j<3; j++) { 00403 if(orient[j] == COLLINEAR) { 00404 i = j; 00405 s = (orient[ccw(j)] == LEFT_TURN) ? edge_vertex : 00406 vertex_edge; 00407 return; 00408 } 00409 } 00410 s = edge_edge; 00411 for(j=0; j<3; j++){ 00412 if(orient[j] == RIGHT_TURN){ 00413 i = (orient[ccw(j)] == RIGHT_TURN) ? j : cw(j); 00414 return; 00415 } 00416 } 00417 } 00418 00419 00420 template < class Gt, class Tds > 00421 inline 00422 void 00423 Triangulation_line_face_circulator_2<Gt,Tds>:: 00424 increment() 00425 { 00426 CGAL_triangulation_precondition(pos != Face_handle()); 00427 if(s == vertex_vertex || s == edge_vertex) { 00428 Orientation o; 00429 do{ 00430 Face_handle n = pos->neighbor(cw(i)); 00431 i = n->index(pos); 00432 pos = n; 00433 if (pos->vertex(i) == _tr->infinite_vertex()){ 00434 o = COLLINEAR; 00435 i = cw(i); 00436 break; 00437 } 00438 o = _tr->orientation(p, q, pos->vertex(i)->point()); 00439 i = cw(i); 00440 }while(o == LEFT_TURN); 00441 00442 if(o == COLLINEAR) { 00443 s = vertex_vertex; 00444 i = ccw(i); 00445 } 00446 else { 00447 s = vertex_edge; 00448 } 00449 } 00450 else { 00451 Face_handle n = pos->neighbor(i); 00452 int ni = n->index(pos); 00453 pos = n ; 00454 Orientation o = _tr->is_infinite(pos->vertex(ni)) ? 00455 COLLINEAR : 00456 _tr->orientation(p,q,pos->vertex(ni)->point()); 00457 00458 switch(o){ 00459 case LEFT_TURN: 00460 s = edge_edge; 00461 i = ccw(ni); 00462 break; 00463 case RIGHT_TURN: 00464 s = edge_edge; 00465 i = cw(ni); 00466 break; 00467 default: 00468 s = edge_vertex; 00469 i = ni; 00470 } 00471 } 00472 } 00473 00474 template < class Gt, class Tds > 00475 void 00476 Triangulation_line_face_circulator_2<Gt,Tds>:: 00477 decrement() 00478 { 00479 CGAL_triangulation_precondition(pos != Face_handle()); 00480 if(s == vertex_vertex || s == vertex_edge) { 00481 if(s == vertex_vertex){ 00482 i = cw(i); 00483 } 00484 Orientation o; 00485 do{ 00486 Face_handle n = pos->neighbor(ccw(i)); 00487 i = n->index(pos); 00488 pos = n; 00489 if (pos->vertex(i) == _tr->infinite_vertex()){ 00490 o = COLLINEAR; 00491 i = ccw(i); 00492 break; 00493 } 00494 o = _tr->orientation(p, q, pos->vertex(i)->point()); 00495 i = ccw(i); 00496 }while(o == LEFT_TURN); 00497 00498 s = (o == COLLINEAR) ? vertex_vertex : edge_vertex; 00499 00500 } 00501 else { // s == edge_edge || s == edge_vertex 00502 // the following is not nice. A better solution is to say 00503 // that index i is at the vertex that is alone on one side of l(p,q) 00504 if(s == edge_edge){ 00505 i = (_tr->orientation 00506 (p, q, 00507 pos->vertex(i)->point()) == 00508 LEFT_TURN) 00509 ? cw(i) : ccw(i); 00510 } 00511 Face_handle n = pos->neighbor(i); 00512 i = n->index(pos); 00513 pos = n; 00514 Orientation o = _tr->is_infinite(pos->vertex(i)) ? 00515 COLLINEAR : 00516 _tr->orientation(p, q, pos->vertex(i)->point()); 00517 00518 s = (o == COLLINEAR) ? vertex_edge : edge_edge; 00519 } 00520 } 00521 00522 template < class Gt, class Tds > 00523 bool 00524 Triangulation_line_face_circulator_2<Gt,Tds>:: 00525 locate(const Point& t, Locate_type <, int &li) 00526 { 00527 switch(s){ 00528 case edge_edge: 00529 case vertex_edge: 00530 { 00531 Orientation o = 00532 _tr->orientation(pos->vertex(ccw(i))->point(), 00533 pos->vertex(cw(i))->point(), 00534 t); 00535 if(o == RIGHT_TURN) return false; 00536 if(o == COLLINEAR){ 00537 lt = Triangulation::EDGE; 00538 li = i; 00539 return true; 00540 } 00541 lt = Triangulation::FACE; 00542 li = 4;//li unused in this case 00543 return true; 00544 } 00545 case vertex_vertex: 00546 { 00547 if(_tr->is_infinite(pos->vertex(i))){ 00548 CGAL_triangulation_assertion( 00549 _tr->orientation( pos->vertex(cw(i))->point(), 00550 pos->vertex(ccw(i))->point(), 00551 t) != LEFT_TURN); 00552 lt = Triangulation::OUTSIDE_CONVEX_HULL; 00553 li = i; 00554 return true; 00555 } 00556 const Point &u = pos->vertex(cw(i))->point(); 00557 const Point &v = pos->vertex(i)->point(); 00558 // u == t was detected earlier 00559 if(_tr->compare_x(v,t)==EQUAL && 00560 _tr->compare_y(v,t)==EQUAL){ 00561 lt = Triangulation::VERTEX; 00562 li = i; 00563 return true; 00564 } 00565 if(_tr->collinear_between(u, t, v)) { 00566 lt = Triangulation::EDGE; 00567 li = ccw(i); 00568 return true; 00569 } 00570 return false; 00571 } 00572 default: // edge_vertex 00573 { 00574 if(_tr->is_infinite(pos->vertex(i))){ 00575 lt = Triangulation::OUTSIDE_CONVEX_HULL; 00576 li = i; 00577 return true; 00578 } 00579 if(_tr->xy_equal(t,pos->vertex(i) ->point()) ){ 00580 li = i; 00581 lt = Triangulation::VERTEX; 00582 return true; 00583 } 00584 if(_tr->collinear_between(p, t, pos->vertex(i)->point())) { 00585 lt = Triangulation::FACE; 00586 return true; 00587 } 00588 return false; 00589 } 00590 } 00591 } 00592 00593 template < class Gt, class Tds > 00594 inline 00595 Triangulation_line_face_circulator_2<Gt,Tds>& 00596 Triangulation_line_face_circulator_2<Gt,Tds>:: 00597 operator++() 00598 { 00599 CGAL_triangulation_precondition( pos != Face_handle()) ; 00600 increment(); 00601 return *this; 00602 } 00603 00604 template < class Gt, class Tds > 00605 inline 00606 Triangulation_line_face_circulator_2<Gt,Tds>& 00607 Triangulation_line_face_circulator_2<Gt,Tds>:: 00608 operator--() 00609 { 00610 CGAL_triangulation_precondition(pos != Face_handle()) ; 00611 decrement(); 00612 return *this; 00613 } 00614 00615 template < class Gt, class Tds > 00616 inline 00617 Triangulation_line_face_circulator_2<Gt,Tds> 00618 Triangulation_line_face_circulator_2<Gt,Tds>:: 00619 operator++(int) 00620 { 00621 Line_face_circulator tmp(*this); 00622 ++(*this); 00623 return tmp; 00624 } 00625 00626 template < class Gt, class Tds > 00627 inline 00628 Triangulation_line_face_circulator_2<Gt,Tds> 00629 Triangulation_line_face_circulator_2<Gt,Tds>:: 00630 operator--(int) 00631 { 00632 Line_face_circulator tmp(*this); 00633 --(*this); 00634 return tmp; 00635 } 00636 00637 template < class Gt, class Tds > 00638 inline bool 00639 Triangulation_line_face_circulator_2<Gt,Tds>:: 00640 operator==(const Line_face_circulator& lfc) const 00641 { 00642 CGAL_triangulation_precondition( pos != Face_handle() && 00643 lfc.pos != Face_handle()); 00644 return ( pos == lfc.pos && _tr == lfc._tr && 00645 s== lfc.s && p==lfc.p && q==lfc.q); 00646 } 00647 00648 template < class Gt, class Tds > 00649 inline bool 00650 Triangulation_line_face_circulator_2<Gt,Tds>:: 00651 operator!=(const Line_face_circulator& lfc) const 00652 { 00653 return !(*this == lfc); 00654 } 00655 00656 template < class Gt, class Tds > 00657 inline bool 00658 Triangulation_line_face_circulator_2<Gt,Tds>:: 00659 is_empty() const 00660 { 00661 return pos == Face_handle(); 00662 } 00663 00664 template < class Gt, class Tds > 00665 inline bool 00666 Triangulation_line_face_circulator_2<Gt,Tds>:: 00667 operator==(Nullptr_t CGAL_triangulation_assertion_code(n)) const 00668 { 00669 CGAL_triangulation_assertion( n == NULL); 00670 return pos == Face_handle(); 00671 } 00672 00673 template < class Gt, class Tds > 00674 inline bool 00675 Triangulation_line_face_circulator_2<Gt,Tds>:: 00676 operator!=(Nullptr_t n) const 00677 { 00678 CGAL_triangulation_assertion( n == NULL); 00679 return !(*this == n); 00680 } 00681 00682 template < class Gt, class Tds > 00683 inline bool 00684 Triangulation_line_face_circulator_2<Gt,Tds>:: 00685 collinear_outside() const 00686 { 00687 // return (_tr->is_infinite(*this)) 00688 // && (s == vertex_vertex) 00689 // && (! _tr->is_infinite((*this)->vertex(i))); 00690 // return true if the circulator is non null 00691 // the line is collinear with a convex hull edge 00692 // and the convex hull is on the left of the line 00693 Face_handle fh = pos; 00694 return ( s == vertex_vertex && 00695 (! _tr->is_infinite(fh)) && 00696 _tr->is_infinite(fh->neighbor(ccw(i)))); 00697 } 00698 00699 CGAL_END_NAMESPACE 00700 #endif //CGAL_TRIANGULATION_LINE_FACE_CIRCULATOR_2_H 00701