00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 # ifndef shape_voronoi2d_hpp
00013 # define shape_voronoi2d_hpp
00014
00015 # include <shape/mesher2d.hpp>
00016 # include <shape/voronoi_site2d.hpp>
00017 # include <shape/bcell2d_voronoi_site2d.hpp>
00018 # include <shape/bcell2d_voronoi_diagram.hpp>
00019
00020 # include <shape/semialgebraic_domain2d_axel.hpp>
00021 # include <stack>
00022
00023 # define STACK std::stack<Cell2d *>
00024
00025 # define TMPL template<class C, class V>
00026 # define Shape geometric<V>
00027 # define VoronoiCurve voronoi_bisector<C,V>
00028 # define VoronoiSite2d voronoi_site2d<C,V >
00029 # define VSite voronoi_site2d<C,V >
00030 # define Cell2dVoronoiSite2d bcell2d_voronoi_site2d<C,V>
00031 # define SELF voronoi2d<C,V>
00032 # define Viewer viewer<V>
00033 # define VCell bcell2d_voronoi_diagram<C,V>
00034 # undef Cell
00035
00036 namespace mmx {
00037 namespace shape {
00038
00039 template<class C, class V=default_env>
00040 class voronoi2d
00041 {
00042
00043 public:
00044
00045 typedef typename mesher2d<C,V>::Point Point;
00046 typedef typename mesher2d<C,V>::Edge Edge;
00047 typedef typename mesher2d<C,V>::Face Face;
00048 typedef typename mesher2d<C,V>::BoundingBox BoundingBox;
00049 typedef typename mesher2d<C,V>::Cell Cell;
00050 typedef typename mesher2d<C,V>::Cell2d Cell2d;
00051 typedef typename mesher2d<C,V>::Curve Curve;
00052 typedef topology<C,V> Topology;
00053
00054 typedef node<Cell*> Node;
00055 typedef kdtree<Cell*> Kdtree;
00056
00057 public:
00058
00059 voronoi2d(const BoundingBox& bx): m_maxprec(0.1), m_minprec(0.01), m_bbx(bx) { };
00060
00061 voronoi2d(Curve * curve) ;
00062 ~voronoi2d(void) {};
00063
00064 void run(void) ;
00065 void push_back(VoronoiSite2d *v);
00066
00067 unsigned const size() { return m_sites.size(); };
00068
00069 void set_precision (double);
00070 void set_smoothness(double);
00071
00072 protected:
00073 bool is_regular (Cell * bcell)
00074 {
00075 return bcell->is_regular();
00076
00077 };
00078
00079 bool insert_regular(Cell * bcell)
00080 {
00081
00082
00083 Seq<Point*> l;
00084 l= ((VCell*)bcell)->intersections();
00085
00086 int * sz;
00087 int * st;
00088 Point *q;
00089
00090 if ( l.size()==2 )
00091 {
00092 this->m_graph.push_vertex(l[0]);
00093 this->m_graph.push_vertex(l[1]);
00094 this->m_graph.push_uedge(l[0],l[1]);
00095
00096 return true;
00097 }
00098
00099 if ( l.size()==4 )
00100 {
00101 this->m_graph.push_vertex(l[0]);
00102 this->m_graph.push_vertex(l[1]);
00103 this->m_graph.push_uedge(l[0],l[1]);
00104 return true;
00105 }
00106
00107 if ( l.size()==1)
00108 {
00109 std::cout<< "SIZE ONE, "<< *bcell<<std::endl;
00110
00111 this->m_graph.push_vertex(l[0]);
00112
00113 foreach( Cell* c, ((VCell*)bcell)->m_objects )
00114 if ( ((Cell2d*)c)->nb_intersect()==1 )
00115 {
00116 sz= ((Cell2dVoronoiSite2d*)c)->m_polynomial.rep().szs();
00117 st= ((Cell2dVoronoiSite2d*)c)->m_polynomial.rep().str();
00118 if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[0]<EPSILON )
00119 {
00120 q= new Point(bcell->xmin(),bcell->ymin(),0);
00121
00122
00123 this->m_graph.push_vertex(q);
00124 this->m_graph.push_uedge(l[0],q);
00125
00126 ((Cell2dVoronoiSite2d*)c)->n_intersections<< q;
00127
00128 foreach( Cell2d *nb, ((Cell2d*)bcell)->s_neighbors )
00129 foreach( Cell* cc, ((VCell*)nb)->m_objects )
00130 if ( cc->is_active() )
00131 {
00132 ((Cell2dVoronoiSite2d*)cc)->n_intersections<< q;
00133 std::cout<<"This Intersections: "<< ((VCell*)bcell)->intersections().size() << std::endl;
00134 std::cout<<"Neib Intersections: "<< nb->intersections().size() << std::endl;
00135 return true;
00136 }
00137 foreach( Cell2d *nb, ((Cell2d*)bcell)->w_neighbors )
00138 foreach( Cell* cc, ((VCell*)nb)->m_objects )
00139 if ( cc->is_active() )
00140 {
00141 ((Cell2dVoronoiSite2d*)cc)->e_intersections<< q;
00142 std::cout<<"This Intersections: "<< ((VCell*)bcell)->intersections().size() << std::endl;
00143 std::cout<<"Neib Intersections: "<< nb->intersections().size() << std::endl;
00144 return true;
00145 }
00146
00147 } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[(sz[0]-1)*st[0]]<EPSILON )
00148 {
00149 q= new Point(bcell->xmax(),bcell->ymax(),0);
00150 std::cout<< "2.add ("<< *q <<")->("<< *l[0] << ") in "<< *bcell<<std::endl;
00151
00152 this->m_graph.push_vertex(q);
00153 this->m_graph.push_uedge(l[0],q);
00154 ((Cell2dVoronoiSite2d*)c)->s_intersections<< q;
00155
00156
00157 foreach( Cell2d *nb, ((VCell*)bcell)->e_neighbors )
00158 foreach( Cell* cc, ((VCell*)nb)->m_objects )
00159 if ( cc->is_active() )
00160 {
00161 ((Cell2dVoronoiSite2d*)cc)->w_intersections<< q;
00162 std::cout<<"This Intersections: "<< ((VCell*)bcell)->intersections().size() << std::endl;
00163 std::cout<<"Neib Intersections: "<< nb->intersections().size() << std::endl;
00164 return true;
00165 }
00166 foreach( Cell2d *nb, ((VCell*)bcell)->n_neighbors )
00167 foreach( Cell* cc, ((VCell*)nb)->m_objects )
00168 if ( cc->is_active() )
00169 {
00170 ((Cell2dVoronoiSite2d*)cc)->s_intersections<< q;
00171 std::cout<<"This Intersections: "<< ((VCell*)bcell)->intersections().size() << std::endl;
00172 std::cout<<"Neib Intersections: "<< nb->intersections().size() << std::endl;
00173 return true;
00174 }
00175
00176 } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[sz[0]*sz[1]-1]<EPSILON )
00177 {
00178 q= new Point(bcell->xmin(),bcell->ymax(),0);
00179
00180 this->m_graph.push_vertex(q);
00181 this->m_graph.push_uedge(l[0],q);
00182
00183 ((Cell2dVoronoiSite2d*)c)->w_intersections<< q;
00184 return true;
00185 } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[(sz[1]-1)*st[1]]<EPSILON )
00186 {
00187 q= new Point(bcell->xmax(),bcell->ymin(),0);
00188
00189 this->m_graph.push_vertex(q);
00190 this->m_graph.push_uedge(l[0],q);
00191 ((Cell2dVoronoiSite2d*)c)->e_intersections<< q;
00192 return true;
00193 }
00194 }
00195 }
00196
00197 if ( l.size()==0)
00198 {
00199 std::cout<< "SIZE ZERO, "<< *bcell<<std::endl;
00200 return true;
00201
00202 foreach( Cell* c, ((VCell*)bcell)->m_objects )
00203 {
00204 sz= ((Cell2dVoronoiSite2d*)c)->m_polynomial.rep().szs();
00205 st= ((Cell2dVoronoiSite2d*)c)->m_polynomial.rep().str();
00206 if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[0]<EPSILON )
00207 {
00208 q= new Point(bcell->xmin(),bcell->ymin(),0);
00209 std::cout<< "1.add ("<< *q <<") in "<< *bcell<<std::endl;
00210 this->m_graph.push_vertex(q);
00211 ((Cell2dVoronoiSite2d*)c)->n_intersections<< q;
00212 return true;
00213 } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[(sz[0]-1)*st[0]]<EPSILON )
00214 {
00215 q= new Point(bcell->xmax(),bcell->ymax(),0);
00216 std::cout<< "1.add ("<< *q <<") in "<< *bcell<<std::endl;
00217 this->m_graph.push_vertex(q);
00218 ((Cell2dVoronoiSite2d*)c)->s_intersections<< q;
00219 return true;
00220 } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[sz[0]*sz[1]-1]<EPSILON )
00221 {
00222 q= new Point(bcell->xmin(),bcell->ymax(),0);
00223 std::cout<< "1.add ("<< *q <<") in "<< *bcell<<std::endl;
00224 this->m_graph.push_uedge(l[0],q);
00225 ((Cell2dVoronoiSite2d*)c)->w_intersections<< q;
00226 return true;
00227 } else if ( ((Cell2dVoronoiSite2d*)c)->m_polynomial[(sz[1]-1)*st[1]]<EPSILON )
00228 {
00229 q= new Point(bcell->xmax(),bcell->ymin(),0);
00230 std::cout<< "1.add ("<< *q <<") in "<< *bcell<<std::endl;
00231 this->m_graph.push_vertex(q);
00232 this->m_graph.push_uedge(l[0],q);
00233 ((Cell2dVoronoiSite2d*)c)->e_intersections<< q;
00234 return true;
00235 }
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244 return true;
00245
00246 };
00247
00248
00249
00250
00251
00252
00253
00254 bool subdivide(Cell * bcell)
00255 { return mesher2d<C,V>::subdivide(bcell,NULL); };
00256
00257 private:
00258
00259 public:
00260
00261 std::list<VoronoiSite2d *> m_sites ;
00262
00263 std::list<VCell *> m_singular_cells;
00264
00265 Graph<Point*> m_graph;
00266
00267 Graph<Cell2d*> m_leaves;
00268 Graph<Cell2d*> b_leaves;
00269
00270 double m_maxprec ;
00271 double m_minprec ;
00272
00273 BoundingBox m_bbx;
00274 Seq<VSite*> m_objects;
00275
00276 Seq<Face *> m_faces;
00277 };
00278
00279
00280
00281 TMPL void
00282 SELF::push_back(VoronoiSite2d *v)
00283 {
00284 this->m_objects.push_back(v);
00285 this->m_sites.push_back(v);
00286
00287
00288 }
00289
00290 TMPL void SELF::set_smoothness(double eps) {
00291 m_maxprec = eps;
00292 }
00293
00294 TMPL void SELF::set_precision(double eps) {
00295 m_minprec = eps;
00296 }
00297
00298 TMPL void
00299 SELF::run() {
00300
00301
00302
00303
00305
00306 std::cout<<"Running, objs="<<this->m_objects.size() << std::endl;
00307
00308
00309 VCell * l = new VCell(this->m_bbx);
00310 foreach( VSite * vcurve, this->m_objects)
00311 {
00312
00313 l->push_back( new Cell2dVoronoiSite2d(vcurve,this->m_bbx) );
00314 }
00315
00316
00317
00318 double maxsz = this->m_maxprec;
00319 double minsz = this->m_minprec;
00320
00321
00322 std::stack<Cell *> bcell_stack;
00323 bcell_stack.push(l);
00324
00325 while(!bcell_stack.empty() ) {
00326
00327
00328 Cell * cl = bcell_stack.top();
00329 bcell_stack.pop();
00330 Cell2d * cl2= dynamic_cast<Cell2d*>(cl);
00331
00332
00333
00334 if(cl->is_active()) {
00335
00336
00337
00338 if(cl->size() > maxsz)
00339 {
00340
00341 Cell * left, * right;
00342 ((bcell<C,V> *)cl)->subdivide(left, right) ;
00343 bcell_stack.push(left);
00344 bcell_stack.push(right);
00345 }
00346 else if(this->is_regular(cl) )
00347 {
00348
00349 this->insert_regular(cl) ;
00350
00351 cl2->m_gnode=
00352 this->m_leaves.push_vertex(cl2);
00353 if ( cl2->is_border() )
00354 this->b_leaves.push_vertex(cl2);
00355 }
00356 else if(cl->size() > minsz)
00357 {
00358
00359 Cell* left, * right;
00360 cl->subdivide(left, right) ;
00361 bcell_stack.push(left);
00362 bcell_stack.push(right);
00363 }
00364 else
00365 {
00366
00367
00368
00369 this->m_singular_cells<< (VCell*)cl2;
00370 ( (VCell*)cl2 )->process_singular() ;
00371
00372 cl2->m_gnode=
00373 this->m_leaves.push_vertex(cl2);
00374 if ( cl2->is_border() )
00375 this->b_leaves.push_vertex(cl2);
00376 }
00377 }
00378 else
00379 {
00380 if ( cl2->is_border() )
00381 this->b_leaves.push_vertex(cl2);
00382 }
00383 }
00384
00385
00386
00387
00388
00389 GraphDfsIter<Cell2d*> dfs(b_leaves);
00390 Cell2d* cl2= NULL;
00391
00392
00393 for (dfs.first(); !dfs.isDone(); dfs.next() )
00394 {
00395 cl2= dfs.currentItem()->get_data();
00396
00397
00398 if (cl2->s_neighbors.size()==0)
00399 foreach(Cell2d* nb, cl2->e_neighbors )
00400 if ( this->b_leaves.member(nb) && nb->s_neighbors.size()==0)
00401 this->b_leaves.push_edge( cl2,nb ) ;
00402 if (cl2->e_neighbors.size()==0)
00403 foreach(Cell2d* nb, cl2->n_neighbors )
00404 if (this->b_leaves.member(nb) && nb->e_neighbors.size()==0)
00405 this->b_leaves.push_edge( cl2,nb ) ;
00406 if (cl2->n_neighbors.size()==0)
00407 foreach(Cell2d* nb, cl2->w_neighbors )
00408 if (this->b_leaves.member(nb)&& nb->n_neighbors.size()==0)
00409 this->b_leaves.push_edge( cl2,nb ) ;
00410 if (cl2->w_neighbors.size()==0)
00411 foreach(Cell2d* nb, cl2->s_neighbors )
00412 if (this->b_leaves.member(nb)&& nb->w_neighbors.size()==0)
00413 this->b_leaves.push_edge( cl2,nb ) ;
00414 }
00415
00416
00418
00419
00420 foreach( VCell* q, m_singular_cells )
00421 { q->compute_boundary();
00422
00423 }
00424
00425
00426 Seq<Cell2d*> nlist;
00427 this->b_leaves.dfs(nlist);
00428
00429 Cell2d* pr;
00430 pr= nlist[nlist.size()-1];
00431
00432 foreach(Cell2d* cl2, nlist)
00433
00434 {
00435
00436
00437
00438 if ( cl2->is_corner() )
00439 pr=cl2;
00440 else {
00441 if ( (cl2->s_neighbors.size()==0 &&
00442 cl2->intersections(0).size()==0 ) ||
00443 (cl2->e_neighbors.size()==0 &&
00444 cl2->intersections(1).size()==0 ) ||
00445 (cl2->n_neighbors.size()==0 &&
00446 cl2->intersections(2).size()==0 ) ||
00447 (cl2->w_neighbors.size()==0 &&
00448 cl2->intersections(3).size()==0 ) )
00449 {
00450 this->b_leaves.push_edge(pr, this->b_leaves.next(cl2) ) ;
00451 this->b_leaves.delete_vertex( cl2 ) ;
00452 }
00453 else
00454 pr=cl2;
00455 }
00456 }
00457
00458 std::cout<<"Border size= "<< nlist.size() <<std::endl;
00459
00460
00461
00462
00463
00464 dfs= GraphDfsIter<Cell2d*>(m_leaves);
00465
00466 for (dfs.first(); !dfs.isDone(); dfs.next() )
00467
00468 {
00469 cl2= dfs.currentItem()->get_data();
00470
00471 foreach(Cell2d* nb, cl2->neighbors() )
00472 this->m_leaves.push_edge( cl2,nb ) ;
00473 }
00474
00475 std::cout<<"Leaf graph Ok." <<std::endl;
00476
00477
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 Point *p= NULL;
00493 Face * f= NULL;
00494 int sgn(1);
00495 unsigned site;
00496
00497 assert( nlist.size()>1);
00498
00499 Cell2d
00500 *t= NULL,
00501 *b= NULL;
00502
00503
00504
00505
00506 for (dfs.first(); !dfs.isDone(); dfs.next() )
00507 {
00508 cl2= dfs.currentItem()->get_data();
00509
00510 if (!( cl2->is_active() &&
00511 (!this->b_leaves.member(cl2)) &&
00512 ((VCell*)cl2)->count() ==1
00513 ))
00514 { continue; }
00515
00516
00517
00518 switch ( cl2->m_gnode->aux() )
00519 {
00520 case 0:
00521 sgn=1 ;
00522 case -1 :
00523 sgn=1 ;
00524 break ;
00525 case 2 :
00526 sgn=-1;
00527 break ;
00528 default :
00529 continue;
00530 }
00531 site=((VCell*)cl2)->site(sgn);
00532 std::cout<<"site: "<< site << std::endl;
00533
00534
00535 f= new Face();
00536
00537
00538 std::cout<<"Getting voronoi bcell of "<<site <<"("<<(sgn==1 ? "+": "-")
00539 <<"), starting "<< *cl2<< std::endl;
00540 p= cl2->starting_point(sgn);
00541
00542
00543 p= cl2->pair(p,sgn);
00544
00545 f->insert(p);
00546 b=cl2;
00547
00548
00549 do {
00550
00551
00552
00553
00554
00555
00556 if( this->m_leaves.member(b) ) {
00557 b->m_gnode->aux( b->m_gnode->aux() + (sgn==1 ? 2:-1) );
00558
00559 }
00560
00561
00562
00563
00564 t= b->neighbor(p);
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 if ( t==NULL)
00590 {
00591
00592
00593
00594
00595
00596
00597 if (b->s_neighbors.size()==0 &&
00598 b->e_neighbors.size()==0 && b->intersections(1).size()==0)
00599 f->insert(new Point(b->xmax(),b->ymin(),0.0) );
00600 if (b->e_neighbors.size()==0 &&
00601 b->n_neighbors.size()==0 && b->intersections(2).size()==0)
00602 f->insert(new Point(b->xmax(),b->ymax(),0.0) );
00603 if (b->n_neighbors.size()==0 &&
00604 b->w_neighbors.size()==0 && b->intersections(3).size()==0)
00605 f->insert(new Point(b->xmin(),b->ymax(),0.0) );
00606 if (b->w_neighbors.size()==0 &&
00607 b->s_neighbors.size()==0 && b->intersections(0).size()==0)
00608 f->insert(new Point(b->xmin(),b->ymin(),0.0) );
00609
00610
00611 b=this->b_leaves.next(b);
00612
00613
00614
00615 if (b->s_neighbors.size()==0 &&
00616 b->e_neighbors.size()==0 && b->intersections(0).size()==0 )
00617 { f->insert(new Point(b->xmax(),b->ymin(),0.0) );
00618 }
00619 else if (b->e_neighbors.size()==0 &&
00620 b->n_neighbors.size()==0 && b->intersections(1).size()==0)
00621 { f->insert(new Point(b->xmax(),b->ymax(),0.0) );
00622 }
00623
00624 else if (b->n_neighbors.size()==0 &&
00625 b->w_neighbors.size()==0 && b->intersections(2).size()==0)
00626 { f->insert(new Point(b->xmin(),b->ymax(),0.0) );
00627 }
00628 else if (b->w_neighbors.size()==0 &&
00629 b->s_neighbors.size()==0 && b->intersections(3).size()==0)
00630 { f->insert(new Point(b->xmin(),b->ymin(),0.0) );
00631 }
00632
00633 if ( this->m_leaves.member(b) )
00634 {
00635 sgn=((VCell*)b)->signof(site);
00636 p= b->starting_point(sgn);
00637 f->insert(p);
00638 std::cout<<"Entering from "<<*b<<" ,sgn="<<sgn<<std::endl;
00639 std::cout<<"insert "<<*p<<std::endl;
00640 p= b->pair(p,sgn);
00641 f->insert(p);
00642 std::cout<<"insert "<<*p<<std::endl;
00643
00644 }
00645 }
00646 else
00647 {
00648
00649 b=t;
00650 if ( b->m_singular.size() > 0 )
00651 f->insert(b->m_singular[0]);
00652 p= b->pair(p,sgn);
00653 f->insert(p);
00654
00655 }
00656
00657 } while (b!=cl2);
00658
00659
00660
00661 f->set_index(site);
00662 this->m_faces<< f;
00663
00664
00665
00666 }
00667
00668 std::cout<<" # faces= "<< this->m_faces.size() << std::endl;
00669
00670
00671 }
00672
00673
00674 TMPL Viewer&
00675 operator<<(Viewer& out, const SELF& tp) {
00676
00677 foreach(Shape* vs, tp.m_objects)
00678 {
00679 out<<" <point color=\"255 127 0\"> "<<
00680 ((VoronoiSite2d *)vs)->x() << " "<<
00681 ((VoronoiSite2d *)vs)->y() << " "<<
00682 ((VoronoiSite2d *)vs)->z() << "</point>\n";
00683 }
00684
00685 return out;
00686 }
00687
00688
00689
00690 }
00691 }
00692
00693 # undef TMPL
00694 # undef AlgebraicCurve
00695 # undef VoronoiSite
00696 # undef VCell
00697 # undef Cell
00698 # undef Cell2dVoronoiBisector
00699 # undef Cell2dFactory
00700 # undef Cell2dVoronoiSite2d
00701 # undef Curve
00702 # undef SELF
00703 # undef VSite
00704 # undef VoronoiSite2d
00705 # undef VoronoiCurve
00706 # undef Viewer
00707 # undef STACK
00708 # undef Shape
00709 # endif