BWAPI
|
00001 // Copyright (c) 1997 INRIA Sophia-Antipolis (France). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Triangulation_2/include/CGAL/Triangulation_2.h $ 00015 // $Id: Triangulation_2.h 49948 2009-06-17 09:00:37Z pmachado $ 00016 // 00017 // 00018 // Author(s) : Olivier Devillers, Mariette Yvinec 00019 00020 #ifndef CGAL_TRIANGULATION_2_H 00021 #define CGAL_TRIANGULATION_2_H 00022 00023 #include <list> 00024 #include <vector> 00025 #include <map> 00026 #include <algorithm> 00027 #include <utility> 00028 #include <iostream> 00029 00030 #include <CGAL/iterator.h> 00031 #include <CGAL/Iterator_project.h> 00032 #include <CGAL/function_objects.h> 00033 00034 #include <CGAL/triangulation_assertions.h> 00035 #include <CGAL/Triangulation_utils_2.h> 00036 00037 #include <CGAL/Triangulation_data_structure_2.h> 00038 #include <CGAL/Triangulation_vertex_base_2.h> 00039 #include <CGAL/Triangulation_face_base_2.h> 00040 #include <CGAL/Triangulation_line_face_circulator_2.h> 00041 #include <CGAL/Random.h> 00042 00043 #include <CGAL/spatial_sort.h> 00044 00045 CGAL_BEGIN_NAMESPACE 00046 template < class Gt, class Tds > class Triangulation_2; 00047 template < class Gt, class Tds > std::istream& operator>> 00048 (std::istream& is, Triangulation_2<Gt,Tds> &tr); 00049 template < class Gt, class Tds > std::ostream& operator<< 00050 (std::ostream& os, const Triangulation_2<Gt,Tds> &tr); 00051 00052 00053 template < class Gt, 00054 class Tds = Triangulation_data_structure_2 < 00055 Triangulation_vertex_base_2<Gt>, 00056 Triangulation_face_base_2<Gt> > > 00057 class Triangulation_2 00058 : public Triangulation_cw_ccw_2 00059 { 00060 friend std::istream& operator>> <> 00061 (std::istream& is, Triangulation_2 &tr); 00062 typedef Triangulation_2<Gt,Tds> Self; 00063 00064 public: 00065 typedef Tds Triangulation_data_structure; 00066 typedef Gt Geom_traits; 00067 typedef typename Geom_traits::Point_2 Point; 00068 typedef typename Geom_traits::Segment_2 Segment; 00069 typedef typename Geom_traits::Triangle_2 Triangle; 00070 typedef typename Geom_traits::Orientation_2 Orientation_2; 00071 typedef typename Geom_traits::Compare_x_2 Compare_x; 00072 typedef typename Geom_traits::Compare_y_2 Compare_y; 00073 00074 typedef typename Tds::size_type size_type; 00075 typedef typename Tds::difference_type difference_type; 00076 00077 typedef typename Tds::Vertex Vertex; 00078 typedef typename Tds::Face Face; 00079 typedef typename Tds::Edge Edge; 00080 typedef typename Tds::Vertex_handle Vertex_handle; 00081 typedef typename Tds::Face_handle Face_handle; 00082 00083 typedef typename Tds::Face_circulator Face_circulator; 00084 typedef typename Tds::Vertex_circulator Vertex_circulator; 00085 typedef typename Tds::Edge_circulator Edge_circulator; 00086 00087 typedef typename Tds::Face_iterator All_faces_iterator; 00088 typedef typename Tds::Edge_iterator All_edges_iterator; 00089 typedef typename Tds::Vertex_iterator All_vertices_iterator; 00090 00091 00092 // This class is used to generate the Finite_*_iterators. 00093 class Infinite_tester 00094 { 00095 const Triangulation_2 *t; 00096 public: 00097 Infinite_tester() {} 00098 Infinite_tester(const Triangulation_2 *tr) : t(tr) {} 00099 00100 bool operator()(const All_vertices_iterator & vit) const { 00101 return t->is_infinite(vit); 00102 } 00103 bool operator()(const All_faces_iterator & fit ) const { 00104 return t->is_infinite(fit); 00105 } 00106 bool operator()(const All_edges_iterator & eit) const { 00107 return t->is_infinite(eit); 00108 } 00109 }; 00110 00111 //We derive in order to add a conversion to handle. 00112 class Finite_vertices_iterator : 00113 public Filter_iterator<All_vertices_iterator, Infinite_tester> 00114 { 00115 typedef Filter_iterator<All_vertices_iterator, Infinite_tester> Base; 00116 typedef Finite_vertices_iterator Self; 00117 public: 00118 Finite_vertices_iterator() : Base() {} 00119 Finite_vertices_iterator(const Base &b) : Base(b) {} 00120 Self & operator++() { Base::operator++(); return *this; } 00121 Self & operator--() { Base::operator--(); return *this; } 00122 Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } 00123 Self operator--(int) { Self tmp(*this); --(*this); return tmp; } 00124 operator const Vertex_handle() const { return Base::base(); } 00125 }; 00126 00127 class Finite_faces_iterator 00128 : public Filter_iterator<All_faces_iterator, Infinite_tester> 00129 { 00130 typedef Filter_iterator<All_faces_iterator, Infinite_tester> Base; 00131 typedef Finite_faces_iterator Self; 00132 public: 00133 Finite_faces_iterator() : Base() {} 00134 Finite_faces_iterator(const Base &b) : Base(b) {} 00135 Self & operator++() { Base::operator++(); return *this; } 00136 Self & operator--() { Base::operator--(); return *this; } 00137 Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } 00138 Self operator--(int) { Self tmp(*this); --(*this); return tmp; } 00139 operator const Face_handle() const { return Base::base(); } 00140 }; 00141 00142 typedef Filter_iterator<All_edges_iterator, 00143 Infinite_tester> 00144 Finite_edges_iterator; 00145 00146 //for backward compatibility 00147 typedef Finite_faces_iterator Face_iterator; 00148 typedef Finite_edges_iterator Edge_iterator; 00149 typedef Finite_vertices_iterator Vertex_iterator; 00150 00151 typedef Triangulation_line_face_circulator_2<Gt,Tds> Line_face_circulator; 00152 00153 // Auxiliary iterators for convenience 00154 // do not use default template argument to please VC++ 00155 typedef Project_point<Vertex> Proj_point; 00156 typedef Iterator_project<Finite_vertices_iterator, 00157 Proj_point, 00158 const Point&, 00159 const Point*, 00160 std::ptrdiff_t, 00161 std::bidirectional_iterator_tag> Point_iterator; 00162 00163 typedef Point value_type; // to have a back_inserter 00164 typedef const value_type& const_reference; 00165 typedef value_type& reference; 00166 00167 00168 enum Locate_type {VERTEX=0, 00169 EDGE, //1 00170 FACE, //2 00171 OUTSIDE_CONVEX_HULL, //3 00172 OUTSIDE_AFFINE_HULL}; //4 00173 00174 //Tag to distinguish Regular triangulations from others; 00175 typedef Tag_false Weighted_tag; 00176 00177 00178 protected: 00179 Gt _gt; 00180 Tds _tds; 00181 Vertex_handle _infinite_vertex; 00182 mutable Random rng; 00183 00184 public: 00185 // CONSTRUCTORS 00186 Triangulation_2(const Geom_traits& geom_traits=Geom_traits()); 00187 Triangulation_2(const Triangulation_2<Gt,Tds> &tr); 00188 00189 //Assignement 00190 Triangulation_2 &operator=(const Triangulation_2 &tr); 00191 00192 //Helping 00193 void copy_triangulation(const Triangulation_2 &tr); 00194 void swap(Triangulation_2 &tr); 00195 void clear(); 00196 00197 00198 //ACCESS FUNCTION 00199 const Geom_traits& geom_traits() const { return _gt;} 00200 const Tds & tds() const { return _tds;} 00201 Tds & tds() { return _tds;} 00202 int dimension() const { return _tds.dimension();} 00203 size_type number_of_vertices() const {return _tds.number_of_vertices() - 1;} 00204 00205 size_type number_of_faces() const; 00206 Vertex_handle infinite_vertex() const; 00207 Vertex_handle finite_vertex() const; 00208 Face_handle infinite_face() const; 00209 Infinite_tester infinite_tester() const; 00210 00211 //SETTING 00212 void set_infinite_vertex(const Vertex_handle& v) {_infinite_vertex=v;} 00213 00214 // CHECKING 00215 bool is_valid(bool verbose = false, int level = 0) const; 00216 00217 // TEST INFINITE FEATURES AND OTHER FEATURES 00218 bool is_infinite(Face_handle f) const; 00219 bool is_infinite(Vertex_handle v) const; 00220 bool is_infinite(Face_handle f, int i) const; 00221 bool is_infinite(const Edge& e) const; 00222 bool is_infinite(const Edge_circulator& ec) const; 00223 bool is_infinite(const All_edges_iterator& ei) const; 00224 bool is_edge(Vertex_handle va, Vertex_handle vb) const; 00225 bool is_edge(Vertex_handle va, Vertex_handle vb, Face_handle& fr, 00226 int & i) const; 00227 bool includes_edge(Vertex_handle va, Vertex_handle vb, 00228 Vertex_handle& vbb, 00229 Face_handle& fr, int & i) const; 00230 bool is_face(Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) const; 00231 bool is_face(Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, 00232 Face_handle &fr) const; 00233 00234 // GEOMETRIC FEATURES AND CONSTRUCTION 00235 Triangle triangle(Face_handle f) const; 00236 Segment segment(Face_handle f, int i) const; 00237 Segment segment(const Edge& e) const; 00238 Segment segment(const Edge_circulator& ec) const; 00239 Segment segment(const All_edges_iterator& ei) const; 00240 Segment segment(const Finite_edges_iterator& ei) const; 00241 Point circumcenter(Face_handle f) const; 00242 Point circumcenter(const Point& p0, 00243 const Point& p1, 00244 const Point& p2) const; 00245 00246 00247 //MOVE - INSERTION - DELETION - Flip 00248 public: 00249 void flip(Face_handle f, int i); 00250 00251 Vertex_handle insert_first(const Point& p); 00252 Vertex_handle insert_second(const Point& p); 00253 Vertex_handle insert_in_edge(const Point& p, Face_handle f,int i); 00254 Vertex_handle insert_in_face(const Point& p, Face_handle f); 00255 Vertex_handle insert_outside_convex_hull(const Point& p, Face_handle f); 00256 Vertex_handle insert_outside_affine_hull(const Point& p); 00257 Vertex_handle insert(const Point &p, Face_handle start = Face_handle() ); 00258 Vertex_handle insert(const Point& p, 00259 Locate_type lt, 00260 Face_handle loc, int li ); 00261 // template < class InputIterator > 00262 // int insert(InputIterator first, InputIterator last); 00263 Vertex_handle push_back(const Point& a); 00264 00265 void remove_degree_3(Vertex_handle v, Face_handle f = Face_handle()); 00266 void remove_first(Vertex_handle v); 00267 void remove_second(Vertex_handle v); 00268 void remove(Vertex_handle v); 00269 00270 // MOVE 00271 bool move(Vertex_handle v, const Point &p); 00272 00273 // POINT LOCATION 00274 Face_handle 00275 march_locate_1D(const Point& t, Locate_type& lt, int& li) const ; 00276 Face_handle 00277 march_locate_2D(Face_handle start, 00278 const Point& t, 00279 Locate_type& lt, 00280 int& li) const; 00281 00282 Face_handle 00283 march_locate_2D_LFC(Face_handle start, 00284 const Point& t, 00285 Locate_type& lt, 00286 int& li) const; 00287 00288 void 00289 compare_walks(const Point& p, 00290 Face_handle c1, Face_handle c2, 00291 Locate_type& lt1, Locate_type& lt2, 00292 int li1, int li2) const; 00293 00294 Face_handle 00295 locate(const Point& p, 00296 Locate_type& lt, 00297 int& li, 00298 Face_handle start = Face_handle()) const; 00299 00300 Face_handle 00301 locate(const Point &p, 00302 Face_handle start = Face_handle()) const; 00303 00304 00305 00306 //TRAVERSING : ITERATORS AND CIRCULATORS 00307 Finite_faces_iterator finite_faces_begin() const; 00308 Finite_faces_iterator finite_faces_end() const; 00309 Finite_vertices_iterator finite_vertices_begin() const; 00310 Finite_vertices_iterator finite_vertices_end() const; 00311 Finite_edges_iterator finite_edges_begin() const; 00312 Finite_edges_iterator finite_edges_end() const; 00313 Point_iterator points_begin() const; 00314 Point_iterator points_end() const; 00315 00316 All_faces_iterator all_faces_begin() const; 00317 All_faces_iterator all_faces_end() const; 00318 All_vertices_iterator all_vertices_begin() const; 00319 All_vertices_iterator all_vertices_end() const; 00320 All_edges_iterator all_edges_begin() const; 00321 All_edges_iterator all_edges_end() const; 00322 00323 //for compatibility with previous versions 00324 Face_iterator faces_begin() const {return finite_faces_begin();} 00325 Face_iterator faces_end() const {return finite_faces_end();} 00326 Edge_iterator edges_begin() const {return finite_edges_begin();} 00327 Edge_iterator edges_end() const {return finite_edges_end();} 00328 Vertex_iterator vertices_begin() const {return finite_vertices_begin();} 00329 Vertex_iterator vertices_end() const {return finite_vertices_end();} 00330 00331 Face_circulator incident_faces( Vertex_handle v, 00332 Face_handle f = Face_handle()) const; 00333 Vertex_circulator incident_vertices(Vertex_handle v, 00334 Face_handle f = Face_handle()) const; 00335 Edge_circulator incident_edges(Vertex_handle v, 00336 Face_handle f = Face_handle()) const; 00337 00338 size_type degree(Vertex_handle v) const; 00339 00340 Vertex_handle mirror_vertex(Face_handle f, int i) const; 00341 int mirror_index(Face_handle v, int i) const; 00342 00343 Line_face_circulator line_walk(const Point& p, 00344 const Point& q, 00345 Face_handle f = Face_handle()) const; 00346 00347 // TO DEBUG 00348 void show_all() const; 00349 void show_vertex(Vertex_handle vh) const; 00350 void show_face( Face_handle fh) const; 00351 00352 // IO 00353 // template < class Stream > 00354 // Stream& draw_triangulation(Stream& os) const; 00355 00356 //PREDICATES 00357 Oriented_side 00358 oriented_side(const Point &p0, const Point &p1, 00359 const Point &p2, const Point &p) const; 00360 00361 Bounded_side 00362 bounded_side(const Point &p0, const Point &p1, 00363 const Point &p2, const Point &p) const; 00364 00365 Oriented_side 00366 oriented_side(Face_handle f, const Point &p) const; 00367 00368 Oriented_side 00369 side_of_oriented_circle(Face_handle f, const Point & p) const; 00370 00371 bool 00372 collinear_between(const Point& p, const Point& q, const Point& r) 00373 const; 00374 00375 Comparison_result compare_x(const Point& p, const Point& q) const; 00376 Comparison_result compare_y(const Point& p, const Point& q) const; 00377 bool xy_equal(const Point& p, const Point& q) const; 00378 Orientation orientation(const Point& p, 00379 const Point& q, 00380 const Point& r) const; 00381 00382 00383 protected: 00384 void remove_1D(Vertex_handle v); 00385 void remove_2D(Vertex_handle v); 00386 bool test_dim_down(Vertex_handle v); 00387 void fill_hole(Vertex_handle v, std::list<Edge> & hole); 00388 void fill_hole_delaunay(std::list<Edge> & hole); 00389 00390 public: 00391 void make_hole(Vertex_handle v, std::list<Edge> & hole); 00392 // template<class EdgeIt> 00393 // Vertex_handle star_hole( Point p, 00394 // EdgeIt edge_begin, 00395 // EdgeIt edge_end); 00396 00397 // template<class EdgeIt, class FaceIt> 00398 // Vertex_handle star_hole( Point p, 00399 // EdgeIt edge_begin, 00400 // EdgeIt edge_end, 00401 // FaceIt face_begin, 00402 // FaceIt face_end); 00403 00404 Face_handle create_face(Face_handle f1, int i1, 00405 Face_handle f2, int i2, 00406 Face_handle f3, int i3); 00407 Face_handle create_face(Face_handle f1, int i1, 00408 Face_handle f2, int i2); 00409 Face_handle create_face(Face_handle f, int i, Vertex_handle v); 00410 Face_handle create_face(Vertex_handle v1, Vertex_handle v2,Vertex_handle v3); 00411 Face_handle create_face(Vertex_handle v1, Vertex_handle v2,Vertex_handle v3, 00412 Face_handle f1, Face_handle f2, Face_handle f3); 00413 Face_handle create_face(); 00414 Face_handle create_face(Face_handle); //calls copy constructor of Face 00415 void delete_face(Face_handle f); 00416 void delete_vertex(Vertex_handle v); 00417 00418 Vertex_handle file_input(std::istream& is); 00419 void file_output(std::ostream& os) const; 00420 00421 private: 00422 Vertex_handle insert_outside_convex_hull_1(const Point& p, Face_handle f); 00423 Vertex_handle insert_outside_convex_hull_2(const Point& p, Face_handle f); 00424 00425 // template members 00426 public: 00427 template < class Stream > 00428 Stream& draw_triangulation(Stream& os) const 00429 { 00430 Finite_edges_iterator it = finite_edges_begin(); 00431 for( ;it != finite_edges_end() ; ++it) { 00432 os << segment(it); 00433 } 00434 return os; 00435 } 00436 00437 template < class InputIterator > 00438 int insert(InputIterator first, InputIterator last) 00439 { 00440 int n = number_of_vertices(); 00441 00442 std::vector<Point> points (first, last); 00443 std::random_shuffle (points.begin(), points.end()); 00444 spatial_sort (points.begin(), points.end(), geom_traits()); 00445 Face_handle f; 00446 for (typename std::vector<Point>::const_iterator p = points.begin(), end = points.end(); 00447 p != end; ++p) 00448 f = insert (*p, f)->face(); 00449 00450 return number_of_vertices() - n; 00451 } 00452 00453 template < class InputIterator > 00454 bool move(InputIterator first, InputIterator last) 00455 { 00456 bool blocked = false; 00457 std::map<Vertex_handle, int> hash; 00458 std::list< std::pair<Vertex_handle, Point> > to_move(first, last); 00459 while(!to_move.empty()) { 00460 std::pair<Vertex_handle, Point> pp = to_move.front(); 00461 to_move.pop_front(); 00462 if(!move(pp.first, pp.second)) { 00463 if(hash[pp.first] == 3) break; 00464 else if(hash[pp.first] == 2) blocked = true; 00465 hash[pp.first]++; 00466 to_move.push_back(pp); 00467 } 00468 } 00469 return !blocked; 00470 } 00471 00472 bool well_oriented(Vertex_handle v) 00473 { 00474 typedef typename Geom_traits::Orientation_2 Orientation_2; 00475 Orientation_2 orientation_2 = geom_traits().orientation_2_object(); 00476 Face_circulator fc = incident_faces(v), done(fc); 00477 do { 00478 if(!is_infinite(fc)) { 00479 Vertex_handle v0 = fc->vertex(0); 00480 Vertex_handle v1 = fc->vertex(1); 00481 Vertex_handle v2 = fc->vertex(2); 00482 if(orientation(v0->point(),v1->point(),v2->point()) 00483 != COUNTERCLOCKWISE) return false; 00484 } 00485 } while(++fc != done); 00486 return true; 00487 } 00488 00489 bool from_convex_hull(Vertex_handle v) { 00490 CGAL_triangulation_precondition(!is_infinite(v)); 00491 Vertex_circulator vc = incident_vertices(v), done(vc); 00492 do { if(is_infinite(vc)) return true; } while(++vc != done); 00493 return false; 00494 } 00495 00496 public: 00497 template<class EdgeIt> 00498 Vertex_handle star_hole( const Point& p, 00499 EdgeIt edge_begin, 00500 EdgeIt edge_end) { 00501 std::list<Face_handle> empty_list; 00502 return star_hole(p, 00503 edge_begin, 00504 edge_end, 00505 empty_list.begin(), 00506 empty_list.end()); 00507 } 00508 00509 template<class EdgeIt, class FaceIt> 00510 Vertex_handle star_hole( const Point& p, 00511 EdgeIt edge_begin, 00512 EdgeIt edge_end, 00513 FaceIt face_begin, 00514 FaceIt face_end) { 00515 typedef typename Triangulation_data_structure::Edge Tds_Edge; 00516 typedef typename Triangulation_data_structure::Face Tds_Face; 00517 Vertex_handle v = _tds.star_hole( edge_begin, edge_end, 00518 face_begin, face_end); 00519 v->set_point(p); 00520 return v; 00521 } 00522 00523 }; 00524 00525 // CONSTRUCTORS 00526 template <class Gt, class Tds > 00527 Triangulation_2<Gt, Tds>:: 00528 Triangulation_2(const Geom_traits& geom_traits) 00529 : _gt(geom_traits), _tds() 00530 { 00531 _infinite_vertex = _tds.insert_first(); 00532 } 00533 00534 // copy constructor duplicates vertices and faces 00535 template <class Gt, class Tds > 00536 Triangulation_2<Gt, Tds>:: 00537 Triangulation_2(const Triangulation_2 &tr) 00538 : _gt(tr._gt) 00539 { 00540 _infinite_vertex = _tds.copy_tds(tr._tds, tr.infinite_vertex()); 00541 } 00542 00543 00544 //Assignement 00545 template <class Gt, class Tds > 00546 Triangulation_2<Gt, Tds> & 00547 Triangulation_2<Gt, Tds>:: 00548 operator=(const Triangulation_2 &tr) 00549 { 00550 copy_triangulation(tr); 00551 return *this; 00552 } 00553 00554 // Helping functions 00555 00556 template <class Gt, class Tds > 00557 void 00558 Triangulation_2<Gt, Tds>:: 00559 copy_triangulation(const Triangulation_2 &tr) 00560 { 00561 _tds.clear(); 00562 _gt = tr._gt; 00563 _infinite_vertex = _tds.copy_tds(tr._tds, tr._infinite_vertex); 00564 } 00565 00566 template <class Gt, class Tds > 00567 void 00568 Triangulation_2<Gt, Tds>:: 00569 swap(Triangulation_2 &tr) 00570 { 00571 Vertex_handle v= _infinite_vertex; 00572 _infinite_vertex = tr._infinite_vertex; 00573 tr._infinite_vertex = v; 00574 00575 _tds.swap(tr._tds); 00576 00577 Geom_traits t = geom_traits(); 00578 _gt = tr.geom_traits(); 00579 tr._gt = t; 00580 } 00581 00582 template <class Gt, class Tds > 00583 void 00584 Triangulation_2<Gt, Tds>:: 00585 clear() 00586 { 00587 _tds.clear(); //detruit tous les sommets et toutes les faces 00588 _infinite_vertex = _tds.insert_first(); 00589 } 00590 00591 template <class Gt, class Tds > 00592 typename Triangulation_2<Gt, Tds>::size_type 00593 Triangulation_2<Gt, Tds>:: 00594 number_of_faces() const 00595 { 00596 size_type count = _tds.number_of_faces(); 00597 Face_circulator fc = incident_faces(infinite_vertex()), 00598 done(fc); 00599 if ( ! fc.is_empty() ) { 00600 do { 00601 --count; ++fc; 00602 } while (fc != done); 00603 } 00604 return count; 00605 } 00606 00607 template <class Gt, class Tds > 00608 inline 00609 typename Triangulation_2<Gt,Tds>::Vertex_handle 00610 Triangulation_2<Gt,Tds>:: 00611 infinite_vertex() const 00612 { 00613 return _infinite_vertex; 00614 } 00615 00616 template <class Gt, class Tds > 00617 inline 00618 typename Triangulation_2<Gt,Tds>::Vertex_handle 00619 Triangulation_2<Gt,Tds>:: 00620 finite_vertex() const 00621 { 00622 CGAL_triangulation_precondition (number_of_vertices() >= 1); 00623 return (finite_vertices_begin()); 00624 } 00625 00626 template <class Gt, class Tds > 00627 inline 00628 typename Triangulation_2<Gt,Tds>::Face_handle 00629 Triangulation_2<Gt,Tds>:: 00630 infinite_face() const 00631 { 00632 return infinite_vertex()->face(); 00633 } 00634 00635 template <class Gt, class Tds > 00636 inline 00637 typename Triangulation_2<Gt,Tds>::Infinite_tester 00638 Triangulation_2<Gt,Tds>:: 00639 infinite_tester() const 00640 { 00641 return Infinite_tester(this); 00642 } 00643 00644 00645 template <class Gt, class Tds > 00646 bool 00647 Triangulation_2<Gt, Tds>:: 00648 is_valid(bool verbose, int level) const 00649 { 00650 bool result = _tds.is_valid(verbose, level); 00651 if (dimension() <= 0 || 00652 (dimension()==1 && number_of_vertices() == 2 ) ) return result; 00653 00654 if (dimension() == 1) { 00655 Finite_vertices_iterator it1 = finite_vertices_begin(), 00656 it2(it1), it3(it1); 00657 ++it2; 00658 ++it3; ++it3; 00659 while( it3 != finite_vertices_end()) { 00660 Orientation s = orientation(it1->point(), 00661 it2->point(), 00662 it3->point()); 00663 result = result && s == COLLINEAR ; 00664 CGAL_triangulation_assertion(result); 00665 ++it1 ; ++it2; ++it3; 00666 } 00667 } 00668 00669 else { //dimension() == 2 00670 for(Finite_faces_iterator it=finite_faces_begin(); 00671 it!=finite_faces_end(); it++) { 00672 CGAL_triangulation_assertion( ! is_infinite(it)); 00673 Orientation s = orientation(it->vertex(0)->point(), 00674 it->vertex(1)->point(), 00675 it->vertex(2)->point()); 00676 CGAL_triangulation_assertion( s == LEFT_TURN ); 00677 result = result && ( s == LEFT_TURN ); 00678 } 00679 00680 Vertex_circulator start = incident_vertices(infinite_vertex()); 00681 Vertex_circulator pc(start); 00682 Vertex_circulator qc(start); ++qc; 00683 Vertex_circulator rc(start); ++rc; ++rc; 00684 do{ 00685 Orientation s = orientation(pc->point(), 00686 qc->point(), 00687 rc->point()); 00688 CGAL_triangulation_assertion( s != LEFT_TURN ); 00689 result = result && ( s != LEFT_TURN ); 00690 ++pc ; ++qc ; ++rc; 00691 }while(pc != start); 00692 00693 // check number of faces. This cannot be done by the Tds 00694 // which does not know the number of components nor the genus 00695 result = result && (number_of_faces() == 2*(number_of_vertices()+1) 00696 - 4 00697 - degree(infinite_vertex())); 00698 CGAL_triangulation_assertion( result); 00699 } 00700 return result; 00701 } 00702 00703 00704 template <class Gt, class Tds > 00705 inline bool 00706 Triangulation_2<Gt, Tds>:: 00707 is_infinite(Face_handle f) const 00708 { 00709 return f->has_vertex(infinite_vertex()); 00710 } 00711 00712 00713 template <class Gt, class Tds > 00714 inline bool 00715 Triangulation_2<Gt, Tds>:: 00716 is_infinite(Vertex_handle v) const 00717 { 00718 return v == infinite_vertex(); 00719 } 00720 00721 template <class Gt, class Tds > 00722 inline bool 00723 Triangulation_2<Gt, Tds>:: 00724 is_infinite(Face_handle f, int i) const 00725 { 00726 return is_infinite(f->vertex(ccw(i))) || 00727 is_infinite(f->vertex(cw(i))); 00728 } 00729 00730 template <class Gt, class Tds > 00731 inline bool 00732 Triangulation_2<Gt, Tds>:: 00733 is_infinite(const Edge& e) const 00734 { 00735 return is_infinite(e.first,e.second); 00736 } 00737 00738 template <class Gt, class Tds > 00739 inline bool 00740 Triangulation_2<Gt, Tds>:: 00741 is_infinite(const Edge_circulator& ec) const 00742 { 00743 return is_infinite(*ec); 00744 } 00745 00746 template <class Gt, class Tds > 00747 inline bool 00748 Triangulation_2<Gt, Tds>:: 00749 is_infinite(const All_edges_iterator& ei) const 00750 { 00751 return is_infinite(*ei); 00752 } 00753 00754 template <class Gt, class Tds > 00755 inline bool 00756 Triangulation_2<Gt, Tds>:: 00757 is_edge(Vertex_handle va, Vertex_handle vb) const 00758 { 00759 return _tds.is_edge( va, vb); 00760 } 00761 00762 template <class Gt, class Tds > 00763 inline bool 00764 Triangulation_2<Gt, Tds>:: 00765 is_edge(Vertex_handle va, Vertex_handle vb, Face_handle& fr, int & i) const 00766 { 00767 return _tds.is_edge(va, vb, fr, i); 00768 } 00769 00770 template <class Gt, class Tds > 00771 bool 00772 Triangulation_2<Gt, Tds>:: 00773 includes_edge(Vertex_handle va, Vertex_handle vb, 00774 Vertex_handle & vbb, 00775 Face_handle& fr, int & i) const 00776 // returns true if the line segment ab contains an edge e of t 00777 // incident to a, false otherwise 00778 // if true, vbb becomes the vertex of e distinct from a 00779 // fr is the face incident to e and e=(fr,i) 00780 // fr is on the right side of a->b 00781 { 00782 Vertex_handle v; 00783 Orientation orient; 00784 int indv; 00785 Edge_circulator ec = incident_edges(va), done(ec); 00786 if (ec != 0) { 00787 do { 00788 //find the index of the other vertex of *ec 00789 indv = 3 - ((*ec).first)->index(va) - (*ec).second ; 00790 v = ((*ec).first)->vertex(indv); 00791 if (!is_infinite(v)) { 00792 if (v==vb) { 00793 vbb = vb; 00794 fr=(*ec).first; 00795 i= (*ec).second; 00796 return true; 00797 } 00798 else { 00799 orient = orientation(va->point(), 00800 vb->point(), 00801 v->point()); 00802 if((orient==COLLINEAR) && 00803 (collinear_between (va->point(), 00804 v->point(), 00805 vb->point()))) { 00806 vbb = v; 00807 fr=(*ec).first; 00808 i= (*ec).second; 00809 return true; 00810 } 00811 } 00812 } 00813 } while (++ec != done); 00814 } 00815 return false; 00816 } 00817 00818 template <class Gt, class Tds > 00819 inline bool 00820 Triangulation_2<Gt, Tds>:: 00821 is_face(Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) const 00822 { 00823 return _tds.is_face(v1, v2, v3); 00824 } 00825 00826 template <class Gt, class Tds > 00827 inline bool 00828 Triangulation_2<Gt, Tds>:: 00829 is_face(Vertex_handle v1, 00830 Vertex_handle v2, 00831 Vertex_handle v3, 00832 Face_handle &fr) const 00833 { 00834 return _tds.is_face(v1, v2, v3, fr); 00835 } 00836 00837 00838 template <class Gt, class Tds > 00839 typename Triangulation_2<Gt, Tds>::Triangle 00840 Triangulation_2<Gt, Tds>:: 00841 triangle(Face_handle f) const 00842 { 00843 CGAL_triangulation_precondition( ! is_infinite(f) ); 00844 typename Gt::Construct_triangle_2 00845 construct_triangle = geom_traits().construct_triangle_2_object(); 00846 return construct_triangle(f->vertex(0)->point(), 00847 f->vertex(1)->point(), 00848 f->vertex(2)->point()); 00849 } 00850 00851 template <class Gt, class Tds > 00852 typename Triangulation_2<Gt, Tds>::Segment 00853 Triangulation_2<Gt, Tds>:: 00854 segment(Face_handle f, int i) const 00855 { 00856 CGAL_triangulation_precondition( ! is_infinite(f,i)); 00857 typename Gt::Construct_segment_2 00858 construct_segment = geom_traits().construct_segment_2_object(); 00859 return construct_segment(f->vertex(ccw(i))->point(), 00860 f->vertex(cw(i))->point()); 00861 } 00862 00863 template <class Gt, class Tds > 00864 typename Triangulation_2<Gt, Tds>::Segment 00865 Triangulation_2<Gt, Tds>:: 00866 segment(const Edge& e) const 00867 { 00868 CGAL_triangulation_precondition(! is_infinite(e)); 00869 typename Gt::Construct_segment_2 00870 construct_segment = geom_traits().construct_segment_2_object(); 00871 return construct_segment(e.first->vertex(ccw(e.second))->point(), 00872 e.first->vertex( cw(e.second))->point()); 00873 } 00874 00875 template <class Gt, class Tds > 00876 typename Triangulation_2<Gt, Tds>::Segment 00877 Triangulation_2<Gt, Tds>:: 00878 segment(const Edge_circulator& ec) const 00879 { 00880 return segment(*ec); 00881 } 00882 00883 template <class Gt, class Tds > 00884 typename Triangulation_2<Gt, Tds>::Segment 00885 Triangulation_2<Gt, Tds>:: 00886 segment(const Finite_edges_iterator& ei) const 00887 { 00888 return segment(*ei); 00889 } 00890 00891 template <class Gt, class Tds > 00892 typename Triangulation_2<Gt, Tds>::Segment 00893 Triangulation_2<Gt, Tds>:: 00894 segment(const All_edges_iterator& ei) const 00895 { 00896 return segment(*ei); 00897 } 00898 00899 template <class Gt, class Tds > 00900 void 00901 Triangulation_2<Gt, Tds>:: 00902 flip(Face_handle f, int i) 00903 { 00904 CGAL_triangulation_precondition ( f != Face_handle() ); 00905 CGAL_triangulation_precondition (i == 0 || i == 1 || i == 2); 00906 CGAL_triangulation_precondition( dimension()==2); 00907 00908 CGAL_triangulation_precondition( !is_infinite(f) && 00909 !is_infinite(f->neighbor(i)) ); 00910 CGAL_triangulation_precondition( 00911 orientation(f->vertex(i)->point(), 00912 f->vertex(cw(i))->point(), 00913 mirror_vertex(f,i)->point()) == RIGHT_TURN && 00914 orientation(f->vertex(i)->point(), 00915 f->vertex(ccw(i))->point(), 00916 mirror_vertex(f,i)->point()) == LEFT_TURN); 00917 _tds.flip(f, i); 00918 return; 00919 } 00920 00921 template <class Gt, class Tds > 00922 typename Triangulation_2<Gt,Tds>::Vertex_handle 00923 Triangulation_2<Gt,Tds>:: 00924 insert_first(const Point& p) 00925 { 00926 CGAL_triangulation_precondition(number_of_vertices() == 0); 00927 Vertex_handle v = _tds.insert_second(); 00928 v->set_point(p); 00929 return v; 00930 } 00931 00932 template <class Gt, class Tds > 00933 typename Triangulation_2<Gt,Tds>::Vertex_handle 00934 Triangulation_2<Gt,Tds>:: 00935 insert_second(const Point& p) 00936 { 00937 CGAL_triangulation_precondition(number_of_vertices() == 1); 00938 Vertex_handle v = _tds.insert_dim_up(infinite_vertex(), true); 00939 v->set_point(p); 00940 return v; 00941 } 00942 00943 template <class Gt, class Tds > 00944 typename Triangulation_2<Gt,Tds>::Vertex_handle 00945 Triangulation_2<Gt,Tds>:: 00946 insert_in_edge(const Point& p, Face_handle f,int i) 00947 { 00948 CGAL_triangulation_exactness_precondition( 00949 orientation(f->vertex(cw(i))->point(), p, 00950 f->vertex(ccw(i))->point()) == COLLINEAR && 00951 collinear_between(f->vertex(cw(i))->point(), p, 00952 f->vertex(ccw(i))->point() ) ); 00953 Vertex_handle v = _tds.insert_in_edge(f,i); 00954 v->set_point(p); 00955 return v; 00956 } 00957 00958 template <class Gt, class Tds > 00959 typename Triangulation_2<Gt,Tds>::Vertex_handle 00960 Triangulation_2<Gt,Tds>:: 00961 insert_in_face(const Point& p, Face_handle f) 00962 { 00963 CGAL_triangulation_precondition(oriented_side(f,p) == ON_POSITIVE_SIDE); 00964 Vertex_handle v= _tds.insert_in_face(f); 00965 v->set_point(p); 00966 return v; 00967 } 00968 00969 template <class Gt, class Tds > 00970 typename Triangulation_2<Gt,Tds>::Vertex_handle 00971 Triangulation_2<Gt,Tds>:: 00972 insert_outside_convex_hull(const Point& p, Face_handle f) 00973 { 00974 CGAL_triangulation_precondition(is_infinite(f) && dimension() >= 1); 00975 Vertex_handle v; 00976 if (dimension() == 1) v=insert_outside_convex_hull_1(p, f); 00977 else v=insert_outside_convex_hull_2(p, f); 00978 v->set_point(p); 00979 return v; 00980 } 00981 00982 template <class Gt, class Tds > 00983 typename Triangulation_2<Gt,Tds>::Vertex_handle 00984 Triangulation_2<Gt,Tds>:: 00985 insert_outside_convex_hull_1(const Point& p, Face_handle f) 00986 { 00987 CGAL_triangulation_precondition( is_infinite(f) && dimension()==1); 00988 CGAL_triangulation_precondition( 00989 orientation( 00990 mirror_vertex(f,f->index(infinite_vertex()))->point(), 00991 f->vertex(1- f->index(infinite_vertex()))->point(), 00992 p) == COLLINEAR && 00993 collinear_between( 00994 mirror_vertex(f,f->index(infinite_vertex()))->point(), 00995 f->vertex(1- f->index(infinite_vertex()))->point(), 00996 p) ); 00997 Vertex_handle v=_tds.insert_in_edge(f, 2); 00998 v->set_point(p); 00999 return v; 01000 } 01001 01002 template <class Gt, class Tds > 01003 typename Triangulation_2<Gt,Tds>::Vertex_handle 01004 Triangulation_2<Gt,Tds>:: 01005 insert_outside_convex_hull_2(const Point& p, Face_handle f) 01006 { 01007 CGAL_triangulation_precondition(is_infinite(f)); 01008 01009 int li = f->index(infinite_vertex()); 01010 01011 CGAL_triangulation_precondition( 01012 orientation(p, 01013 f->vertex(ccw(li))->point(), 01014 f->vertex(cw(li))->point()) == LEFT_TURN); 01015 01016 std::list<Face_handle> ccwlist; 01017 std::list<Face_handle> cwlist; 01018 01019 Face_circulator fc = incident_faces(infinite_vertex(), f); 01020 bool done = false; 01021 while(! done) { 01022 fc--; 01023 li = fc->index(infinite_vertex()); 01024 const Point& q = fc->vertex(ccw(li))->point(); 01025 const Point& r = fc->vertex(cw(li))->point(); 01026 if(orientation(p,q,r) == LEFT_TURN ) { ccwlist.push_back(fc); } 01027 else {done=true;} 01028 } 01029 01030 fc = incident_faces(infinite_vertex(), f); 01031 done = false; 01032 while(! done){ 01033 fc++; 01034 li = fc->index(infinite_vertex()); 01035 const Point& q = fc->vertex(ccw(li))->point(); 01036 const Point& r = fc->vertex(cw(li))->point(); 01037 if(orientation(p,q,r) == LEFT_TURN ) { cwlist.push_back(fc);} 01038 else {done=true;} 01039 } 01040 01041 Vertex_handle v = _tds.insert_in_face(f); 01042 v->set_point(p); 01043 01044 Face_handle fh; 01045 while ( ! ccwlist.empty()) { 01046 fh = ccwlist.front(); 01047 li = ccw(fh->index(infinite_vertex())); 01048 _tds.flip( fh, li); 01049 ccwlist.pop_front(); 01050 } 01051 01052 while ( ! cwlist.empty()) { 01053 fh = cwlist.front(); 01054 li = cw(fh->index(infinite_vertex())); 01055 _tds.flip( fh, li); 01056 cwlist.pop_front(); 01057 } 01058 01059 //reset infinite_vertex()->face(); 01060 fc = incident_faces(v); 01061 while( ! is_infinite(fc)) { fc++;} 01062 infinite_vertex()->set_face(fc); 01063 01064 return v; 01065 } 01066 01067 template <class Gt, class Tds > 01068 typename Triangulation_2<Gt,Tds>::Vertex_handle 01069 Triangulation_2<Gt,Tds>:: 01070 insert_outside_affine_hull(const Point& p) 01071 { 01072 CGAL_triangulation_precondition(dimension() < 2); 01073 bool conform = false; 01074 if (dimension() == 1) { 01075 Face_handle f = (*finite_edges_begin()).first; 01076 Orientation orient = orientation( f->vertex(0)->point(), 01077 f->vertex(1)->point(), 01078 p); 01079 CGAL_triangulation_precondition(orient != COLLINEAR); 01080 conform = ( orient == COUNTERCLOCKWISE); 01081 } 01082 Vertex_handle v = _tds.insert_dim_up( infinite_vertex(), conform); 01083 v->set_point(p); 01084 return v; 01085 } 01086 01087 template <class Gt, class Tds > 01088 typename Triangulation_2<Gt,Tds>::Vertex_handle 01089 Triangulation_2<Gt,Tds>:: 01090 insert(const Point &p, Face_handle start) 01091 { 01092 Locate_type lt; 01093 int li; 01094 Face_handle loc = locate (p, lt, li, start); 01095 return insert(p, lt, loc, li); 01096 } 01097 01098 01099 template <class Gt, class Tds > 01100 typename Triangulation_2<Gt,Tds>::Vertex_handle 01101 Triangulation_2<Gt,Tds>:: 01102 insert(const Point& p, Locate_type lt, Face_handle loc, int li) 01103 // insert a point p, whose localisation is known (lt, f, i) 01104 { 01105 if(number_of_vertices() == 0) { 01106 return(insert_first(p)); 01107 } 01108 01109 if(number_of_vertices() == 1) { 01110 if (lt == VERTEX) return finite_vertex(); 01111 else return(insert_second(p)); 01112 } 01113 01114 switch(lt) { 01115 case FACE: 01116 return insert_in_face(p,loc); 01117 case EDGE: 01118 return insert_in_edge(p,loc,li); 01119 case OUTSIDE_CONVEX_HULL: 01120 return insert_outside_convex_hull(p,loc); 01121 case OUTSIDE_AFFINE_HULL: 01122 return insert_outside_affine_hull(p); 01123 case VERTEX: 01124 return loc->vertex(li); 01125 } 01126 CGAL_triangulation_assertion(false); // locate step failed 01127 return Vertex_handle(); 01128 } 01129 01130 01131 template <class Gt, class Tds > 01132 inline 01133 typename Triangulation_2<Gt,Tds>::Vertex_handle 01134 Triangulation_2<Gt,Tds>:: 01135 push_back(const Point &p) 01136 { 01137 return insert(p); 01138 } 01139 01140 template <class Gt, class Tds > 01141 inline void 01142 Triangulation_2<Gt,Tds>:: 01143 remove_degree_3(Vertex_handle v, Face_handle f) 01144 { 01145 if (f == Face_handle()) f=v->face(); 01146 _tds.remove_degree_3(v, f); 01147 return; 01148 } 01149 01150 template <class Gt, class Tds > 01151 inline void 01152 Triangulation_2<Gt,Tds>:: 01153 remove_first(Vertex_handle v) 01154 { 01155 _tds.remove_second(v); 01156 return; 01157 } 01158 01159 template <class Gt, class Tds > 01160 inline void 01161 Triangulation_2<Gt,Tds>:: 01162 remove_second(Vertex_handle v) 01163 { 01164 _tds.remove_dim_down(v); 01165 return; 01166 } 01167 01168 template <class Gt, class Tds > 01169 void 01170 Triangulation_2<Gt,Tds>:: 01171 remove(Vertex_handle v) 01172 { 01173 CGAL_triangulation_precondition( v != Vertex_handle()); 01174 CGAL_triangulation_precondition( !is_infinite(v)); 01175 01176 if (number_of_vertices() == 1) remove_first(v); 01177 else if (number_of_vertices() == 2) remove_second(v); 01178 else if ( dimension() == 1) remove_1D(v); 01179 else remove_2D(v); 01180 return; 01181 } 01182 01183 template <class Gt, class Tds > 01184 inline void 01185 Triangulation_2<Gt, Tds>:: 01186 remove_1D(Vertex_handle v) 01187 { 01188 _tds.remove_1D(v); 01189 } 01190 01191 template <class Gt, class Tds > 01192 bool 01193 Triangulation_2<Gt,Tds>:: 01194 test_dim_down(Vertex_handle v) 01195 { 01196 //test the dimensionality of the resulting triangulation 01197 //upon removing of vertex v 01198 //it goes down to 1 iff 01199 // 1) any finite face is incident to v 01200 // 2) all vertices are collinear 01201 CGAL_triangulation_precondition(dimension() == 2); 01202 bool dim1 = true; 01203 Finite_faces_iterator fit = finite_faces_begin(); 01204 while (dim1==true && fit != finite_faces_end()) { 01205 dim1 = dim1 && fit->has_vertex(v); 01206 fit++; 01207 } 01208 Face_circulator fic = incident_faces(v); 01209 while (is_infinite(fic)) {++fic;} 01210 Face_circulator done(fic); 01211 Face_handle start(fic); int iv = start->index(v); 01212 const Point& p = start->vertex(cw(iv))->point(); 01213 const Point& q = start->vertex(ccw(iv))->point(); 01214 while ( dim1 && ++fic != done) { 01215 iv = fic->index(v); 01216 if (fic->vertex(ccw(iv)) != infinite_vertex()) { 01217 dim1 = dim1 && 01218 orientation(p, q, fic->vertex(ccw(iv))->point()) == COLLINEAR; 01219 } 01220 } 01221 return dim1; 01222 } 01223 01224 template <class Gt, class Tds > 01225 void 01226 Triangulation_2<Gt,Tds>:: 01227 remove_2D(Vertex_handle v) 01228 { 01229 if (test_dim_down(v)) { _tds.remove_dim_down(v); } 01230 else { 01231 std::list<Edge> hole; 01232 make_hole(v, hole); 01233 fill_hole(v, hole); 01234 delete_vertex(v); 01235 } 01236 return; 01237 } 01238 01239 template <class Gt, class Tds > 01240 void 01241 Triangulation_2<Gt, Tds>:: 01242 make_hole ( Vertex_handle v, std::list<Edge> & hole) 01243 { 01244 std::list<Face_handle> to_delete; 01245 01246 Face_handle f, fn; 01247 int i, in ; 01248 Vertex_handle vv; 01249 01250 Face_circulator fc = incident_faces(v); 01251 Face_circulator done(fc); 01252 do { 01253 f = fc; fc++; 01254 i = f->index(v); 01255 fn = f->neighbor(i); 01256 in = fn->index(f); 01257 vv = f->vertex(cw(i)); 01258 if( vv->face()== f) vv->set_face(fn); 01259 vv = f->vertex(ccw(i)); 01260 if( vv->face()== f) vv->set_face(fn); 01261 fn->set_neighbor(in, Face_handle()); 01262 hole.push_back(Edge(fn,in)); 01263 to_delete.push_back(f); 01264 } 01265 while(fc != done); 01266 01267 while (! to_delete.empty()){ 01268 delete_face(to_delete.front()); 01269 to_delete.pop_front(); 01270 } 01271 return; 01272 } 01273 01274 template <class Gt, class Tds > 01275 void 01276 Triangulation_2<Gt, Tds>:: 01277 fill_hole ( Vertex_handle v, std::list< Edge > & hole ) 01278 { 01279 // uses the fact that the hole is starshaped 01280 // with repect to v->point() 01281 typedef std::list<Edge> Hole; 01282 01283 Face_handle ff, fn; 01284 int ii , in; 01285 Vertex_handle v0, v1, v2; 01286 Bounded_side side; 01287 01288 //stack algorithm to create faces 01289 // create face v0,v1,v2 01290 //if v0,v1,v2 are finite vertices 01291 // and form a left_turn 01292 // and triangle v0v1v2 does not contain v->point() 01293 if( hole.size() != 3) { 01294 typename Hole::iterator hit = hole.begin(); 01295 typename Hole::iterator next= hit; 01296 while( hit != hole.end() && hole.size() != 3) { 01297 ff = (*hit).first; 01298 ii = (*hit).second; 01299 v0 = ff->vertex(cw(ii)); 01300 v1 = ff->vertex(ccw(ii)); 01301 if( !is_infinite(v0) && !is_infinite(v1)) { 01302 next=hit; next++; 01303 if(next == hole.end()) next=hole.begin(); 01304 fn = (*next).first; 01305 in = (*next).second; 01306 v2 = fn->vertex(ccw(in)); 01307 if ( !is_infinite(v2) && 01308 orientation(v0->point(), v1->point(), v2->point()) == LEFT_TURN ) { 01309 side = bounded_side(v0->point(), 01310 v1->point(), 01311 v2->point(), 01312 v->point()); 01313 01314 if( side == ON_UNBOUNDED_SIDE || 01315 (side == ON_BOUNDARY && orientation(v0->point(), 01316 v->point(), 01317 v2->point()) == COLLINEAR && 01318 collinear_between(v0->point(),v->point(),v2->point()) )) 01319 { 01320 //create face 01321 Face_handle newf = create_face(ff,ii,fn,in); 01322 typename Hole::iterator tempo=hit; 01323 hit = hole.insert(hit,Edge(newf,1)); //push newf 01324 hole.erase(tempo); //erase ff 01325 hole.erase(next); //erase fn 01326 if (hit != hole.begin() ) --hit; 01327 continue; 01328 } 01329 } 01330 } 01331 ++hit; 01332 } 01333 } 01334 01335 // either the hole has only three edges 01336 // or all its finite vertices are reflex or flat 01337 // except may be one vertex whose corresponding ear 01338 // includes the vertex being removed 01339 01340 // deal with the last left_turn if any 01341 if(hole.size() != 3) { 01342 typename Hole::iterator hit=hole.begin(); 01343 while(hit != hole.end()) { 01344 ff = (*hit).first; ii = (*hit).second; 01345 hit++; 01346 if(hit != hole.end()) { fn = (*hit).first; in = (*hit).second;} 01347 else { fn = ((hole.front()).first); in = (hole.front()).second;} 01348 if ( !is_infinite(ff->vertex(cw(ii))) && 01349 !is_infinite(fn->vertex(cw(in))) && 01350 !is_infinite(fn->vertex(ccw(in))) && 01351 orientation(ff->vertex(cw(ii))->point(), 01352 fn->vertex(cw(in))->point(), 01353 fn->vertex(ccw(in))->point()) == LEFT_TURN) { 01354 create_face(ff,ii,fn,in); 01355 break; 01356 } 01357 } 01358 } 01359 01360 // deal with a reflex chain of convex hull edges 01361 if(hole.size() != 3) { 01362 // look for infinite vertex 01363 ff = (hole.front()).first; 01364 ii = (hole.front()).second; 01365 while ( ! is_infinite(ff->vertex(cw(ii)))){ 01366 hole.push_back(hole.front()); 01367 hole.pop_front(); 01368 ff = (hole.front()).first; 01369 ii = (hole.front()).second; 01370 } 01371 //create faces 01372 while(hole.size() != 3){ 01373 ff = (hole.front()).first; 01374 ii = (hole.front()).second; 01375 hole.pop_front(); 01376 fn = (hole.front()).first; 01377 in = (hole.front()).second; 01378 hole.pop_front(); 01379 Face_handle newf = create_face(ff,ii,fn,in); 01380 hole.push_front(Edge(newf,1)); 01381 } 01382 } 01383 01384 // now hole has three edges 01385 typename Hole::iterator hit; 01386 hit = hole.begin(); 01387 // I don't know why the following yelds a segmentation fault 01388 // create_face( (*hit).first, (*hit).second, 01389 // (* ++hit).first, (*hit).second, 01390 // (* ++hit).first, (*hit).second); 01391 ff = (*hit).first; ii = (*hit).second; 01392 fn = (* ++hit).first; in = (*hit).second; 01393 Face_handle f3 = (* ++hit).first; 01394 int i3 = (*hit).second; 01395 create_face(ff,ii,fn,in,f3,i3); 01396 } 01397 01398 template <class Gt, class Tds > 01399 void 01400 Triangulation_2<Gt, Tds>:: 01401 fill_hole_delaunay(std::list<Edge> & first_hole) 01402 { 01403 typename Gt::Side_of_oriented_circle_2 01404 in_circle = geom_traits().side_of_oriented_circle_2_object(); 01405 01406 typedef std::list<Edge> Hole; 01407 typedef std::list<Hole> Hole_list; 01408 01409 Face_handle f, ff, fn; 01410 int i, ii, in; 01411 Hole_list hole_list; 01412 Hole hole; 01413 01414 hole_list.push_front(first_hole); 01415 01416 while( ! hole_list.empty()) 01417 { 01418 hole = hole_list.front(); 01419 hole_list.pop_front(); 01420 typename Hole::iterator hit = hole.begin(); 01421 01422 // if the hole has only three edges, create the triangle 01423 if (hole.size() == 3) { 01424 hit = hole.begin(); 01425 f = (*hit).first; i = (*hit).second; 01426 ff = (* ++hit).first; ii = (*hit).second; 01427 fn = (* ++hit).first; in = (*hit).second; 01428 create_face(f,i,ff,ii,fn,in); 01429 continue; 01430 } 01431 01432 // else find an edge with two finite vertices 01433 // on the hole boundary 01434 // and the new triangle adjacent to that edge 01435 // cut the hole and push it back 01436 01437 // first, ensure that a neighboring face 01438 // whose vertices on the hole boundary are finite 01439 // is the first of the hole 01440 bool finite= false; 01441 while (!finite){ 01442 ff = (hole.front()).first; 01443 ii = (hole.front()).second; 01444 if ( is_infinite(ff->vertex(cw(ii))) || 01445 is_infinite(ff->vertex(ccw(ii)))) { 01446 hole.push_back(hole.front()); 01447 hole.pop_front(); 01448 } 01449 else finite=true; 01450 } 01451 01452 // take the first neighboring face and pop it; 01453 ff = (hole.front()).first; 01454 ii =(hole.front()).second; 01455 hole.pop_front(); 01456 01457 Vertex_handle v0 = ff->vertex(cw(ii)); 01458 Vertex_handle v1 = ff->vertex(ccw(ii)); 01459 Vertex_handle v2 = infinite_vertex(); 01460 Vertex_handle v3; 01461 const Point& p0 = v0->point(); 01462 const Point& p1 = v1->point(); 01463 01464 typename Hole::iterator hdone = hole.end(); 01465 hit = hole.begin(); 01466 typename Hole::iterator cut_after(hit); 01467 01468 // if tested vertex is c with respect to the vertex opposite 01469 // to NULL neighbor, 01470 // stop at the before last face; 01471 hdone--; 01472 while( hit != hdone) { 01473 fn = (*hit).first; 01474 in = (*hit).second; 01475 Vertex_handle vv = fn->vertex(ccw(in)); 01476 if (is_infinite(vv)) { 01477 if(is_infinite(v2)) cut_after = hit; 01478 } 01479 else { // vv is a finite vertex 01480 const Point & p = vv->point(); 01481 if (orientation(p0,p1,p) == COUNTERCLOCKWISE) { 01482 if (is_infinite(v2)) { v2=vv; v3=vv; cut_after=hit;} 01483 else{ 01484 if (in_circle(p0,p1,v3->point(),p) == ON_POSITIVE_SIDE){ 01485 v2=vv; v3=vv; cut_after=hit;} 01486 } 01487 } 01488 } 01489 ++hit; 01490 } 01491 01492 // create new triangle and update adjacency relations 01493 Face_handle newf; 01494 01495 //update the hole and push back in the Hole_List stack 01496 // if v2 belongs to the neighbor following or preceding *f 01497 // the hole remain a single hole 01498 // otherwise it is split in two holes 01499 01500 fn = (hole.front()).first; 01501 in = (hole.front()).second; 01502 if (fn->has_vertex(v2, i) && i == fn->ccw(in)) { 01503 newf = create_face(ff,ii,fn,in); 01504 hole.pop_front(); 01505 hole.push_front(Edge( newf,1)); 01506 hole_list.push_front(hole); 01507 } 01508 else{ 01509 fn = (hole.back()).first; 01510 in = (hole.back()).second; 01511 if (fn->has_vertex(v2, i) && i== fn->cw(in)) { 01512 newf = create_face(fn,in,ff,ii); 01513 hole.pop_back(); 01514 hole.push_back(Edge(newf,1)); 01515 hole_list.push_front(hole); 01516 } 01517 else{ 01518 // split the hole in two holes 01519 newf = create_face(ff,ii,v2); 01520 Hole new_hole; 01521 ++cut_after; 01522 while( hole.begin() != cut_after ) 01523 { 01524 new_hole.push_back(hole.front()); 01525 hole.pop_front(); 01526 } 01527 01528 hole.push_front(Edge( newf,1)); 01529 new_hole.push_front(Edge( newf,0)); 01530 hole_list.push_front(hole); 01531 hole_list.push_front(new_hole); 01532 } 01533 } 01534 } 01535 } 01536 01537 template <class Gt, class Tds > 01538 bool 01539 Triangulation_2<Gt, Tds>:: 01540 move(Vertex_handle v, const Point &p) { 01541 CGAL_triangulation_precondition(!is_infinite(v)); 01542 const int dim = dimension(); 01543 01544 if(dim == 2) { 01545 Point ant = v->point(); 01546 v->set_point(p); 01547 if(well_oriented(v)) { 01548 if(!from_convex_hull(v)) { 01549 return true; 01550 } 01551 } 01552 v->set_point(ant); 01553 } 01554 01555 Locate_type lt; 01556 int li; 01557 Vertex_handle inserted; 01558 Face_handle loc = locate(p, lt, li); 01559 01560 if(lt == VERTEX) return false; 01561 01562 if(dim < 0) return true; 01563 01564 if(dim == 0) { 01565 v->point() = p; 01566 return true; 01567 } 01568 01569 if((loc != NULL) && (dim == 1)) { 01570 if(loc->has_vertex(v)) { 01571 v->point() = p; 01572 } else { 01573 inserted = insert(p, lt, loc, li); 01574 Face_handle f = v->face(); 01575 int i = f->index(v); 01576 if (i==0) {f = f->neighbor(1);} 01577 CGAL_triangulation_assertion(f->index(v) == 1); 01578 Face_handle g= f->neighbor(0); 01579 f->set_vertex(1, g->vertex(1)); 01580 f->set_neighbor(0, g->neighbor(0)); 01581 g->neighbor(0)->set_neighbor(1,f); 01582 g->vertex(1)->set_face(f); 01583 delete_face(g); 01584 Face_handle f_ins = inserted->face(); 01585 i = f_ins->index(inserted); 01586 if (i==0) {f_ins = f_ins->neighbor(1);} 01587 CGAL_triangulation_assertion(f_ins->index(inserted) == 1); 01588 Face_handle g_ins = f_ins->neighbor(0); 01589 f_ins->set_vertex(1, v); 01590 g_ins->set_vertex(0, v); 01591 std::swap(*v, *inserted); 01592 delete_vertex(inserted); 01593 } 01594 return true; 01595 } 01596 01597 if((loc != NULL) && test_dim_down(v)) { 01598 v->point() = p; 01599 int i = loc->index(v); 01600 Face_handle locl; 01601 int i_locl; 01602 if(is_infinite(loc)) { 01603 int i_inf = loc->index(infinite_vertex()); 01604 locl = loc->neighbor(i_inf); 01605 i_locl = locl->index(v); 01606 } else { locl = loc; i_locl = i; } 01607 if(orientation(p, locl->vertex(ccw(i_locl))->point(), 01608 locl->vertex(cw(i_locl))->point()) == COLLINEAR) { 01609 _tds.dim_2D_1D(loc, i); 01610 } 01611 return true; 01612 } 01613 01614 inserted = insert(p, lt, loc, li); 01615 01616 std::list<Edge> hole; 01617 make_hole(v, hole); 01618 fill_hole(v, hole); 01619 01620 // fixing pointer 01621 Face_circulator fc = incident_faces(inserted), done(fc); 01622 std::list<Face_handle> faces_pt; 01623 do { faces_pt.push_back(fc); } while(++fc != done); 01624 while(!faces_pt.empty()) { 01625 Face_handle f = faces_pt.front(); 01626 faces_pt.pop_front(); 01627 int i = f->index(inserted); 01628 f->set_vertex(i, v); 01629 } 01630 std::swap(*v, *inserted); 01631 delete_vertex(inserted); 01632 01633 return true; 01634 } 01635 01636 template <class Gt, class Tds > 01637 inline 01638 typename Triangulation_2<Gt, Tds>::Face_handle 01639 Triangulation_2<Gt, Tds>:: 01640 create_face(Face_handle f1, int i1, 01641 Face_handle f2, int i2, 01642 Face_handle f3, int i3) 01643 { 01644 return _tds.create_face(f1, i1, f2, i2, f3, i3); 01645 } 01646 01647 template <class Gt, class Tds > 01648 inline 01649 typename Triangulation_2<Gt, Tds>::Face_handle 01650 Triangulation_2<Gt, Tds>:: 01651 create_face(Face_handle f1, int i1, 01652 Face_handle f2, int i2) 01653 { 01654 return _tds.create_face(f1, i1, f2, i2); 01655 } 01656 01657 template <class Gt, class Tds > 01658 inline 01659 typename Triangulation_2<Gt, Tds>::Face_handle 01660 Triangulation_2<Gt, Tds>:: 01661 create_face(Face_handle f, int i, Vertex_handle v) 01662 { 01663 return _tds.create_face(f, i, v); 01664 } 01665 01666 template <class Gt, class Tds > 01667 inline 01668 typename Triangulation_2<Gt, Tds>::Face_handle 01669 Triangulation_2<Gt, Tds>:: 01670 create_face(Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) 01671 { 01672 return _tds.create_face(v1, v2, v3); 01673 } 01674 01675 template <class Gt, class Tds > 01676 inline 01677 typename Triangulation_2<Gt, Tds>::Face_handle 01678 Triangulation_2<Gt, Tds>:: 01679 create_face(Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, 01680 Face_handle f1, Face_handle f2, Face_handle f3) 01681 { 01682 return _tds.create_face(v1, v2, v3, f1, f2, f3); 01683 } 01684 01685 template <class Gt, class Tds > 01686 inline 01687 typename Triangulation_2<Gt, Tds>::Face_handle 01688 Triangulation_2<Gt, Tds>:: 01689 create_face(Face_handle fh) 01690 { 01691 return _tds.create_face(fh); 01692 } 01693 01694 01695 01696 template <class Gt, class Tds > 01697 inline 01698 typename Triangulation_2<Gt, Tds>::Face_handle 01699 Triangulation_2<Gt, Tds>:: 01700 create_face() 01701 { 01702 return _tds.create_face(); 01703 } 01704 01705 template <class Gt, class Tds > 01706 inline 01707 void 01708 Triangulation_2<Gt, Tds>:: 01709 delete_face(Face_handle f) 01710 { 01711 _tds.delete_face(f); 01712 } 01713 01714 template <class Gt, class Tds > 01715 inline 01716 void 01717 Triangulation_2<Gt, Tds>:: 01718 delete_vertex(Vertex_handle v) 01719 { 01720 _tds.delete_vertex(v); 01721 } 01722 01723 // POINT LOCATION 01724 template <class Gt, class Tds > 01725 typename Triangulation_2<Gt, Tds>::Face_handle 01726 Triangulation_2<Gt, Tds>:: 01727 march_locate_1D(const Point& t, 01728 Locate_type& lt, 01729 int& li) const 01730 { 01731 Face_handle ff = infinite_face(); 01732 int iv = ff->index(infinite_vertex()); 01733 Face_handle f = ff->neighbor(iv); 01734 Orientation pqt = orientation(f->vertex(0)->point(), 01735 f->vertex(1)->point(), 01736 t); 01737 if(pqt == RIGHT_TURN || pqt == LEFT_TURN) { 01738 lt = OUTSIDE_AFFINE_HULL; 01739 li = 4 ;// should not be used 01740 return Face_handle(); 01741 } 01742 01743 int i= f->index(ff); 01744 if (collinear_between(t,f->vertex(1-i)->point(),f->vertex(i)->point())) { 01745 lt = OUTSIDE_CONVEX_HULL; 01746 li = iv; 01747 return ff; 01748 } 01749 01750 if( xy_equal(t,f->vertex(1-i)->point()) ){ 01751 lt = VERTEX; 01752 li=1-i; 01753 return f; 01754 } 01755 01756 ff = ff->neighbor(1-iv); //the other infinite face 01757 iv = ff->index(infinite_vertex()); 01758 f = ff->neighbor(iv); 01759 i = f->index(ff); 01760 if (collinear_between(t,f->vertex(1-i)->point(),f->vertex(i)->point())) { 01761 lt = OUTSIDE_CONVEX_HULL; 01762 li = iv; 01763 return ff; 01764 } 01765 if( xy_equal(t,f->vertex(1-i)->point()) ){ 01766 lt = VERTEX; 01767 li=1-i; 01768 return f; 01769 } 01770 01771 Finite_edges_iterator eit= finite_edges_begin(); 01772 Vertex_handle u,v; 01773 for( ; eit != finite_edges_end() ; eit++) { 01774 u = (*eit).first->vertex(0); 01775 v = (*eit).first->vertex(1); 01776 if(xy_equal(t,v->point())){ 01777 lt = VERTEX; 01778 li = 1; 01779 return (*eit).first; 01780 } 01781 if(collinear_between(u->point(), t, v->point())){ 01782 lt = EDGE; 01783 li = 2; 01784 return (*eit).first; 01785 } 01786 } 01787 CGAL_triangulation_assertion(false); 01788 return Face_handle(); 01789 } 01790 01791 template <class Gt, class Tds > 01792 typename Triangulation_2<Gt, Tds>::Face_handle 01793 Triangulation_2<Gt, Tds>:: 01794 march_locate_2D_LFC(Face_handle start, 01795 const Point& t, 01796 Locate_type& lt, 01797 int& li) const 01798 { 01799 // CGAL_triangulation_precondition( ! is_infinite(start) ); 01800 const Point& p = start->vertex(0)->point(); 01801 const Point& q = start->vertex(1)->point(); 01802 const Point& r = start->vertex(2)->point(); 01803 if(xy_equal(t,p)) { 01804 lt = VERTEX; 01805 li = 0; 01806 return start; 01807 } 01808 01809 Line_face_circulator lfc; 01810 01811 Orientation o2 = orientation(p, q, t); 01812 Orientation o0 = orientation(q, r, t); 01813 Orientation o1 = orientation(r, p, t); 01814 if( (o2 == LEFT_TURN)&& (o1 == LEFT_TURN)) { 01815 lfc = Line_face_circulator(start, 0, 01816 Line_face_circulator::vertex_edge, 01817 this, p, t); 01818 } else if ( (o0 == LEFT_TURN)&& (o2 == LEFT_TURN)) { 01819 lfc = Line_face_circulator(start, 1, 01820 Line_face_circulator::vertex_edge, 01821 this, q, t); 01822 } else if ( (o1 == LEFT_TURN)&& (o0 == LEFT_TURN)) { 01823 lfc = Line_face_circulator(start, 2, 01824 Line_face_circulator::vertex_edge, 01825 this, r, t); 01826 } if( (o2 == RIGHT_TURN)&& (o1 == RIGHT_TURN)) { 01827 lfc = Line_face_circulator(start, 0, 01828 Line_face_circulator::edge_vertex, 01829 this, p, t); 01830 } else if ( (o0 == RIGHT_TURN)&& (o2 == RIGHT_TURN)) { 01831 lfc = Line_face_circulator(start, 1, 01832 Line_face_circulator::edge_vertex, 01833 this, q, t); 01834 } else if ( (o1 == RIGHT_TURN)&& (o0 == RIGHT_TURN)) { 01835 lfc = Line_face_circulator(start, 2, 01836 Line_face_circulator::edge_vertex, 01837 this, r, t); 01838 }else { 01839 lfc = Line_face_circulator(start->vertex(0), this, t); 01840 } 01841 if(lfc==0 || lfc.collinear_outside()){ 01842 // point t lies outside or on the convex hull 01843 // we walk on the convex hull to find it out 01844 Face_circulator fc = incident_faces(infinite_vertex()); 01845 Face_circulator done(fc); 01846 int ic = fc->index(infinite_vertex()); 01847 if (xy_equal(t,fc->vertex(cw(ic))->point())){ 01848 lt = VERTEX; 01849 li = cw(ic); 01850 return fc; 01851 } 01852 Orientation ori; 01853 do{ // walking ccw around convex hull 01854 ic = fc->index(infinite_vertex()); 01855 if (xy_equal(t,fc->vertex(ccw(ic))->point())){ 01856 lt = VERTEX; 01857 li = ccw(ic); 01858 return fc; 01859 } 01860 ori = orientation( fc->vertex(cw(ic))->point(), 01861 fc->vertex(ccw(ic))->point(), t); 01862 if (ori == RIGHT_TURN) { 01863 lt = OUTSIDE_CONVEX_HULL; 01864 li = ic; 01865 return fc; 01866 } 01867 if (ori == COLLINEAR && 01868 collinear_between(fc->vertex(cw(ic))->point(), 01869 t, 01870 fc->vertex(ccw(ic))->point()) ) { 01871 lt = EDGE; 01872 li = ic; 01873 return fc; 01874 } 01875 } while (--fc != done); 01876 //should not arrive there; 01877 CGAL_triangulation_assertion(fc != done); 01878 } 01879 01880 while(! lfc.locate(t, lt, li) ){ 01881 ++lfc; 01882 } 01883 return lfc; 01884 } 01885 01886 template <class Gt, class Tds > 01887 void 01888 Triangulation_2<Gt, Tds>:: 01889 compare_walks(const Point& p, 01890 Face_handle c1, Face_handle c2, 01891 Locate_type& lt1, Locate_type& lt2, 01892 int li1, int li2) const 01893 { 01894 bool b = true; 01895 b = b && (lt1 == lt2); 01896 if((lt1 == lt2) && (lt1 == VERTEX)) { 01897 b = b && ( c1->vertex(li1) == c2->vertex(li2) ); 01898 } else if((lt1 == lt2) && (lt1 == EDGE)) { 01899 b = b && ((c1 == c2) || ( (c1->neighbor(li1) == c2) && (c2->neighbor(li2) == c1))); 01900 }else if((lt1 == lt2) && (lt1 == OUTSIDE_CONVEX_HULL)) { 01901 b = b && (is_infinite(c1) && is_infinite(c2)); 01902 } else { 01903 b = b && (lt1 == lt2); 01904 b = b && (lt1 == FACE); 01905 b = b && (c1 == c2); 01906 } 01907 01908 if ( c1 != c2) { 01909 std::cerr << "from compare_walks " << std::endl; 01910 std::cerr << "point " << p << std::endl; 01911 std::cerr << "locate 1 " << &*c1 << "\t" << lt1 << "\t" << li1 01912 << std::endl; 01913 std::cerr << "locate 2 " << &*c2 << "\t" << lt2 << "\t" << li2 01914 << std::endl; 01915 std::cerr << std::endl; 01916 show_face(c1); 01917 std::cerr << std::endl; 01918 show_face(c2); 01919 std::cerr << std::endl; 01920 } 01921 01922 CGAL_triangulation_assertion(b); 01923 } 01924 01925 01926 #if 1 01927 01928 template <class Gt, class Tds > typename Triangulation_2<Gt, Tds>::Face_handle 01929 Triangulation_2<Gt, Tds>:: 01930 march_locate_2D(Face_handle c, 01931 const Point& t, 01932 Locate_type& lt, 01933 int& li) const 01934 { 01935 CGAL_triangulation_assertion(! is_infinite(c)); 01936 01937 Face_handle prev = Face_handle(); 01938 bool first = true; 01939 while (1) { 01940 if ( is_infinite(c) ) { 01941 // c must contain t in its interior 01942 lt = OUTSIDE_CONVEX_HULL; 01943 li = c->index(infinite_vertex()); 01944 return c; 01945 } 01946 01947 // else c is finite 01948 // Instead of testing its edges in a random order we do the following 01949 // until we find a neighbor to go further: 01950 // As we come from prev we do not have to check the edge leading to prev 01951 // Now we flip a coin in order to decide if we start checking the 01952 // edge before or the edge after the edge leading to prev 01953 // We do loop unrolling in order to find out if this is faster. 01954 // In the very beginning we do not have a prev, but for the first step 01955 // we do not need randomness 01956 int left_first = rng.template get_bits<1>(); 01957 01958 const Point & p0 = c->vertex( 0 )->point(); 01959 const Point & p1 = c->vertex( 1 )->point(); 01960 const Point & p2 = c->vertex( 2 )->point(); 01961 Orientation o0, o1, o2; 01962 01963 if(first){ 01964 prev = c; 01965 first = false; 01966 o0 = orientation(p0,p1,t); 01967 if ( o0 == NEGATIVE ) { 01968 c = c->neighbor( 2 ); 01969 continue; 01970 } 01971 o1 = orientation(p1,p2,t); 01972 if ( o1 == NEGATIVE ) { 01973 c = c->neighbor( 0 ); 01974 continue; 01975 } 01976 o2 = orientation(p2,p0,t); 01977 if ( o2 == NEGATIVE ) { 01978 c = c->neighbor( 1 ); 01979 continue; 01980 } 01981 } else if(left_first){ 01982 if(c->neighbor(0) == prev){ 01983 prev = c; 01984 o0 = orientation(p0,p1,t); 01985 if ( o0 == NEGATIVE ) { 01986 c = c->neighbor( 2 ); 01987 continue; 01988 } 01989 o2 = orientation(p2,p0,t); 01990 if ( o2 == NEGATIVE ) { 01991 c = c->neighbor( 1 ); 01992 continue; 01993 } 01994 o1 = POSITIVE; 01995 } else if(c->neighbor(1) == prev){ 01996 prev = c; 01997 o1 = orientation(p1,p2,t); 01998 if ( o1 == NEGATIVE ) { 01999 c = c->neighbor( 0 ); 02000 continue; 02001 } 02002 o0 = orientation(p0,p1,t); 02003 if ( o0 == NEGATIVE ) { 02004 c = c->neighbor( 2 ); 02005 continue; 02006 } 02007 o2 = POSITIVE; 02008 } else { 02009 prev = c; 02010 o2 = orientation(p2,p0,t); 02011 if ( o2 == NEGATIVE ) { 02012 c = c->neighbor( 1 ); 02013 continue; 02014 } 02015 o1 = orientation(p1,p2,t); 02016 if ( o1 == NEGATIVE ) { 02017 c = c->neighbor( 0 ); 02018 continue; 02019 } 02020 o0 = POSITIVE; 02021 } 02022 02023 } else { // right_first 02024 if(c->neighbor(0) == prev){ 02025 prev = c; 02026 o2 = orientation(p2,p0,t); 02027 if ( o2 == NEGATIVE ) { 02028 c = c->neighbor( 1 ); 02029 continue; 02030 } 02031 o0 = orientation(p0,p1,t); 02032 if ( o0 == NEGATIVE ) { 02033 c = c->neighbor( 2 ); 02034 continue; 02035 } 02036 o1 = POSITIVE; 02037 } else if(c->neighbor(1) == prev){ 02038 prev = c; 02039 o0 = orientation(p0,p1,t); 02040 if ( o0 == NEGATIVE ) { 02041 c = c->neighbor( 2 ); 02042 continue; 02043 } 02044 o1 = orientation(p1,p2,t); 02045 if ( o1 == NEGATIVE ) { 02046 c = c->neighbor( 0 ); 02047 continue; 02048 } 02049 o2 = POSITIVE; 02050 } else { 02051 prev = c; 02052 o1 = orientation(p1,p2,t); 02053 if ( o1 == NEGATIVE ) { 02054 c = c->neighbor( 0 ); 02055 continue; 02056 } 02057 o2 = orientation(p2,p0,t); 02058 if ( o2 == NEGATIVE ) { 02059 c = c->neighbor( 1 ); 02060 continue; 02061 } 02062 o0 = POSITIVE; 02063 } 02064 } 02065 02066 // now p is in c or on its boundary 02067 int sum = ( o0 == COLLINEAR ) 02068 + ( o1 == COLLINEAR ) 02069 + ( o2 == COLLINEAR ); 02070 switch (sum) { 02071 case 0: 02072 { 02073 lt = FACE; 02074 li = 4; 02075 break; 02076 } 02077 case 1: 02078 { 02079 lt = EDGE; 02080 li = ( o0 == COLLINEAR ) ? 2 : 02081 ( o1 == COLLINEAR ) ? 0 : 02082 1; 02083 break; 02084 } 02085 case 2: 02086 { 02087 lt = VERTEX; 02088 li = ( o0 != COLLINEAR ) ? 2 : 02089 ( o1 != COLLINEAR ) ? 0 : 02090 1; 02091 break; 02092 } 02093 } 02094 return c; 02095 } 02096 } 02097 02098 02099 #else 02100 02101 template <class Gt, class Tds > typename Triangulation_2<Gt, Tds>::Face_handle 02102 Triangulation_2<Gt, Tds>:: 02103 march_locate_2D(Face_handle c, 02104 const Point& t, 02105 Locate_type& lt, 02106 int& li) const 02107 { 02108 CGAL_triangulation_assertion(! is_infinite(c)); 02109 02110 Face_handle prev = Face_handle(); 02111 while (1) { 02112 if ( is_infinite(c) ) { 02113 // c must contain t in its interior 02114 lt = OUTSIDE_CONVEX_HULL; 02115 li = c->index(infinite_vertex()); 02116 return c; 02117 } 02118 02119 // else c is finite 02120 // we test its edges in a random order until we find a 02121 // neighbor to go further 02122 02123 int i = rng.template get_bits<2>(); 02124 int ccwi = ccw(i); 02125 int cwi = cw(i); 02126 const Point & p0 = c->vertex( i )->point(); 02127 const Point & p1 = c->vertex( ccwi )->point(); 02128 Orientation o0, o1, o2; 02129 CGAL_triangulation_assertion(orientation(p0,p1,c->vertex( cwi )->point())==POSITIVE); 02130 if(c->neighbor(cwi) == prev){ 02131 o0 = POSITIVE; 02132 } else { 02133 o0 = orientation(p0,p1,t); 02134 if ( o0 == NEGATIVE ) { 02135 prev = c; 02136 c = c->neighbor( cwi ); 02137 continue; 02138 } 02139 } 02140 const Point & p2 = c->vertex( cwi )->point(); 02141 if(c->neighbor(i) == prev){ 02142 o1 = POSITIVE; 02143 } else { 02144 o1 = orientation(p1,p2,t); 02145 if ( o1 == NEGATIVE ) { 02146 prev = c; 02147 c = c->neighbor( i ); 02148 continue; 02149 } 02150 } 02151 if(c->neighbor(ccwi) == prev){ 02152 o2 = POSITIVE; 02153 } else { 02154 o2 = orientation(p2,p0,t); 02155 if ( o2 == NEGATIVE ) { 02156 prev = c; 02157 c = c->neighbor( ccwi ); 02158 continue; 02159 } 02160 } 02161 02162 // now p is in c or on its boundary 02163 int sum = ( o0 == COLLINEAR ) 02164 + ( o1 == COLLINEAR ) 02165 + ( o2 == COLLINEAR ); 02166 switch (sum) { 02167 case 0: 02168 { 02169 lt = FACE; 02170 li = 4; 02171 break; 02172 } 02173 case 1: 02174 { 02175 lt = EDGE; 02176 li = ( o0 == COLLINEAR ) ? cwi : 02177 ( o1 == COLLINEAR ) ? i : 02178 ccwi; 02179 break; 02180 } 02181 case 2: 02182 { 02183 lt = VERTEX; 02184 li = ( o0 != COLLINEAR ) ? cwi : 02185 ( o1 != COLLINEAR ) ? i : 02186 ccwi; 02187 break; 02188 } 02189 } 02190 return c; 02191 } 02192 } 02193 02194 02195 #endif 02196 02197 02198 02199 02200 template <class Gt, class Tds > 02201 typename Triangulation_2<Gt, Tds>::Face_handle 02202 Triangulation_2<Gt,Tds>:: 02203 locate(const Point& p, 02204 Locate_type& lt, 02205 int& li, 02206 Face_handle start) const 02207 { 02208 if (dimension() < 0) { 02209 lt = OUTSIDE_AFFINE_HULL; 02210 li = 4; // li should not be used in this case 02211 return Face_handle(); 02212 } 02213 if( dimension() == 0) { 02214 // Do not use finite_vertex directly because there can be hidden vertices 02215 // (regular triangulations) 02216 if (xy_equal(p,finite_vertex()->face()->vertex(0)->point())){ 02217 lt = VERTEX ; 02218 } 02219 else{ 02220 lt = OUTSIDE_AFFINE_HULL; 02221 } 02222 li = 4; // li should not be used in this case 02223 return Face_handle(); 02224 } 02225 if(dimension() == 1){ 02226 return march_locate_1D(p, lt, li); 02227 } 02228 02229 if(start == Face_handle()){ 02230 start = infinite_face()-> 02231 neighbor(infinite_face()->index(infinite_vertex())); 02232 }else if(is_infinite(start)){ 02233 start = start->neighbor(start->index(infinite_vertex())); 02234 } 02235 02236 #if ( ! defined(CGAL_ZIG_ZAG_WALK)) && ( ! defined(CGAL_LFC_WALK)) 02237 #define CGAL_ZIG_ZAG_WALK 02238 #endif 02239 02240 #ifdef CGAL_ZIG_ZAG_WALK 02241 Face_handle res1 = march_locate_2D(start, p, lt, li); 02242 #endif 02243 #ifdef CGAL_LFC_WALK 02244 Locate_type lt2; 02245 int li2; 02246 Face_handle res2 = march_locate_2D_LFC(start, p, lt2, li2); 02247 #endif 02248 02249 #if defined(CGAL_ZIG_ZAG_WALK) && defined(CGAL_LFC_WALK) 02250 compare_walks(p, 02251 res1, res2, 02252 lt, lt2, 02253 li, li2); 02254 #endif 02255 02256 #ifdef CGAL_ZIG_ZAG_WALK 02257 return res1; 02258 #endif 02259 02260 #ifdef CGAL_LFC_WALK 02261 lt = lt2; 02262 li = li2; 02263 return res2; 02264 #endif 02265 02266 } 02267 02268 02269 template <class Gt, class Tds > 02270 typename Triangulation_2<Gt, Tds>:: Face_handle 02271 Triangulation_2<Gt, Tds>:: 02272 locate(const Point &p, 02273 Face_handle start) const 02274 { 02275 Locate_type lt; 02276 int li; 02277 return locate(p, lt, li, start); 02278 } 02279 02280 template <class Gt, class Tds > 02281 typename Triangulation_2<Gt, Tds>::Finite_faces_iterator 02282 Triangulation_2<Gt, Tds>:: 02283 finite_faces_begin() const 02284 { 02285 if ( dimension() < 2 ) 02286 return finite_faces_end(); 02287 return CGAL::filter_iterator( all_faces_end(), 02288 Infinite_tester(this), 02289 all_faces_begin() ); 02290 } 02291 02292 template <class Gt, class Tds > 02293 typename Triangulation_2<Gt, Tds>::Finite_faces_iterator 02294 Triangulation_2<Gt, Tds>:: 02295 finite_faces_end() const 02296 { 02297 return CGAL::filter_iterator( all_faces_end(), 02298 Infinite_tester(this) ); 02299 } 02300 02301 template <class Gt, class Tds > 02302 typename Triangulation_2<Gt, Tds>::Finite_vertices_iterator 02303 Triangulation_2<Gt, Tds>:: 02304 finite_vertices_begin() const 02305 { 02306 if ( number_of_vertices() <= 0 ) 02307 return finite_vertices_end(); 02308 return CGAL::filter_iterator( all_vertices_end(), 02309 Infinite_tester(this), 02310 all_vertices_begin() ); 02311 } 02312 02313 template <class Gt, class Tds > 02314 typename Triangulation_2<Gt, Tds>::Finite_vertices_iterator 02315 Triangulation_2<Gt, Tds>:: 02316 finite_vertices_end() const 02317 { 02318 return CGAL::filter_iterator(all_vertices_end(), 02319 Infinite_tester(this)); 02320 } 02321 02322 template <class Gt, class Tds > 02323 typename Triangulation_2<Gt, Tds>::Finite_edges_iterator 02324 Triangulation_2<Gt, Tds>:: 02325 finite_edges_begin() const 02326 { 02327 if ( dimension() < 1 ) 02328 return finite_edges_end(); 02329 return CGAL::filter_iterator( all_edges_end(), 02330 infinite_tester(), 02331 all_edges_begin()); 02332 } 02333 02334 template <class Gt, class Tds > 02335 typename Triangulation_2<Gt, Tds>::Finite_edges_iterator 02336 Triangulation_2<Gt, Tds>:: 02337 finite_edges_end() const 02338 { 02339 return CGAL::filter_iterator(all_edges_end(), 02340 infinite_tester() ); 02341 } 02342 02343 template <class Gt, class Tds > 02344 typename Triangulation_2<Gt, Tds>::Point_iterator 02345 Triangulation_2<Gt, Tds>:: 02346 points_begin() const 02347 { 02348 return Point_iterator(finite_vertices_begin()); 02349 } 02350 02351 template <class Gt, class Tds > 02352 typename Triangulation_2<Gt, Tds>::Point_iterator 02353 Triangulation_2<Gt, Tds>:: 02354 points_end() const 02355 { 02356 return Point_iterator(finite_vertices_end()); 02357 } 02358 02359 template <class Gt, class Tds > 02360 typename Triangulation_2<Gt, Tds>::All_faces_iterator 02361 Triangulation_2<Gt, Tds>:: 02362 all_faces_begin() const 02363 { 02364 return _tds.faces_begin(); 02365 } 02366 02367 template <class Gt, class Tds > 02368 typename Triangulation_2<Gt, Tds>::All_faces_iterator 02369 Triangulation_2<Gt, Tds>:: 02370 all_faces_end() const 02371 { 02372 return _tds.faces_end();; 02373 } 02374 02375 template <class Gt, class Tds > 02376 typename Triangulation_2<Gt, Tds>::All_vertices_iterator 02377 Triangulation_2<Gt, Tds>:: 02378 all_vertices_begin() const 02379 { 02380 return _tds.vertices_begin(); 02381 } 02382 02383 template <class Gt, class Tds > 02384 typename Triangulation_2<Gt, Tds>::All_vertices_iterator 02385 Triangulation_2<Gt, Tds>:: 02386 all_vertices_end() const 02387 { 02388 return _tds.vertices_end(); 02389 } 02390 02391 template <class Gt, class Tds > 02392 typename Triangulation_2<Gt, Tds>::All_edges_iterator 02393 Triangulation_2<Gt, Tds>:: 02394 all_edges_begin() const 02395 { 02396 return _tds.edges_begin(); 02397 } 02398 02399 template <class Gt, class Tds > 02400 typename Triangulation_2<Gt, Tds>::All_edges_iterator 02401 Triangulation_2<Gt, Tds>:: 02402 all_edges_end() const 02403 { 02404 return _tds.edges_end(); 02405 } 02406 02407 template <class Gt, class Tds > 02408 inline 02409 typename Triangulation_2<Gt, Tds>::Face_circulator 02410 Triangulation_2<Gt, Tds>:: 02411 incident_faces(Vertex_handle v, Face_handle f) const 02412 { 02413 return _tds.incident_faces(v,f); 02414 } 02415 02416 template <class Gt, class Tds > 02417 inline 02418 typename Triangulation_2<Gt, Tds>::Vertex_circulator 02419 Triangulation_2<Gt, Tds>:: 02420 incident_vertices(Vertex_handle v, Face_handle f) const 02421 { 02422 return _tds.incident_vertices(v,f); 02423 } 02424 02425 template <class Gt, class Tds > 02426 inline 02427 typename Triangulation_2<Gt, Tds>::Edge_circulator 02428 Triangulation_2<Gt, Tds>:: 02429 incident_edges(Vertex_handle v, Face_handle f) const 02430 { 02431 return _tds.incident_edges(v,f); 02432 } 02433 02434 template <class Gt, class Tds > 02435 inline 02436 typename Triangulation_2<Gt, Tds>::size_type 02437 Triangulation_2<Gt, Tds>:: 02438 degree(Vertex_handle v) const 02439 { 02440 return _tds.degree(v); 02441 } 02442 02443 template <class Gt, class Tds > 02444 inline 02445 typename Triangulation_2<Gt, Tds>::Vertex_handle 02446 Triangulation_2<Gt, Tds>:: 02447 mirror_vertex(Face_handle f, int i) const 02448 { 02449 return _tds.mirror_vertex(f,i); 02450 } 02451 02452 template <class Gt, class Tds > 02453 inline 02454 int 02455 Triangulation_2<Gt, Tds>:: 02456 mirror_index(Face_handle f, int i) const 02457 { 02458 return _tds.mirror_index(f,i); 02459 } 02460 02461 template <class Gt, class Tds > 02462 typename Triangulation_2<Gt, Tds>::Line_face_circulator 02463 Triangulation_2<Gt, Tds>:: 02464 line_walk(const Point& p, const Point& q, Face_handle f) const 02465 { 02466 CGAL_triangulation_precondition( (dimension() == 2) && 02467 ! xy_equal(p,q)); 02468 Line_face_circulator lfc = (f == Face_handle()) 02469 ? Line_face_circulator(p, q, this) 02470 : Line_face_circulator(p, q, f, this); 02471 02472 // the following lines may be useless : 02473 // Line_face_circulator(p,q...) returns either a null circulator 02474 // or a pointer to a finite face (to be checked) 02475 if( (!lfc.is_empty()) && is_infinite( lfc )){ 02476 do { ++lfc ;} 02477 while (is_infinite(lfc)); 02478 } 02479 return lfc; 02480 } 02481 02482 template <class Gt, class Tds > 02483 Oriented_side 02484 Triangulation_2<Gt, Tds>:: 02485 oriented_side(const Point &p0, const Point &p1, 02486 const Point &p2, const Point &p) const 02487 { 02488 // return position of point p with respect to the oriented triangle p0p1p2 02489 // depends on the orientation of the vertices 02490 Bounded_side bs=bounded_side(p0,p1,p2,p); 02491 if (bs == ON_BOUNDARY) return ON_ORIENTED_BOUNDARY; 02492 Orientation ot = orientation(p0, p1, p2); 02493 if (bs == ON_BOUNDED_SIDE) 02494 return (ot == LEFT_TURN) ? ON_POSITIVE_SIDE : ON_NEGATIVE_SIDE; 02495 // bs == ON_UNBOUNDED_SIDE 02496 return (ot == LEFT_TURN) ? ON_NEGATIVE_SIDE : ON_POSITIVE_SIDE; 02497 } 02498 02499 02500 02501 template <class Gt, class Tds > 02502 Bounded_side 02503 Triangulation_2<Gt, Tds>:: 02504 bounded_side(const Point &p0, const Point &p1, 02505 const Point &p2, const Point &p) const 02506 { 02507 // return position of point p with respect to triangle p0p1p2 02508 CGAL_triangulation_precondition( orientation(p0, p1, p2) != COLLINEAR); 02509 Orientation o1 = orientation(p0, p1, p), 02510 o2 = orientation(p1, p2, p), 02511 o3 = orientation(p2, p0, p); 02512 02513 if (o1 == COLLINEAR){ 02514 if (o2 == COLLINEAR || o3 == COLLINEAR) return ON_BOUNDARY; 02515 if (collinear_between(p0, p, p1)) return ON_BOUNDARY; 02516 return ON_UNBOUNDED_SIDE; 02517 } 02518 02519 if (o2 == COLLINEAR){ 02520 if (o3 == COLLINEAR) return ON_BOUNDARY; 02521 if (collinear_between(p1, p, p2)) return ON_BOUNDARY; 02522 return ON_UNBOUNDED_SIDE; 02523 } 02524 02525 if (o3 == COLLINEAR){ 02526 if (collinear_between(p2, p, p0)) return ON_BOUNDARY; 02527 return ON_UNBOUNDED_SIDE; 02528 } 02529 02530 // from here none ot, o1, o2 and o3 are known to be non null 02531 if (o1 == o2 && o2 == o3) return ON_BOUNDED_SIDE; 02532 return ON_UNBOUNDED_SIDE; 02533 } 02534 02535 02536 template <class Gt, class Tds > 02537 Oriented_side 02538 Triangulation_2<Gt, Tds>:: 02539 oriented_side(Face_handle f, const Point &p) const 02540 { 02541 CGAL_triangulation_precondition ( dimension()==2); 02542 return oriented_side(f->vertex(0)->point(), 02543 f->vertex(1)->point(), 02544 f->vertex(2)->point(), 02545 p); 02546 } 02547 02548 template < class Gt, class Tds > 02549 Oriented_side 02550 Triangulation_2<Gt,Tds>:: 02551 side_of_oriented_circle(Face_handle f, const Point & p) const 02552 { 02553 if ( ! is_infinite(f) ) { 02554 typename Gt::Side_of_oriented_circle_2 02555 in_circle = geom_traits().side_of_oriented_circle_2_object(); 02556 return in_circle(f->vertex(0)->point(), 02557 f->vertex(1)->point(), 02558 f->vertex(2)->point(),p); 02559 } 02560 02561 int i = f->index(infinite_vertex()); 02562 Orientation o = orientation(f->vertex(ccw(i))->point(), 02563 f->vertex(cw(i))->point(), 02564 p); 02565 return (o == NEGATIVE) ? ON_NEGATIVE_SIDE : 02566 (o == POSITIVE) ? ON_POSITIVE_SIDE : 02567 ON_ORIENTED_BOUNDARY; 02568 } 02569 02570 02571 02572 template <class Gt, class Tds > 02573 bool 02574 Triangulation_2<Gt, Tds>:: 02575 collinear_between(const Point& p, const Point& q, const Point& r) const 02576 { 02577 // return true if point q is strictly between p and r 02578 // p,q and r are supposed to be collinear points 02579 Comparison_result c_pr = compare_x(p, r); 02580 Comparison_result c_pq; 02581 Comparison_result c_qr; 02582 if(c_pr == EQUAL) { 02583 //c_pr = compare_y(p, r); 02584 c_pq = compare_y(p, q); 02585 c_qr = compare_y(q, r); 02586 } else { 02587 c_pq = compare_x(p, q); 02588 c_qr = compare_x(q, r); 02589 } 02590 return ( (c_pq == SMALLER) && (c_qr == SMALLER) ) || 02591 ( (c_pq == LARGER) && (c_qr == LARGER) ); 02592 02593 } 02594 02595 template <class Gt, class Tds > 02596 inline 02597 Comparison_result 02598 Triangulation_2<Gt, Tds>:: 02599 compare_x(const Point& p, const Point& q) const 02600 { 02601 return geom_traits().compare_x_2_object()(p,q); 02602 } 02603 02604 template <class Gt, class Tds > 02605 inline 02606 Comparison_result 02607 Triangulation_2<Gt, Tds>:: 02608 compare_y(const Point& p, const Point& q) const 02609 { 02610 return geom_traits().compare_y_2_object()(p,q); 02611 } 02612 02613 template <class Gt, class Tds > 02614 inline 02615 bool 02616 Triangulation_2<Gt, Tds>:: 02617 xy_equal(const Point& p, const Point& q) const 02618 { 02619 return compare_x(p,q)== EQUAL && compare_y(p,q)== EQUAL ; 02620 } 02621 02622 template <class Gt, class Tds > 02623 inline 02624 Orientation 02625 Triangulation_2<Gt, Tds>:: 02626 orientation(const Point& p, const Point& q,const Point& r ) const 02627 { 02628 return geom_traits().orientation_2_object()(p,q,r); 02629 } 02630 02631 template<class Gt, class Tds> 02632 inline 02633 typename Triangulation_2<Gt,Tds>::Point 02634 Triangulation_2<Gt,Tds>:: 02635 circumcenter (const Point& p0, const Point& p1, const Point& p2) const 02636 { 02637 return 02638 geom_traits().construct_circumcenter_2_object()(p0,p1,p2); 02639 } 02640 02641 02642 template <class Gt, class Tds > 02643 typename Triangulation_2<Gt, Tds>::Point 02644 Triangulation_2<Gt, Tds>:: 02645 circumcenter(Face_handle f) const 02646 { 02647 CGAL_triangulation_precondition (dimension()==2); 02648 // typename Gt::Construct_circumcenter_2 02649 // circumcenter = geom_traits().construct_circumcenter_2_object(); 02650 return circumcenter((f->vertex(0))->point(), 02651 (f->vertex(1))->point(), 02652 (f->vertex(2))->point()); 02653 } 02654 02655 02656 template <class Gt, class Tds > 02657 void 02658 Triangulation_2<Gt, Tds>:: 02659 show_all() const 02660 { 02661 std::cerr<< "AFFICHE TOUTE LA TRIANGULATION :"<<std::endl; 02662 std::cerr << std::endl<<"====> "<< this; 02663 std::cerr << " dimension " << dimension() << std::endl; 02664 std::cerr << "nb of vertices " << number_of_vertices() << std::endl; 02665 02666 if (dimension() < 1) return; 02667 if(dimension() == 1) { 02668 std::cerr<<" all edges "<<std::endl; 02669 All_edges_iterator aeit; 02670 for(aeit = all_edges_begin(); aeit != all_edges_end(); aeit++){ 02671 show_face(aeit->first); 02672 } 02673 return; 02674 } 02675 02676 std::cerr<<" faces finies "<<std::endl; 02677 Finite_faces_iterator fi; 02678 for(fi = finite_faces_begin(); fi != finite_faces_end(); fi++) { 02679 show_face(fi); 02680 } 02681 02682 std::cerr <<" faces infinies "<<std::endl; 02683 All_faces_iterator afi; 02684 for(afi = all_faces_begin(); afi != all_faces_end(); afi++) { 02685 if(is_infinite(afi)) show_face(afi); 02686 } 02687 02688 if (number_of_vertices()>1) { 02689 std::cerr << "affichage des sommets de la triangulation reguliere" 02690 <<std::endl; 02691 All_vertices_iterator vi; 02692 for( vi = all_vertices_begin(); vi != all_vertices_end(); vi++){ 02693 show_vertex(vi); 02694 std::cerr << " / face associee : " 02695 << (void*)(&(*(vi->face())))<< std::endl;; 02696 } 02697 std::cerr<<std::endl; 02698 } 02699 return; 02700 } 02701 02702 template <class Gt, class Tds > 02703 void 02704 Triangulation_2<Gt, Tds>:: 02705 show_vertex(Vertex_handle vh) const 02706 { 02707 if(is_infinite(vh)) std::cerr << "inf \t"; 02708 else std::cerr << vh->point() << "\t"; 02709 return; 02710 } 02711 02712 template <class Gt, class Tds > 02713 void 02714 Triangulation_2<Gt, Tds>:: 02715 show_face(Face_handle fh) const 02716 { 02717 std::cerr << "face : "<<(void*)&(*fh)<<" => "<<std::endl; 02718 int i = fh->dimension(); 02719 switch(i){ 02720 case 0: 02721 std::cerr <<"point :" ; show_vertex(fh->vertex(0)); 02722 std::cerr <<" / voisin " << &(*(fh->neighbor(0))); 02723 std::cerr <<"[" ; show_vertex(fh->neighbor(0)->vertex(0)); 02724 std::cerr <<"]" << std::endl; 02725 break; 02726 case 1: 02727 std::cerr <<"point :" ; show_vertex(fh->vertex(0)); 02728 std::cerr <<" / voisin " << &(*(fh->neighbor(0))); 02729 std::cerr <<"[" ; show_vertex(fh->neighbor(0)->vertex(0)); 02730 std::cerr <<"/" ; show_vertex(fh->neighbor(0)->vertex(1)); 02731 std::cerr <<"]" <<std::endl; 02732 02733 std::cerr <<"point :" ; show_vertex(fh->vertex(1)); 02734 std::cerr <<" / voisin " << &(*(fh->neighbor(1))); 02735 std::cerr <<"[" ; show_vertex(fh->neighbor(1)->vertex(0)); 02736 std::cerr <<"/" ; show_vertex(fh->neighbor(1)->vertex(1)); 02737 std::cerr <<"]" <<std::endl; 02738 break; 02739 case 2: 02740 std::cerr <<"point :" ; show_vertex(fh->vertex(0)); 02741 std::cerr <<" / voisin " << &(*(fh->neighbor(0))); 02742 std::cerr <<"[" ; show_vertex(fh->neighbor(0)->vertex(0)); 02743 std::cerr <<"/" ; show_vertex(fh->neighbor(0)->vertex(1)); 02744 std::cerr <<"/" ; show_vertex(fh->neighbor(0)->vertex(2)); 02745 std::cerr <<"]" <<std::endl; 02746 02747 std::cerr <<"point :" ; show_vertex(fh->vertex(1)); 02748 std::cerr <<" / voisin " << &(*(fh->neighbor(1))); 02749 std::cerr <<"[" ; show_vertex(fh->neighbor(1)->vertex(0)); 02750 std::cerr <<"/" ; show_vertex(fh->neighbor(1)->vertex(1)); 02751 std::cerr <<"/" ; show_vertex(fh->neighbor(1)->vertex(2)); 02752 std::cerr <<"]" <<std::endl; 02753 02754 std::cerr <<"point :" ; show_vertex(fh->vertex(2)); 02755 std::cerr <<" / voisin " << &(*(fh->neighbor(2))); 02756 std::cerr <<"[" ; show_vertex(fh->neighbor(2)->vertex(0)); 02757 std::cerr <<"/" ; show_vertex(fh->neighbor(2)->vertex(1)); 02758 std::cerr <<"/" ; show_vertex(fh->neighbor(2)->vertex(2)); 02759 std::cerr <<"]" <<std::endl; 02760 break; 02761 } 02762 return; 02763 } 02764 02765 template <class Gt, class Tds > 02766 void 02767 Triangulation_2<Gt, Tds>:: 02768 file_output(std::ostream& os) const 02769 { 02770 _tds.file_output(os, infinite_vertex(), true); 02771 } 02772 02773 template <class Gt, class Tds > 02774 typename Triangulation_2<Gt, Tds>::Vertex_handle 02775 Triangulation_2<Gt, Tds>:: 02776 file_input(std::istream& is) 02777 { 02778 clear(); 02779 Vertex_handle v= _tds.file_input(is, true); 02780 set_infinite_vertex(v); 02781 return v; 02782 } 02783 02784 template <class Gt, class Tds > 02785 std::ostream& 02786 operator<<(std::ostream& os, const Triangulation_2<Gt, Tds> &tr) 02787 { 02788 tr.file_output(os); 02789 return os ; 02790 } 02791 02792 02793 02794 template < class Gt, class Tds > 02795 std::istream& 02796 operator>>(std::istream& is, Triangulation_2<Gt, Tds> &tr) 02797 { 02798 tr.file_input(is); 02799 CGAL_triangulation_assertion(tr.is_valid()); 02800 return is; 02801 } 02802 02803 CGAL_END_NAMESPACE 02804 02805 02806 #endif //CGAL_TRIANGULATION_2_H 02807