home *** CD-ROM | disk | FTP | other *** search
- #include <LEDA/window.h>
- #include <LEDA/delaunay_tree.h>
-
-
- window* Wp;
-
- const double R = 1000; // "length of inifinite rays"
-
- int ymax;
-
- int segment_to_points(segment s, list(point)& out, double dist)
- {
- int n = int(s.length()/dist) + 2;
-
- double dx = (s.xcoord2() - s.xcoord1())/n;
- double dy = (s.ycoord2() - s.ycoord1())/n;
- double x = s.xcoord1();
- double y = s.ycoord1();
-
- out.append(s.start());
-
- for(int i = 0; i<n; i++)
- { x += dx + 0.001 * rrandom();
- y += dy + 0.001 * rrandom();
- out.append(point(x,y));
- }
-
- out.permute();
-
- return n;
-
- }
-
- int circle_to_points(circle C, list(point)& out, double dist)
- {
- point c = C.center();
- double r = C.radius();
- int n = int(6.283 * r/dist);
-
- double alpha = 0;
- double d = 6.283/n;
-
- for(int i = 0; i<n; i++)
- { out.append(c.translate(alpha,r + 0.0001 * rrandom()));
- alpha += d;
- }
-
- out.permute();
-
- return n;
-
- }
-
-
-
-
- void draw_vor_site(double x, double y)
- { Wp->draw_point(x,y); }
-
- void draw_vor_seg(double x1, double y1, double x2, double y2,double,double)
- { Wp->draw_segment(x1,y1,x2,y2,blue); }
-
-
- void draw_triang_seg(double x1, double y1, double x2, double y2)
- { Wp->draw_segment(x1,y1,x2,y2,red);
- }
-
- void infi_pt(double x1, double y1, double x2, double y2, double *x, double* y)
- /* retourne le point a l'infini dans la direction x2 y2 depuis x1 y1*/
- {
- vector v(x2,y2);
-
- v = v.norm();
-
- *x = x1 + R * v[0];
- *y = y1 + R * v[1];
-
- }
-
-
- declare(DELAUNAY_TREE,int)
-
- DELAUNAY_TREE(int) DT;
-
- DT_item it = nil;
- bool vor = false;
- bool triang = false;
- list(segment) CH;
-
- void redraw()
- { list(DT_item) L;
- DT.all_items(L);
- Wp->clear();
- forall(it,L) *Wp << DT.key(it);
- it = nil;
- vor = false;
- triang = false;
- CH.clear();
- }
-
-
- void interactive(window& W)
- {
-
- W.set_mode(xor_mode);
-
- panel P("DYNAMIC VORONOI DIAGRAMS");
-
- P.text_item(" based on Delaunay Trees ");
- P.text_item(" by Olivier Devillers ");
- P.text_item(" INRIA Sofia-Antipolis ");
- P.text_item(" ");
- P.text_item("BUTTON | left middle right ");
- P.text_item("----------+-----------------------------------");
- P.text_item("unshifted | insert voronoi menu ");
- P.text_item("shifted | segment delaunay delete ");
- P.text_item("ctrl | circle convex hull locate ");
- P.text_item(" ");
-
- int key = 0;
-
- int input = 0; // 0:mouse, 1: random
- int grid_width = 0;
- int line_width = 1;
- int node_width = 4;
- int N = 100;
-
- P.choice_item("input",input,"mouse","random");
-
- P.int_item("grid width ",grid_width,0,40,10);
- P.int_item("#sites ",N);
- P.int_item("line width", line_width,1,5);
- P.int_item("node width", node_width,1,10);
-
-
- for(;;)
- {
- P.open();
-
- W.set_line_width(line_width);
- W.set_node_width(node_width);
- W.set_grid_mode(grid_width);
-
- real x, y;
-
- it = nil;
- vor = false;
- triang = false;
- CH.clear();
-
-
- if (input == 1)
- { init_random();
- DT.clear();
- W.clear();
- while (N--)
- { point p(random(10,500),random(10,ymax));
- DT.insert(p,N);
- W << p;
- }
-
- DT.trace_voronoi_edges( draw_vor_seg,infi_pt);
- W.flush();
- vor = true;
- }
-
-
- while ( (key = W.read_mouse(x,y)) != 3 )
- {
- segment s;
-
- // undo previous drawings
-
- if (vor) DT.trace_voronoi_edges(draw_vor_seg,infi_pt);
- if (triang) DT.trace_triang_edges(draw_triang_seg);
- if (!CH.empty()) forall(s,CH) W.draw_arrow(s,green);
- if (it != nil) W.draw_filled_node(DT.key(it));
-
-
- vor = false;
- triang = false;
- CH.clear();
- it = nil;
-
- point p(x,y);
-
- switch (key) {
-
- case 1 : { W << p;
- DT.insert(p,0);
- break;
- }
-
- case -1 : { list(point) pl;
- real x1,y1;
- W.read_mouse_seg(x,y,x1,y1);
- segment s(x,y,x1,y1);
- segment_to_points(s,pl,10/W.scale());
- point p;
- forall(p,pl)
- { W << p;
- DT.insert(p,0);
- }
- break;
- }
-
- case 4 : { list(point) pl;
- real x1,y1;
- W.read_mouse_circle(x,y,x1,y1);
- point p(x,y);
- real r = p.distance(point(x1,y1));
- circle_to_points(circle(p,r),pl,10/W.scale());
- forall(p,pl)
- { W << p;
- DT.insert(p,0);
- }
- break;
- }
-
-
-
- case 2 : DT.trace_voronoi_edges( draw_vor_seg,infi_pt);
- vor = true;
- break;
-
- case -2 : DT.trace_triang_edges( draw_triang_seg);
- triang = true;
- break;
-
- case 5: { // convex hull
- list(DT_item) L;
- list_item it;
- DT.convex_hull(L);
- cout << "Convex Hull =\n";
- forall_items(it,L)
- { point p = DT.key(L[it]);
- point q = DT.key(L[L.cyclic_succ(it)]);
- cout << p;
- newline;
- CH.append(segment(p,q));
- W.draw_arrow(p,q,green);
- }
- newline;
- break;
- }
-
- case 3 : // panel
- break;
-
-
- case -3 : it = DT.neighbor(p);
- if (it)
- { W << DT.key(it);
- DT.del_item(it);
- }
- it = nil;
- break;
-
- case 6 : it = DT.neighbor(p);
- if (it)
- { W.draw_filled_node(DT.key(it));
- cout << DT.inf(it) << "\n";
- }
- break;
-
-
-
- } // switch
-
- W.flush();
-
- } // while
-
- } // for(;;)
-
- }
-
-
-
- void demo(int N, int wait)
- { int i;
-
- for(;;)
- {
- DT.clear();
- Wp->clear();
- Wp->message(form("%d sites",N));
- Wp->flush();
-
- for (i=0; i<N ; i++)
- { point p(random(10,500),random(10,ymax));
- DT.insert(p,i);
- *Wp << p;
- }
-
-
- //DT.trace_voronoi_sites( draw_vor_site);
-
- DT.trace_voronoi_edges( draw_vor_seg,infi_pt);
- Wp->flush();
- sleep(wait);
-
- Wp->clear();
-
- DT.trace_triang_edges( draw_triang_seg);
- Wp->flush();
- sleep(wait);
- }
-
- }
-
-
- main(int argc, char** argv)
- {
- int position=0, N=0;
- float f1=0, f2=0;
-
- float w,h,xpos,ypos;
-
- string_istream arguments(argc-1,argv+1);
-
- arguments >> f1;
- arguments >> f2;
-
-
- if (f1 == 0 && f2 == 0)
- { f1 = 0.75;
- f2 = 0.95;
- }
- else
- if (f2 == 0)
- f2 = f1;
- else
- { arguments >> position;
- arguments >> N;
- }
-
- w = SCREEN_WIDTH*f1;
- h = SCREEN_HEIGHT*f2;
-
- switch(position) {
-
- case 0: xpos = SCREEN_WIDTH - w; // upper right corner
- ypos = 0;
- break;
-
- case 1: xpos = 0; // upper left corner
- ypos = 0;
- break;
-
- case 2: xpos = 0;
- ypos = SCREEN_HEIGHT - h; // lower left corner
- break;
-
- case 3: xpos = SCREEN_WIDTH - w; // lower right corner
- ypos = SCREEN_HEIGHT - h;
- break;
- }
-
-
- window W(w,h,xpos,ypos);
-
- W.set_flush(false);
- W.set_node_width(5);
-
- W.init(0,512,0);
-
- Wp = &W;
-
- ymax = int(W.ymax()-10);
-
- if (N==0)
- interactive(W);
- else
- demo(N,1);
-
- }
-