BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Delaunay_triangulation_2.h
Go to the documentation of this file.
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/Delaunay_triangulation_2.h $
00015 // $Id: Delaunay_triangulation_2.h 46169 2008-10-08 13:44:06Z pmachado $
00016 // 
00017 //
00018 // Author(s)     : Mariette Yvinec
00019 
00020 
00021 
00022 #ifndef CGAL_DELAUNAY_TRIANGULATION_2_H
00023 #define CGAL_DELAUNAY_TRIANGULATION_2_H
00024 
00025 #include <CGAL/Triangulation_2.h>
00026 #include <CGAL/iterator.h>
00027 
00028 CGAL_BEGIN_NAMESPACE
00029 
00030 template < class Gt, 
00031            class Tds = Triangulation_data_structure_2 <
00032                            Triangulation_vertex_base_2<Gt> > >
00033 class Delaunay_triangulation_2 : public Triangulation_2<Gt,Tds>
00034 {
00035 public:
00036   typedef Gt Geom_traits;
00037   typedef typename Geom_traits::Point_2       Point;
00038   typedef typename Geom_traits::Segment_2     Segment;
00039   typedef typename Geom_traits::Triangle_2    Triangle;
00040   
00041 
00042   typedef typename Geom_traits::Orientation_2 Orientation_2;
00043   typedef typename Geom_traits::Compare_x_2   Compare_x;
00044   typedef typename Geom_traits::Compare_y_2   Compare_y;
00045   typedef typename Geom_traits::Side_of_oriented_circle_2 
00046                                               Side_of_oriented_circle;
00047 
00048   
00049   typedef Triangulation_2<Gt,Tds>                       Triangulation;
00050   typedef typename Triangulation::Locate_type           Locate_type;
00051   typedef typename Triangulation::Face_handle           Face_handle;
00052   typedef typename Triangulation::Vertex_handle         Vertex_handle;
00053   typedef typename Triangulation::Edge                  Edge;
00054   typedef typename Triangulation::Edge_circulator       Edge_circulator;
00055   typedef typename Triangulation::Face_circulator       Face_circulator;
00056   typedef typename Triangulation::Vertex_circulator     Vertex_circulator;
00057   typedef typename Triangulation::Finite_edges_iterator Finite_edges_iterator;
00058   typedef typename Triangulation::Finite_faces_iterator Finite_faces_iterator;
00059   typedef typename Triangulation::Finite_vertices_iterator 
00060                                                      Finite_vertices_iterator;
00061 
00062  
00063 #ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
00064   using Triangulation::side_of_oriented_circle;
00065   using Triangulation::circumcenter;
00066 #endif
00067 
00068 
00069  Delaunay_triangulation_2(const Gt& gt = Gt())
00070   : Triangulation_2<Gt,Tds>(gt) {}
00071   
00072   Delaunay_triangulation_2(
00073                const Delaunay_triangulation_2<Gt,Tds> &tr)
00074        : Triangulation_2<Gt,Tds>(tr)
00075   {   CGAL_triangulation_postcondition( is_valid() );  }
00076   
00077 // CHECK -QUERY
00078   bool is_valid(bool verbose = false, int level = 0) const;
00079 
00080   Vertex_handle
00081   nearest_vertex(const Point& p, Face_handle f= Face_handle()) const;
00082   
00083   bool does_conflict(const Point  &p, Face_handle fh) const;// deprecated
00084   bool test_conflict(const Point  &p, Face_handle fh) const;
00085   bool find_conflicts(const Point  &p,                //deprecated
00086                       std::list<Face_handle>& conflicts,
00087                       Face_handle start= Face_handle() ) const;
00088   //  //template member functions, declared and defined at the end 
00089   // template <class OutputItFaces, class OutputItBoundaryEdges> 
00090   // std::pair<OutputItFaces,OutputItBoundaryEdges>
00091   // get_conflicts_and_boundary(const Point  &p, 
00092   //                            OutputItFaces fit, 
00093   //                            OutputItBoundaryEdges eit,
00094   //                            Face_handle start) const;
00095   // template <class OutputItFaces>
00096   // OutputItFaces
00097   // get_conflicts (const Point  &p, 
00098   //                OutputItFaces fit, 
00099   //                Face_handle start ) const;
00100   // template <class OutputItBoundaryEdges>
00101   // OutputItBoundaryEdges
00102   // get_boundary_of_conflicts(const Point  &p, 
00103   //                           OutputItBoundaryEdges eit, 
00104   //                           Face_handle start ) const;
00105    
00106  
00107   // DUAL
00108   Point dual (Face_handle f) const;
00109   Object dual(const Edge &e) const ;
00110   Object dual(const Edge_circulator& ec) const;
00111   Object dual(const Finite_edges_iterator& ei) const;
00112   
00113   //INSERTION-REMOVAL
00114   Vertex_handle insert(const Point  &p, 
00115                        Face_handle start = Face_handle() );
00116   Vertex_handle insert(const Point& p,
00117                        Locate_type lt,
00118                        Face_handle loc, int li );
00119   Vertex_handle push_back(const Point &p);
00120 
00121   void  remove(Vertex_handle v );
00122   void restore_Delaunay(Vertex_handle v);
00123 
00124   // MOVE
00125   bool move(Vertex_handle v, const Point &p);
00126 
00127 #ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2  
00128   using Triangulation::cw;
00129   using Triangulation::ccw;
00130   using Triangulation::geom_traits;
00131 #endif
00132 
00133 private:
00134   void propagating_flip(Face_handle& f,int i);
00135   void remove_2D(Vertex_handle v );
00136 
00137   Vertex_handle nearest_vertex_2D(const Point& p, Face_handle f) const;
00138   Vertex_handle nearest_vertex_1D(const Point& p) const;
00139 
00140   void  look_nearest_neighbor(const Point& p,
00141                               Face_handle f,
00142                               int i,
00143                               Vertex_handle& nn) const;
00144 
00145 public:
00146   template < class Stream>
00147   Stream& draw_dual(Stream & ps)
00148     {
00149       Finite_edges_iterator eit= this->finite_edges_begin();
00150       for (; eit != this->finite_edges_end(); ++eit) {
00151         Object o = dual(eit);
00152         typename Geom_traits::Line_2  l;
00153         typename Geom_traits::Ray_2   r;
00154         Segment s;
00155         if (CGAL::assign(s,o)) ps << s;
00156         if (CGAL::assign(r,o)) ps << r;
00157         if (CGAL::assign(l,o)) ps << l;
00158       }
00159       return ps;
00160     }
00161 
00162   template < class InputIterator >
00163   int
00164   insert(InputIterator first, InputIterator last)
00165     {
00166       int n = this->number_of_vertices();
00167 
00168       std::vector<Point> points (first, last);
00169       std::random_shuffle (points.begin(), points.end());
00170       spatial_sort (points.begin(), points.end(), geom_traits());
00171       Face_handle f;
00172       for (typename std::vector<Point>::const_iterator p = points.begin(), end = points.end();
00173               p != end; ++p)
00174           f = insert (*p, f)->face();
00175 
00176       return this->number_of_vertices() - n;
00177     }
00178 
00179   template < class InputIterator >
00180   bool move(InputIterator first, InputIterator last)
00181   {
00182     bool blocked = false;
00183     std::map<Vertex_handle, int> hash;
00184     std::list< std::pair<Vertex_handle, Point> > to_move(first, last);
00185     while(!to_move.empty()) {
00186       std::pair<Vertex_handle, Point> pp = to_move.front();
00187       to_move.pop_front();
00188       if(!move(pp.first, pp.second)) {
00189         if(hash[pp.first] == 3) break;
00190         else if(hash[pp.first] == 2) blocked = true;
00191         hash[pp.first]++;
00192         to_move.push_back(pp);
00193       }
00194     }
00195     return !blocked;
00196   }
00197 
00198 
00199   template <class OutputItFaces, class OutputItBoundaryEdges> 
00200   std::pair<OutputItFaces,OutputItBoundaryEdges>
00201   get_conflicts_and_boundary(const Point  &p, 
00202                              OutputItFaces fit, 
00203                              OutputItBoundaryEdges eit,
00204                              Face_handle start = Face_handle()) const {
00205     CGAL_triangulation_precondition( this->dimension() == 2);
00206     int li;
00207     Locate_type lt;
00208     Face_handle fh = locate(p,lt,li, start);
00209     switch(lt) {
00210     case Triangulation::OUTSIDE_AFFINE_HULL:
00211     case Triangulation::VERTEX:
00212       return std::make_pair(fit,eit);
00213     case Triangulation::FACE:
00214     case Triangulation::EDGE:
00215     case Triangulation::OUTSIDE_CONVEX_HULL:
00216       *fit++ = fh; //put fh in OutputItFaces
00217       std::pair<OutputItFaces,OutputItBoundaryEdges>
00218         pit = std::make_pair(fit,eit);
00219       pit = propagate_conflicts(p,fh,0,pit);
00220       pit = propagate_conflicts(p,fh,1,pit);
00221       pit = propagate_conflicts(p,fh,2,pit);
00222       return pit;    
00223     }
00224     CGAL_triangulation_assertion(false);
00225     return std::make_pair(fit,eit);
00226   } 
00227 
00228   template <class OutputItFaces> 
00229   OutputItFaces
00230   get_conflicts (const Point  &p, 
00231                  OutputItFaces fit, 
00232                  Face_handle start= Face_handle()) const {
00233     std::pair<OutputItFaces,Emptyset_iterator> pp = 
00234       get_conflicts_and_boundary(p,fit,Emptyset_iterator(),start);
00235     return pp.first;
00236   }
00237 
00238   template <class OutputItBoundaryEdges> 
00239   OutputItBoundaryEdges
00240   get_boundary_of_conflicts(const Point  &p, 
00241                             OutputItBoundaryEdges eit, 
00242                             Face_handle start= Face_handle()) const {
00243     std::pair<Emptyset_iterator, OutputItBoundaryEdges> pp = 
00244       get_conflicts_and_boundary(p,Emptyset_iterator(),eit,start);
00245     return pp.second;
00246   }
00247 
00248 private:
00249   template <class OutputItFaces, class OutputItBoundaryEdges> 
00250   std::pair<OutputItFaces,OutputItBoundaryEdges>
00251   propagate_conflicts (const Point  &p,
00252                        Face_handle fh, 
00253                        int i,
00254                        std::pair<OutputItFaces,OutputItBoundaryEdges>
00255                        pit)  const {
00256     Face_handle fn = fh->neighbor(i);
00257     if (! test_conflict(p,fn)) {
00258       *(pit.second)++ = Edge(fn, fn->index(fh));
00259     } else {
00260       *(pit.first)++ = fn;
00261       int j = fn->index(fh);
00262       pit = propagate_conflicts(p,fn,ccw(j),pit);
00263       pit = propagate_conflicts(p,fn,cw(j), pit);
00264     }
00265     return pit;
00266   }
00267 
00268 protected:
00269 
00270   void restore_edges(Vertex_handle v)
00271   {
00272     std::list<Edge> edges;
00273     Face_circulator fc = this->incident_faces(v), done(fc);
00274     int degree = 0;
00275     do {
00276       if((++degree) > 3) break;
00277     } while(++fc != done);
00278     fc = this->incident_faces(v);
00279     done = fc;
00280     if(degree == 3) {
00281       do {
00282         int i = fc->index(v);
00283         edges.push_back(Edge(fc, i));
00284       } while(++fc != done);
00285     } else {
00286       do {
00287         int i = fc->index(v);
00288         edges.push_back(Edge(fc, i));
00289         edges.push_back(Edge(fc, this->cw(i)));
00290       } while(++fc != done);
00291     }
00292     while(!edges.empty()) {
00293       const Edge &e = edges.front();
00294       Face_handle f = e.first;
00295       int i = e.second;
00296       edges.pop_front();
00297       if(this->is_infinite(f->vertex(i))) continue;
00298       Face_handle fi = f->neighbor(i);
00299       int mi = this->_tds.mirror_index(f, i);
00300       Vertex_handle vm = this->_tds.mirror_vertex(f, i);
00301       if(this->is_infinite(vm)) continue;
00302       if(this->side_of_oriented_circle(f, vm->point()) == ON_POSITIVE_SIDE) {
00303         this->_tds.flip(f, i);
00304         edges.push_back(Edge(f, i));
00305         edges.push_back(Edge(f, this->cw(i)));
00306         edges.push_back(Edge(fi, this->cw(mi)));
00307         edges.push_back(Edge(fi, mi));
00308       }
00309     }
00310   }
00311 
00312 
00313 };
00314 
00315 template < class Gt, class Tds >
00316 inline bool
00317 Delaunay_triangulation_2<Gt,Tds>::
00318 test_conflict(const Point  &p, Face_handle fh) const
00319 {
00320   // return true  if P is inside the circumcircle of fh
00321   // if fh is infinite, return true when p is in the positive
00322   // halfspace or on the boundary and in the  finite edge of fh
00323   Oriented_side os = side_of_oriented_circle(fh,p);
00324   if (os == ON_POSITIVE_SIDE) return true;
00325  
00326   if (os == ON_ORIENTED_BOUNDARY && is_infinite(fh)) {
00327     int i = fh->index(this->infinite_vertex());
00328     return collinear_between(fh->vertex(cw(i))->point(), p,
00329                              fh->vertex(ccw(i))->point() );
00330   }
00331 
00332   return false;
00333 }
00334 
00335 template < class Gt, class Tds >
00336 inline bool
00337 Delaunay_triangulation_2<Gt,Tds>::
00338 does_conflict(const Point  &p, Face_handle fh) const
00339 {
00340   return test_conflict(p,fh);
00341 }
00342 
00343 template < class Gt, class Tds >
00344 inline bool
00345 Delaunay_triangulation_2<Gt,Tds>::
00346 find_conflicts(const Point  &p, 
00347                std::list<Face_handle>& conflicts,
00348                Face_handle start ) const
00349 {
00350   get_conflicts(p, std::back_inserter(conflicts), start);
00351   return (! conflicts.empty());
00352 }
00353 
00354 template < class Gt, class Tds >
00355 bool
00356 Delaunay_triangulation_2<Gt,Tds>::
00357 is_valid(bool verbose, int level) const
00358 {
00359   bool result = Triangulation_2<Gt,Tds>::is_valid(verbose, level);
00360 
00361   for( Finite_faces_iterator it = this->finite_faces_begin(); 
00362        it != this->finite_faces_end() ; it++) {
00363     for(int i=0; i<3; i++) {
00364       if ( ! is_infinite( this->mirror_vertex(it,i))) {
00365         result = result &&  ON_POSITIVE_SIDE != 
00366           side_of_oriented_circle( it, this->mirror_vertex(it,i)->point());
00367       }
00368       CGAL_triangulation_assertion( result );
00369     }
00370   }
00371   return result;
00372 }
00373 
00374 template < class Gt, class Tds >
00375 typename Delaunay_triangulation_2<Gt,Tds>::Vertex_handle
00376 Delaunay_triangulation_2<Gt,Tds>:: 
00377 nearest_vertex(const Point  &p, Face_handle f) const
00378 {
00379   switch (this->dimension()) {
00380   case 0:
00381     if (this->number_of_vertices() == 0) return Vertex_handle();
00382     if (this->number_of_vertices() == 1) return this->finite_vertex();
00383     //break;
00384   case 1:
00385     return nearest_vertex_1D(p);
00386     //break;      
00387   case 2:
00388     return nearest_vertex_2D(p,f);
00389     //break;
00390   }
00391   return Vertex_handle();
00392 }
00393   
00394 template < class Gt, class Tds >
00395 typename Delaunay_triangulation_2<Gt,Tds>::Vertex_handle
00396 Delaunay_triangulation_2<Gt,Tds>:: 
00397 nearest_vertex_2D(const Point& p, Face_handle f) const
00398 {
00399   CGAL_triangulation_precondition(this->dimension() == 2);
00400   f = locate(p,f);
00401 
00402   typename Geom_traits::Compare_distance_2 
00403     compare_distance =  this->geom_traits().compare_distance_2_object();
00404   Vertex_handle nn =  !is_infinite(f->vertex(0)) ? f->vertex(0):f->vertex(1);
00405   if ( !is_infinite(f->vertex(1)) && compare_distance(p,
00406                                             f->vertex(1)->point(),
00407                                             nn->point()) == SMALLER) 
00408     nn=f->vertex(1);
00409   if ( !is_infinite(f->vertex(2)) && compare_distance(p,
00410                                             f->vertex(2)->point(), 
00411                                             nn->point()) == SMALLER) 
00412     nn=f->vertex(2);
00413        
00414   look_nearest_neighbor(p,f,0,nn);
00415   look_nearest_neighbor(p,f,1,nn);
00416   look_nearest_neighbor(p,f,2,nn);
00417   return nn;
00418 }
00419 
00420 template < class Gt, class Tds >
00421 typename Delaunay_triangulation_2<Gt,Tds>::Vertex_handle
00422 Delaunay_triangulation_2<Gt,Tds>:: 
00423 nearest_vertex_1D(const Point& p) const
00424 {
00425   typename Geom_traits::Compare_distance_2 
00426     compare_distance =  this->geom_traits().compare_distance_2_object();
00427   Vertex_handle nn;
00428   
00429   Finite_vertices_iterator vit=this->finite_vertices_begin();
00430   nn = vit;
00431   for ( ; vit != this->finite_vertices_end(); ++vit){
00432     if (compare_distance(p, vit->point(), nn->point()) == SMALLER) 
00433       nn = vit;
00434   } 
00435   return nn;
00436 }
00437   
00438 template < class Gt, class Tds >
00439 void
00440 Delaunay_triangulation_2<Gt,Tds>::
00441 look_nearest_neighbor(const Point& p,
00442                       Face_handle f,
00443                       int i,
00444                       Vertex_handle& nn) const
00445 {
00446   Face_handle  ni=f->neighbor(i);
00447   if ( ON_POSITIVE_SIDE != side_of_oriented_circle(ni,p) ) return;
00448 
00449   typename Geom_traits::Compare_distance_2 
00450     compare_distance =  this->geom_traits().compare_distance_2_object();
00451   i = ni->index(f);
00452   if ( !is_infinite(ni->vertex(i)) &&
00453        compare_distance(p, 
00454               ni->vertex(i)->point(),
00455               nn->point())  == SMALLER)  nn=ni->vertex(i);
00456     
00457   // recursive exploration of triangles whose circumcircle contains p
00458   look_nearest_neighbor(p, ni, ccw(i), nn);
00459   look_nearest_neighbor(p, ni, cw(i), nn);
00460 } 
00461 
00462 //DUALITY
00463 template<class Gt, class Tds>
00464 inline
00465 typename Delaunay_triangulation_2<Gt,Tds>::Point
00466 Delaunay_triangulation_2<Gt,Tds>::
00467 dual (Face_handle f) const
00468 {
00469   CGAL_triangulation_precondition (this->dimension()==2);
00470   return circumcenter(f);
00471 }
00472 
00473   
00474 template < class Gt, class Tds >
00475 Object
00476 Delaunay_triangulation_2<Gt,Tds>::
00477 dual(const Edge &e) const
00478 {
00479   typedef typename Geom_traits::Line_2        Line;
00480   typedef typename Geom_traits::Ray_2         Ray;
00481 
00482   CGAL_triangulation_precondition (!is_infinite(e));
00483   if( this->dimension()== 1 ){
00484     const Point& p = (e.first)->vertex(cw(e.second))->point();
00485     const Point& q = (e.first)->vertex(ccw(e.second))->point();
00486     Line l  = this->geom_traits().construct_bisector_2_object()(p,q);
00487     return make_object(l);
00488   }
00489                     
00490   // dimension==2
00491   if( (!is_infinite(e.first)) &&
00492       (!is_infinite(e.first->neighbor(e.second))) ) {
00493     Segment s = this->geom_traits().construct_segment_2_object()
00494                           (dual(e.first),dual(e.first->neighbor(e.second)));
00495     return make_object(s);
00496   } 
00497   // one of the adjacent faces is infinite
00498   Face_handle f; int i;
00499   if (is_infinite(e.first)) {
00500     f=e.first->neighbor(e.second); i=f->index(e.first);
00501   }
00502   else {
00503     f=e.first; i=e.second;
00504   }
00505   const Point& p = f->vertex(cw(i))->point();
00506   const Point& q = f->vertex(ccw(i))->point();
00507   Line l = this->geom_traits().construct_bisector_2_object()(p,q);
00508   Ray r = this->geom_traits().construct_ray_2_object()(dual(f), l);
00509   return make_object(r);
00510 }
00511   
00512 template < class Gt, class Tds >
00513 inline Object
00514 Delaunay_triangulation_2<Gt,Tds>::  
00515 dual(const Edge_circulator& ec) const
00516 {
00517   return dual(*ec);
00518 }
00519   
00520 template < class Gt, class Tds >
00521 inline Object
00522 Delaunay_triangulation_2<Gt,Tds>::
00523 dual(const Finite_edges_iterator& ei) const
00524 {
00525   return dual(*ei);
00526 }
00527   
00528 template < class Gt, class Tds >
00529 inline
00530 typename Delaunay_triangulation_2<Gt,Tds>::Vertex_handle
00531 Delaunay_triangulation_2<Gt,Tds>::
00532 insert(const Point  &p,  Face_handle start)
00533 {
00534   Locate_type lt;
00535   int li;
00536   Face_handle loc = locate (p, lt, li, start);
00537   return insert(p, lt, loc, li);
00538 }
00539   
00540 template < class Gt, class Tds >
00541 inline
00542 typename Delaunay_triangulation_2<Gt,Tds>::Vertex_handle
00543 Delaunay_triangulation_2<Gt,Tds>::
00544 push_back(const Point &p)
00545 {
00546   return insert(p);
00547 }
00548   
00549 template < class Gt, class Tds >
00550 inline
00551 typename Delaunay_triangulation_2<Gt,Tds>::Vertex_handle
00552 Delaunay_triangulation_2<Gt,Tds>::
00553 insert(const Point  &p, Locate_type lt, Face_handle loc, int li)
00554 {
00555   Vertex_handle v = Triangulation_2<Gt,Tds>::insert(p,lt,loc,li);
00556   restore_Delaunay(v);
00557   return(v);
00558 }
00559 
00560 
00561 template < class Gt, class Tds >
00562 void
00563 Delaunay_triangulation_2<Gt,Tds>::
00564 restore_Delaunay(Vertex_handle v)
00565 {
00566   if(this->dimension() <= 1) return;
00567 
00568   Face_handle f=v->face();
00569   Face_handle next;
00570   int i;
00571   Face_handle start(f);
00572   do {
00573     i = f->index(v);
00574     next = f->neighbor(ccw(i));  // turn ccw around v
00575     propagating_flip(f,i);
00576     f=next;
00577   } while(next != start);
00578   return;
00579 }
00580 
00581 template < class Gt, class Tds >
00582 void
00583 Delaunay_triangulation_2<Gt,Tds>::
00584 remove(Vertex_handle v)
00585 {
00586   CGAL_triangulation_precondition( v != Vertex_handle());
00587   CGAL_triangulation_precondition( !is_infinite(v));
00588 
00589   if ( this->dimension() <= 1) Triangulation::remove(v);
00590   else  remove_2D(v);
00591 
00592   return;
00593 }
00594 
00595 template < class Gt, class Tds >
00596 void
00597 Delaunay_triangulation_2<Gt,Tds>::
00598 propagating_flip(Face_handle& f,int i)
00599 {
00600   Face_handle n = f->neighbor(i);
00601       
00602   if ( ON_POSITIVE_SIDE != 
00603        side_of_oriented_circle(n,  f->vertex(i)->point()) ) {          
00604     return;
00605   }
00606   flip(f, i);
00607   propagating_flip(f,i);
00608   i = n->index(f->vertex(i));
00609   propagating_flip(n,i);
00610 }
00611 
00612 template <class Gt, class Tds >
00613 void
00614 Delaunay_triangulation_2<Gt,Tds>::
00615 remove_2D(Vertex_handle v)
00616 {
00617   if (test_dim_down(v)) {  this->_tds.remove_dim_down(v);  }
00618   else {
00619     std::list<Edge> hole;
00620     make_hole(v, hole);
00621     fill_hole_delaunay(hole);
00622     delete_vertex(v);
00623   }
00624   return;       
00625 }
00626 
00627 template <class Gt, class Tds >
00628 bool
00629 Delaunay_triangulation_2<Gt,Tds>::
00630 move(Vertex_handle v, const Point &p) {
00631   CGAL_triangulation_precondition(!is_infinite(v));
00632   const int dim = this->dimension();
00633 
00634   if(dim == 2) {
00635     Point ant = v->point();
00636     v->set_point(p);
00637     if(well_oriented(v)) {
00638       restore_edges(v);
00639       return true;
00640     }
00641     v->set_point(ant);
00642   }
00643 
00644   Locate_type lt;
00645   int li;
00646   Vertex_handle inserted;
00647   Face_handle loc = locate(p, lt, li, v->face());
00648 
00649   if(lt == Triangulation_2<Gt,Tds>::VERTEX) return false;
00650 
00651   if(dim < 0) return true;
00652 
00653   if(dim == 0) {
00654     v->point() = p;
00655     return true;
00656   }
00657 
00658   if((loc != NULL) && (dim == 1)) {
00659     if(loc->has_vertex(v)) {
00660       v->point() = p;
00661     } else {
00662       inserted = insert(p, lt, loc, li);
00663       Face_handle f = v->face();
00664       int i = f->index(v);
00665       if (i==0) {f = f->neighbor(1);}
00666       CGAL_triangulation_assertion(f->index(v) == 1);
00667       Face_handle g= f->neighbor(0);
00668       f->set_vertex(1, g->vertex(1));
00669       f->set_neighbor(0,g->neighbor(0));
00670       g->neighbor(0)->set_neighbor(1,f);
00671       g->vertex(1)->set_face(f);
00672       this->delete_face(g);
00673       Face_handle f_ins = inserted->face();
00674       i = f_ins->index(inserted);
00675       if (i==0) {f_ins = f_ins->neighbor(1);}
00676       CGAL_triangulation_assertion(f_ins->index(inserted) == 1);
00677       Face_handle g_ins = f_ins->neighbor(0);
00678       f_ins->set_vertex(1, v);
00679       g_ins->set_vertex(0, v);
00680       std::swap(*v, *inserted);
00681       this->delete_vertex(inserted);
00682     }
00683     return true;
00684   }
00685 
00686   if((loc != NULL) && this->test_dim_down(v)) {
00687     v->point() = p;
00688     int i = loc->index(v);
00689     Face_handle locl;
00690     int i_locl;
00691     if(is_infinite(loc)) {
00692       int i_inf = loc->index(this->infinite_vertex());
00693       locl = loc->neighbor(i_inf);
00694       i_locl = locl->index(v);
00695     } else { locl = loc; i_locl = i; }
00696     if(this->orientation(p, locl->vertex(ccw(i_locl))->point(),
00697                             locl->vertex(cw(i_locl))->point()) == COLLINEAR) {
00698       this->_tds.dim_2D_1D(loc, i);
00699     }
00700     return true;
00701   }
00702 
00703   inserted = insert(p, lt, loc, li);
00704 
00705   std::list<Edge> hole;
00706   make_hole(v, hole);
00707   fill_hole_delaunay(hole);
00708 
00709   // fixing pointer
00710   Face_circulator fc = incident_faces(inserted), done(fc);
00711   std::list<Face_handle> faces_pt;
00712   do { faces_pt.push_back(fc); } while(++fc != done);
00713   while(!faces_pt.empty()) {
00714     Face_handle f = faces_pt.front();
00715     faces_pt.pop_front();
00716     int i = f->index(inserted);
00717     f->set_vertex(i, v);
00718   }
00719   std::swap(*v, *inserted);
00720   this->delete_vertex(inserted);
00721 
00722   return true;
00723 }
00724 
00725 
00726 CGAL_END_NAMESPACE
00727 
00728 #endif // CGAL_DELAUNAY_TRIANGULATION_2_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines