|
BWAPI
|
00001 // Copyright (c) 2003,2004,2005,2006 INRIA Sophia-Antipolis (France) and 00002 // Notre Dame University (U.S.A.). 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/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2_impl.h $ 00015 // $Id: Segment_Delaunay_graph_2_impl.h 48908 2009-04-26 14:03:12Z spion $ 00016 // 00017 // 00018 // Author(s) : Menelaos Karavelas <mkaravel@cse.nd.edu> 00019 00020 00021 // class implementation continued 00022 //================================= 00023 00024 CGAL_BEGIN_NAMESPACE 00025 00026 //==================================================================== 00027 //==================================================================== 00028 // CONSTRUCTORS 00029 //==================================================================== 00030 //==================================================================== 00031 00032 // copy constructor 00033 template<class Gt, class ST, class D_S, class LTag> 00034 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00035 Segment_Delaunay_graph_2(const Segment_Delaunay_graph_2& other) 00036 : DG(other.geom_traits()) 00037 { 00038 Segment_Delaunay_graph_2& 00039 non_const_other = const_cast<Segment_Delaunay_graph_2&>(other); 00040 copy(non_const_other); 00041 CGAL_postcondition( is_valid() ); 00042 } 00043 00044 // assignment operator 00045 template<class Gt, class ST, class D_S, class LTag> 00046 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Self& 00047 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00048 operator=(const Self& other) 00049 { 00050 if ( this != &other ) { 00051 Segment_Delaunay_graph_2& 00052 non_const_other = const_cast<Segment_Delaunay_graph_2&>(other); 00053 copy(non_const_other); 00054 } 00055 return (*this); 00056 } 00057 00058 //==================================================================== 00059 //==================================================================== 00060 // METHODS FOR INSERTION 00061 //==================================================================== 00062 //==================================================================== 00063 00064 //-------------------------------------------------------------------- 00065 // insertion of first three sites 00066 //-------------------------------------------------------------------- 00067 00068 template<class Gt, class ST, class D_S, class LTag> 00069 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00070 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00071 insert_first(const Storage_site_2& ss, const Point_2& ) 00072 { 00073 CGAL_precondition( number_of_vertices() == 0 ); 00074 00075 Vertex_handle v = this->_tds.insert_second(); 00076 v->set_site(ss); 00077 return v; 00078 } 00079 00080 template<class Gt, class ST, class D_S, class LTag> 00081 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00082 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00083 insert_second(const Storage_site_2& ss, const Point_2& p) 00084 { 00085 CGAL_precondition( number_of_vertices() == 1 ); 00086 // p0 is actually a point 00087 Site_2 p0 = finite_vertices_begin()->site(); 00088 // MK: change the equality test between points by the functor in 00089 // geometric traits 00090 Site_2 tp = Site_2::construct_site_2(p); 00091 if ( same_points(tp,p0) ) { 00092 // merge info of identical sites 00093 merge_info(finite_vertices_begin(), ss); 00094 return finite_vertices_begin(); 00095 } 00096 00097 return create_vertex_dim_up(ss); 00098 } 00099 00100 template<class Gt, class ST, class D_S, class LTag> 00101 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00102 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00103 insert_third(const Storage_site_2& ss, const Point_2& p) 00104 { 00105 Site_2 t = Site_2::construct_site_2(p); 00106 return insert_third(t, ss); 00107 } 00108 00109 template<class Gt, class ST, class D_S, class LTag> 00110 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00111 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00112 insert_third(const Site_2& t, const Storage_site_2& ss) 00113 { 00114 CGAL_precondition( number_of_vertices() == 2 ); 00115 00116 // p0 and p1 are actually points 00117 Vertex_handle v0 = finite_vertices_begin(); 00118 Vertex_handle v1 = ++finite_vertices_begin(); 00119 Site_2 t0 = v0->site(); 00120 Site_2 t1 = v1->site(); 00121 00122 if ( same_points(t, t0) ) { 00123 // merge info of identical sites 00124 merge_info(v0, ss); 00125 return v0; 00126 } 00127 if ( same_points(t, t1) ) { 00128 // merge info of identical sites 00129 merge_info(v1, ss); 00130 return v1; 00131 } 00132 00133 Vertex_handle v = create_vertex_dim_up(ss); 00134 00135 Face_handle f(finite_faces_begin()); 00136 00137 Site_2 s1 = f->vertex(0)->site(); 00138 Site_2 s2 = f->vertex(1)->site(); 00139 Site_2 s3 = f->vertex(2)->site(); 00140 00141 Orientation o = 00142 geom_traits().orientation_2_object()(s1, s2, s3); 00143 00144 if ( o != COLLINEAR ) { 00145 if ( o == RIGHT_TURN ) { 00146 f->reorient(); 00147 for (int i = 0; i < 3; i++) { 00148 f->neighbor(i)->reorient(); 00149 } 00150 } 00151 } else { 00152 typename Geom_traits::Compare_x_2 compare_x = 00153 geom_traits().compare_x_2_object(); 00154 00155 Comparison_result xcmp12 = compare_x(s1, s2); 00156 if ( xcmp12 == SMALLER ) { // x1 < x2 00157 Comparison_result xcmp23 = compare_x(s2, s3); 00158 if ( xcmp23 == SMALLER ) { // x2 < x3 00159 flip(f, f->index(v1)); 00160 } else { 00161 Comparison_result xcmp31 = compare_x(s3, s1); 00162 if ( xcmp31 == SMALLER ) { // x3 < x1 00163 flip(f, f->index(v0)); 00164 } else { // x1 < x3 < x2 00165 flip(f, f->index(v)); 00166 } 00167 } 00168 } else if ( xcmp12 == LARGER ) { // x1 > x2 00169 Comparison_result xcmp32 = compare_x(s3, s2); 00170 if ( xcmp32 == SMALLER ) { // x3 < x2 00171 flip(f, f->index(v1)); 00172 } else { 00173 Comparison_result xcmp13 = compare_x(s1, s3); 00174 if ( xcmp13 == SMALLER ) { // x1 < x3 00175 flip(f, f->index(v0)); 00176 } else { // x2 < x3 < x1 00177 flip(f, f->index(v)); 00178 } 00179 } 00180 } else { // x1 == x2 00181 typename Geom_traits::Compare_y_2 compare_y = 00182 geom_traits().compare_y_2_object(); 00183 00184 Comparison_result ycmp12 = compare_y(s1, s2); 00185 if ( ycmp12 == SMALLER ) { // y1 < y2 00186 Comparison_result ycmp23 = compare_y(s2, s3); 00187 if ( ycmp23 == SMALLER ) { // y2 < y3 00188 flip(f, f->index(v1)); 00189 } else { 00190 Comparison_result ycmp31 = compare_y(s3, s1); 00191 if ( ycmp31 == SMALLER ) { // y3 < y1 00192 flip(f, f->index(v0)); 00193 } else { // y1 < y3 < y2 00194 flip(f, f->index(v)); 00195 } 00196 } 00197 } else if ( ycmp12 == LARGER ) { // y1 > y2 00198 Comparison_result ycmp32 = compare_y(s3, s2); 00199 if ( ycmp32 == SMALLER ) { // y3 < y2 00200 flip(f, f->index(v1)); 00201 } else { 00202 Comparison_result ycmp13 = compare_y(s1, s3); 00203 if ( ycmp13 == SMALLER ) { // y1 < y3 00204 flip(f, f->index(v0)); 00205 } else { // y2 < y3 < y1 00206 flip(f, f->index(v)); 00207 } 00208 } 00209 } else { 00210 // this line should never have been reached 00211 CGAL_error(); 00212 } 00213 } 00214 } 00215 00216 return v; 00217 } 00218 00219 00220 template<class Gt, class ST, class D_S, class LTag> 00221 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00222 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00223 insert_third(const Storage_site_2& ss, Vertex_handle , Vertex_handle ) 00224 { 00225 CGAL_precondition( number_of_vertices() == 2 ); 00226 00227 // this can only be the case if the first site is a segment 00228 CGAL_precondition( dimension() == 1 ); 00229 00230 Vertex_handle v = create_vertex_dim_up(ss); 00231 00232 Face_circulator fc = incident_faces(v); 00233 00234 while ( true ) { 00235 Face_handle f(fc); 00236 if ( !is_infinite(f) ) { 00237 flip(f, f->index(v)); 00238 break; 00239 } 00240 ++fc; 00241 } 00242 00243 return v; 00244 } 00245 00246 //-------------------------------------------------------------------- 00247 // insertion of a point 00248 //-------------------------------------------------------------------- 00249 00250 template<class Gt, class ST, class D_S, class LTag> 00251 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00252 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00253 insert_point(const Storage_site_2& ss, const Point_2& p, Vertex_handle vnear) 00254 { 00255 int n = number_of_vertices(); 00256 if ( n == 0 ) { 00257 return insert_first(ss, p); 00258 } else if ( n == 1 ) { 00259 return insert_second(ss, p); 00260 } else if ( n == 2 ) { 00261 return insert_third(ss, p); 00262 } 00263 00264 Site_2 t = Site_2::construct_site_2(p); 00265 return insert_point(ss, t, vnear); 00266 } 00267 00268 00269 template<class Gt, class ST, class D_S, class LTag> 00270 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00271 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00272 insert_point(const Storage_site_2& ss, const Site_2& t, 00273 Vertex_handle vnear) 00274 { 00275 CGAL_precondition( t.is_point() ); 00276 CGAL_assertion( number_of_vertices() > 2 ); 00277 00278 //********************************************************************* 00279 //********************************************************************* 00280 //********************************************************************* 00281 //********************************************************************* 00282 //********************************************************************* 00283 //********************************************************************* 00284 //********************************************************************* 00285 //********************************************************************* 00286 //********************************************************************* 00287 //********************************************************************* 00288 //********************************************************************* 00289 // MK::ERROR: I need to write a insert_point_no_search method that 00290 // does not search for the nearest neighbor; this should be used by 00291 // insert_point. Below the first version of the code is correct. The 00292 // second is what the insert_point method should do before calling 00293 // insert_point_no_search. 00294 00295 // first find the nearest neighbor 00296 #if 1 00297 Vertex_handle vnearest = nearest_neighbor( t, vnear ); 00298 #else 00299 Vertex_handle vnearest; 00300 if ( vnear == Vertex_handle() ) { 00301 vnearest = nearest_neighbor( t, vnear ); 00302 } else { 00303 vnearest = vnear; 00304 } 00305 #endif 00306 00307 //********************************************************************* 00308 //********************************************************************* 00309 //********************************************************************* 00310 //********************************************************************* 00311 //********************************************************************* 00312 //********************************************************************* 00313 //********************************************************************* 00314 //********************************************************************* 00315 //********************************************************************* 00316 //********************************************************************* 00317 //********************************************************************* 00318 00319 00320 // check is the point has already been inserted or lies on 00321 // a segment already inserted 00322 Arrangement_type at_res = arrangement_type(t, vnearest); 00323 if ( vnearest->is_point() ) { 00324 if ( at_res == AT2::IDENTICAL ) { 00325 // merge info of identical sites 00326 merge_info(vnearest, ss); 00327 return vnearest; 00328 } 00329 } else { 00330 CGAL_assertion( vnearest->is_segment() ); 00331 CGAL_assertion( at_res != AT2::TOUCH_1 ); 00332 CGAL_assertion( at_res != AT2::TOUCH_2 ); 00333 CGAL_assertion( at_res == AT2::DISJOINT || at_res == AT2::INTERIOR ); 00334 if ( at_res == AT2::INTERIOR ) { 00335 CGAL_assertion( t.is_input() ); 00336 00337 Vertex_triple vt = insert_exact_point_on_segment(ss, t, vnearest); 00338 return vt.first; 00339 } else { 00340 // the point to be inserted does not belong to the interior of a 00341 // segment 00342 CGAL_assertion( at_res == AT2::DISJOINT ); 00343 } 00344 } 00345 00346 return insert_point2(ss, t, vnearest); 00347 } 00348 00349 template<class Gt, class ST, class D_S, class LTag> 00350 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00351 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00352 insert_point2(const Storage_site_2& ss, const Site_2& t, 00353 Vertex_handle vnearest) 00354 { 00355 CGAL_precondition( t.is_point() ); 00356 CGAL_assertion( number_of_vertices() > 2 ); 00357 00358 CGAL_expensive_precondition 00359 ( nearest_neighbor(t, vnearest) == vnearest ); 00360 00361 // find the first conflict 00362 00363 #if !defined(CGAL_NO_ASSERTIONS) && !defined(NDEBUG) 00364 // verify that there are no intersections... 00365 Vertex_circulator vc = incident_vertices(vnearest); 00366 Vertex_circulator vc_start = vc; 00367 do { 00368 Vertex_handle vv(vc); 00369 Arrangement_type at_res = arrangement_type(t, vv); 00370 00371 CGAL_assertion( at_res == AT2::DISJOINT ); 00372 ++vc; 00373 } while ( vc != vc_start ); 00374 #endif 00375 00376 // first look for conflict with vertex 00377 Face_circulator fc_start = incident_faces(vnearest); 00378 Face_circulator fc = fc_start; 00379 Face_handle start_f; 00380 Sign s; 00381 00382 std::map<Face_handle,Sign> sign_map; 00383 00384 do { 00385 Face_handle f(fc); 00386 00387 s = incircle(f, t); 00388 00389 sign_map[f] = s; 00390 00391 if ( s == NEGATIVE ) { 00392 start_f = f; 00393 break; 00394 } 00395 ++fc; 00396 } while ( fc != fc_start ); 00397 00398 // we are not in conflict with a Voronoi vertex, so we have to 00399 // be in conflict with the interior of a Voronoi edge 00400 if ( s != NEGATIVE ) { 00401 Edge_circulator ec_start = incident_edges(vnearest); 00402 Edge_circulator ec = ec_start; 00403 00404 bool interior_in_conflict(false); 00405 Edge e; 00406 do { 00407 e = *ec; 00408 00409 Sign s1 = sign_map[e.first]; 00410 Sign s2 = sign_map[e.first->neighbor(e.second)]; 00411 00412 if ( s1 == s2 ) { 00413 interior_in_conflict = edge_interior(e, t, s1); 00414 } else { 00415 // It seems that there was a problem here when one of the 00416 // signs was positive and the other zero. In this case we 00417 // still check pretending that both signs where positive 00418 interior_in_conflict = edge_interior(e, t, POSITIVE); 00419 } 00420 00421 if ( interior_in_conflict ) { break; } 00422 ++ec; 00423 } while ( ec != ec_start ); 00424 00425 sign_map.clear(); 00426 00427 CGAL_assertion( interior_in_conflict ); 00428 00429 return insert_degree_2(e, ss); 00430 } 00431 00432 00433 // we are in conflict with a Voronoi vertex; start from that and 00434 // find the entire conflict region and then repair the diagram 00435 List l; 00436 Face_map fm; 00437 00438 Triple<bool, Vertex_handle, Arrangement_type> 00439 vcross(false, Vertex_handle(), AT2::DISJOINT); 00440 00441 // MK:: NEED TO WRITE A FUNCTION CALLED find_conflict_region WHICH 00442 // IS GIVEN A STARTING FACE, A LIST, A FACE MAP, A VERTEX MAP AND A 00443 // LIST OF FLIPPED EDGES AND WHAT IS DOES IS INITIALIZE THE CONFLICT 00444 // REGION AND EXPANDS THE CONFLICT REGION. 00445 initialize_conflict_region(start_f, l); 00446 expand_conflict_region(start_f, t, ss, l, fm, sign_map, vcross); 00447 00448 CGAL_assertion( !vcross.first ); 00449 00450 Vertex_handle v = create_vertex(ss); 00451 00452 retriangulate_conflict_region(v, l, fm); 00453 00454 return v; 00455 } 00456 00457 //-------------------------------------------------------------------- 00458 // insertion of a point that lies on a segment 00459 //-------------------------------------------------------------------- 00460 00461 template<class Gt, class ST, class D_S, class LTag> 00462 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Face_pair 00463 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00464 find_faces_to_split(const Vertex_handle& v, const Site_2& t) const 00465 { 00466 CGAL_precondition( v->is_segment() ); 00467 00468 #ifndef CGAL_NO_ASSERTIONS 00469 { 00470 // count number of adjacent infinite faces 00471 Face_circulator fc = incident_faces(v); 00472 Face_circulator fc_start = fc; 00473 int n_inf = 0; 00474 do { 00475 if ( is_infinite(fc) ) { n_inf++; } 00476 fc++; 00477 } while ( fc != fc_start ); 00478 CGAL_assertion( n_inf == 0 || n_inf == 2 || n_inf == 4 ); 00479 } 00480 #endif 00481 00482 Face_circulator fc1 = incident_faces(v); 00483 Face_circulator fc2 = fc1; ++fc2; 00484 Face_circulator fc_start = fc1; 00485 Face_handle f1, f2; 00486 bool found_f1 = false, found_f2 = false; 00487 Site_2 sitev_supp = v->site().supporting_site(); 00488 do { 00489 Face_handle ff1(fc1), ff2(fc2); 00490 00491 Oriented_side os1, os2; 00492 00493 if ( is_infinite(ff1) ) { 00494 int id_v = ff1->index(v); 00495 int cw_v = this->cw( id_v ); 00496 int ccw_v = this->ccw( id_v ); 00497 00498 Site_2 sv_ep; 00499 if ( is_infinite( ff1->vertex(cw_v) ) ) { 00500 CGAL_assertion( !is_infinite( ff1->vertex(ccw_v) ) ); 00501 CGAL_assertion( ff1->vertex(ccw_v)->site().is_point() ); 00502 sv_ep = ff1->vertex(ccw_v)->site(); 00503 } else { 00504 CGAL_assertion( !is_infinite( ff1->vertex( cw_v) ) ); 00505 CGAL_assertion( ff1->vertex( cw_v)->site().is_point() ); 00506 sv_ep = ff1->vertex( cw_v)->site(); 00507 } 00508 00509 os1 = oriented_side(sv_ep, sitev_supp, t); 00510 } else { 00511 os1 = oriented_side(fc1->vertex(0)->site(), 00512 fc1->vertex(1)->site(), 00513 fc1->vertex(2)->site(), 00514 sitev_supp, t); 00515 } 00516 00517 if ( is_infinite(ff2) ) { 00518 int id_v = ff2->index(v); 00519 int cw_v = this->cw( id_v ); 00520 int ccw_v = this->ccw( id_v ); 00521 00522 Site_2 sv_ep; 00523 if ( is_infinite( ff2->vertex(cw_v) ) ) { 00524 CGAL_assertion( !is_infinite( ff2->vertex(ccw_v) ) ); 00525 CGAL_assertion( ff2->vertex(ccw_v)->site().is_point() ); 00526 sv_ep = ff2->vertex(ccw_v)->site(); 00527 } else { 00528 CGAL_assertion( !is_infinite( ff2->vertex( cw_v) ) ); 00529 CGAL_assertion( ff2->vertex( cw_v)->site().is_point() ); 00530 sv_ep = ff2->vertex( cw_v)->site(); 00531 } 00532 00533 os2 = oriented_side(sv_ep, sitev_supp, t); 00534 } else { 00535 os2 = oriented_side(fc2->vertex(0)->site(), 00536 fc2->vertex(1)->site(), 00537 fc2->vertex(2)->site(), 00538 sitev_supp, t); 00539 } 00540 00541 if ( !found_f1 && 00542 os1 != ON_POSITIVE_SIDE && os2 == ON_POSITIVE_SIDE ) { 00543 f1 = ff2; 00544 found_f1 = true; 00545 } 00546 00547 if ( !found_f2 && 00548 os1 == ON_POSITIVE_SIDE && os2 != ON_POSITIVE_SIDE ) { 00549 f2 = ff2; 00550 found_f2 = true; 00551 } 00552 00553 if ( found_f1 && found_f2 ) { break; } 00554 00555 ++fc1, ++fc2; 00556 } while ( fc_start != fc1 ); 00557 00558 00559 CGAL_assertion( found_f1 && found_f2 ); 00560 CGAL_assertion( f1 != f2 ); 00561 00562 return Face_pair(f1, f2); 00563 } 00564 00565 template<class Gt, class ST, class D_S, class LTag> 00566 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_triple 00567 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00568 insert_exact_point_on_segment(const Storage_site_2& ss, const Site_2& t, 00569 Vertex_handle v) 00570 { 00571 // splits the segment site v->site() in two and inserts represented by t 00572 // on return the three vertices are, respectively, the vertex 00573 // corresponding to t and the two subsegments of v->site() 00574 00575 CGAL_assertion( t.is_point() ); 00576 CGAL_assertion( t.is_input() ); 00577 00578 Storage_site_2 ssitev = v->storage_site(); 00579 00580 CGAL_assertion( ssitev.is_segment() ); 00581 00582 Face_pair fpair = find_faces_to_split(v, t); 00583 00584 boost::tuples::tuple<Vertex_handle,Vertex_handle,Face_handle,Face_handle> 00585 qq = this->_tds.split_vertex(v, fpair.first, fpair.second); 00586 00587 // now I need to update the sites for vertices v1 and v2 00588 Vertex_handle v1 = boost::tuples::get<0>(qq); //qq.first; 00589 Storage_site_2 ssv1 = split_storage_site(ssitev, ss, true); 00590 v1->set_site( ssv1 ); 00591 00592 Vertex_handle v2 = boost::tuples::get<1>(qq); //qq.second; 00593 Storage_site_2 ssv2 = split_storage_site(ssitev, ss, false); 00594 v2->set_site( ssv2 ); 00595 00596 Face_handle qqf = boost::tuples::get<2>(qq); //qq.third; 00597 Vertex_handle vsx = 00598 this->_tds.insert_in_edge(qqf, cw(qqf->index(v1))); 00599 00600 vsx->set_site(ss); 00601 // merge info of point and segment; the point lies on the segment 00602 merge_info(vsx, ssitev); 00603 00604 return Vertex_triple(vsx, v1, v2); 00605 } 00606 00607 template<class Gt, class ST, class D_S, class LTag> 00608 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_triple 00609 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00610 insert_point_on_segment(const Storage_site_2& ss, const Site_2& , 00611 Vertex_handle v, const Tag_true&) 00612 { 00613 // splits the segment site v->site() in two and inserts the point of 00614 // intersection of t and v->site() 00615 // on return the three vertices are, respectively, the point of 00616 // intersection and the two subsegments of v->site() 00617 00618 Storage_site_2 ssitev = v->storage_site(); 00619 Storage_site_2 ssx = st_.construct_storage_site_2_object()(ss, ssitev); 00620 00621 Site_2 sitev = ssitev.site(); 00622 00623 Face_pair fpair = find_faces_to_split(v, ssx.site()); 00624 00625 boost::tuples::tuple<Vertex_handle,Vertex_handle,Face_handle,Face_handle> 00626 qq = this->_tds.split_vertex(v, fpair.first, fpair.second); 00627 00628 // now I need to update the sites for vertices v1 and v2 00629 Vertex_handle v1 = boost::tuples::get<0>(qq); //qq.first; 00630 Vertex_handle v2 = boost::tuples::get<1>(qq); //qq.second; 00631 00632 Storage_site_2 ssv1 = 00633 st_.construct_storage_site_2_object()(ssitev, ss, true); 00634 00635 Storage_site_2 ssv2 = 00636 st_.construct_storage_site_2_object()(ssitev, ss, false); 00637 00638 Site_2 sv1 = ssv1.site(); 00639 Site_2 sv2 = ssv2.site(); 00640 v1->set_site( ssv1 ); 00641 v2->set_site( ssv2 ); 00642 00643 Face_handle qqf = boost::tuples::get<2>(qq); //qq.third; 00644 Vertex_handle vsx = 00645 this->_tds.insert_in_edge(qqf, cw(qqf->index(v1))); 00646 00647 vsx->set_site(ssx); 00648 00649 return Vertex_triple(vsx, v1, v2); 00650 } 00651 00652 //-------------------------------------------------------------------- 00653 // insertion of a segment 00654 //-------------------------------------------------------------------- 00655 template<class Gt, class ST, class D_S, class LTag> 00656 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00657 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00658 insert_segment(const Storage_site_2& ss, const Site_2& t, Vertex_handle vnear) 00659 { 00660 CGAL_precondition( t.is_segment() ); 00661 CGAL_precondition( t.is_input() ); 00662 00663 if ( is_degenerate_segment(t) ) { 00664 Storage_site_2 ss_src = ss.source_site(); 00665 convert_info(ss_src, ss, true); 00666 return insert_point(ss_src, t.source(), vnear); 00667 } 00668 00669 Storage_site_2 ss_src = ss.source_site(); 00670 convert_info(ss_src, ss, true); 00671 Storage_site_2 ss_trg = ss.target_site(); 00672 convert_info(ss_trg, ss, false); 00673 00674 Vertex_handle v0 = insert_point( ss_src, t.source(), vnear ); 00675 CGAL_assertion( is_valid() ); 00676 Vertex_handle v1 = insert_point( ss_trg, t.target(), v0 ); 00677 CGAL_assertion( is_valid() ); 00678 00679 if ( number_of_vertices() == 2 ) { 00680 return insert_third(ss, v0, v1); 00681 } 00682 00683 return insert_segment_interior(t, ss, v0); 00684 } 00685 00686 00687 template<class Gt, class ST, class D_S, class LTag> 00688 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00689 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00690 insert_segment_interior(const Site_2& t, const Storage_site_2& ss, 00691 Vertex_handle vnearest) 00692 { 00693 CGAL_precondition( t.is_segment() ); 00694 CGAL_precondition( number_of_vertices() > 2 ); 00695 00696 CGAL_assertion( vnearest != Vertex_handle() ); 00697 00698 // find the first conflict 00699 00700 // first look if there are intersections... 00701 Vertex_circulator vc = incident_vertices(vnearest); 00702 Vertex_circulator vc_start = vc; 00703 do { 00704 Vertex_handle vv(vc); 00705 if ( is_infinite(vv) ) { 00706 vc++; 00707 continue; 00708 } 00709 00710 Arrangement_type at_res = arrangement_type(t, vv); 00711 00712 if ( vv->is_segment() ) { 00713 if ( at_res == AT2::DISJOINT || at_res == AT2::TOUCH_1 || 00714 at_res == AT2::TOUCH_2 || at_res == AT2::TOUCH_11 || 00715 at_res == AT2::TOUCH_12 || at_res == AT2::TOUCH_21 || 00716 at_res == AT2::TOUCH_22 ) { 00717 // do nothing 00718 } else if ( at_res == AT2::IDENTICAL ) { 00719 // merge info of identical items 00720 merge_info(vv, ss); 00721 return vv; 00722 } else if ( at_res == AT2::CROSSING ) { 00723 Intersections_tag itag; 00724 return insert_intersecting_segment(ss, t, vv, itag); 00725 } else if ( at_res == AT2::TOUCH_11_INTERIOR_1 ) { 00726 Vertex_handle vp = second_endpoint_of_segment(vv); 00727 Storage_site_2 ssvp = vp->storage_site(); 00728 Storage_site_2 sss = split_storage_site(ss, ssvp, false); 00729 00730 Storage_site_2 sss1 = split_storage_site(ss, ssvp, true); 00731 // merge the info of the first (common) subsegment 00732 merge_info(vv, sss1); 00733 // merge the info of the (common) splitting endpoint 00734 merge_info(vp, ss); 00735 00736 return insert_segment_interior(sss.site(), sss, vp); 00737 } else if ( at_res == AT2::TOUCH_12_INTERIOR_1 ) { 00738 Vertex_handle vp = first_endpoint_of_segment(vv); 00739 Storage_site_2 ssvp = vp->storage_site(); 00740 Storage_site_2 sss = split_storage_site(ss, ssvp, true); 00741 00742 Storage_site_2 sss1 = split_storage_site(ss, ssvp, false); 00743 // merge the info of the second (common) subsegment 00744 // merge_info(vv, sss); 00745 // merge the info of the (common) splitting endpoint 00746 merge_info(vp, ss); 00747 00748 return insert_segment_interior(sss.site(), sss, vp); 00749 } else { 00750 // this should never be reached; the only possible values for 00751 // at_res are DISJOINT, CROSSING, TOUCH_11_INTERIOR_1 00752 // and TOUCH_12_INTERIOR_1 00753 CGAL_error(); 00754 } 00755 } else { 00756 CGAL_assertion( vv->is_point() ); 00757 if ( at_res == AT2::INTERIOR ) { 00758 Storage_site_2 ssvv = vv->storage_site(); 00759 if ( ssvv.is_input() ) { 00760 Storage_site_2 ss1 = split_storage_site(ss, ssvv, true); 00761 Storage_site_2 ss2 = split_storage_site(ss, ssvv, false); 00762 // merge the info of the splitting point and the segment 00763 merge_info(vv, ss); 00764 insert_segment_interior(ss1.site(), ss1, vv); 00765 return insert_segment_interior(ss2.site(), ss2, vv); 00766 } else { 00767 // this should never be reached; the only possible values for 00768 // at_res are DISJOINT and INTERIOR 00769 CGAL_error(); 00770 } 00771 } 00772 } 00773 ++vc; 00774 } while ( vc != vc_start ); 00775 00776 // first look for conflict with vertex 00777 Face_circulator fc_start = incident_faces(vnearest); 00778 Face_circulator fc = fc_start; 00779 Face_handle start_f; 00780 Sign s; 00781 00782 std::map<Face_handle,Sign> sign_map; 00783 00784 do { 00785 Face_handle f(fc); 00786 00787 s = incircle(f, t); 00788 00789 sign_map[f] = s; 00790 00791 if ( s == NEGATIVE ) { 00792 start_f = f; 00793 break; 00794 } 00795 ++fc; 00796 } while ( fc != fc_start ); 00797 00798 // segments must have a conflict with at least one vertex 00799 CGAL_assertion( s == NEGATIVE ); 00800 00801 // we are in conflict with a Voronoi vertex; start from that and 00802 // find the entire conflict region and then repair the diagram 00803 List l; 00804 Face_map fm; 00805 00806 Triple<bool, Vertex_handle, Arrangement_type> 00807 vcross(false, Vertex_handle(), AT2::DISJOINT); 00808 00809 // MK:: NEED TO WRITE A FUNCTION CALLED find_conflict_region WHICH 00810 // IS GIVEN A STARTING FACE, A LIST, A FACE MAP, A VERTEX MAP AND A 00811 // LIST OF FLIPPED EDGES AND WHAT IS DOES IS INITIALIZE THE CONFLICT 00812 // REGION AND EXPANDS THE CONFLICT REGION. 00813 initialize_conflict_region(start_f, l); 00814 expand_conflict_region(start_f, t, ss, l, fm, sign_map, vcross); 00815 00816 CGAL_assertion( vcross.third == AT2::DISJOINT || 00817 vcross.third == AT2::CROSSING || 00818 vcross.third == AT2::INTERIOR ); 00819 00820 // the following condition becomes true only if intersecting 00821 // segments are found 00822 if ( vcross.first ) { 00823 if ( t.is_segment() ) { 00824 if ( vcross.third == AT2::CROSSING ) { 00825 Intersections_tag itag; 00826 return insert_intersecting_segment(ss, t, vcross.second, itag); 00827 } else if ( vcross.third == AT2::INTERIOR ) { 00828 Storage_site_2 ssvv = vcross.second->storage_site(); 00829 Storage_site_2 ss1 = split_storage_site(ss, ssvv, true); 00830 Storage_site_2 ss2 = split_storage_site(ss, ssvv, false); 00831 // merge the info of the splitting point and the segment 00832 merge_info(vcross.second, ss); 00833 insert_segment_interior(ss1.site(), ss1, vcross.second); 00834 return insert_segment_interior(ss2.site(), ss2, vcross.second); 00835 } else { 00836 // this should never be reached; the only possible values for 00837 // vcross.third are CROSSING, INTERIOR and DISJOINT 00838 CGAL_error(); 00839 } 00840 } 00841 } 00842 00843 // no intersecting segment has been found; we insert the segment as 00844 // usual... 00845 Vertex_handle v = create_vertex(ss); 00846 00847 retriangulate_conflict_region(v, l, fm); 00848 00849 return v; 00850 } 00851 00852 00853 //-------------------------------------------------------------------- 00854 // insertion of an intersecting segment 00855 //-------------------------------------------------------------------- 00856 template<class Gt, class ST, class D_S, class LTag> 00857 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00858 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00859 insert_intersecting_segment_with_tag(const Storage_site_2& /* ss */, 00860 const Site_2& /* t */, Vertex_handle /* v */, 00861 Tag_false) 00862 { 00863 #if defined(__POWERPC__) && \ 00864 defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ == 4) 00865 // hack to avoid nasty warning for G++ 3.4 on Darwin 00866 static int i; 00867 #else 00868 static int i = 0; 00869 #endif 00870 if ( i == 0 ) { 00871 i = 1; 00872 print_error_message(); 00873 } 00874 return Vertex_handle(); 00875 } 00876 00877 template<class Gt, class ST, class D_S, class LTag> 00878 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 00879 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00880 insert_intersecting_segment_with_tag(const Storage_site_2& ss, 00881 const Site_2& t, Vertex_handle v, 00882 Tag_true tag) 00883 { 00884 CGAL_precondition( t.is_segment() && v->is_segment() ); 00885 00886 const Storage_site_2& ssitev = v->storage_site(); 00887 Site_2 sitev = ssitev.site(); 00888 00889 if ( same_segments(t, sitev) ) { 00890 merge_info(v, ss); 00891 return v; 00892 } 00893 00894 Vertex_triple vt = insert_point_on_segment(ss, t, v, tag); 00895 00896 Vertex_handle vsx = vt.first; 00897 00898 Storage_site_2 ss3 = st_.construct_storage_site_2_object()(ss, ssitev, true); 00899 Storage_site_2 ss4 = st_.construct_storage_site_2_object()(ss, ssitev, false); 00900 Site_2 s3 = ss3.site(); 00901 Site_2 s4 = ss4.site(); 00902 00903 insert_segment_interior(s3, ss3, vsx); 00904 insert_segment_interior(s4, ss4, vsx); 00905 return vsx; 00906 } 00907 00908 //-------------------------------------------------------------------- 00909 //-------------------------------------------------------------------- 00910 // helper methods for insertion (find conflict region) 00911 //-------------------------------------------------------------------- 00912 //-------------------------------------------------------------------- 00913 00914 template<class Gt, class ST, class D_S, class LTag> 00915 void 00916 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00917 initialize_conflict_region(const Face_handle& f, List& l) 00918 { 00919 00920 00921 l.clear(); 00922 for (int i = 0; i < 3; i++) { 00923 l.push_back(sym_edge(f, i)); 00924 } 00925 } 00926 00927 00928 template<class Gt, class ST, class D_S, class LTag> 00929 void 00930 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 00931 expand_conflict_region(const Face_handle& f, const Site_2& t, 00932 const Storage_site_2& ss, 00933 List& l, Face_map& fm, 00934 std::map<Face_handle,Sign>& sign_map, 00935 Triple<bool,Vertex_handle,Arrangement_type>& vcross) 00936 { 00937 if ( fm.find(f) != fm.end() ) { return; } 00938 00939 // this is done to stop the recursion when intersecting segments 00940 // are found 00941 if ( vcross.first ) { return; } 00942 00943 // setting fm[f] to true means that the face has been reached and 00944 // that the face is available for recycling. If we do not want the 00945 // face to be available for recycling we must set this flag to 00946 // false. 00947 fm[f] = true; 00948 00949 // CGAL_assertion( fm.find(f) != fm.end() ); 00950 00951 for (int i = 0; i < 3; i++) { 00952 Face_handle n = f->neighbor(i); 00953 00954 bool face_registered = (fm.find(n) != fm.end()); 00955 00956 if ( !face_registered ) { 00957 for (int j = 0; j < 3; j++) { 00958 Vertex_handle vf = n->vertex(j); 00959 00960 if ( is_infinite(vf) ) { continue; } 00961 00962 Arrangement_type at_res = arrangement_type(t, vf); 00963 00964 CGAL_assertion( vcross.third == AT2::DISJOINT || 00965 vcross.third == AT2::CROSSING || 00966 vcross.third == AT2::INTERIOR ); 00967 00968 if ( vf->is_segment() ) { 00969 CGAL_assertion( at_res != AT2::IDENTICAL ); 00970 CGAL_assertion( at_res != AT2::TOUCH_11_INTERIOR_1 ); 00971 CGAL_assertion( at_res != AT2::TOUCH_12_INTERIOR_1 ); 00972 00973 if ( at_res == AT2::CROSSING ) { 00974 vcross.first = true; 00975 vcross.second = vf; 00976 vcross.third = AT2::CROSSING; 00977 l.clear(); 00978 fm.clear(); 00979 return; 00980 } else { 00981 CGAL_assertion ( at_res == AT2::DISJOINT || 00982 at_res == AT2::TOUCH_1 || 00983 at_res == AT2::TOUCH_2 || 00984 at_res == AT2::TOUCH_11 || 00985 at_res == AT2::TOUCH_12 || 00986 at_res == AT2::TOUCH_21 || 00987 at_res == AT2::TOUCH_22 ); 00988 // we do nothing in these cases 00989 } 00990 } else { 00991 CGAL_assertion( vf->is_point() ); 00992 if ( at_res == AT2::INTERIOR ) { 00993 vcross.first = true; 00994 vcross.second = vf; 00995 vcross.third = AT2::INTERIOR; 00996 l.clear(); 00997 fm.clear(); 00998 return; 00999 } 01000 } 01001 } 01002 } 01003 01004 Sign s = incircle(n, t); 01005 01006 sign_map[n] = s; 01007 01008 Sign s_f = sign_map[f]; 01009 01010 if ( s == POSITIVE ) { continue; } 01011 if ( s != s_f ) { continue; } 01012 01013 bool interior_in_conflict = edge_interior(f, i, t, s); 01014 01015 if ( !interior_in_conflict ) { continue; } 01016 01017 if ( face_registered ) { continue; } 01018 01019 Edge e = sym_edge(f, i); 01020 01021 CGAL_assertion( l.is_in_list(e) ); 01022 int j = this->_tds.mirror_index(f, i); 01023 Edge e_before = sym_edge(n, ccw(j)); 01024 Edge e_after = sym_edge(n, cw(j)); 01025 if ( !l.is_in_list(e_before) ) { 01026 l.insert_before(e, e_before); 01027 } 01028 if ( !l.is_in_list(e_after) ) { 01029 l.insert_after(e, e_after); 01030 } 01031 l.remove(e); 01032 01033 expand_conflict_region(n, t, ss, l, fm, sign_map, vcross); 01034 01035 // this is done to stop the recursion when intersecting segments 01036 // are found 01037 // if ( fm.size() == 0 && l.size() == 0 ) { return; } 01038 if ( vcross.first ) { return; } 01039 } // for-loop 01040 } 01041 01042 01043 //-------------------------------------------------------------------- 01044 // retriangulate conflict region 01045 //-------------------------------------------------------------------- 01046 01047 template<class Gt, class ST, class D_S, class LTag> 01048 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 01049 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01050 add_bogus_vertex(Edge e, List& l) 01051 { 01052 Edge esym = sym_edge(e); 01053 Face_handle g1 = e.first; 01054 Face_handle g2 = esym.first; 01055 01056 Vertex_handle v = insert_degree_2(e); 01057 01058 Face_circulator fc(v); 01059 Face_handle f1(fc); 01060 Face_handle f2(++fc); 01061 int i1 = f1->index(v); 01062 int i2 = f2->index(v); 01063 01064 CGAL_assertion( ((f1->neighbor(i1) == g1) && (f2->neighbor(i2) == g2)) || 01065 ((f1->neighbor(i1) == g2) && (f2->neighbor(i2) == g1)) ); 01066 01067 Edge ee, eesym; 01068 if ( f1->neighbor(i1) == g1 ) { 01069 ee = Edge(f2, i2); 01070 eesym = Edge(f1, i1); 01071 } else { 01072 ee = Edge(f1, i1); 01073 eesym = Edge(f2, i2); 01074 } 01075 01076 l.replace(e, ee); 01077 l.replace(esym, eesym); 01078 01079 return v; 01080 } 01081 01082 01083 template<class Gt, class ST, class D_S, class LTag> 01084 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_list 01085 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01086 add_bogus_vertices(List& l) 01087 { 01088 Vertex_list vertex_list; 01089 01090 std::set<Edge> edge_list; 01091 01092 edge_list.clear(); 01093 01094 Edge e_start = l.front(); 01095 Edge e = e_start; 01096 01097 do { 01098 Edge esym = sym_edge(e); 01099 if ( l.is_in_list(esym) && 01100 edge_list.find(esym) == edge_list.end() ) { 01101 edge_list.insert(e); 01102 } 01103 e = l.next(e); 01104 } while ( e != e_start ); 01105 01106 typename std::set<Edge>::iterator it; 01107 01108 for (it = edge_list.begin(); it != edge_list.end(); ++it) { 01109 Vertex_handle v = add_bogus_vertex(*it, l); 01110 vertex_list.push_back(v); 01111 } 01112 01113 return vertex_list; 01114 } 01115 01116 template<class Gt, class ST, class D_S, class LTag> 01117 void 01118 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01119 remove_bogus_vertices(Vertex_list& vl) 01120 { 01121 while ( vl.size() > 0 ) { 01122 Vertex_handle v = vl.front(); 01123 vl.pop_front(); 01124 remove_degree_2(v); 01125 } 01126 } 01127 01128 01129 template<class Gt, class ST, class D_S, class LTag> 01130 void 01131 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01132 retriangulate_conflict_region(Vertex_handle v, List& l, 01133 Face_map& fm) 01134 { 01135 // 1. add the bogus vetrices 01136 Vertex_list dummy_vertices = add_bogus_vertices(l); 01137 01138 // 2. repair the face pointers... 01139 Edge e_start = l.front(); 01140 Edge eit = e_start; 01141 do { 01142 Edge esym = sym_edge(eit); 01143 Face_handle f = eit.first; 01144 int k = eit.second; 01145 CGAL_assertion( !l.is_in_list(esym) ); 01146 CGAL_assertion( fm.find(f) == fm.end() ); 01147 f->vertex(ccw(k))->set_face(f); 01148 f->vertex( cw(k))->set_face(f); 01149 eit = l.next(eit); 01150 } while ( eit != e_start ); 01151 01152 // 3. copy the edge list to a vector of edges and clear the edge list 01153 std::vector<Edge> ve; 01154 01155 Edge efront = l.front(); 01156 Edge e = efront; 01157 do { 01158 ve.push_back(e); 01159 e = l.next(e); 01160 } while ( e != efront ); 01161 01162 l.clear(); 01163 01164 // 4. retriangulate the hole 01165 this->_tds.star_hole(v, ve.begin(), ve.end()); 01166 01167 // 5. remove the bogus vertices 01168 remove_bogus_vertices(dummy_vertices); 01169 01170 // 6. remove the unused faces 01171 typename Face_map::iterator it; 01172 for (it = fm.begin(); it != fm.end(); ++it) { 01173 Face_handle fh = (*it).first; 01174 this->_tds.delete_face(fh); 01175 } 01176 01177 fm.clear(); 01178 01179 // 7. DONE!!!! 01180 } 01181 01182 //==================================================================== 01183 //==================================================================== 01184 // METHODS FOR REMOVAL 01185 //==================================================================== 01186 //==================================================================== 01187 01188 template<class Gt, class ST, class D_S, class LTag> 01189 bool 01190 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01191 is_star(const Vertex_handle& v) const 01192 { 01193 CGAL_precondition( v->storage_site().is_point() ); 01194 01195 Vertex_circulator vc_start = incident_vertices(v); 01196 Vertex_circulator vc = vc_start; 01197 Storage_site_2 p = v->storage_site(); 01198 01199 size_type count = 0; 01200 do { 01201 Storage_site_2 ss = vc->storage_site(); 01202 if ( ss.is_segment() && is_endpoint_of_segment(p, ss) ) { 01203 ++count; 01204 // if ( count == 3 ) { break; } 01205 if ( count == 3 ) { return true; } 01206 } 01207 ++vc; 01208 } while ( vc != vc_start ); 01209 01210 return false; 01211 } 01212 01213 01214 template<class Gt, class ST, class D_S, class LTag> 01215 bool 01216 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01217 is_linear_chain(const Vertex_handle& v0, const Vertex_handle& v1, 01218 const Vertex_handle& v2) const 01219 { 01220 Site_2 tt[3] = { v0->site(), v1->site(), v2->site() }; 01221 01222 if ( tt[1].is_point() && 01223 tt[0].is_segment() && 01224 tt[2].is_segment() && 01225 is_endpoint_of_segment(tt[1], tt[0]) && 01226 is_endpoint_of_segment(tt[1], tt[2]) ) { 01227 typename Geom_traits::Equal_2 are_equal = geom_traits().equal_2_object(); 01228 Site_2 s_end[2]; 01229 if ( are_equal( tt[1], tt[0].source_site() ) ) { 01230 s_end[0] = tt[0].target_site(); 01231 } else { 01232 s_end[0] = tt[0].source_site(); 01233 } 01234 01235 if ( are_equal( tt[1], tt[2].source_site() ) ) { 01236 s_end[1] = tt[2].target_site(); 01237 } else { 01238 s_end[1] = tt[2].source_site(); 01239 } 01240 01241 typename Geom_traits::Orientation_2 orientation = 01242 geom_traits().orientation_2_object(); 01243 01244 return orientation(s_end[0], s_end[1], tt[1]) == COLLINEAR; 01245 } 01246 return false; 01247 } 01248 01249 01250 template<class Gt, class ST, class D_S, class LTag> 01251 bool 01252 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01253 is_flippable(const Face_handle& f, int i) const 01254 { 01255 CGAL_assertion( !is_infinite(f->vertex( cw(i) )) ); 01256 01257 Vertex_handle v_other = f->vertex( ccw(i) ); 01258 Vertex_handle v0 = f->vertex( i ); 01259 Vertex_handle v1 = this->_tds.mirror_vertex( f, i ); 01260 01261 if ( is_infinite(v_other) || is_infinite(v0) || is_infinite(v1) ) { 01262 return false; 01263 } 01264 01265 Vertex_handle v = f->vertex( cw(i) ); 01266 01267 Storage_site_2 ss = v->storage_site(); 01268 Storage_site_2 ss_other = v_other->storage_site(); 01269 if ( ss_other.is_point() && ss.is_segment() && 01270 is_endpoint_of_segment(ss_other, ss) && is_star(v_other) ) { 01271 return false; 01272 } 01273 01274 if ( is_linear_chain(v0, v_other, v1) ) { return false; } 01275 01276 return (v0 != v1) && is_degenerate_edge(f, i); 01277 } 01278 01279 01280 template<class Gt, class ST, class D_S, class LTag> 01281 void 01282 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01283 minimize_degree(const Vertex_handle& v) 01284 { 01285 CGAL_precondition ( degree(v) > 3 ); 01286 01287 Face_circulator fc_start = incident_faces(v); 01288 Face_circulator fc = incident_faces(v); 01289 bool found(false); 01290 do { 01291 Face_handle f = Face_handle(fc); 01292 int i = ccw( f->index(v) ); 01293 01294 CGAL_assertion( f->vertex( cw(i) ) == v ); 01295 01296 if ( is_flippable(f,i) ) { 01297 Edge e = flip(f, i); 01298 f = e.first; 01299 01300 if ( !f->has_vertex(v) ) { 01301 f = e.first->neighbor(e.second); 01302 CGAL_assertion( f->has_vertex(v) ); 01303 } 01304 01305 fc = --( incident_faces(v,f) ); 01306 fc_start = fc; 01307 found = true; 01308 } else { 01309 ++fc; 01310 found = false; 01311 } 01312 } while ( found || fc != fc_start ); 01313 } 01314 01315 template<class Gt, class ST, class D_S, class LTag> 01316 void 01317 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01318 equalize_degrees(const Vertex_handle& v, Self& small_d, 01319 std::map<Vertex_handle,Vertex_handle>& vmap, 01320 List& l) const 01321 { 01322 size_type deg = degree(v); 01323 CGAL_assertion( l.size() <= deg ); 01324 if ( l.size() == deg ) { return; } 01325 #if 0 01326 std::cerr << "size of l : " << l.size() << std::endl; 01327 std::cerr << "degree of v: " << deg << std::endl; 01328 #endif 01329 01330 // typedef std::map<Edge,Edge> Edge_map; 01331 // maps edges on the boundary of the conflict region from the small 01332 // diagram to edges of the star of v in the small diagram 01333 // Edge_map emap; 01334 01335 Edge e_small_start = l.front(); 01336 Edge e_small = e_small_start; 01337 bool found; 01338 Edge e_small_begin; 01339 Edge e_large_begin; 01340 do { 01341 found = false; 01342 Vertex_handle v_sml_src = e_small.first->vertex(cw(e_small.second)); 01343 Vertex_handle v_sml_trg = e_small.first->vertex(ccw(e_small.second)); 01344 01345 // first we find a first edge in common 01346 Face_circulator fc_start = incident_faces(v); 01347 Face_circulator fc = fc_start; 01348 01349 do { 01350 int id = fc->index(v); 01351 Vertex_handle v_lrg_src = fc->vertex(ccw(id)); 01352 Vertex_handle v_lrg_trg = fc->vertex(cw(id)); 01353 if ( vmap[v_sml_src] == v_lrg_src && vmap[v_sml_trg] == v_lrg_trg ) { 01354 found = true; 01355 e_large_begin = Edge(fc, id); 01356 e_small_begin = e_small; 01357 break; 01358 } 01359 } while ( ++fc != fc_start ); 01360 if ( found ) { break; } 01361 e_small = l.next(e_small); 01362 } while ( e_small != e_small_start ); 01363 01364 CGAL_assertion( found ); 01365 01366 Face_circulator fc_start = incident_faces(v, e_large_begin.first); 01367 Face_circulator fc = fc_start; 01368 e_small = e_small_begin; 01369 do { 01370 int id = fc->index(v); 01371 Vertex_handle vsml_src = e_small.first->vertex(cw(e_small.second)); 01372 Vertex_handle vsml_trg = e_small.first->vertex(ccw(e_small.second)); 01373 Vertex_handle vlrg_src = fc->vertex(ccw(id)); 01374 Vertex_handle vlrg_trg = fc->vertex(cw(id)); 01375 if ( vmap[vsml_src] != vlrg_src || vmap[vsml_trg] != vlrg_trg ) { 01376 Edge e_small_prev = l.previous(e_small); 01377 std::cerr << "size of l: " << l.size() << std::endl; 01378 l.remove(e_small); 01379 01380 std::cerr << "size of l: " << l.size() << std::endl; 01381 01382 Edge e_small_new = small_d.flip(e_small); 01383 Edge e_small_new_sym = small_d.sym_edge(e_small_new); 01384 Face_handle f1 = e_small_new.first; 01385 Face_handle f2 = e_small_new_sym.first; 01386 01387 if ( f2->vertex(e_small_new_sym.second) == vsml_src ) { 01388 std::swap(f1, f2); 01389 std::swap(e_small_new, e_small_new_sym); 01390 CGAL_assertion( f1->vertex(e_small_new.second) == vsml_src ); 01391 CGAL_assertion( f2->vertex(e_small_new_sym.second) == vsml_trg ); 01392 } 01393 01394 Edge to_list1(f1, cw(e_small_new.second)); 01395 Edge to_list2(f2, ccw(e_small_new_sym.second)); 01396 01397 e_small = small_d.sym_edge(to_list1); 01398 01399 l.insert_after(e_small_prev, e_small); 01400 std::cerr << "size of l: " << l.size() << std::endl; 01401 l.insert_after(e_small, small_d.sym_edge(to_list2)); 01402 std::cerr << "size of l: " << l.size() << std::endl; 01403 } else { 01404 e_small = l.next(e_small); 01405 ++fc; 01406 } 01407 CGAL_assertion( l.size() <= deg ); 01408 } while ( fc != fc_start ); 01409 01410 #if 0 01411 std::cerr << "size of l : " << l.size() << std::endl; 01412 std::cerr << "degree of v: " << deg << std::endl; 01413 #endif 01414 01415 #if !defined(CGAL_NO_ASSERTIONS) && !defined(NDEBUG) 01416 // we go around the boundary of the conflict region verify that all 01417 // edges are there 01418 CGAL_assertion( l.size() == degree(v) ); 01419 e_small = e_small_begin; 01420 fc_start = incident_faces(v, e_large_begin.first); 01421 fc = fc_start; 01422 do { 01423 int id = fc->index(v); 01424 Vertex_handle vsml_src = e_small.first->vertex(cw(e_small.second)); 01425 Vertex_handle vsml_trg = e_small.first->vertex(ccw(e_small.second)); 01426 Vertex_handle vlrg_src = fc->vertex(ccw(id)); 01427 Vertex_handle vlrg_trg = fc->vertex(cw(id)); 01428 CGAL_assertion(vmap[vsml_src] == vlrg_src && vmap[vsml_trg] == vlrg_trg ); 01429 01430 // go to next edge 01431 e_small = l.next(e_small); 01432 } while ( ++fc != fc_start ); 01433 #endif 01434 } 01435 01436 template<class Gt, class ST, class D_S, class LTag> 01437 void 01438 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01439 expand_conflict_region_remove(const Face_handle& f, const Site_2& t, 01440 const Storage_site_2& ss, 01441 List& l, Face_map& fm, Sign_map& sign_map) 01442 { 01443 if ( fm.find(f) != fm.end() ) { return; } 01444 01445 // setting fm[f] to true means that the face has been reached and 01446 // that the face is available for recycling. If we do not want the 01447 // face to be available for recycling we must set this flag to 01448 // false. 01449 fm[f] = true; 01450 01451 // CGAL_assertion( fm.find(f) != fm.end() ); 01452 01453 for (int i = 0; i < 3; i++) { 01454 Face_handle n = f->neighbor(i); 01455 01456 bool face_registered = (fm.find(n) != fm.end()); 01457 01458 Sign s = incircle(n, t); 01459 01460 sign_map[n] = s; 01461 01462 Sign s_f = sign_map[f]; 01463 01464 if ( s == POSITIVE ) { continue; } 01465 if ( s != s_f ) { continue; } 01466 01467 bool interior_in_conflict = edge_interior(f, i, t, s); 01468 01469 if ( !interior_in_conflict ) { continue; } 01470 01471 if ( face_registered ) { continue; } 01472 01473 Edge e = sym_edge(f, i); 01474 01475 CGAL_assertion( l.is_in_list(e) ); 01476 int j = this->_tds.mirror_index(f, i); 01477 Edge e_before = sym_edge(n, ccw(j)); 01478 Edge e_after = sym_edge(n, cw(j)); 01479 if ( !l.is_in_list(e_before) ) { 01480 l.insert_before(e, e_before); 01481 } 01482 if ( !l.is_in_list(e_after) ) { 01483 l.insert_after(e, e_after); 01484 } 01485 l.remove(e); 01486 01487 expand_conflict_region_remove(n, t, ss, l, fm, sign_map); 01488 } // for-loop 01489 } 01490 01491 01492 template<class Gt, class ST, class D_S, class LTag> 01493 void 01494 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01495 find_conflict_region_remove(const Vertex_handle& v, 01496 const Vertex_handle& vnearest, 01497 List& l, Face_map& fm, Sign_map&) 01498 { 01499 CGAL_precondition( vnearest != Vertex_handle() ); 01500 Storage_site_2 ss = v->storage_site(); 01501 Site_2 t = ss.site(); 01502 01503 // find the first conflict 01504 01505 // first look for conflict with vertex 01506 Face_circulator fc_start = incident_faces(vnearest); 01507 Face_circulator fc = fc_start; 01508 Face_handle start_f; 01509 Sign s; 01510 01511 Sign_map sign_map; 01512 01513 do { 01514 Face_handle f(fc); 01515 01516 s = incircle(f, t); 01517 01518 sign_map[f] = s; 01519 01520 if ( s == NEGATIVE ) { 01521 start_f = f; 01522 break; 01523 } 01524 ++fc; 01525 } while ( fc != fc_start ); 01526 01527 CGAL_assertion( s == NEGATIVE ); 01528 01529 // we are not in conflict with a Voronoi vertex, so we have to 01530 // be in conflict with the interior of a Voronoi edge 01531 if ( s != NEGATIVE ) { 01532 Edge_circulator ec_start = incident_edges(vnearest); 01533 Edge_circulator ec = ec_start; 01534 01535 bool interior_in_conflict(false); 01536 Edge e; 01537 do { 01538 e = *ec; 01539 01540 Sign s1 = sign_map[e.first]; 01541 Sign s2 = sign_map[e.first->neighbor(e.second)]; 01542 01543 if ( s1 == s2 ) { 01544 interior_in_conflict = edge_interior(e, t, s1); 01545 } else { 01546 // It seems that there was a problem here when one of the 01547 // signs was positive and the other zero. In this case we 01548 // still check pretending that both signs where positive 01549 interior_in_conflict = edge_interior(e, t, POSITIVE); 01550 } 01551 01552 if ( interior_in_conflict ) { break; } 01553 ++ec; 01554 } while ( ec != ec_start ); 01555 01556 sign_map.clear(); 01557 01558 CGAL_assertion( interior_in_conflict ); 01559 01560 l.push_back(e); 01561 l.push_back(sym_edge(e)); 01562 return; 01563 } 01564 01565 initialize_conflict_region(start_f, l); 01566 expand_conflict_region_remove(start_f, t, ss, l, fm, sign_map); 01567 } 01568 01569 01570 //-------------------------------------------------------------------- 01571 //-------------------------------------------------------------------- 01572 01573 template<class Gt, class ST, class D_S, class LTag> 01574 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::size_type 01575 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01576 count_faces(const List& l) const 01577 { 01578 std::vector<Face_handle> flist; 01579 get_faces(l, std::back_inserter(flist)); 01580 return flist.size(); 01581 } 01582 01583 //-------------------------------------------------------------------- 01584 //-------------------------------------------------------------------- 01585 01586 template<class Gt, class ST, class D_S, class LTag> 01587 void 01588 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01589 fill_hole(const Self& small_d, const Vertex_handle& v, const List& l, 01590 std::map<Vertex_handle,Vertex_handle>& vmap) 01591 { 01592 #if 0 01593 std::cerr << "size of l : " << l.size() << std::endl; 01594 std::cerr << "degree of v: " << degree(v) << std::endl; 01595 #endif 01596 01597 typedef std::map<Edge,Edge> Edge_map; 01598 // maps edges on the boundary of the conflict region from the small 01599 // diagram to edges of the star of v in the small diagram 01600 Edge_map emap; 01601 01602 Edge e_sml_sym = sym_edge(l.front()); 01603 01604 Vertex_handle v_sml_src = e_sml_sym.first->vertex(ccw(e_sml_sym.second)); 01605 Vertex_handle v_sml_trg = e_sml_sym.first->vertex(cw(e_sml_sym.second)); 01606 01607 // first we find a first edge in common 01608 Face_circulator fc_start = incident_faces(v); 01609 Face_circulator fc = fc_start; 01610 Face_circulator fc_begin; 01611 bool found = false; 01612 do { 01613 int id = fc->index(v); 01614 Vertex_handle v_lrg_src = fc->vertex(ccw(id)); 01615 Vertex_handle v_lrg_trg = fc->vertex(cw(id)); 01616 if ( vmap[v_sml_src] == v_lrg_src && vmap[v_sml_trg] == v_lrg_trg ) { 01617 found = true; 01618 fc_begin = fc; 01619 break; 01620 } 01621 } while ( ++fc != fc_start ); 01622 CGAL_assertion( found ); 01623 01624 // container of faces to delete 01625 std::list<Face_handle> to_delete; 01626 01627 // next we go around the boundary of the conflict region and map all edges 01628 Edge e_small = l.front(); 01629 fc_start = incident_faces(v, fc_begin); 01630 fc = fc_start; 01631 do { 01632 int id = fc->index(v); 01633 #if !defined(CGAL_NO_ASSERTIONS) && !defined(NDEBUG) 01634 Vertex_handle vsml_src = e_small.first->vertex(cw(e_small.second)); 01635 Vertex_handle vsml_trg = e_small.first->vertex(ccw(e_small.second)); 01636 Vertex_handle vlrg_src = fc->vertex(ccw(id)); 01637 Vertex_handle vlrg_trg = fc->vertex(cw(id)); 01638 CGAL_assertion(vmap[vsml_src] == vlrg_src && vmap[vsml_trg] == vlrg_trg ); 01639 #endif 01640 // set mapping 01641 emap[e_small] = sym_edge(fc, id); 01642 // keep face for deletion 01643 to_delete.push_back(fc); 01644 // go to next edge 01645 e_small = l.next(e_small); 01646 } while ( ++fc != fc_start ); 01647 01648 01649 // map the faces of the small diagram with the new faces of the 01650 // large diagram 01651 std::map<Face_handle,Face_handle> fmap; 01652 std::vector<Face_handle> f_small, f_large; 01653 01654 small_d.get_faces(l, std::back_inserter(f_small)); 01655 for (unsigned int i = 0; i < f_small.size(); i++) { 01656 Face_handle f = this->_tds.create_face(); 01657 fmap[ f_small[i] ] = f; 01658 f_large.push_back(f); 01659 } 01660 01661 CGAL_assertion( l.size() == degree(v) ); 01662 CGAL_assertion( f_small.size() == f_large.size() ); 01663 CGAL_assertion( f_small.size() == l.size() - 2 ); 01664 CGAL_assertion( f_small.size() == count_faces(l) ); 01665 01666 // set the vertices for the new faces; also set the face for each 01667 // vertex 01668 for (typename std::vector<Face_handle>::iterator fit = f_small.begin(); 01669 fit != f_small.end(); ++fit) { 01670 Face_handle ff_small = *fit; 01671 Face_handle f = fmap[ff_small]; 01672 01673 for (int i = 0; i < 3; ++i) { 01674 CGAL_assertion( vmap.find(ff_small->vertex(i)) != vmap.end() ); 01675 f->set_vertex(i, vmap[ff_small->vertex(i)]); 01676 // we are setting the face for each vertex a lot of times; we 01677 // could possibly do it faster if we use the edges on the 01678 // boundary of the conflict region 01679 // in fact we may not even need it since the make_hole method 01680 // updates the faces of the vertices of the boundary of the 01681 // hole, and we do not introduce any new vertices 01682 f->vertex(i)->set_face(f); 01683 } 01684 } 01685 01686 // set the neighbors for each face 01687 for (typename std::vector<Face_handle>::iterator fit = f_small.begin(); 01688 fit != f_small.end(); ++fit) { 01689 Face_handle ff_small = *fit; 01690 01691 for (int i = 0; i < 3; i++) { 01692 Face_handle f = fmap[ff_small]; 01693 Face_handle n_small = ff_small->neighbor(i); 01694 if ( fmap.find(n_small) != fmap.end() ) { 01695 // this is one of the new faces 01696 f->set_neighbor(i, fmap[n_small]); 01697 } else { 01698 // otherwise it is one of the old faces outside the conflict 01699 // region; we have to use the edge map in this case 01700 Edge e_small_sym = small_d.sym_edge(ff_small, i); 01701 CGAL_assertion(emap.find(e_small_sym) != emap.end()); 01702 01703 Edge e_large = emap[e_small_sym]; 01704 f->set_neighbor(i, e_large.first); 01705 e_large.first->set_neighbor(e_large.second, f); 01706 } 01707 } 01708 } 01709 01710 // delete the unused faces and the vertex 01711 while ( !to_delete.empty() ) { 01712 delete_face(to_delete.front()); 01713 to_delete.pop_front(); 01714 } 01715 delete_vertex(v); 01716 } 01717 01718 //-------------------------------------------------------------------- 01719 //-------------------------------------------------------------------- 01720 01721 template<class Gt, class ST, class D_S, class LTag> 01722 bool 01723 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01724 remove_first(const Vertex_handle& v) 01725 { 01726 Delaunay_graph::remove_first(v); 01727 return true; 01728 } 01729 01730 template<class Gt, class ST, class D_S, class LTag> 01731 bool 01732 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01733 remove_second(const Vertex_handle& v) 01734 { 01735 Delaunay_graph::remove_second(v); 01736 return true; 01737 } 01738 01739 template<class Gt, class ST, class D_S, class LTag> 01740 bool 01741 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01742 remove_third(const Vertex_handle& v) 01743 { 01744 if ( is_degree_2(v) ) { 01745 CGAL_assertion( v->storage_site().is_point() ); 01746 Face_handle fh( incident_faces(v) ); 01747 int i = fh->index(v); 01748 flip(fh, i); 01749 } else if ( degree(v) == 4 ) { 01750 Edge_circulator ec = incident_edges(v); 01751 for (int i = 0; i < 4; i++) { 01752 Edge e = *ec; 01753 Edge sym = sym_edge(e); 01754 if ( e.first->vertex(e.second) != sym.first->vertex(sym.second) ) { 01755 flip(e); 01756 break; 01757 } 01758 ++ec; 01759 } 01760 } 01761 01762 this->_tds.remove_dim_down( v ); 01763 return true; 01764 } 01765 01766 //-------------------------------------------------------------------- 01767 //-------------------------------------------------------------------- 01768 01769 template<class Gt, class ST, class D_S, class LTag> 01770 void 01771 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01772 compute_small_diagram(const Vertex_handle& v, Self& small_d) const 01773 { 01774 Vertex_circulator vc_start = incident_vertices(v); 01775 Vertex_circulator vc = vc_start; 01776 01777 // insert all neighboring sites 01778 do { 01779 if ( !is_infinite(vc) ) { 01780 Site_2 t = vc->site(); 01781 if ( t.is_input() ) { 01782 small_d.insert(t); 01783 } else if ( t.is_point() ) { 01784 small_d.insert(t.supporting_site(0)); 01785 /*Vertex_handle vnear =*/ small_d.insert(t.supporting_site(1)); 01786 // vh_small = sdg_small.nearest_neighbor(t, vnear); 01787 } else { 01788 CGAL_assertion( t.is_segment() ); 01789 /*Vertex_handle vnear =*/ small_d.insert(t.supporting_site()); 01790 // vh_small = sdg_small.nearest_neighbor(t, vnear); 01791 } 01792 // CGAL_assertion( vh_small != Vertex_handle() ); 01793 // vmap[vh_small] = vh_large; 01794 } 01795 ++vc; 01796 } while ( vc != vc_start ); 01797 } 01798 01799 //-------------------------------------------------------------------- 01800 //-------------------------------------------------------------------- 01801 01802 template<class Gt, class ST, class D_S, class LTag> 01803 void 01804 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01805 compute_vertex_map(const Vertex_handle& v, const Self& small_d, 01806 std::map<Vertex_handle,Vertex_handle>& vmap) const 01807 { 01808 Vertex_circulator vc_start = incident_vertices(v); 01809 Vertex_circulator vc = vc_start; 01810 Vertex_handle vh_large, vh_small; 01811 01812 do { 01813 vh_large = Vertex_handle(vc); 01814 if ( is_infinite(vh_large) ) { 01815 vh_small = small_d.infinite_vertex(); 01816 vmap[vh_small] = vh_large; 01817 } else { 01818 #if !defined(CGAL_NO_ASSERTIONS) && !defined(NDEBUG) 01819 vh_small = Vertex_handle(); 01820 #endif 01821 Site_2 t = vc->site(); 01822 if ( t.is_input() ) { 01823 if ( t.is_segment() ) { 01824 Vertex_handle vv = small_d.nearest_neighbor( t.source() ); 01825 Vertex_circulator vvc_start = small_d.incident_vertices(vv); 01826 Vertex_circulator vvc = vvc_start; 01827 do { 01828 if ( small_d.same_segments(t, vvc) ) { 01829 vh_small = vvc; 01830 break; 01831 } 01832 } while ( ++vvc != vvc_start ); 01833 CGAL_assertion( small_d.same_segments(t, vh_small) ); 01834 } else { 01835 CGAL_assertion( t.is_point() ); 01836 vh_small = small_d.nearest_neighbor( t.point() ); 01837 CGAL_assertion( small_d.same_points(t, vh_small->site()) ); 01838 } 01839 } else if ( t.is_segment() ) { 01840 Vertex_handle vv = 01841 small_d.nearest_neighbor( t.source_site(), Vertex_handle() ); 01842 Vertex_circulator vvc_start = small_d.incident_vertices(vv); 01843 Vertex_circulator vvc = vvc_start; 01844 do { 01845 if ( small_d.same_segments(t, vvc) ) { 01846 vh_small = vvc; 01847 break; 01848 } 01849 } while ( ++vvc != vvc_start ); 01850 CGAL_assertion( small_d.same_segments(t, vh_small) ); 01851 } else { 01852 CGAL_assertion( t.is_point() ); 01853 vh_small = small_d.nearest_neighbor( t, Vertex_handle() ); 01854 CGAL_assertion( small_d.same_points(t, vh_small->site()) ); 01855 } 01856 CGAL_assertion( vh_small != Vertex_handle() ); 01857 vmap[vh_small] = vh_large; 01858 } 01859 ++vc; 01860 } while ( vc != vc_start ); 01861 } 01862 01863 01864 //-------------------------------------------------------------------- 01865 //-------------------------------------------------------------------- 01866 01867 template<class Gt, class ST, class D_S, class LTag> 01868 void 01869 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01870 remove_degree_d_vertex(const Vertex_handle& v) 01871 { 01872 #if 0 01873 Self sdg_small; 01874 compute_small_diagram(v, sdg_small); 01875 std::map<Vertex_handle,Vertex_handle> vmap; 01876 compute_vertex_map(v, sdg_small, vmap); 01877 01878 // find nearest neighbor of v in small diagram 01879 Site_2 t = v->site(); 01880 Vertex_handle vn; 01881 01882 CGAL_assertion( t.is_input() ); 01883 01884 if ( t.is_point() ) { 01885 vn = sdg_small.nearest_neighbor( t.point() ); 01886 } else { 01887 vn = sdg_small.nearest_neighbor( t.source() ); 01888 } 01889 CGAL_assertion( vn != Vertex_handle() ); 01890 01891 List l; 01892 Face_map fm; 01893 Sign_map sign_map; 01894 01895 sdg_small.find_conflict_region_remove(v, vn, l, fm, sign_map); 01896 01897 fm.clear(); 01898 sign_map.clear(); 01899 01900 equalize_degrees(v, sdg_small, vmap, l); 01901 01902 fill_hole(sdg_small, v, l, vmap); 01903 01904 l.clear(); 01905 return; 01906 01907 #else 01908 minimize_degree(v); 01909 int deg = degree(v); 01910 if ( deg == 3 ) { 01911 remove_degree_3(v); 01912 return; 01913 } 01914 if ( deg == 2 ) { 01915 remove_degree_2(v); 01916 return; 01917 } 01918 01919 Self sdg_small; 01920 compute_small_diagram(v, sdg_small); 01921 01922 if ( sdg_small.number_of_vertices() <= 2 ) { 01923 CGAL_assertion( sdg_small.number_of_vertices() == 2 ); 01924 CGAL_assertion( deg == 4 ); 01925 Edge_circulator ec_start = incident_edges(v); 01926 Edge_circulator ec = ec_start; 01927 do { 01928 if ( is_infinite(*ec) ) { break; } 01929 ++ec; 01930 } while ( ec != ec_start ); 01931 CGAL_assertion( is_infinite(ec) ); 01932 flip(*ec); 01933 remove_degree_3(v); 01934 return; 01935 } 01936 01937 std::map<Vertex_handle,Vertex_handle> vmap; 01938 compute_vertex_map(v, sdg_small, vmap); 01939 01940 // find nearest neighbor of v in small diagram 01941 Site_2 t = v->site(); 01942 Vertex_handle vn; 01943 01944 CGAL_assertion( t.is_input() ); 01945 01946 // here we find a site in the small diagram that serves as a 01947 // starting point for finding all conflicts. 01948 // To do that we find the nearest neighbor of t if t is a point; 01949 // t is guarranteed to have a conflict with its nearest neighbor 01950 // If t is a segment, then one endpoint of t is enough; t is 01951 // guarranteed to have a conflict with the Voronoi edges around 01952 // this endpoint 01953 if ( t.is_point() ) { 01954 vn = sdg_small.nearest_neighbor( t.point() ); 01955 } else { 01956 vn = sdg_small.nearest_neighbor( t.source() ); 01957 } 01958 CGAL_assertion( vn != Vertex_handle() ); 01959 01960 List l; 01961 Face_map fm; 01962 Sign_map sign_map; 01963 01964 sdg_small.find_conflict_region_remove(v, vn, l, fm, sign_map); 01965 01966 fill_hole(sdg_small, v, l, vmap); 01967 01968 l.clear(); 01969 fm.clear(); 01970 sign_map.clear(); 01971 #endif 01972 } 01973 01974 //-------------------------------------------------------------------- 01975 //-------------------------------------------------------------------- 01976 01977 template<class Gt, class ST, class D_S, class LTag> 01978 bool 01979 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 01980 remove_base(const Vertex_handle& v) 01981 { 01982 Storage_site_2 ssv = v->storage_site(); 01983 CGAL_precondition( ssv.is_input() ); 01984 01985 // first consider the case where we have up to 2 points 01986 size_type n = number_of_vertices(); 01987 01988 if ( n == 1 ) { 01989 return remove_first(v); 01990 } else if ( n == 2 ) { 01991 return remove_second(v); 01992 } 01993 01994 // secondly check if the point to be deleted is adjacent to a segment 01995 if ( ssv.is_point() ) { 01996 Vertex_circulator vc_start = incident_vertices(v); 01997 Vertex_circulator vc = vc_start; 01998 01999 do { 02000 Storage_site_2 ss = vc->storage_site(); 02001 if ( ss.is_segment() && is_endpoint_of_segment(ssv, ss) ) { 02002 return false; 02003 } 02004 ++vc; 02005 } while ( vc != vc_start ); 02006 } 02007 02008 // now do the deletion 02009 if ( n == 3 ) { 02010 return remove_third(v); 02011 } 02012 02013 int deg = degree(v); 02014 if ( deg == 2 ) { 02015 remove_degree_2(v); 02016 } else if ( deg == 3 ) { 02017 remove_degree_3(v); 02018 } else { 02019 remove_degree_d_vertex(v); 02020 } 02021 02022 return true; 02023 } 02024 02025 //-------------------------------------------------------------------- 02026 //-------------------------------------------------------------------- 02027 02028 template<class Gt, class ST, class D_S, class LTag> 02029 bool 02030 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02031 remove(const Vertex_handle& v) 02032 { 02033 CGAL_precondition( !is_infinite(v) ); 02034 const Storage_site_2& ss = v->storage_site(); 02035 02036 if ( !ss.is_input() ) { return false; } 02037 02038 Point_handle h1, h2; 02039 bool is_point = ss.is_point(); 02040 if ( is_point ) { 02041 h1 = ss.point(); 02042 } else { 02043 CGAL_assertion( ss.is_segment() ); 02044 h1 = ss.source_of_supporting_site(); 02045 h2 = ss.target_of_supporting_site(); 02046 } 02047 02048 bool success = remove_base(v); 02049 02050 if ( success ) { 02051 // unregister the input site 02052 if ( is_point ) { 02053 unregister_input_site( h1 ); 02054 } else { 02055 unregister_input_site( h1, h2 ); 02056 } 02057 } 02058 return success; 02059 } 02060 02061 //-------------------------------------------------------------------- 02062 //-------------------------------------------------------------------- 02063 // combinatorial operations 02064 //-------------------------------------------------------------------- 02065 //-------------------------------------------------------------------- 02066 02067 //-------------------------------------------------------------------- 02068 //-------------------------------------------------------------------- 02069 // point location 02070 //-------------------------------------------------------------------- 02071 //-------------------------------------------------------------------- 02072 template<class Gt, class ST, class D_S, class LTag> 02073 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 02074 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02075 nearest_neighbor(const Site_2& p, 02076 Vertex_handle start_vertex) const 02077 { 02078 CGAL_precondition( p.is_point() ); 02079 02080 if ( number_of_vertices() == 0 ) { 02081 return Vertex_handle(); 02082 } 02083 02084 if ( start_vertex == Vertex_handle() ) { 02085 start_vertex = finite_vertex(); 02086 } 02087 02088 // if ( start_vertex == NULL ) { return start_vertex; } 02089 02090 Vertex_handle vclosest; 02091 Vertex_handle v = start_vertex; 02092 02093 if ( number_of_vertices() < 3 ) { 02094 vclosest = v; 02095 Finite_vertices_iterator vit = finite_vertices_begin(); 02096 for (; vit != finite_vertices_end(); ++vit) { 02097 Vertex_handle v1(vit); 02098 if ( v1 != vclosest /*&& !is_infinite(v1)*/ ) { 02099 Site_2 t0 = vclosest->site(); 02100 Site_2 t1 = v1->site(); 02101 if ( side_of_bisector(t0, t1, p) == ON_NEGATIVE_SIDE ) { 02102 vclosest = v1; 02103 } 02104 } 02105 } 02106 return vclosest; 02107 } 02108 02109 do { 02110 vclosest = v; 02111 Site_2 t0 = v->site(); 02112 // if ( t0.is_point() && same_points(p, t0) ) { 02113 // return vclosest; 02114 // } 02115 Vertex_circulator vc_start = incident_vertices(v); 02116 Vertex_circulator vc = vc_start; 02117 do { 02118 if ( !is_infinite(vc) ) { 02119 Vertex_handle v1(vc); 02120 Site_2 t1 = v1->site(); 02121 Oriented_side os = side_of_bisector(t0, t1, p); 02122 02123 if ( os == ON_NEGATIVE_SIDE ) { 02124 v = v1; 02125 break; 02126 } 02127 } 02128 ++vc; 02129 } while ( vc != vc_start ); 02130 } while ( vclosest != v ); 02131 02132 return vclosest; 02133 } 02134 02135 //---------------------------------------------------------------------- 02136 //---------------------------------------------------------------------- 02137 // methods for the predicates 02138 //---------------------------------------------------------------------- 02139 //---------------------------------------------------------------------- 02140 02141 template<class Gt, class ST, class D_S, class LTag> 02142 Sign 02143 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02144 incircle(const Face_handle& f, const Site_2& q) const 02145 { 02146 if ( !is_infinite(f) ) { 02147 return incircle(f->vertex(0)->site(), 02148 f->vertex(1)->site(), 02149 f->vertex(2)->site(), q); 02150 } 02151 02152 int inf_i(-1); // to avoid compiler warning 02153 for (int i = 0; i < 3; i++) { 02154 if ( is_infinite(f->vertex(i)) ) { 02155 inf_i = i; 02156 break; 02157 } 02158 } 02159 return incircle( f->vertex( ccw(inf_i) )->site(), 02160 f->vertex( cw(inf_i) )->site(), q ); 02161 } 02162 02163 02164 template<class Gt, class ST, class D_S, class LTag> 02165 Sign 02166 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02167 incircle(const Vertex_handle& v0, const Vertex_handle& v1, 02168 const Vertex_handle& v2, const Vertex_handle& v) const 02169 { 02170 CGAL_precondition( !is_infinite(v) ); 02171 02172 if ( !is_infinite(v0) && !is_infinite(v1) && 02173 !is_infinite(v2) ) { 02174 return incircle(v0->site(), v1->site(), 02175 v2->site(), v->site()); 02176 } 02177 02178 if ( is_infinite(v0) ) { 02179 CGAL_precondition( !is_infinite(v1) && !is_infinite(v2) ); 02180 return incircle( v1->site(), v2->site(), v->site()); 02181 } 02182 if ( is_infinite(v1) ) { 02183 CGAL_precondition( !is_infinite(v0) && !is_infinite(v2) ); 02184 return incircle( v2->site(), v0->site(), v->site()); 02185 } 02186 02187 CGAL_assertion( is_infinite(v2) ); 02188 CGAL_precondition( !is_infinite(v0) && !is_infinite(v1) ); 02189 return incircle( v0->site(), v1->site(), v->site()); 02190 } 02191 02192 02193 // this the finite edge interior predicate for a degenerate edge 02194 template<class Gt, class ST, class D_S, class LTag> 02195 bool 02196 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02197 finite_edge_interior(const Face_handle& f, int i, const Site_2& q, 02198 Sign sgn, int) const 02199 { 02200 if ( !is_infinite( this->_tds.mirror_vertex(f, i) ) ) { 02201 CGAL_precondition( is_infinite(f->vertex(i)) ); 02202 02203 Face_handle g = f->neighbor(i); 02204 int j = this->_tds.mirror_index(f, i); 02205 02206 return finite_edge_interior(g, j, q, sgn, 0 /* degenerate */); 02207 } 02208 02209 CGAL_precondition( is_infinite( this->_tds.mirror_vertex(f, i) ) ); 02210 02211 Site_2 t1 = f->vertex( ccw(i) )->site(); 02212 Site_2 t2 = f->vertex( cw(i) )->site(); 02213 02214 if ( is_infinite(f->vertex(i)) ) { 02215 return finite_edge_interior(t1, t2, q, sgn); 02216 } 02217 02218 Site_2 t3 = f->vertex(i)->site(); 02219 return finite_edge_interior(t1, t2, t3, q, sgn); 02220 } 02221 02222 template<class Gt, class ST, class D_S, class LTag> 02223 bool 02224 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02225 finite_edge_interior(const Vertex_handle& v1, const Vertex_handle& v2, 02226 const Vertex_handle& v3, const Vertex_handle& v4, 02227 const Vertex_handle& v, Sign sgn, int) const 02228 { 02229 CGAL_precondition( !is_infinite(v1) && !is_infinite(v2) && 02230 !is_infinite(v) ); 02231 if ( !is_infinite( v4 ) ) { 02232 CGAL_precondition( is_infinite(v3) ); 02233 02234 return 02235 finite_edge_interior(v2, v1, v4, v3, v, sgn, 0 /* degenerate */); 02236 } 02237 02238 CGAL_precondition( is_infinite( v4 ) ); 02239 02240 Site_2 t1 = v1->site(); 02241 Site_2 t2 = v2->site(); 02242 Site_2 q = v->site(); 02243 02244 if ( is_infinite(v3) ) { 02245 return finite_edge_interior(t1, t2, q, sgn); 02246 } 02247 02248 Site_2 t3 = v3->site(); 02249 return finite_edge_interior(t1, t2, t3, q, sgn); 02250 } 02251 02252 template<class Gt, class ST, class D_S, class LTag> 02253 bool 02254 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02255 infinite_edge_interior(const Face_handle& f, int i, 02256 const Site_2& q, Sign sgn) const 02257 { 02258 if ( !is_infinite( f->vertex(ccw(i)) ) ) { 02259 CGAL_precondition( is_infinite( f->vertex(cw(i)) ) ); 02260 Face_handle g = f->neighbor(i); 02261 int j = this->_tds.mirror_index(f, i); 02262 02263 return infinite_edge_interior(g, j, q, sgn); 02264 } 02265 02266 CGAL_precondition( is_infinite( f->vertex(ccw(i)) ) ); 02267 02268 Site_2 t2 = f->vertex( cw(i) )->site(); 02269 Site_2 t3 = f->vertex( i )->site(); 02270 Site_2 t4 = this->_tds.mirror_vertex(f, i)->site(); 02271 02272 return infinite_edge_interior(t2, t3, t4, q, sgn); 02273 } 02274 02275 02276 template<class Gt, class ST, class D_S, class LTag> 02277 bool 02278 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02279 infinite_edge_interior(const Vertex_handle& v1, 02280 const Vertex_handle& v2, 02281 const Vertex_handle& v3, 02282 const Vertex_handle& v4, 02283 const Vertex_handle& v, Sign sgn) const 02284 { 02285 CGAL_precondition( !is_infinite(v3) && !is_infinite(v4) && 02286 !is_infinite(v) ); 02287 02288 if ( !is_infinite( v1 ) ) { 02289 CGAL_precondition( is_infinite( v2 ) ); 02290 02291 return infinite_edge_interior(v2, v1, v4, v3, v, sgn); 02292 } 02293 02294 CGAL_precondition( is_infinite( v1 ) ); 02295 02296 Site_2 t2 = v2->site(); 02297 Site_2 t3 = v3->site(); 02298 Site_2 t4 = v4->site(); 02299 Site_2 q = v->site(); 02300 02301 return infinite_edge_interior(t2, t3, t4, q, sgn); 02302 } 02303 02304 02305 02306 02307 template<class Gt, class ST, class D_S, class LTag> 02308 bool 02309 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02310 edge_interior(const Vertex_handle& v1, 02311 const Vertex_handle& v2, 02312 const Vertex_handle& v3, 02313 const Vertex_handle& v4, 02314 const Vertex_handle& v, Sign sgn) const 02315 { 02316 CGAL_precondition( !is_infinite(v) ); 02317 02318 bool is_inf_v1 = is_infinite(v1); 02319 bool is_inf_v2 = is_infinite(v2); 02320 bool is_inf_v3 = is_infinite(v3); 02321 bool is_inf_v4 = is_infinite(v4); 02322 02323 bool result; 02324 02325 if ( !is_inf_v1 && !is_inf_v2 && !is_inf_v3 && !is_inf_v4 ) { 02326 result = finite_edge_interior(v1, v2, v3, v4, v, sgn); 02327 } else if ( is_inf_v3 || is_inf_v4 ) { 02328 result = finite_edge_interior(v1, v2, v3, v4, v, sgn, 0/* degenerate */); 02329 } else { 02330 result = infinite_edge_interior(v1, v2, v3, v4, v, sgn); 02331 } 02332 02333 return result; 02334 } 02335 02336 02337 template<class Gt, class ST, class D_S, class LTag> 02338 bool 02339 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02340 edge_interior(const Face_handle& f, int i, 02341 const Site_2& q, Sign sgn) const 02342 { 02343 Face_handle g = f->neighbor(i); 02344 02345 bool is_inf_f = is_infinite(f); 02346 bool is_inf_g = is_infinite(g); 02347 02348 bool result; 02349 02350 if ( !is_inf_f && !is_inf_g ) { 02351 result = finite_edge_interior(f, i, q, sgn); 02352 } else if ( !is_inf_f || !is_inf_g ) { 02353 result = finite_edge_interior(f, i, q, sgn, 0 /* denegerate */); 02354 } else { 02355 if ( !is_infinite(f, i) ) { 02356 result = finite_edge_interior(f, i, q, sgn, 0 /* degenerate */); 02357 } else { 02358 result = infinite_edge_interior(f, i, q, sgn); 02359 } 02360 } 02361 02362 return result; 02363 } 02364 02365 02366 template<class Gt, class ST, class D_S, class LTag> 02367 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Arrangement_type 02368 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02369 arrangement_type(const Site_2& p, const Site_2& q) const 02370 { 02371 typedef typename Geom_traits::Arrangement_type_2 AT2; 02372 typedef typename AT2::result_type Arrangement_type; 02373 02374 Arrangement_type res = geom_traits().arrangement_type_2_object()(p, q); 02375 02376 // The valeus that have to be treated are the following: 02377 // DISJOINT, TOUCH_1, TOUCH_2, CROSSING, IDENTICAL, INTERIOR, 02378 // TOUCH_11_INTERIOR_1, TOUCH_12_INTERIOR_1, TOUCH_21_INTERIOR_1 and 02379 // TOUCH_22_INTERIOR_1. 02380 // 02381 // The remaining values will either never appear because of one of 02382 // the following reasons: 02383 // 1. we insert the endpoints of the segments first and then the 02384 // interior (OVERLAPPING_*, INTERIOR_*, TOUCH_*_INTERIOR_2). 02385 // 2. the values have no meaning since we consider the segments to 02386 // be open (TOUCH_INTERIOR_*). In this case, the conflict will 02387 // appear when we test with the endpoint. 02388 // 3. a conflict will first happen with an endpoint before testing 02389 // for the segment (TOUCH_2*_INTERIOR_1). In this case the 02390 // segment to be inserted will first find an endpoint in its 02391 // interior before actually finding that there is another segment 02392 // it overlaps with. 02393 02394 CGAL_assertion( res != AT2::INTERIOR_1 ); 02395 CGAL_assertion( res != AT2::INTERIOR_2 ); 02396 02397 CGAL_assertion( res != AT2::OVERLAPPING_11 ); 02398 CGAL_assertion( res != AT2::OVERLAPPING_12 ); 02399 CGAL_assertion( res != AT2::OVERLAPPING_21 ); 02400 CGAL_assertion( res != AT2::OVERLAPPING_22 ); 02401 02402 CGAL_assertion( res != AT2::TOUCH_11_INTERIOR_2 ); 02403 CGAL_assertion( res != AT2::TOUCH_21_INTERIOR_2 ); 02404 CGAL_assertion( res != AT2::TOUCH_12_INTERIOR_2 ); 02405 CGAL_assertion( res != AT2::TOUCH_22_INTERIOR_2 ); 02406 02407 CGAL_assertion( res != AT2::TOUCH_21_INTERIOR_1 ); 02408 CGAL_assertion( res != AT2::TOUCH_22_INTERIOR_1 ); 02409 02410 if ( res == AT2::TOUCH_INTERIOR_12 || res == AT2::TOUCH_INTERIOR_21 || 02411 res == AT2::TOUCH_INTERIOR_11 || res == AT2::TOUCH_INTERIOR_22 ) { 02412 return AT2::DISJOINT; 02413 } 02414 if ( res == AT2::TOUCH_11 || res == AT2::TOUCH_12 || 02415 res == AT2::TOUCH_21 || res == AT2::TOUCH_22 ) { 02416 return AT2::DISJOINT; 02417 } 02418 02419 return res; 02420 } 02421 02422 //-------------------------------------------------------------------- 02423 //-------------------------------------------------------------------- 02424 // embedding and visualization methods and constructions for primal 02425 // and dual 02426 //-------------------------------------------------------------------- 02427 //-------------------------------------------------------------------- 02428 02429 // primal 02430 template<class Gt, class ST, class D_S, class LTag> 02431 Object 02432 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02433 primal(const Edge e) const 02434 { 02435 typedef typename Gt::Line_2 Line_2; 02436 typedef typename Gt::Ray_2 Ray_2; 02437 02438 CGAL_precondition( !is_infinite(e) ); 02439 02440 if ( this->dimension() == 1 ) { 02441 Site_2 p = (e.first)->vertex(cw(e.second))->site(); 02442 Site_2 q = (e.first)->vertex(ccw(e.second))->site(); 02443 02444 Line_2 l = construct_sdg_bisector_2_object()(p,q); 02445 return make_object(l); 02446 } 02447 02448 // dimension == 2 02449 // none of the two adjacent faces is infinite 02450 if( (!is_infinite(e.first)) && 02451 (!is_infinite(e.first->neighbor(e.second))) ) { 02452 Site_2 p = (e.first)->vertex( ccw(e.second) )->site(); 02453 Site_2 q = (e.first)->vertex( cw(e.second) )->site(); 02454 Site_2 r = (e.first)->vertex( e.second )->site(); 02455 Site_2 s = this->_tds.mirror_vertex(e.first, e.second)->site(); 02456 return construct_sdg_bisector_segment_2_object()(p,q,r,s); 02457 } 02458 02459 // both of the adjacent faces are infinite 02460 if ( is_infinite(e.first) && 02461 is_infinite(e.first->neighbor(e.second)) ) { 02462 Site_2 p = (e.first)->vertex(cw(e.second))->site(); 02463 Site_2 q = (e.first)->vertex(ccw(e.second))->site(); 02464 Line_2 l = construct_sdg_bisector_2_object()(p,q); 02465 return make_object(l); 02466 } 02467 02468 // only one of the adjacent faces is infinite 02469 CGAL_assertion( is_infinite( e.first ) || 02470 is_infinite( e.first->neighbor(e.second) ) 02471 ); 02472 02473 CGAL_assertion( !(is_infinite( e.first ) && 02474 is_infinite( e.first->neighbor(e.second) ) 02475 ) 02476 ); 02477 02478 CGAL_assertion( is_infinite(e.first->vertex(e.second)) || 02479 is_infinite(this->_tds.mirror_vertex(e.first, e.second)) ); 02480 02481 Edge ee = e; 02482 if ( is_infinite( e.first->vertex(e.second) ) ) { 02483 ee = sym_edge(e); 02484 } 02485 Site_2 p = ee.first->vertex( ccw(ee.second) )->site(); 02486 Site_2 q = ee.first->vertex( cw(ee.second) )->site(); 02487 Site_2 r = ee.first->vertex( ee.second )->site(); 02488 02489 Ray_2 ray = construct_sdg_bisector_ray_2_object()(p,q,r); 02490 return make_object(ray); 02491 } 02492 02493 //-------------------------------------------------------------------- 02494 //-------------------------------------------------------------------- 02495 // validity test method 02496 //-------------------------------------------------------------------- 02497 //-------------------------------------------------------------------- 02498 template<class Gt, class ST, class D_S, class LTag> 02499 bool Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02500 is_valid(bool verbose, int level) const 02501 { 02502 if (level < 0) { return true; } 02503 02504 if (number_of_vertices() <= 1) { 02505 if ( verbose && number_of_vertices() == 1 ) { 02506 std::cerr << "SDGDS is ok... " << std::flush; 02507 } 02508 return true; 02509 } 02510 02511 // level 0 test: check the TDS 02512 bool result = data_structure().is_valid(verbose, level); 02513 02514 if ( result && verbose ) { 02515 std::cerr << "SDGDS is ok... " << std::flush; 02516 } 02517 02518 if (level == 0) { return result; } 02519 02520 // level 1 test: do the incircle tests 02521 if (number_of_vertices() < 3) { return true; } 02522 02523 for (All_edges_iterator eit = all_edges_begin(); 02524 eit != all_edges_end(); ++eit) { 02525 Edge e = *eit; 02526 Face_handle f = e.first; 02527 02528 Vertex_handle v = this->_tds.mirror_vertex(f, e.second); 02529 02530 if ( f->vertex(e.second) == v ) { continue; } 02531 if ( !is_infinite(v) ) { 02532 result = result && 02533 ( incircle(f, v->site()) != NEGATIVE ); 02534 } 02535 Edge sym_e = sym_edge(e); 02536 f = sym_e.first; 02537 v = this->_tds.mirror_vertex(f, sym_e.second); 02538 02539 if ( !is_infinite(v) ) { 02540 result = result && 02541 ( incircle(f, v->site()) != NEGATIVE ); 02542 } 02543 } 02544 02545 if ( result && verbose ) { 02546 std::cerr << "Segment Delaunay graph is ok..." << std::flush; 02547 } 02548 if ( !result && verbose ) { 02549 std::cerr << "Segment Delaunay graph is NOT valid..." << std::flush; 02550 } 02551 02552 return result; 02553 } 02554 02555 02556 //-------------------------------------------------------------------- 02557 //-------------------------------------------------------------------- 02558 // misc 02559 //-------------------------------------------------------------------- 02560 //-------------------------------------------------------------------- 02561 02562 02563 template<class Gt, class ST, class D_S, class LTag> 02564 void 02565 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02566 print_error_message() const 02567 { 02568 std::cerr << std::endl; 02569 std::cerr << "WARNING:" << std::endl; 02570 std::cerr << "A segment-segment intersection was found." 02571 << std::endl; 02572 std::cerr << "The Segment_Delaunay_graph_2 class is not configured" 02573 << " to handle this situation." << std::endl; 02574 std::cerr << "Please look at the documentation on how to handle" 02575 << " this behavior." << std::endl; 02576 std::cerr << std::endl; 02577 } 02578 02579 //-------------------------------------------------------------------- 02580 //-------------------------------------------------------------------- 02581 // the copy method 02582 //-------------------------------------------------------------------- 02583 //-------------------------------------------------------------------- 02584 02585 template<class Gt, class ST, class D_S, class LTag> 02586 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Storage_site_2 02587 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02588 copy_storage_site(const Storage_site_2& ss_other, Handle_map& hm, 02589 const Tag_false&) 02590 { 02591 if ( ss_other.is_segment() ) { 02592 Point_handle p0 = hm[ ss_other.source_of_supporting_site() ]; 02593 Point_handle p1 = hm[ ss_other.target_of_supporting_site() ]; 02594 return st_.construct_storage_site_2_object()(p0, p1); 02595 } else { 02596 Point_handle p0 = hm[ ss_other.point() ]; 02597 return st_.construct_storage_site_2_object()(p0); 02598 } 02599 } 02600 02601 template<class Gt, class ST, class D_S, class LTag> 02602 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Storage_site_2 02603 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02604 copy_storage_site(const Storage_site_2& ss_other, Handle_map& hm, 02605 const Tag_true&) 02606 { 02607 if ( ss_other.is_segment() ) { 02608 if ( ss_other.is_input() ) { 02609 Point_handle p0 = hm[ ss_other.source_of_supporting_site() ]; 02610 Point_handle p1 = hm[ ss_other.target_of_supporting_site() ]; 02611 return st_.construct_storage_site_2_object()(p0, p1); 02612 } else if ( ss_other.is_input(0) ) { 02613 Point_handle p0 = hm[ ss_other.source_of_supporting_site() ]; 02614 Point_handle p1 = hm[ ss_other.target_of_supporting_site() ]; 02615 Point_handle p4 = hm[ ss_other.source_of_crossing_site(1) ]; 02616 Point_handle p5 = hm[ ss_other.target_of_crossing_site(1) ]; 02617 return st_.construct_storage_site_2_object()(p0, p1, p4, p5, true); 02618 } else if ( ss_other.is_input(1) ) { 02619 Point_handle p0 = hm[ ss_other.source_of_supporting_site() ]; 02620 Point_handle p1 = hm[ ss_other.target_of_supporting_site() ]; 02621 Point_handle p2 = hm[ ss_other.source_of_crossing_site(0) ]; 02622 Point_handle p3 = hm[ ss_other.target_of_crossing_site(0) ]; 02623 return st_.construct_storage_site_2_object()(p0, p1, p2, p3, false); 02624 } else { 02625 Point_handle p0 = hm[ ss_other.source_of_supporting_site() ]; 02626 Point_handle p1 = hm[ ss_other.target_of_supporting_site() ]; 02627 Point_handle p2 = hm[ ss_other.source_of_crossing_site(0) ]; 02628 Point_handle p3 = hm[ ss_other.target_of_crossing_site(0) ]; 02629 Point_handle p4 = hm[ ss_other.source_of_crossing_site(1) ]; 02630 Point_handle p5 = hm[ ss_other.target_of_crossing_site(1) ]; 02631 return st_.construct_storage_site_2_object()(p0, p1, p2, p3, p4, p5); 02632 } 02633 } else { 02634 if ( ss_other.is_input() ) { 02635 Point_handle p0 = hm[ ss_other.point() ]; 02636 return st_.construct_storage_site_2_object()(p0); 02637 } else { 02638 Point_handle p2 = hm[ ss_other.source_of_supporting_site(0) ]; 02639 Point_handle p3 = hm[ ss_other.target_of_supporting_site(0) ]; 02640 Point_handle p4 = hm[ ss_other.source_of_supporting_site(1) ]; 02641 Point_handle p5 = hm[ ss_other.target_of_supporting_site(1) ]; 02642 return st_.construct_storage_site_2_object()(p2, p3, p4, p5); 02643 } 02644 } 02645 } 02646 02647 template<class Gt, class ST, class D_S, class LTag> 02648 void 02649 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02650 copy(Segment_Delaunay_graph_2& other) 02651 { 02652 // first copy the point container 02653 pc_ = other.pc_; 02654 02655 // copy storage traits 02656 st_ = other.st_; 02657 02658 // first create a map between the old point handles and the new ones 02659 Handle_map hm; 02660 02661 Point_handle it_other = other.pc_.begin(); 02662 Point_handle it_this = pc_.begin(); 02663 for (; it_other != other.pc_.end(); ++it_other, ++it_this) { 02664 hm.insert( Point_handle_pair(it_other, it_this) ); 02665 } 02666 02667 copy(other, hm); 02668 } 02669 02670 template<class Gt, class ST, class D_S, class LTag> 02671 void 02672 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02673 copy(Segment_Delaunay_graph_2& other, Handle_map& hm) 02674 { 02675 // second, copy the site representation info for the input sites 02676 // using the correct handles (i.e., the handles from the new point 02677 // container 02678 isc_.clear(); 02679 typename Input_sites_container::iterator iit_other = other.isc_.begin(); 02680 for (; iit_other != other.isc_.end(); ++iit_other) { 02681 Site_rep_2 old_srep = *iit_other; 02682 Site_rep_2 new_srep( hm[boost::tuples::get<0>(old_srep)], 02683 hm[boost::tuples::get<1>(old_srep)], 02684 boost::tuples::get<2>(old_srep) ); 02685 isc_.insert( new_srep ); 02686 } 02687 02688 CGAL_assertion( pc_.size() == other.pc_.size() ); 02689 CGAL_assertion( isc_.size() == other.isc_.size() ); 02690 02691 #ifndef CGAL_NO_ASSERTIONS 02692 { 02693 Point_handle it_other = other.pc_.begin(); 02694 Point_handle it_this = pc_.begin(); 02695 for (; it_other != other.pc_.end(); ++it_other, ++it_this) { 02696 CGAL_assertion( *it_other == *it_this ); 02697 } 02698 } 02699 #endif 02700 02701 // then copy the diagram 02702 DG::operator=(other); 02703 02704 // now we have to update the sotrage sites in each vertex of the 02705 // diagram and also update the 02706 02707 // then update the storage sites for each vertex 02708 Intersections_tag itag; 02709 02710 Finite_vertices_iterator vit_other = other.finite_vertices_begin(); 02711 Finite_vertices_iterator vit_this = finite_vertices_begin(); 02712 for (; vit_other != other.finite_vertices_end(); vit_other++, 02713 vit_this++) { 02714 Storage_site_2 ss_other = vit_other->storage_site(); 02715 02716 #ifndef CGAL_NO_ASSERTIONS 02717 Storage_site_2 ss_this = vit_this->storage_site(); 02718 if ( ss_other.is_segment() ) { 02719 CGAL_assertion( ss_this.is_segment() ); 02720 CGAL_assertion( same_segments(ss_this.site(), ss_other.site()) ); 02721 } else { 02722 CGAL_assertion( ss_this.is_point() ); 02723 CGAL_assertion( same_points(ss_this.site(), ss_other.site()) ); 02724 } 02725 #endif 02726 02727 Storage_site_2 new_ss_this = copy_storage_site(ss_other, hm, itag); 02728 vit_this->set_site( new_ss_this ); 02729 } 02730 } 02731 02732 //-------------------------------------------------------------------- 02733 //-------------------------------------------------------------------- 02734 // getting endpoints of segments 02735 //-------------------------------------------------------------------- 02736 //-------------------------------------------------------------------- 02737 02738 template<class Gt, class ST, class D_S, class LTag> 02739 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 02740 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02741 first_endpoint_of_segment(const Vertex_handle& v) const 02742 { 02743 CGAL_assertion( v->is_segment() ); 02744 Site_2 fe = v->site().source_site(); 02745 Vertex_circulator vc_start = incident_vertices(v); 02746 Vertex_circulator vc = vc_start; 02747 do { 02748 // Vertex_handle vv(vc); 02749 if ( !is_infinite(vc) && vc->is_point() ) { 02750 if ( same_points(fe, vc->site()) ) { 02751 return Vertex_handle(vc); 02752 } 02753 } 02754 vc++; 02755 } while ( vc != vc_start ); 02756 02757 // we should never reach this point 02758 CGAL_error(); 02759 return Vertex_handle(); 02760 } 02761 02762 template<class Gt, class ST, class D_S, class LTag> 02763 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle 02764 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02765 second_endpoint_of_segment(const Vertex_handle& v) const 02766 { 02767 CGAL_assertion( v->is_segment() ); 02768 Site_2 fe = v->site().target_site(); 02769 Vertex_circulator vc_start = incident_vertices(v); 02770 Vertex_circulator vc = vc_start; 02771 do { 02772 // Vertex_handle vv(vc); 02773 if ( !is_infinite(vc) && vc->is_point() ) { 02774 if ( same_points(fe, vc->site()) ) { 02775 return Vertex_handle(vc); 02776 } 02777 } 02778 vc++; 02779 } while ( vc != vc_start ); 02780 02781 // we should never reach this point 02782 CGAL_error(); 02783 return Vertex_handle(); 02784 } 02785 02786 //-------------------------------------------------------------------- 02787 //-------------------------------------------------------------------- 02788 // file I/O 02789 //-------------------------------------------------------------------- 02790 //-------------------------------------------------------------------- 02791 02792 template<class Gt, class ST, class D_S, class LTag> 02793 void 02794 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02795 file_output(std::ostream& os, const Storage_site_2& t, 02796 Point_handle_mapper& P) const 02797 { 02798 CGAL_precondition( t.is_defined() ); 02799 02800 if ( t.is_point() ) { 02801 // 0 for point 02802 os << 0; 02803 if ( is_ascii(os) ) { os << ' '; } 02804 if ( t.is_input() ) { 02805 // 0 for input 02806 os << 0; 02807 if ( is_ascii(os) ) { os << ' '; } 02808 os << P[t.point()]; 02809 } else { 02810 // 1 for non-input 02811 os << 1; 02812 if ( is_ascii(os) ) { os << ' '; } 02813 os << P[t.source_of_supporting_site(0)]; 02814 if ( is_ascii(os) ) { os << ' '; } 02815 os << P[t.target_of_supporting_site(0)]; 02816 if ( is_ascii(os) ) { os << ' '; } 02817 os << P[t.source_of_supporting_site(1)]; 02818 if ( is_ascii(os) ) { os << ' '; } 02819 os << P[t.target_of_supporting_site(1)]; 02820 } 02821 } else { // t is a segment 02822 // 1 for segment 02823 os << 1; 02824 if ( is_ascii(os) ) { os << ' '; } 02825 if ( t.is_input() ) { 02826 // 0 for input 02827 os << 0; 02828 if ( is_ascii(os) ) { os << ' '; } 02829 os << P[t.source_of_supporting_site()]; 02830 if ( is_ascii(os) ) { os << ' '; } 02831 os << P[t.target_of_supporting_site()]; 02832 } else if ( t.is_input(0) ) { 02833 // 1 for input source 02834 os << 1; 02835 if ( is_ascii(os) ) { os << ' '; } 02836 os << P[t.source_of_supporting_site()]; 02837 if ( is_ascii(os) ) { os << ' '; } 02838 os << P[t.target_of_supporting_site()]; 02839 if ( is_ascii(os) ) { os << ' '; } 02840 os << P[t.source_of_crossing_site(1)]; 02841 if ( is_ascii(os) ) { os << ' '; } 02842 os << P[t.target_of_crossing_site(1)]; 02843 } else if ( t.is_input(1) ) { 02844 // 2 for input target 02845 os << 2; 02846 if ( is_ascii(os) ) { os << ' '; } 02847 os << P[t.source_of_supporting_site()]; 02848 if ( is_ascii(os) ) { os << ' '; } 02849 os << P[t.target_of_supporting_site()]; 02850 if ( is_ascii(os) ) { os << ' '; } 02851 os << P[t.source_of_crossing_site(0)]; 02852 if ( is_ascii(os) ) { os << ' '; } 02853 os << P[t.target_of_crossing_site(0)]; 02854 } else { 02855 // 3 for non-input src & trg 02856 os << 3; 02857 if ( is_ascii(os) ) { os << ' '; } 02858 os << P[t.source_of_supporting_site()]; 02859 if ( is_ascii(os) ) { os << ' '; } 02860 os << P[t.target_of_supporting_site()]; 02861 if ( is_ascii(os) ) { os << ' '; } 02862 os << P[t.source_of_crossing_site(0)]; 02863 if ( is_ascii(os) ) { os << ' '; } 02864 os << P[t.target_of_crossing_site(0)]; 02865 if ( is_ascii(os) ) { os << ' '; } 02866 os << P[t.source_of_crossing_site(1)]; 02867 if ( is_ascii(os) ) { os << ' '; } 02868 os << P[t.target_of_crossing_site(1)]; 02869 } 02870 } 02871 } 02872 02873 template<class Gt, class ST, class D_S, class LTag> 02874 void 02875 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02876 file_input(std::istream& is, Storage_site_2& t, 02877 const Point_handle_vector& P, const Tag_false&) const 02878 { 02879 int type, input; 02880 is >> type >> input; 02881 CGAL_assertion( type == 0 || type == 1 ); 02882 CGAL_assertion( input == 0 ); 02883 if ( type == 0 ) { 02884 // we have an input point 02885 size_type p; 02886 is >> p; 02887 t = st_.construct_storage_site_2_object()(P[p]); 02888 } else { 02889 CGAL_assertion( type == 1 ); 02890 // we have an input segment 02891 size_type p1, p2; 02892 is >> p1 >> p2; 02893 t = st_.construct_storage_site_2_object()(P[p1], P[p2]); 02894 } 02895 } 02896 02897 template<class Gt, class ST, class D_S, class LTag> 02898 void 02899 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02900 file_input(std::istream& is, Storage_site_2& t, 02901 const Point_handle_vector& P, const Tag_true&) const 02902 { 02903 int type, input; 02904 is >> type >> input; 02905 CGAL_assertion( type == 0 || type == 1 ); 02906 CGAL_assertion( input >= 0 && input <= 3 ); 02907 if ( type == 0 ) { 02908 // we have a point 02909 if ( input == 0 ) { 02910 // we have an input point 02911 size_type p; 02912 is >> p; 02913 t = st_.construct_storage_site_2_object()(P[p]); 02914 } else { 02915 // we have a point that is the intersection of two segments 02916 CGAL_assertion( input == 1 ); 02917 size_type p1, p2, q1, q2; 02918 is >> p1 >> p2 >> q1 >> q2; 02919 t = st_.construct_storage_site_2_object()(P[p1], P[p2], P[q1], P[q2]); 02920 } 02921 } else { 02922 // we have a segment 02923 CGAL_assertion( type == 1 ); 02924 if ( input == 0 ) { 02925 // we have an input segment 02926 size_type p1, p2; 02927 is >> p1 >> p2; 02928 t = st_.construct_storage_site_2_object()(P[p1], P[p2]); 02929 } else if ( input < 3 ) { 02930 // we have a segment whose source or target is input but not both 02931 size_type p1, p2, q1, q2; 02932 is >> p1 >> p2 >> q1 >> q2; 02933 t = st_.construct_storage_site_2_object()(P[p1], P[p2], 02934 P[q1], P[q2], input == 1); 02935 } else { 02936 // we have a segment whose neither its source nor its target is input 02937 CGAL_assertion( input == 3 ); 02938 size_type p1, p2, q1, q2, r1, r2; 02939 is >> p1 >> p2 >> q1 >> q2 >> r1 >> r2; 02940 t = st_.construct_storage_site_2_object()(P[p1], P[p2], 02941 P[q1], P[q2], 02942 P[r1], P[r2]); 02943 } 02944 } 02945 } 02946 02947 //-------------------------------------------------------------------- 02948 02949 template<class Gt, class ST, class D_S, class LTag> 02950 void 02951 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 02952 file_output(std::ostream& os, Point_handle_mapper& P, 02953 bool print_point_container) const 02954 { 02955 // ouput to a file 02956 size_type n = this->_tds.number_of_vertices(); 02957 size_type m = this->_tds.number_of_full_dim_faces(); 02958 02959 CGAL_assertion( n >= 1 ); 02960 02961 if( is_ascii(os) ) { 02962 os << n << ' ' << m << ' ' << dimension() << std::endl; 02963 } else { 02964 os << n << m << dimension(); 02965 } 02966 02967 // points in point container and input sites container 02968 if ( print_point_container ) { 02969 if ( is_ascii(os) ) { os << std::endl; } 02970 os << pc_.size(); 02971 if ( is_ascii(os) ) { os << std::endl; } 02972 for (const_Point_handle ph = pc_.begin(); ph != pc_.end(); ++ph) { 02973 os << *ph; 02974 if ( is_ascii(os) ) { os << std::endl; } 02975 } 02976 02977 // print the input sites container 02978 if ( is_ascii(os) ) { os << std::endl; } 02979 os << isc_.size(); 02980 if ( is_ascii(os) ) { os << std::endl; } 02981 for (typename Input_sites_container::const_iterator it = isc_.begin(); 02982 it != isc_.end(); ++it) { 02983 os << P[boost::tuples::get<0>(*it)]; 02984 if ( is_ascii(os) ) { os << " "; } 02985 os << P[boost::tuples::get<1>(*it)]; 02986 if ( is_ascii(os) ) { os << std::endl; } 02987 } 02988 } 02989 02990 std::map<Vertex_handle,int> V; 02991 std::map<Face_handle,int> F; 02992 02993 // first vertex (infinite vertex) 02994 size_type inum = 0; 02995 V[infinite_vertex()] = inum++; 02996 02997 // finite vertices 02998 if (is_ascii(os)) os << std::endl; 02999 for (Finite_vertices_iterator vit = finite_vertices_begin(); 03000 vit != finite_vertices_end(); ++vit) { 03001 V[vit] = inum++; 03002 // os << vit->site(); 03003 file_output(os, vit->storage_site(), P); 03004 // write non-combinatorial info of the vertex 03005 // os << *vit ; 03006 if ( is_ascii(os) ) { os << std::endl; } 03007 } 03008 if ( is_ascii(os) ) { os << std::endl; } 03009 03010 // vertices of the faces 03011 inum = 0; 03012 int dim = (dimension() == -1 ? 1 : dimension() + 1); 03013 for(All_faces_iterator fit = all_faces_begin(); 03014 fit != all_faces_end(); ++fit) { 03015 F[fit] = inum++; 03016 for(int j = 0; j < dim ; ++j) { 03017 os << V[ fit->vertex(j) ]; 03018 if( is_ascii(os) ) { os << ' '; } 03019 } 03020 // write non-combinatorial info of the face 03021 // os << *fit ; 03022 if( is_ascii(os) ) { os << std::endl; } 03023 } 03024 if( is_ascii(os) ) { os << std::endl; } 03025 03026 // neighbor pointers of the faces 03027 for( All_faces_iterator it = all_faces_begin(); 03028 it != all_faces_end(); ++it) { 03029 for(int j = 0; j < dimension()+1; ++j){ 03030 os << F[ it->neighbor(j) ]; 03031 if( is_ascii(os) ) { os << ' '; } 03032 } 03033 if( is_ascii(os) ) { os << std::endl; } 03034 } 03035 03036 if ( is_ascii(os) ) { os << std::endl; } 03037 } 03038 03039 03040 03041 template<class Gt, class ST, class D_S, class LTag> 03042 void 03043 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>:: 03044 file_input(std::istream& is, bool read_handle_vector, 03045 Point_handle_vector& P) 03046 { 03047 //input from file 03048 size_type n, m; 03049 int d; 03050 is >> n >> m >> d; 03051 03052 CGAL_assertion( n >= 1 ); 03053 03054 size_type i = 0; 03055 Storage_site_2 ss; 03056 03057 if ( read_handle_vector ) { 03058 pc_.clear(); 03059 size_type np; 03060 is >> np; 03061 for (; i < np; i++) { 03062 Point_2 p; 03063 is >> p; 03064 std::pair<Point_handle,bool> res = pc_.insert(p); 03065 P.push_back(res.first); 03066 CGAL_assertion( P[i] == res.first ); 03067 } 03068 03069 // now read the input sites container 03070 isc_.clear(); 03071 size_type nisc; 03072 is >> nisc; 03073 int id1, id2; 03074 for (i = 0; i < nisc; i++) { 03075 is >> id1 >> id2; 03076 isc_.insert( Site_rep_2(P[id1], P[id2], id1 == id2) ); 03077 } 03078 } 03079 03080 if ( n == 1 ) { 03081 CGAL_assertion( d == -1 ); 03082 if ( number_of_vertices() > 0 ) { clear(); } 03083 return; 03084 } 03085 if ( n == 2 ) { 03086 CGAL_assertion( d == 0 ); 03087 if ( number_of_vertices() > 0 ) { clear(); } 03088 file_input(is, ss, P, Intersections_tag()); 03089 insert_first(ss, *ss.point()); 03090 return; 03091 } 03092 if ( n == 3 ) { 03093 CGAL_assertion( d == 1 ); 03094 if ( number_of_vertices() > 0 ) { clear(); } 03095 file_input(is, ss, P, Intersections_tag()); 03096 insert_first(ss, *ss.point()); 03097 file_input(is, ss, P, Intersections_tag()); 03098 insert_second(ss, *ss.point()); 03099 return; 03100 } 03101 03102 if (this->_tds.number_of_vertices() != 0) { this->_tds.clear(); } 03103 03104 this->_tds.set_dimension(d); 03105 03106 std::vector<Vertex_handle> V(n); 03107 std::vector<Face_handle> F(m); 03108 03109 // first vertex (infinite vertex) 03110 V[0] = this->_tds.create_vertex(); 03111 this->set_infinite_vertex(V[0]); 03112 i = 1; 03113 03114 // read vertices 03115 for (; i < n; ++i) { 03116 V[i] = this->_tds.create_vertex(); 03117 file_input(is, ss, P, Intersections_tag()); 03118 V[i]->set_site(ss); 03119 // read non-combinatorial info of the vertex 03120 // is >> *(V[i]); 03121 } 03122 03123 // Creation of the faces 03124 int index; 03125 int dim = (dimension() == -1 ? 1 : dimension() + 1); 03126 03127 for (i = 0; i < m; ++i) { 03128 F[i] = this->_tds.create_face(); 03129 for (int j = 0; j < dim ; ++j){ 03130 is >> index; 03131 F[i]->set_vertex(j, V[index]); 03132 // The face pointer of vertices is set too often, 03133 // but otherwise we had to use a further map 03134 V[index]->set_face(F[i]); 03135 } 03136 // read in non-combinatorial info of the face 03137 // is >> *(F[i]) ; 03138 } 03139 03140 // Setting the neighbor pointers 03141 for (i = 0; i < m; ++i) { 03142 for (int j = 0; j < dimension()+1; ++j){ 03143 is >> index; 03144 F[i]->set_neighbor(j, F[index]); 03145 } 03146 } 03147 } 03148 03149 03150 CGAL_END_NAMESPACE 03151 03152 // EOF
1.7.6.1