dtriang_demo.c
Upload User: gzelex
Upload Date: 2007-01-07
Package Size: 707k
Code Size: 6k
Development Platform:

MultiPlatform

  1. #include <LEDA/graph.h>
  2. #include <LEDA/plane_alg.h>
  3. #include <LEDA/window.h>
  4. window W;
  5. void draw_graph(const GRAPH<point,edge>& G)
  6. { edge_array<bool> drawn(G,false);
  7.   node v;
  8.   forall_nodes(v,G) W.draw_filled_node(G[v],blue);
  9.   edge e;
  10.   forall_edges(e,G) 
  11.     if (!drawn[e])
  12.     { W.draw_edge(G[source(e)],G[target(e)],blue);
  13.       drawn[G[e]] = drawn[e] = true;
  14.      }
  15.  }
  16. point center(point a, point b, point c)
  17. { line L1 = p_bisector(a,b);
  18.   line L2 = p_bisector(a,c);
  19.   point m;
  20.   L1.intersection(L2,m);
  21.   return m;
  22. }
  23. void draw_circle(point a, point b, point c)
  24. { line L1 = p_bisector(a,b);
  25.   line L2 = p_bisector(a,c);
  26.   point m;
  27.   L1.intersection(L2,m);
  28.   W.draw_disc(m,m.distance(a),violet);
  29. }
  30. #define next_face_edge(x)  G.cyclic_adj_pred(G[x])
  31. void draw_voro(window& W, const GRAPH<point,edge>& G)
  32.   point nil_point;
  33.   edge_array<bool>  visited(G,false);
  34.   edge_array<point> vnode(G,nil_point);
  35.   edge e;
  36.   forall_edges(e,G)
  37.      if (identical(vnode[e],nil_point))
  38.      { edge e1 = next_face_edge(e);
  39.        edge e2 = next_face_edge(e1);
  40.        point a = G[source(e)];
  41.        point b = G[source(e1)];
  42.        point c = G[source(e2)];
  43.        vnode[e] = vnode[e1] = vnode[e2] = center(a,b,c);
  44.      }
  45. /*
  46.   node v;
  47.   forall_nodes(v,G) W.draw_point(G[v],blue);
  48. */
  49.   forall_edges(e,G)
  50.      if (!visited[e])
  51.      { edge r = G[e];
  52.        visited[r] = visited[e] = true;
  53.        W.draw_segment(vnode[e], vnode[r],red);
  54.      }
  55. }
  56. /*
  57. void build_voro(window& W, const GRAPH<point,edge>& G)
  58.   point nil_point;
  59.   GRAPH<rat_point,rat_point> V;
  60.   d_array<rat_point,node>  A;
  61.   edge_array<point> vnode(G,nil_point);
  62.   edge e;
  63.   forall_edges(e,G)
  64.      if (identical(vnode[e],nil_point))
  65.      { edge e1 = next_face_edge(e);
  66.        edge e2 = next_face_edge(e1);
  67.        point a = G[source(e)];
  68.        point b = G[source(e1)];
  69.        point c = G[source(e2)];
  70.        rat_point m = center(a,b,c);
  71.        node v = V.new_node(m);
  72.        vnode[e] = vnode[e1] = vnode[e2] = v;
  73.      }
  74.   forall_edges(e,G)
  75.        V.new_edge(vnode[e], vnode[G[e]], G[source(e)]);
  76. }
  77. */
  78. void activate_edge(const GRAPH<point,edge>& G, edge e)
  79. { W.draw_edge(G[source(e)],G[target(e)],blue);
  80.   W.draw_edge(G[source(e)],G[target(e)],red);
  81.  }
  82. void inactivate_edge(const GRAPH<point,edge>& G, edge e)
  83. { W.draw_edge(G[source(e)],G[target(e)],red);
  84.   W.draw_edge(G[source(e)],G[target(e)],blue);
  85.  }
  86. static int  flip_count = 0;
  87. static int  speed = 40;
  88. static bool animate = false;
  89. void animate_flip(const GRAPH<point,edge>& G, edge e, int n)
  90. { point a = G[source(e)];
  91.   point b = G[target(G.cyclic_adj_pred(e))];
  92.   point c = G[target(e)];
  93.   point d = G[target(G.cyclic_adj_succ(e))];
  94.   W.del_messages();
  95.   W.message(string(" %2d flips",flip_count++));
  96.   
  97.   segment s1(a,b);
  98.   segment s2(c,d);
  99.   double l1 = s1.length()/n;
  100.   double l2 = s2.length()/n;
  101.   double a1 = s1.angle(); 
  102.   double a2 = s2.angle(); 
  103.   while (n--)
  104.   { point a_new = a.translate(a1,l1);
  105.     point c_new = c.translate(a2,l2);
  106.     W.draw_edge(a_new,c_new,red);
  107.     W.draw_edge(a,c,red);
  108.     a = a_new;
  109.     c = c_new;
  110.    }
  111.   W.draw_edge(a,c,red);
  112.   W.draw_edge(a,c,blue);
  113. }
  114. edge locate_point(const GRAPH<point,edge>& G, point p)
  115. { edge e;
  116.   forall_edges(e,G)
  117.   { edge e1 = next_face_edge(e);
  118.     point a = G[source(e)];
  119.     point b = G[target(e)];
  120.     point c = G[target(e1)];
  121.     if ( left_turn(a,b,p) && left_turn(b,c,p) && left_turn(c,a,p) ) return e;
  122.    }
  123.   return nil;
  124. }
  125. inline bool flip_test(const GRAPH<point,edge>& G, edge e)
  126. { point a = G[source(e)];
  127.   point b = G[target(G.cyclic_adj_pred(e))];
  128.   point c = G[target(e)];
  129.   point d = G[target(G.cyclic_adj_succ(e))];
  130.   return right_turn(b,a,d) && right_turn(b,d,c) && incircle(a,b,c,d);
  131.  }
  132. void DELAUNAY_FLIPPING(GRAPH<point,edge>& G)
  133. {
  134.   edge_map<list_item> It(G,nil);
  135.   list<edge> L;
  136.   edge E[4];
  137.   edge e;
  138.   forall_edges(e,G) 
  139.     if (It[e] == nil && flip_test(G,e)) 
  140.     { It[G[e]] = It[e] = L.append(e);
  141.       if (animate) activate_edge(G,e);
  142.      }
  143.   while ( !L.empty() )
  144.   { flip_count++;
  145.     edge e = L.pop();
  146.     edge x = G.cyclic_adj_pred(e); 
  147.     if (animate) animate_flip(G,e,8000/speed);
  148.     // delete diagonal
  149.     G.del_edge(G[e]);
  150.     G.del_edge(e);
  151.     // collect face edges of quadriliteral
  152.     for(int i = 0; i < 4; i++) 
  153.     { E[i] = x; 
  154.       x = next_face_edge(x); 
  155.      }
  156.     // insert new diagonal
  157.     e = G.new_edge(E[1],source(E[3]));
  158.     G[e] = G.new_edge(E[3],source(E[1]),e);
  159.     // test collected edges 
  160.     for(int j=0; j<4; j++)
  161.     { edge e = E[j];
  162.       if (flip_test(G,e))
  163.         { if (It[e] == nil) 
  164.           It[G[e]] = It[e] = L.push(e); 
  165.           if (animate) activate_edge(G,e);
  166.          }
  167.       else
  168.           if (It[e] != nil)
  169.           { L.del_item(It[e]);
  170.             It[G[e]] = It[e] = nil;
  171.             if (animate) inactivate_edge(G,e);
  172.            }
  173.      }
  174.    }
  175.  }
  176. random_source& operator>>(random_source& R, point& p)
  177. { double x,y;
  178.   R >> x >>y;
  179.   p = point(1000*x,1000*y);
  180.   return R;
  181. }
  182. main()
  183. {
  184.    int N = 1000;
  185.    bool grid = false;
  186.    panel P;
  187.    P.int_item("speed",speed,1,100);
  188.    P.bool_item("animate",animate);
  189.    P.bool_item("grid",grid);
  190.    P.int_item("#points",N,0,10000);
  191.    P.open();
  192.    list<point> L;
  193.    random_source ran(0,100);
  194. //window W;
  195. W.init(-5,105,-5);
  196. if (grid) W.set_grid_mode(4);
  197. W.set_node_width(3);
  198. W.set_mode(xor_mode);
  199. int infinity = 200;
  200. L.append(point(-infinity,-infinity));
  201. L.append(point(-infinity,+infinity));
  202. L.append(point(+infinity,-infinity));
  203. L.append(point(+infinity,+infinity));
  204. point p;
  205. for(int i=0; i<N; i++) 
  206. { ran >> p;
  207.   L.append(p);
  208.   W.draw_point(p,blue);
  209.  }
  210. GRAPH<point,edge> G;
  211. TRIANGULATE_POINTS(L,G);
  212. DELAUNAY_FLIPPING(G);
  213. if (!animate)
  214. { W.clear();
  215.   draw_graph(G);
  216.  }
  217. W.read_mouse();
  218. /*
  219. draw_voro(W,G);
  220. W.read_mouse();
  221. W.clear();
  222. draw_graph(G);
  223. */
  224. for(;;)
  225. { int but = W.read_mouse(p);
  226.   if (but == 1)
  227.   { edge e = locate_point(G,p);
  228.     if ( e != nil)
  229.     { node v = G.new_node(p);
  230.       W.draw_filled_node(p);
  231.       for(int i=0; i<3; i++)
  232.       { edge x = G.new_edge(e,v);
  233.         G[x] = G.new_edge(v,source(e),x);
  234.         e = next_face_edge(e);
  235.         W.draw_edge(G[source(x)],p,blue);
  236.        }
  237.       animate = true;
  238.       DELAUNAY_FLIPPING(G);
  239.      }
  240.    }
  241.    if (but == 2) // display circle 
  242.    { edge e = locate_point(G,p);
  243.      int v;
  244.      double a,b;
  245.      if ( e != nil)
  246.      { edge x = next_face_edge(e);
  247.        draw_circle(G[source(e)],G[target(e)],G[target(x)]);
  248.        while (W.read_event(v,a,b) != button_release_event);
  249.        draw_circle(G[source(e)],G[target(e)],G[target(x)]);
  250.       }
  251.     }
  252.    if (but == 3) break;
  253. }
  254. return 0;
  255. }