|
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/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
1.7.6.1