diff --git a/Packages/Triangulation_2/include/CGAL/Triangulation_2.h b/Packages/Triangulation_2/include/CGAL/Triangulation_2.h index 21dbe00251c..b9e08e20f3f 100644 --- a/Packages/Triangulation_2/include/CGAL/Triangulation_2.h +++ b/Packages/Triangulation_2/include/CGAL/Triangulation_2.h @@ -1,4 +1,3 @@ - // ============================================================================ // // Copyright (c) 1997 The CGAL Consortium @@ -110,14 +109,12 @@ protected: public: - +// CONSTRUCTORS Triangulation_2(const Geom_traits& geom_traits=Geom_traits()) : _gt(geom_traits) { init(); } - - // copy constructor duplicates vertices and faces Triangulation_2(const Triangulation_2 &tr) @@ -186,7 +183,7 @@ public: } while (fc != done); } return count; -} + } const Vertex_handle infinite_vertex() const @@ -212,103 +209,11 @@ public: public: // CHECKING - bool is_valid(bool verbose = false, int level = 0) const - { - bool result = _tds.is_valid(); - - Face_iterator it; - switch(dimension()) { - case 0 : - break; - case 1 : - // TODO - break; - case 2 : - for(it=faces_begin(); it!=faces_end(); it++){ - CGAL_triangulation_assertion( !is_infinite(it)); - Orientation s = geom_traits().orientation(it->vertex(0)->point(), - it->vertex(1)->point(), - it->vertex(2)->point()); - CGAL_triangulation_assertion( s == LEFTTURN ); - result = result && ( s == LEFTTURN ); - } - - if (number_of_vertices() <= 2) return result; - Vertex_circulator start = infinite_vertex()->incident_vertices(), - pc(start), - qc(start), - rc(start); - ++qc; - ++rc; - ++rc; - do{ - Orientation s = geom_traits().orientation(pc->point(), - qc->point(), - rc->point()); - CGAL_triangulation_assertion( s != LEFTTURN ); - result = result && ( s != LEFTTURN ); - pc = qc; - qc = rc; - ++rc; - }while(pc != start); - - return result; - } - - + bool is_valid(bool verbose = false, int level = 0) const; + // TO DEBUG - void show_all() -{ - cerr<< "AFFICHE TOUTE LA TRIANGULATION :"< "<dimension(); - switch(i){ - case 0: - cerr <<"point :"<<(fi->vertex(0)->point())<<" / voisin "<<&(*(fi->neighbor(0))) - <<"["<<(fi->neighbor(0))->vertex(0)->point()<<"]" - <vertex(0)->point())<<" / voisin "<<&(*(fi->neighbor(0))) - <<"["<<(fi->neighbor(0))->vertex(0)->point() - <<"/"<<(fi->neighbor(0))->vertex(1)->point()<<"]" - <vertex(1)->point())<<" / voisin "<<&(*(fi->neighbor(1))) - <<"["<<(fi->neighbor(1))->vertex(0)->point() - <<"/"<<(fi->neighbor(1))->vertex(1)->point()<<"]" - <vertex(0)->point())<<" / voisin "<<&(*(fi->neighbor(0))) - <<"["<<(fi->neighbor(0))->vertex(0)->point() - <<"/"<<(fi->neighbor(0))->vertex(1)->point() - <<"/"<<(fi->neighbor(0))->vertex(2)->point()<<"]" - <vertex(1)->point())<<" / voisin "<<&(*(fi->neighbor(1))) - <<"["<<(fi->neighbor(1))->vertex(0)->point() - <<"/"<<(fi->neighbor(1))->vertex(1)->point() - <<"/"<<(fi->neighbor(1))->vertex(2)->point()<<"]" - <vertex(2)->point())<<" / voisin "<<&(*(fi->neighbor(2))) - <<"["<<(fi->neighbor(2))->vertex(0)->point() - <<"/"<<(fi->neighbor(2))->vertex(1)->point() - <<"/"<<(fi->neighbor(2))->vertex(2)->point()<<"]" - <neighbor(i); - CGAL_triangulation_precondition( !is_infinite(f) && - !is_infinite(f->neighbor(i)) ); - CGAL_triangulation_precondition( - geom_traits().orientation(f->vertex(i)->point(), - f->vertex(cw(i))->point(), - (f->neighbor(i))->vertex((f->neighbor(i))->index(f))->point() ) - == RIGHTTURN - && - geom_traits().orientation(f->vertex(i)->point(), - f->vertex(ccw(i))->point(), - (f->neighbor(i))->vertex((f->neighbor(i))->index(f))->point() ) - == LEFTTURN - ); - - _tds.flip( &(*f), i); - return; - } + void flip(Face_handle& f, int i); + void insert_first(const Vertex_handle& v) { @@ -460,193 +343,28 @@ public: private: -void insert_outside_convex_hull_1(Vertex_handle v, Face_handle f) - { - int i = f->index(infinite_vertex()); - Face_handle n = f->neighbor(i); - int in = n->index(f); - CGAL_triangulation_precondition( ! is_infinite(n)); - CGAL_triangulation_precondition( - geom_traits().orientation( n->vertex(in)->point(), - n->vertex(1-in)->point(), - v->point() ) == CGAL_COLLINEAR && - collinear_between( n->vertex(in)->point(), - n->vertex(1-in)->point(), - v->point()) ); - _tds.insert_in_edge(&(*v), &(*f), 2); - return; - } - +void insert_outside_convex_hull_1(Vertex_handle v, Face_handle f); void insert_outside_convex_hull_2(Vertex_handle v, Face_handle f) - { - CGAL_triangulation_precondition(is_infinite(f)); - - int li = f->index(infinite_vertex()); - - list ccwlist; - list cwlist; - - - Point p = v->point(); - Point q,r; - - li = f->index(infinite_vertex()); - q = f->vertex(ccw(li))->point(); - r = f->vertex(cw(li))->point(); - CGAL_triangulation_precondition( - geom_traits().orientation(p,q,r) == CGAL_LEFTTURN); - - Face_circulator fc = infinite_vertex()->incident_faces(f); - bool done = false; - while(! done) { - fc--; - li = fc->index(infinite_vertex()); - q = fc->vertex(ccw(li))->point(); - r = fc->vertex(cw(li))->point(); - if(geom_traits().orientation(p,q,r) == CGAL_LEFTTURN ) { - ccwlist.push_back(&(*fc)); - } - else {done=true;} - } - - fc= infinite_vertex()->incident_faces(f); - done = false; - while(! done){ - fc++; - li = fc->index(infinite_vertex()); - q = fc->vertex(ccw(li))->point(); - r = fc->vertex(cw(li))->point(); - if(geom_traits().orientation(p,q,r) == CGAL_LEFTTURN ) { - cwlist.push_back(&(*fc)); - } - else {done=true;} - } - - _tds.insert_in_face( &(*v), &(*f)); - - Face_handle fh; - while ( ! ccwlist.empty()) { - fh = ccwlist.front(); - li = ccw(fh->index(infinite_vertex())); - _tds.flip( &(*fh) , li); - ccwlist.pop_front(); - } - - while ( ! cwlist.empty()) { - fh = cwlist.front(); - li = cw(fh->index(infinite_vertex())); - _tds.flip( &(*fh) , li); - cwlist.pop_front(); - } - - //reset infinite_vertex()->face(); - fc = v->incident_faces(); - while( ! is_infinite(&(*fc))) { - fc++;} - infinite_vertex()->set_face(&(*fc)); - - } - public : -void insert_outside_affine_hull(Vertex_handle v) - { - CGAL_triangulation_precondition(dimension() == 1); - Face_handle f = (*edges_begin()).first; - CGAL_Orientation or = geom_traits().orientation( f->vertex(0)->point(), - f->vertex(1)->point(), - v->point()); - CGAL_triangulation_precondition(or != CGAL_COLLINEAR); - bool conform = ( or == CGAL_COUNTERCLOCKWISE); +void insert_outside_affine_hull(Vertex_handle v); - _tds.insert_outside_affine_hull( &(*v), &(*infinite_vertex()), conform); - return; - } - - - - - Vertex_handle insert(const Point& p, - Locate_type& lt, - Face_handle f = Face_handle() ) - { - Vertex_handle v; - if(number_of_vertices() == 0) { - v = new Vertex(p); - lt = OUTSIDE_AFFINE_HULL; - //_tds.insert_first(&(*v)); - insert_first(v); - return v; - } - if(number_of_vertices() == 1) { - if (geom_traits().compare(p,finite_vertex()->point()) ) { - lt = VERTEX; - return finite_vertex(); - } - v = new Vertex(p); - lt = OUTSIDE_AFFINE_HULL; - //_tds.insert_second(&(*v)); - insert_second(v); - return v; - } + Locate_type& lt, + Face_handle f = Face_handle() ); - int li; - Face_handle loc = locate(p, lt, li, f); - switch(lt){ - case FACE: - { - v = new Vertex(p); - //_tds.insert_in_face( &(*v), &(*loc)); - insert_in_face(v,loc); - break; - } - - case EDGE: - { - v = new Vertex(p); - //_tds.insert_on_edge( &(*v), &(*loc), li); - insert_in_edge(v,loc,li); - break; - } +Vertex_handle insert(const Point &p, + Face_handle f = Face_handle() ) +{ + Locate_type lt; + return insert(p, lt, f); +} - case OUTSIDE_CONVEX_HULL: - { - v = new Vertex(p); - insert_outside_convex_hull(v,loc); - break; - } - - case OUTSIDE_AFFINE_HULL: - { - v = new Vertex(p); - //_tds.insert_collinear_outside( &(*v), &(*loc),li); - insert_outside_affine_hull(v); - break; - } - - case VERTEX: - return loc->vertex(li); - - default: - CGAL_triangulation_assertion(false); // locate step failed - } - return v; - } - - - Vertex_handle insert(const Point &p, - Face_handle f = Face_handle() ) - { - Locate_type lt; - return insert(p, lt, f); - } - - Vertex_handle push_back(const Point &p) - { - Locate_type lt; - return insert(p, lt, NULL); - } +Vertex_handle push_back(const Point &p) +{ + Locate_type lt; + return insert(p, lt, NULL); +} #ifndef CGAL_CFG_NO_MEMBER_TEMPLATES template < class InputIterator > @@ -710,7 +428,7 @@ Vertex_handle insert(const Point& p, -public: +public: void remove_degree_3(Vertex_handle v, Face_handle f = Face_handle()) { @@ -734,34 +452,15 @@ void remove_second(Vertex_handle v) return; } -void remove(Vertex_handle v) - { - CGAL_triangulation_precondition( ! v.is_null() ); - CGAL_triangulation_precondition( !is_infinite(v)); - - if (number_of_vertices() == 1) { - remove_first(v); - return; - } - - if (number_of_vertices() == 2) { - remove_second(v); - } - else{ - if ( dimension() == 1) remove_1D(v); - else remove_2D(v); - } - - // v.Delete(); - // set_number_of_vertices(number_of_vertices()-1); - return; - } +void remove(Vertex_handle v); protected: - void remove_1D(Vertex_handle v) - { - _tds.remove_1D(&(*v)); - } + void remove_1D(Vertex_handle v); + void remove_2D(Vertex_handle v); + +private: +void make_hole ( Vertex_handle v, list & hole); +void fill_hole ( Vertex_handle v, list< Edge > & hole ); public: @@ -776,183 +475,23 @@ public: const Point& t, Locate_type& lt, int& li) const; - - Face_handle + Face_handle locate(const Point& p, Locate_type& lt, int& li, - Face_handle start = Face_handle()) const - { - if(number_of_vertices() < 2) { - if(number_of_vertices() == 0) { - lt = OUTSIDE; - } else { // number_of_vertices() == 1 - lt = geom_traits().compare(p,finite_vertex()->point()) ? - VERTEX : OUTSIDE; - } - return NULL; - } - if(dimension() == 1){ - return march_locate_1D(p, lt, li); - } - - if(start.is_null()){ - start = infinite_face()-> - neighbor(infinite_face()->index(infinite_vertex())); - }else if(is_infinite(start)){ - start = start->neighbor(start->index(infinite_vertex())); - } - - return march_locate_2D(start, p, lt, li); - } - - void remove_2D(Vertex_handle v) - { - //test the dimensionality of the resulting triangulation - //it goes down to 1 iff - // 1) any finite face is incident to v - // 2) all vertices are colinear - bool dim1 = true; - Face_iterator fit = faces_begin(); - while (dim1==true && fit != faces_end()) { - dim1 = dim1 && fit->has_vertex(v); - fit++; - } - Face_circulator fic = v->incident_faces(); - while (is_infinite(fic)) {++fic;} - Face_circulator done(fic); - Face_handle start(fic); int iv = start->index(v); - Point p = start->vertex(cw(iv))->point(), q = start->vertex(ccw(iv))->point(); - while ( dim1 && ++fic != done) { - iv = fic->index(v); - if (fic->vertex(ccw(iv)) != infinite_vertex()) { - dim1 = dim1 && - geom_traits().orientation(p, q, fic->vertex(ccw(iv))->point()) - == CGAL_COLLINEAR; - } - } - - if (dim1) { - _tds.remove_down(&(*v)); - } - else { - list hole; - make_hole(v, hole); - fill_hole(v, hole); - v.Delete(); - set_number_of_vertices(number_of_vertices()-1); - } - return; - } - - -void make_hole ( Vertex_handle v, list & hole) - { - - list::iterator hit; - list to_delete; - - Face_handle f, ff, fn; - int i =0,ii =0, in =0; - Vertex_handle vv; - - Face_circulator fc = v->incident_faces(); - Face_circulator done(fc); - do { - f = (*fc).handle(); fc++; - i = f->index(v); - fn = f->neighbor(i); - in = fn->index(f); - vv = f->vertex(cw(i)); - if( vv->face()== f) vv->set_face(fn); - vv = f->vertex(ccw(i)); - if( vv->face()== f) vv->set_face(fn); - fn->set_neighbor(in, NULL); - hole.push_back(Edge(fn,in)); - to_delete.push_back(f); - } - while(fc != done); - - while (! to_delete.empty()){ - (to_delete.front()).Delete(); - to_delete.pop_front(); - } - return; - } - - -void fill_hole ( Vertex_handle v, list< Edge > & hole ) - { - typedef list< Edge > Hole; - - Point p = v->point(); - Face_handle f, ff, fn; - int i =0,ii =0, in =0; - Vertex_handle v0, v1, v2; - Point p0, p1, p2; - Triangle t; - CGAL_Bounded_side side; - CGAL_Orientation or; - int nhole; - - if( hole.size() != 3) { - // find the first edge v0v1 on the hole boundary - // such that - // v0, v1 and the next vertex v2 are all finite - // v0v1v2 is a left turn and - // triangle v0v1v2 does not contain the removed point - - // if found create face v0v1v2 - // stop when no more faces can be created that way - - nhole= hole.size(); - // nhole decount the number of hole edges passed - // from the last created edges - while (hole.size()>3 && nhole>0) { - //ff = (Face *) ( (hole.front()).first); - ff = hole.front().first; - ii = (hole.front()).second; - hole.pop_front(); - - v0 = ff->vertex(cw(ii)); - v1 = ff->vertex(ccw(ii)); - if( !is_infinite(v0) && !is_infinite(v1)) { - //fn = (Face *) ( (hole.front()).first); - fn = hole.front().first; - in = (hole.front()).second; - - v2 = fn->vertex(ccw(in)); - if( !is_infinite(v2)) { - p0 = v0->point(); - p1 = v1->point(); - p2 = v2->point(); - or = geom_traits().orientation(p0,p1,p2); - if ( or == CGAL_LEFTTURN) { - side = bounded_side(p0,p1,p2, p); - if( side == CGAL_ON_UNBOUNDED_SIDE || - (side == CGAL_ON_BOUNDARY && collinear_between(p0, p, p2)) ) { - //create face - Face_handle newf = new Face(v0,v1,v2); - newf->set_neighbor(2,ff); - newf->set_neighbor(0,fn); - ff->set_neighbor(ii, newf); - fn->set_neighbor(in,newf); - hole.pop_front(); - //hole.push_front(Hole_neighbor(&(*newf),1)); - hole.push_front(Edge(newf,1)); - nhole = hole.size(); - continue; - } - } - } - } - - // not possible to create face v0,v1,v2; - //hole.push_back(Hole_neighbor(&(*ff),ii)); - hole.push_back( Edge (ff,ii)); - nhole--; + Face_handle start = Face_handle()) const; +inline Face_handle +locate(const Point &p, + Face_handle start = Face_handle()) const +{ + Locate_type lt; + int li; + return locate(p, lt, li, start); +} + + //TRAVERSING : ITERATORS AND CIRCULATORS Face_iterator faces_begin() const { @@ -1044,135 +583,168 @@ inline if( (!lfc.is_empty()) && is_infinite( lfc )){ return Line_face_circulator(); - } + } return lfc; } // not documented public: - Oriented_side - oriented_side(const Point &p0, const Point &p1, - const Point &p2, const Point &p) const; +Oriented_side +oriented_side(const Point &p0, const Point &p1, + const Point &p2, const Point &p) const; - Bounded_side - bounded_side(const Point &p0, const Point &p1, - const Point &p2, const Point &p) const; +Bounded_side +bounded_side(const Point &p0, const Point &p1, + const Point &p2, const Point &p) const; - Oriented_side - oriented_side(const Face_handle& f, const Point &p) const - { - return oriented_side(f->vertex(0)->point(), - f->vertex(1)->point(), - f->vertex(2)->point(), - p); - } - - - - - // NOT DOCUMENTED - bool - collinear_between(const Point& p, const Point& q, const Point& r) const - { - Comparison_result c_pr = geom_traits().compare_x(p, r); - Comparison_result c_pq; - Comparison_result c_qr; - if(c_pr == EQUAL) { - c_pr = geom_traits().compare_y(p, r); - c_pq = geom_traits().compare_y(p, q); - c_qr = geom_traits().compare_y(q, r); - } else { - c_pq = geom_traits().compare_x(p, q); - c_qr = geom_traits().compare_x(q, r); - } - return ( (c_pq == SMALLER) && (c_qr == SMALLER) ) || - ( (c_qr == LARGER) && (c_pq == LARGER) ); - - } +Oriented_side +oriented_side(const Face_handle& f, const Point &p) const; +bool +collinear_between(const Point& p, const Point& q, const Point& r) const; + }; template -void -Triangulation_2:: -insert_outside(const Vertex_handle& vp, const Face_handle& f) +bool +Triangulation_2:: +is_valid(bool verbose = false, int level = 0) const { - CGAL_triangulation_precondition(is_infinite(f)); + bool result = _tds.is_valid(); - std::list ccwlist; - std::list cwlist; - - int li; - Point p = vp->point(); - Point q,r; - - li = f->index(infinite_vertex()); - q = f->vertex(ccw(li))->point(); - r = f->vertex(cw(li))->point(); - CGAL_triangulation_precondition( geom_traits().orientation(p,q,r) - == LEFTTURN); - - Face_circulator fc = infinite_vertex()->incident_faces(f); - bool done = false; - while(! done) { - fc--; - li = fc->index(infinite_vertex()); - q = fc->vertex(ccw(li))->point(); - r = fc->vertex(cw(li))->point(); - if(geom_traits().orientation(p,q,r) == LEFTTURN ) { - ccwlist.push_back(&(*fc)); - } - else {done=true;} + Face_iterator it; + switch(dimension()) { + case 0 : + break; + case 1 : + // TODO + break; + case 2 : + for(it=faces_begin(); it!=faces_end(); it++){ + CGAL_triangulation_assertion( !is_infinite(it)); + Orientation s = geom_traits().orientation(it->vertex(0)->point(), + it->vertex(1)->point(), + it->vertex(2)->point()); + CGAL_triangulation_assertion( s == LEFTTURN ); + result = result && ( s == LEFTTURN ); } - fc= infinite_vertex()->incident_faces(f); - done = false; - while(! done){ - fc++; - li = fc->index(infinite_vertex()); - q = fc->vertex(ccw(li))->point(); - r = fc->vertex(cw(li))->point(); - if(geom_traits().orientation(p,q,r) == LEFTTURN ) { - cwlist.push_back(&(*fc)); - } - else {done=true;} - } + if (number_of_vertices() <= 2) return result; + Vertex_circulator start = infinite_vertex()->incident_vertices(), + pc(start), + qc(start), + rc(start); + ++qc; + ++rc; + ++rc; + do{ + Orientation s = geom_traits().orientation(pc->point(), + qc->point(), + rc->point()); + CGAL_triangulation_assertion( s != LEFTTURN ); + result = result && ( s != LEFTTURN ); + pc = qc; + qc = rc; + ++rc; + }while(pc != start); - _tds.insert_in_face( &(*vp), &(*f)); + return result; + } - Face_handle fh; - while ( ! ccwlist.empty()) { - fh = ccwlist.front(); - li = ccw(fh->index(infinite_vertex())); - _tds.flip( &(*fh) , li); - ccwlist.pop_front(); - } +template +void +Triangulation_2:: +show_all() +{ + cerr<< "AFFICHE TOUTE LA TRIANGULATION :"<index(infinite_vertex())); - _tds.flip( &(*fh) , li); - cwlist.pop_front(); - } +template +void +Triangulation_2:: +show_face( typename Tds::Face_iterator fi) +{ + cerr << "face : "<<(void*)&(*fi)<<" => "<dimension(); + switch(i){ + case 0: + cerr <<"point :"<<(fi->vertex(0)->point())<<" / voisin "<<&(*(fi->neighbor(0))) + <<"["<<(fi->neighbor(0))->vertex(0)->point()<<"]" + <vertex(0)->point())<<" / voisin "<<&(*(fi->neighbor(0))) + <<"["<<(fi->neighbor(0))->vertex(0)->point() + <<"/"<<(fi->neighbor(0))->vertex(1)->point()<<"]" + <vertex(1)->point())<<" / voisin "<<&(*(fi->neighbor(1))) + <<"["<<(fi->neighbor(1))->vertex(0)->point() + <<"/"<<(fi->neighbor(1))->vertex(1)->point()<<"]" + <vertex(0)->point())<<" / voisin "<<&(*(fi->neighbor(0))) + <<"["<<(fi->neighbor(0))->vertex(0)->point() + <<"/"<<(fi->neighbor(0))->vertex(1)->point() + <<"/"<<(fi->neighbor(0))->vertex(2)->point()<<"]" + <vertex(1)->point())<<" / voisin "<<&(*(fi->neighbor(1))) + <<"["<<(fi->neighbor(1))->vertex(0)->point() + <<"/"<<(fi->neighbor(1))->vertex(1)->point() + <<"/"<<(fi->neighbor(1))->vertex(2)->point()<<"]" + <vertex(2)->point())<<" / voisin "<<&(*(fi->neighbor(2))) + <<"["<<(fi->neighbor(2))->vertex(0)->point() + <<"/"<<(fi->neighbor(2))->vertex(1)->point() + <<"/"<<(fi->neighbor(2))->vertex(2)->point()<<"]" + <face(); - fc = vp->incident_faces(); - while( ! is_infinite(&(*fc))) { - fc++;} - infinite_vertex()->set_face(&(*fc)); - } +template +void +Triangulation_2:: +flip(Face_handle& f, int i) + { + CGAL_triangulation_precondition ( ! f.is_null() ); + CGAL_triangulation_precondition (i == 0 || i == 1 || i == 2); + //Face_handle n = f->neighbor(i); + CGAL_triangulation_precondition( !is_infinite(f) && + !is_infinite(f->neighbor(i)) ); + CGAL_triangulation_precondition( + geom_traits().orientation(f->vertex(i)->point(), + f->vertex(cw(i))->point(), + (f->neighbor(i))->vertex((f->neighbor(i))->index(f))->point() ) + == RIGHTTURN + && + geom_traits().orientation(f->vertex(i)->point(), + f->vertex(ccw(i))->point(), + (f->neighbor(i))->vertex((f->neighbor(i))->index(f))->point() ) + == LEFTTURN + ); + + _tds.flip( &(*f), i); + return; + } template Triangulation_2::Vertex_handle Triangulation_2:: insert(const Point& p, Locate_type& lt, Face_handle f) -{ + { Vertex_handle v; if(number_of_vertices() == 0) { v = new Vertex(p); - lt = OUTSIDE; + lt = OUTSIDE_AFFINE_HULL; //_tds.insert_first(&(*v)); insert_first(v); return v; @@ -1183,7 +755,7 @@ insert(const Point& p, Locate_type& lt, Face_handle f) return finite_vertex(); } v = new Vertex(p); - lt = OUTSIDE; + lt = OUTSIDE_AFFINE_HULL; //_tds.insert_second(&(*v)); insert_second(v); return v; @@ -1191,7 +763,6 @@ insert(const Point& p, Locate_type& lt, Face_handle f) int li; Face_handle loc = locate(p, lt, li, f); - switch(lt){ case FACE: { @@ -1200,183 +771,321 @@ insert(const Point& p, Locate_type& lt, Face_handle f) insert_in_face(v,loc); break; } - case OUTSIDE: - { - v = new Vertex(p); - insert_outside(v,loc); - break; - } + case EDGE: { v = new Vertex(p); - //_tds.insert_in_edge( &(*v), &(*loc), li); + //_tds.insert_on_edge( &(*v), &(*loc), li); insert_in_edge(v,loc,li); break; } - case COLLINEAR_OUTSIDE: + + case OUTSIDE_CONVEX_HULL: + { + v = new Vertex(p); + insert_outside_convex_hull(v,loc); + break; + } + + case OUTSIDE_AFFINE_HULL: { v = new Vertex(p); //_tds.insert_collinear_outside( &(*v), &(*loc),li); - insert_collinear_outside(v,loc,li); + insert_outside_affine_hull(v); break; } + case VERTEX: return loc->vertex(li); + default: CGAL_triangulation_assertion(false); // locate step failed } return v; } + + + + + template void Triangulation_2:: +insert_outside_convex_hull_1(Vertex_handle v, Face_handle f) + { + int i = f->index(infinite_vertex()); + Face_handle n = f->neighbor(i); + int in = n->index(f); + CGAL_triangulation_precondition( ! is_infinite(n)); + CGAL_triangulation_precondition( + geom_traits().orientation( n->vertex(in)->point(), + n->vertex(1-in)->point(), + v->point() ) == CGAL_COLLINEAR && + collinear_between( n->vertex(in)->point(), + n->vertex(1-in)->point(), + v->point()) ); + _tds.insert_in_edge(&(*v), &(*f), 2); + return; + } + +template +void +Triangulation_2:: +insert_outside_convex_hull_2(Vertex_handle v, Face_handle f) + { + CGAL_triangulation_precondition(is_infinite(f)); + + int li = f->index(infinite_vertex()); + + list ccwlist; + list cwlist; + + + Point p = v->point(); + Point q,r; + + li = f->index(infinite_vertex()); + q = f->vertex(ccw(li))->point(); + r = f->vertex(cw(li))->point(); + CGAL_triangulation_precondition( + geom_traits().orientation(p,q,r) == CGAL_LEFTTURN); + + Face_circulator fc = infinite_vertex()->incident_faces(f); + bool done = false; + while(! done) { + fc--; + li = fc->index(infinite_vertex()); + q = fc->vertex(ccw(li))->point(); + r = fc->vertex(cw(li))->point(); + if(geom_traits().orientation(p,q,r) == CGAL_LEFTTURN ) { + ccwlist.push_back(&(*fc)); + } + else {done=true;} + } + + fc= infinite_vertex()->incident_faces(f); + done = false; + while(! done){ + fc++; + li = fc->index(infinite_vertex()); + q = fc->vertex(ccw(li))->point(); + r = fc->vertex(cw(li))->point(); + if(geom_traits().orientation(p,q,r) == CGAL_LEFTTURN ) { + cwlist.push_back(&(*fc)); + } + else {done=true;} + } + + _tds.insert_in_face( &(*v), &(*f)); + + Face_handle fh; + while ( ! ccwlist.empty()) { + fh = ccwlist.front(); + li = ccw(fh->index(infinite_vertex())); + _tds.flip( &(*fh) , li); + ccwlist.pop_front(); + } + + while ( ! cwlist.empty()) { + fh = cwlist.front(); + li = cw(fh->index(infinite_vertex())); + _tds.flip( &(*fh) , li); + cwlist.pop_front(); + } + + //reset infinite_vertex()->face(); + fc = v->incident_faces(); + while( ! is_infinite(&(*fc))) { + fc++;} + infinite_vertex()->set_face(&(*fc)); + + } + +template +void +Triangulation_2:: +insert_outside_affine_hull(Vertex_handle v) + { + CGAL_triangulation_precondition(dimension() == 1); + Face_handle f = (*edges_begin()).first; + CGAL_Orientation or = geom_traits().orientation( f->vertex(0)->point(), + f->vertex(1)->point(), + v->point()); + CGAL_triangulation_precondition(or != CGAL_COLLINEAR); + bool conform = ( or == CGAL_COUNTERCLOCKWISE); + + _tds.insert_outside_affine_hull( &(*v), &(*infinite_vertex()), conform); + return; + } + +template +void +Triangulation_2:: +remove(Vertex_handle v) + { + CGAL_triangulation_precondition( ! v.is_null() ); + CGAL_triangulation_precondition( !is_infinite(v)); + + if (number_of_vertices() == 1) { + remove_first(v); + return; + } + + if (number_of_vertices() == 2) { + remove_second(v); + } + else{ + if ( dimension() == 1) remove_1D(v); + else remove_2D(v); + } + + // v.Delete(); + // set_number_of_vertices(number_of_vertices()-1); + return; + } + +template +void +Triangulation_2:: remove_1D(Vertex_handle v) { - //deal with one dimensional case - Face_handle f1, f2, f1n, f2n; - int i1,i2,i1n,i2n; - - switch( v->degree()) { - case 2 : - f1= v->face(); i1= f1->index(v); - f2= f1->neighbor(cw(i1)); i2= f2->index(v); - f1n = f1->neighbor(i1); i1n = f1n->index(f1); - f2n = f2->neighbor(i2); i2n = f2n->index(f2); - f1n->set_neighbor(i1n,f2n); f2n->set_neighbor(i2n,f1n); - f1->vertex(cw(i1))->set_face(f1n); - f1->vertex(ccw(i1))->set_face(f1n); - f1.Delete(); f2.Delete(); - return; - - case 4 : - int j1,j2,j1n,j2n; - f1= v->face(); i1= f1->index(v); - j1 = (is_infinite(f1->vertex(cw(i1)))) ? ccw(i1) : cw(i1); - // j1 is the other finite vertex of f1 - // 3-i1-j1 is the index of the infinite_vertex in face f1 - f2 = f1->neighbor(3-i1-j1); i2 = f2->index(v); - j2 = f2->index(f1->vertex(j1)); - f1n = f1->neighbor(j1); i1n = f1n->index(v); j1n = f1n->index(f1); - f2n = f2->neighbor(j2); i2n = f2n->index(v); j2n = f2n->index(f2); - - // update f1n and f2n - f1n->set_vertex(i1n,f1->vertex(j1)); - f2n->set_vertex(i2n,f2->vertex(j2)); - if(f1->neighbor(i1) != f2) { - Face_handle ff1 = f1->neighbor(i1); - Face_handle ff2 = f2->neighbor(i2); - f1n->set_neighbor(j1n,ff1); ff1->set_neighbor(ff1->index(f1),f1n); - f2n->set_neighbor(j2n,ff2); ff2->set_neighbor(ff2->index(f2),f2n); - } - else { - f1n->set_neighbor(j1n,f2n); - f2n->set_neighbor(j2n,f1n); - } + _tds.remove_1D(&(*v)); +} - // update the face() pointer of the remaining vertices of f1 and f2 - f1->vertex(j1)->set_face(f1n); - f2->vertex(j2)->set_face(f2n); - infinite_vertex()->set_face(f1n); - - f1.Delete(); f2.Delete(); - return; - } - } template void Triangulation_2:: remove_2D(Vertex_handle v) + { + //test the dimensionality of the resulting triangulation + //it goes down to 1 iff + // 1) any finite face is incident to v + // 2) all vertices are colinear + bool dim1 = true; + Face_iterator fit = faces_begin(); + while (dim1==true && fit != faces_end()) { + dim1 = dim1 && fit->has_vertex(v); + fit++; + } + Face_circulator fic = v->incident_faces(); + while (is_infinite(fic)) {++fic;} + Face_circulator done(fic); + Face_handle start(fic); int iv = start->index(v); + Point p = start->vertex(cw(iv))->point(), q = start->vertex(ccw(iv))->point(); + while ( dim1 && ++fic != done) { + iv = fic->index(v); + if (fic->vertex(ccw(iv)) != infinite_vertex()) { + dim1 = dim1 && + geom_traits().orientation(p, q, fic->vertex(ccw(iv))->point()) + == CGAL_COLLINEAR; + } + } + + if (dim1) { + _tds.remove_down(&(*v)); + } + else { + list hole; + make_hole(v, hole); + fill_hole(v, hole); + v.Delete(); + set_number_of_vertices(number_of_vertices()-1); + } + return; + } + +template +void +Triangulation_2:: +make_hole ( Vertex_handle v, list & hole) { - // General case - - // remove incident faces - // set up list of faces neighboring the hole - // in ccw order around the hole - - // problem with gcc link - typedef std::pair Hole_neighbor; - //typedef pair Hole_neighbor; - //typedef pair Hole_neighbor; - typedef std::list Hole; - - - Hole hole; - typename Hole::iterator hit; - std::list to_delete; + + list::iterator hit; + list to_delete; Face_handle f, ff, fn; int i =0,ii =0, in =0; Vertex_handle vv; - Point p = v->point(); - + Face_circulator fc = v->incident_faces(); Face_circulator done(fc); do { f = (*fc).handle(); fc++; i = f->index(v); fn = f->neighbor(i); - vv = f->vertex(f->cw(i)); - if( vv->face()== f) vv->set_face(fn); - vv = f->vertex(f->ccw(i)); - if( vv->face()== f) vv->set_face(fn); in = fn->index(f); + vv = f->vertex(cw(i)); + if( vv->face()== f) vv->set_face(fn); + vv = f->vertex(ccw(i)); + if( vv->face()== f) vv->set_face(fn); fn->set_neighbor(in, NULL); - hole.push_back(Hole_neighbor(&(*fn),in)); - //hole.push_back(Hole_neighbor(fn,in)); - // to_delete.push_back(f); - to_delete.push_back(&(*f)); + hole.push_back(Edge(fn,in)); + to_delete.push_back(f); } while(fc != done); while (! to_delete.empty()){ - delete to_delete.front(); + (to_delete.front()).Delete(); to_delete.pop_front(); } - - Vertex_handle v0, v1, v2; - Point p0, p1, p2; - Bounded_side side; - Orientation or; - int nhole; + return; + } - if( hole.size() != 3) { - // find the first edge v0v1 on the hole boundary - // such that - // v0, v1 and the next vertex v2 are all finite - // v0v1v2 is a left turn and - // triangle v0v1v2 does not contain the removed point - - // if found create face v0v1v2 - // stop when no more faces can be created that way +template +void +Triangulation_2:: +fill_hole ( Vertex_handle v, list< Edge > & hole ) + { + typedef list< Edge > Hole; + + Point p = v->point(); + Face_handle f, ff, fn; + int i =0,ii =0, in =0; + Vertex_handle v0, v1, v2; + Point p0, p1, p2; + Triangle t; + CGAL_Bounded_side side; + CGAL_Orientation or; + int nhole; + + if( hole.size() != 3) { + // find the first edge v0v1 on the hole boundary + // such that + // v0, v1 and the next vertex v2 are all finite + // v0v1v2 is a left turn and + // triangle v0v1v2 does not contain the removed point + + // if found create face v0v1v2 + // stop when no more faces can be created that way - nhole= hole.size(); - // nhole decount the number of hole edges passed - // from the last created edges - while (hole.size()>3 && nhole>0) { - ff = (Face *) ( (hole.front()).first); - //ff = hole.front().first - ii = (hole.front()).second; - hole.pop_front(); + nhole= hole.size(); + // nhole decount the number of hole edges passed + // from the last created edges + while (hole.size()>3 && nhole>0) { + //ff = (Face *) ( (hole.front()).first); + ff = hole.front().first; + ii = (hole.front()).second; + hole.pop_front(); - v0 = ff->vertex(cw(ii)); - v1 = ff->vertex(ccw(ii)); - if( !is_infinite(v0) && !is_infinite(v1)) { - fn = (Face *) ( (hole.front()).first); - //fn = hole.front().first - in = (hole.front()).second; + v0 = ff->vertex(cw(ii)); + v1 = ff->vertex(ccw(ii)); + if( !is_infinite(v0) && !is_infinite(v1)) { + //fn = (Face *) ( (hole.front()).first); + fn = hole.front().first; + in = (hole.front()).second; - v2 = fn->vertex(ccw(in)); - if( !is_infinite(v2)) { - p0 = v0->point(); - p1 = v1->point(); - p2 = v2->point(); - or = geom_traits().orientation(p0,p1,p2); - if ( or == LEFTTURN) { + v2 = fn->vertex(ccw(in)); + if( !is_infinite(v2)) { + p0 = v0->point(); + p1 = v1->point(); + p2 = v2->point(); + or = geom_traits().orientation(p0,p1,p2); + if ( or == CGAL_LEFTTURN) { side = bounded_side(p0,p1,p2, p); - if( side == ON_UNBOUNDED_SIDE || - (side == ON_BOUNDARY && collinear_between(p0, p, p2)) ) { + if( side == CGAL_ON_UNBOUNDED_SIDE || + (side == CGAL_ON_BOUNDARY && collinear_between(p0, p, p2)) ) { //create face Face_handle newf = new Face(v0,v1,v2); newf->set_neighbor(2,ff); @@ -1384,7 +1093,8 @@ remove_2D(Vertex_handle v) ff->set_neighbor(ii, newf); fn->set_neighbor(in,newf); hole.pop_front(); - hole.push_front(Hole_neighbor(&(*newf),1)); + //hole.push_front(Hole_neighbor(&(*newf),1)); + hole.push_front(Edge(newf,1)); nhole = hole.size(); continue; } @@ -1393,12 +1103,10 @@ remove_2D(Vertex_handle v) } // not possible to create face v0,v1,v2; - hole.push_back(Hole_neighbor(&(*ff),ii)); + //hole.push_back(Hole_neighbor(&(*ff),ii)); + hole.push_back( Edge (ff,ii)); nhole--; - } - } - - // either the hole has only three edges + // either the hole has only three edges // or all its finite vertices are reflex or flat // except may be one vertex whose corresponding ear // includes the vertex being removed @@ -1492,647 +1200,13 @@ remove_2D(Vertex_handle v) } } - // POINT LOCATION -public: -class Line_face_circulator - : public CGAL_Bidirectional_circulator_base, - public Face::Face_handle -{ -public: - typedef Face value_type; - typedef Face & reference; - typedef const Face & const_reference; - typedef unsigned int size_type; - typedef int distance_type; - - enum State {undefined = -1, - vertex_vertex, - vertex_edge, - edge_vertex, - edge_edge}; -private: - CGAL_Triangulation_2* _tr; - State s; - int i; - Point p, q; - - - -public: - Line_face_circulator() - : Face::Face_handle(), _tr(NULL), s(undefined), i(-1) - {} - - Line_face_circulator(const Line_face_circulator& lfc) - : Face::Face_handle(& (*lfc)), _tr(lfc._tr), s(lfc.s), i(lfc.i), - p(lfc.p), q(lfc.q) - {} - -~Line_face_circulator() - {} - - -Line_face_circulator(const Face_handle& face, - int index, - State state, - CGAL_Triangulation_2 * t, - const Point& pp, - const Point& qq) - : Face::Face_handle(face), _tr(t), s(state), i(index), p(pp), q(qq) - { - CGAL_triangulation_precondition(p != q); - CGAL_triangulation_precondition(t->dimension() ==2); - } - - Line_face_circulator& - operator=(const Line_face_circulator& lfc) - { - ptr() = lfc.ptr(); - i = lfc.i; - s = lfc.s; - _tr = lfc._tr; - p = lfc.p; - q = lfc.q; - return *this; - } - - Line_face_circulator(Vertex_handle v, - CGAL_Triangulation_2* tr, - const Point& dir) - : _tr(tr) - { - CGAL_triangulation_precondition( - (! _tr->is_infinite(v)) && - (_tr->dimension() == 2) && - (! _tr->geom_traits().compare(v->point(),dir))); - - p=v->point(); - q=dir; - - //cerr << " p " << p << " q " << q << endl; - - Face_circulator fc = v->incident_faces(); - Face_circulator done = fc; - - //cerr << "(" << fc->vertex(0)->point() << ", " - // <vertex(1)->point() << ", " - // << fc->vertex(2)->point() << ")" << endl ; - - int ic = fc->index(v); - Vertex_handle vt= fc->vertex(ccw(ic)); - CGAL_Orientation ptq; - if (! _tr->is_infinite(vt)) - ptq = _tr->geom_traits().orientation(p, vt->point(), q); - - - while( _tr->is_infinite(vt) || ptq == CGAL_RIGHTTURN) { - ++fc; - if (fc == done) { - // no edge on the left of pq , pq is a supporting line - // set ptr() to the right infinite face - while ( ! _tr->is_infinite(fc)) - { ++fc;} - ic = fc->index(_tr->infinite_vertex()); - if( _tr->geom_traits().orientation( - fc->vertex( cw(ic))->point(), - fc->vertex( ccw(ic))->point(), - q) != CGAL_RIGHTTURN) { ++fc;} - ptr() = &(*fc); - i = fc->index(_tr->infinite_vertex()); - s = vertex_vertex; - return; - } - - ic = fc->index(v); - vt= fc->vertex(ccw(ic)); - if (! _tr->is_infinite(vt)) - ptq = _tr->geom_traits().orientation(p, vt->point(), q); - } - - - // now vt is a finite vertex and ptq is COLLINEAR or LEFTTURN - Vertex_handle vr = fc-> vertex(cw(ic)); - CGAL_Orientation prq; - if (! _tr->is_infinite(vr)) - prq = _tr->geom_traits().orientation(p, vr->point(), q); - - while ( (!_tr->is_infinite(vr)) && (!(prq == CGAL_RIGHTTURN ))){ - ++fc; - ic = fc->index(v); - vr = fc-> vertex(cw(ic)); - if (! _tr->is_infinite(vr)) - prq = _tr->geom_traits().orientation(p, vr->point(), q); - } - - - ptr() = &(*fc); - // reset vt, vt is finite and ptq is still COLLINEAR or LEFTTURN - ic = fc->index(v); - vt= fc->vertex(ccw(ic)); - ptq = _tr->geom_traits().orientation(p, vt->point(), q); - - - - if (_tr->is_infinite(vr)) { - s = vertex_vertex; - if (ptq == CGAL_LEFTTURN) { - i = fc->index(vr); - } - else {// ptq == CGAL_COLLINEAR - i= fc->index(vt); - } - } - else{ // vr is a finite vertex} - if (ptq == CGAL_LEFTTURN) { - s = vertex_edge; - i = ic; - } - else { // ptq == CGAL_COLLINEAR - s = vertex_vertex; - i = fc->index(vt); - } - } - - - } - - - - - - - Line_face_circulator(const Point& pp, - const Point& qq, - CGAL_Triangulation_2 * t) - : _tr(t), s(undefined), p(pp), q(qq) - { - CGAL_triangulation_precondition(pp != qq); - CGAL_triangulation_precondition(t->dimension() ==2); - - Vertex_handle inf = _tr->infinite_vertex(); - Face_circulator fc = inf->incident_faces(), - done(fc); - i = fc->index(inf); - - Point l = fc->vertex(cw(i))->point(), - r = fc->vertex(ccw(i))->point(); - - CGAL_Orientation pql = _tr->geom_traits().orientation(p, q, l), - pqr = _tr->geom_traits().orientation(p, q, r); - - - do{ - if( (pql == CGAL_LEFTTURN) && (pqr == CGAL_RIGHTTURN) ){ - *this = ++Line_face_circulator( fc->handle() , - i, - vertex_edge, - t, - p, - q); - return; - } else if ( (pql == CGAL_LEFTTURN) && - (pqr == CGAL_COLLINEAR) ){ - *this = ++Line_face_circulator( fc->handle() , - ccw(i), - vertex_vertex, - t, - p, - q); - return; - } else if( (pql == CGAL_COLLINEAR) && - (pqr == CGAL_COLLINEAR) ){ - Face_handle n = fc->neighbor(i); - int ni = n->index( fc->handle() ); - Vertex_handle vn = n->vertex(ni); - if(_tr->geom_traits().orientation(p, q, vn->point()) == - CGAL_LEFTTURN){ - // the entire triangulation is to the left of line (p,q). - // There might be further collinear edges, so we might have - // to walk back on the hull. - while(1){ - ++fc; - i = fc->index(inf); - l = fc->vertex(cw(i))->point(); - if(_tr->geom_traits().orientation(p, q, l) == - CGAL_COLLINEAR){ - continue; - } else { - // we went one step to far back - --fc; - i = fc->index(inf); - ptr() = &(*fc->neighbor(i)); - i = cw(ptr()->index( fc->handle() )); - s = vertex_vertex; - return; - } - } - } else { - // the entire triangulation is to the right of line (p,q). - // here are no faces to traverse, so we give the circulator - // a singular value - return; - } - } else { - --fc; - l = r; - pql = pqr; - i = fc->index(inf); - r = fc->vertex(ccw(i))->point(); - pqr = _tr->geom_traits().orientation(p, q, r); - } - }while(fc != done); - // if line (p,q) does not intersect the convex hull in an edge - // the circulator has a singular value - } - - Line_face_circulator(const Point& pp, - const Point& qq, - const Face_handle& ff, - CGAL_Triangulation_2* t) - : Face::Face_handle(ff), _tr(t), s(undefined), p(pp), q(qq) - { - CGAL_triangulation_precondition(p != q); - CGAL_triangulation_precondition(t->dimension() ==2); - //CGAL_triangulation_precondition(_tr->is_infinite(f) || - // _tr->oriented_side(f,p) != CGAL_ON_NEGATIVE_SIDE); - - int j; - if(_tr->is_infinite(ptr()->handle())){ - *this = Line_face_circulator(p, q, t); - return; - } - - - // Test whether p lies on a vertex - for(j = 0; j < 3; j++){ - if(ptr()->vertex(j)->point() == p){ - *this = Line_face_circulator( ptr()->vertex(j), t, q); - return; - } - } - - // Test whether p lies on an edge - for(j = 0; j < 3; j++){ - if(_tr->geom_traits().orientation(ptr()->vertex(j)->point(), - ptr()->vertex(ccw(j))->point(), - p) == CGAL_COLLINEAR){ - CGAL_Orientation jpq = - _tr->geom_traits().orientation(ptr()->vertex(j)->point(), - p, - q); - CGAL_Orientation p_cwj_q = - _tr->geom_traits().orientation(p, - ptr()->vertex(cw(j))->point(), - q); - switch(jpq){ - case CGAL_COLLINEAR: - if(p_cwj_q == CGAL_RIGHTTURN){ - s = vertex_vertex; - i = ccw(j); - return; - } - else if(! _tr->is_infinite(ptr()->neighbor(cw(j)))){ - Face_handle n = ptr()->neighbor(cw(j)); - i = cw(n->index(ptr()->handle())); - ptr() = &(*n); - s = vertex_vertex; - return; - } else { - // singular value - return; - } - case CGAL_RIGHTTURN: - i = cw(j); - s = (p_cwj_q == CGAL_COLLINEAR) ? vertex_edge : - edge_edge; - break; - default: // CGAL_LEFTTURN - switch(p_cwj_q){ - case CGAL_COLLINEAR: - s = edge_vertex; - i = cw(j); - return; - case CGAL_RIGHTTURN: - s = edge_edge; - i = j; - return; - default: - s = edge_edge; - i = ccw(j); - return; - } - } - } - } - - // p lies in the interior of the face - CGAL_Orientation or[3]; - for(j=0; j<3; j++){ - or[j] = - _tr->geom_traits().orientation(p,q,ptr()->vertex(j)->point()); - } - for(j=0; j<3; j++){ - if(or[j] == CGAL_COLLINEAR){ - i = j; - s = (or[ccw(j)] == CGAL_LEFTTURN) ? edge_vertex : - vertex_edge; - return; - } - } - s = edge_edge; - for(j=0; j<3; j++){ - if(or[j] == CGAL_RIGHTTURN){ - i = (or[ccw(j)] == CGAL_RIGHTTURN) ? j : cw(j); - return; - } - } - } - - void increment() - { - CGAL_triangulation_precondition(s != undefined); - if(s == vertex_vertex || s == edge_vertex){ - CGAL_Orientation o; - Point r; - do{ - Face_handle n = ptr()->neighbor(cw(i)); - i = n->index(ptr()->handle()); - ptr() = &(*n); - if (n->vertex(i) == _tr->infinite_vertex()){ - o = CGAL_COLLINEAR; - i = cw(i); - break; - } - r = n->vertex(i)->point(); - i = cw(i); - }while((o = _tr->geom_traits().orientation(p, q, r)) == - CGAL_LEFTTURN); - - if(o == CGAL_COLLINEAR){ - s = vertex_vertex; - i = ccw(i); - } else { - s = vertex_edge; - } - } else { - Face_handle n = ptr()->neighbor(i); - int ni = n->index(ptr()->handle()); - ptr() = &(*n); - CGAL_Orientation o = _tr->is_infinite(ptr()->vertex(ni)) ? - CGAL_COLLINEAR : - _tr->geom_traits().orientation(p,q,ptr()->vertex(ni)->point()); - - switch(o){ - case CGAL_LEFTTURN: - s = edge_edge; - i = ccw(ni); - break; - case CGAL_RIGHTTURN: - s = edge_edge; - i = cw(ni); - break; - default: - s = edge_vertex; - i = ni; - } - } - } - - - void decrement() - { - CGAL_triangulation_precondition(s != undefined); - if(s == vertex_vertex || s == vertex_edge){ - if(s == vertex_vertex){ - i = cw(i); - } - CGAL_Orientation o; - Point r; - do{ - Face_handle n = ptr()->neighbor(ccw(i)); - i = n->index(ptr()->handle()); - ptr() = &(*n); - if (n->vertex(i) == _tr->infinite_vertex()){ - o = CGAL_COLLINEAR; - i = ccw(i); - break; - } - r = n->vertex(i)->point(); - i = ccw(i); - }while((o = _tr->geom_traits().orientation(p, q, r)) == - CGAL_LEFTTURN); - - s = (o == CGAL_COLLINEAR) ? vertex_vertex : edge_vertex; - - } else { // s == edge_edge || s == edge_vertex - // the following is not nice. A better solution is to say - // that index i is at the vertex that is alone on one side of l(p,q) - if(s == edge_edge){ - i = (_tr->geom_traits().orientation - (p, q, - ptr()->vertex(i)->point()) == - CGAL_LEFTTURN) - ? cw(i) : ccw(i); - } - Face_handle n = ptr()->neighbor(i); - i = n->index(ptr()->handle()); - ptr() = &(*n); - CGAL_Orientation o = _tr->is_infinite(ptr()->vertex(i)) ? - CGAL_COLLINEAR : - _tr->geom_traits().orientation(p, q, ptr()->vertex(i)->point()); - - s = (o == CGAL_COLLINEAR) ? vertex_edge : edge_edge; - } - } - - bool - locate(const Point& t, - Locate_type <, - int &li) - { - switch(s){ - - case edge_edge: - case vertex_edge: - { - CGAL_Orientation o = - _tr->geom_traits().orientation(ptr()->vertex(ccw(i))->point(), - ptr()->vertex(cw(i))->point(), - t); - if(o == CGAL_RIGHTTURN){ - return false; - } - if(o == CGAL_COLLINEAR){ - lt = EDGE; - li = i; - return true; - } - lt = FACE; - return true; - } - case vertex_vertex: - { - if(_tr->is_infinite(ptr()->vertex(i))){ - CGAL_triangulation_assertion(_tr->geom_traits().orientation( - ptr()->vertex(cw(i))->point(), - ptr()->vertex(ccw(i))->point(), - t) != CGAL_LEFTTURN); - lt = OUTSIDE_CONVEX_HULL; - li = i; - return true; - } - - Point u = ptr()->vertex(cw(i))->point(); - Point v = ptr()->vertex(i)->point(); - // u == t was detected earlier - if(_tr->geom_traits().compare_x(v,t)==CGAL_EQUAL && - _tr->geom_traits().compare_y(v,t)==CGAL_EQUAL){ - lt = VERTEX; - li = i; - return true; - } - if(_tr->collinear_between(u, t, v)){ - lt = EDGE; - li = ccw(i); - return true; - } - return false; - } - default: // edge_vertex - { - if(_tr->is_infinite(ptr()->vertex(i))){ - lt = OUTSIDE_CONVEX_HULL; - li = i; - return true; - } - if(_tr->geom_traits().compare_x(t,ptr()->vertex(i) - ->point())==CGAL_EQUAL && - _tr->geom_traits().compare_y(t,ptr()->vertex(i) - ->point())==CGAL_EQUAL ){ - li = i; - lt = VERTEX; - return true; - } - if(_tr->collinear_between(p, t, ptr()->vertex(i) - ->point())){ - lt = FACE; - return true; - } - return false; - } - } - } - - - Line_face_circulator& - operator++() - { - if (ptr()==NULL) { - return *this; // circulator has singular value - } - //xfc while (_tr->is_infinite(ptr()->handle())) - // increment(); - //we are looking for a finite face but stop - //if back to the origin - // strange behavoiur - //why not simply increment and step through infinite faces - //as other circulators do !!! - //Face_handle origin = ptr()->handle(); - //do - increment(); - //while ((_tr->is_infinite(ptr()->handle())) - // && (ptr()->handle() != origin)); - - return *this; - } - - - Line_face_circulator& - operator--() - { - if (ptr()==NULL) { - return *this; // circulator has singular value - } - // while (_tr->is_infinite(ptr()->handle())) - decrement(); - return *this; - } - - - Line_face_circulator - operator++(int) - { - Line_face_circulator tmp(*this); - ++(*this); - return tmp; - } - - - Line_face_circulator - operator--(int) - { - Line_face_circulator tmp(*this); - --(*this); - return tmp; - } - - bool - operator==(const Line_face_circulator& lfc) const - { - CGAL_triangulation_precondition - ( ptr() != NULL && lfc.ptr() != NULL ); - return ptr() == lfc.ptr(); - } - - bool - operator!=(const Line_face_circulator& lfc) const - { - CGAL_triangulation_precondition - ( ptr() != NULL && lfc.ptr() != NULL ); - return ptr() != lfc.ptr(); - } - - - inline bool - is_empty() - { - return s == undefined; - } - - - inline bool - operator==(CGAL_NULL_TYPE n) const - { - CGAL_triangulation_assertion( n == NULL); - return s == undefined; - } - - inline bool - operator!=(CGAL_NULL_TYPE n) const - { - return !(*this == n); - } - - bool - collinear_outside() const - { - - return (_tr->is_infinite(ptr()->handle())) - && (s == vertex_vertex) - && (! _tr->is_infinite(ptr()->vertex(i))); - } - - - - }; - - - - Face_handle - march_locate_1D(const Point& t, +template +Triangulation_2::Face_handle +Triangulation_2:: +march_locate_1D(const Point& t, Locate_type& lt, int& li) const @@ -2257,13 +1331,14 @@ march_locate_2D(const Face_handle& start, return lfc; } - - Face_handle - locate(const Point& p, +template +Face_handle +Triangulation_2:: +locate(const Point& p, Locate_type& lt, int& li, Face_handle start = Face_handle()) const - { +{ if( dimension() == 0) { if(number_of_vertices() == 0) { lt = OUTSIDE_AFFINE_HULL; @@ -2285,115 +1360,10 @@ march_locate_2D(const Face_handle& start, } return march_locate_2D(start, p, lt, li); - } +} - inline Face_handle - locate(const Point &p, - Face_handle start = Face_handle()) const - { - Locate_type lt; - int li; - return locate(p, lt, li, start); - } - - - - - //TRAVERSING : ITERATORS AND CIRCULATORS - Face_iterator faces_begin() const - { - CGAL_Triangulation_2* - ncthis = (CGAL_Triangulation_2 *)this; - return Face_iterator(ncthis); - } - Face_iterator faces_end() const - { - CGAL_Triangulation_2* - ncthis = (CGAL_Triangulation_2 *)this; - return Face_iterator(ncthis, 1); - } - Vertex_iterator vertices_begin() const - { - CGAL_Triangulation_2* - ncthis = (CGAL_Triangulation_2*)this; - return Vertex_iterator(ncthis); - } - Vertex_iterator vertices_end() const - { - CGAL_Triangulation_2* - ncthis = (CGAL_Triangulation_2*)this; - return Vertex_iterator(ncthis,1); - } - Edge_iterator edges_begin() const - { - CGAL_Triangulation_2* - ncthis = (CGAL_Triangulation_2*)this; - return Edge_iterator(ncthis); - } - Edge_iterator edges_end() const - { - CGAL_Triangulation_2* - ncthis = (CGAL_Triangulation_2*)this; - return Edge_iterator(ncthis,1); - } -inline - Face_circulator incident_faces( const Vertex_handle& v) const - { - return v->incident_faces(); - } - - inline - Face_circulator incident_faces( - const Vertex_handle& v, const Face_handle& f) const - { - return v->incident_faces(f); - } - - inline - Vertex_circulator incident_vertices(const Vertex_handle& v) const - { - return v->incident_vertices(); - } - - inline - Vertex_circulator incident_vertices(const Vertex_handle& v, - const Face_handle& f) const - { - return v->incident_vertices(f); - } - - inline - Edge_circulator incident_edgees(const Vertex_handle& v) const - { - return v->incident_edges(); - } - - inline - Edge_circulator incident_edges(const Vertex_handle& v, - const Face_handle& f) const - { - return v->incident_edges(f); - } - - - Line_face_circulator - line_walk(const Point& p, - const Point& q, - Face_handle f = Face_handle()) - { - CGAL_triangulation_precondition( (dimension() == 2) && (p != q) ); - - Line_face_circulator lfc = (f.is_null()) - ? Line_face_circulator(p, q, this) - : Line_face_circulator(p, q, f, this); - - if( (!lfc.is_empty()) && is_infinite( lfc )){ - return Line_face_circulator(); - } - return lfc; - return start; - } + template Oriented_side Triangulation_2:: @@ -2487,9 +1457,32 @@ bounded_side(const Point &p0, const Point &p1, return ON_UNBOUNDED_SIDE; } +template +bool +Triangulation_2:: +collinear_between(const Point& p, const Point& q, const Point& r) const + { + Comparison_result c_pr = geom_traits().compare_x(p, r); + Comparison_result c_pq; + Comparison_result c_qr; + if(c_pr == EQUAL) { + c_pr = geom_traits().compare_y(p, r); + c_pq = geom_traits().compare_y(p, q); + c_qr = geom_traits().compare_y(q, r); + } else { + c_pq = geom_traits().compare_x(p, q); + c_qr = geom_traits().compare_x(q, r); + } + return ( (c_pq == SMALLER) && (c_qr == SMALLER) ) || + ( (c_qr == LARGER) && (c_pq == LARGER) ); + + } - Oriented_side - oriented_side(const Face_handle& f, const Point &p) const + +template +Oriented_side +Triangulation_2:: +oriented_side(const Face_handle& f, const Point &p) const { CGAL_triangulation_precondition ( dimension()==2); return oriented_side(f->vertex(0)->point(),