triang_demo.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:4k
开发平台:

MultiPlatform

  1. #include <LEDA/window.h>
  2. #include <LEDA/plane_alg.h>
  3. #include <LEDA/point.h>
  4. #include <LEDA/map.h>
  5. window W;
  6. void draw_circle(window& W, point a, point b, point c)
  7. { line L1 = p_bisector(a,b);
  8.   line L2 = p_bisector(a,c);
  9.   point m;
  10.   L1.intersection(L2,m);
  11.   W.draw_disc(m,m.distance(a),violet);
  12. }
  13. static int  flip_count = 0;
  14. static int  visited_edges = 0;
  15. static int  speed = 40;
  16. static bool animate = false;
  17. void animate_flip(point a, point b, point c, point d, int n)
  18. {
  19.   W.del_messages();
  20.   W.message(string(" %2d flips",flip_count++));
  21.   
  22.   segment s1(a,b);
  23.   segment s2(c,d);
  24.   double l1 = s1.length()/n;
  25.   double l2 = s2.length()/n;
  26.   double a1 = s1.angle(); 
  27.   double a2 = s2.angle(); 
  28.   while (n--)
  29.   { point a_new = a.translate(a1,l1);
  30.     point c_new = c.translate(a2,l2);
  31.     W.draw_edge(a_new,c_new,red);
  32.     W.draw_edge(a,c,red);
  33.     a = a_new;
  34.     c = c_new;
  35.    }
  36.   W.draw_edge(a,c,red);
  37.   W.draw_edge(a,c,blue);
  38. }
  39.    
  40.   
  41. void flipping(GRAPH<point,edge> &G)
  42. {
  43.   edge_map<bool> marked(G,false);
  44.   list<edge> L;
  45.   edge e;
  46.   forall_edges(e,G)  marked[e] = false;
  47.   forall_edges(e,G) 
  48.     if ( !marked[e] )
  49.     { L.append(e);
  50.       marked[e] = true;
  51.       marked[G[e]] = true;
  52.       if (animate) W.draw_edge(G[source(e)],G[target(e)],red);
  53.      }
  54.   while ( !L.empty() )
  55.   { visited_edges++;
  56.     edge e = L.pop();
  57.     marked[e] = false;
  58.     marked[G[e]] = false;
  59.     edge e1 =  G.cyclic_adj_pred(e); 
  60.     edge e2 =  G.cyclic_adj_pred(G[e1]); 
  61.     edge e3 =  G.cyclic_adj_pred(G[e]); 
  62.     edge e4 =  G.cyclic_adj_pred(G[e3]); 
  63.     point a = G[source(e1)];
  64.     point b = G[source(e2)];
  65.     point c = G[source(e3)];
  66.     point d = G[source(e4)];
  67.     if ( orientation(b,a,d) > 0 && orientation(b,d,c) > 0
  68.          && incircle(a,b,c,d) > 0)
  69.     { 
  70.       if (animate) animate_flip(a,b,c,d,8000/speed);
  71.       G.del_edge(G[e]);
  72.       G.del_edge(e);
  73.       e = G.new_edge(e2,source(e4),nil);
  74.       G[e] = G.new_edge(e4,source(e2),e);
  75.       marked[e] = false;
  76.       marked[G[e]] = false;
  77.       if ( !marked[e1]) 
  78.       { L.append(e1); 
  79.         marked[e1] = marked[G[e1]] = true; 
  80.         if (animate)
  81.         { W.draw_edge(a,b,blue);
  82.           W.draw_edge(a,b,red);
  83.          }
  84.        }
  85.       if ( !marked[e2]) 
  86.       { L.append(e2); 
  87.         marked[e2] = marked[G[e2]] = true; 
  88.         if (animate)
  89.         { W.draw_edge(b,c,blue);
  90.           W.draw_edge(b,c,red);
  91.          }
  92.        }
  93.       if ( !marked[e3]) 
  94.       { L.append(e3); 
  95.         marked[e3] = marked[G[e3]] = true; 
  96.         if (animate)
  97.         { W.draw_edge(c,d,blue);
  98.           W.draw_edge(c,d,red);
  99.          }
  100.        }
  101.       if ( !marked[e4]) 
  102.       { L.append(e4); 
  103.         marked[e4] = marked[G[e4]] = true; 
  104.         if (animate)
  105.         { W.draw_edge(d,a,blue);
  106.           W.draw_edge(d,a,red);
  107.          }
  108.        }
  109.      }
  110.      else
  111.      if (animate)
  112.      { W.draw_edge(a,c,red);
  113.        W.draw_edge(a,c,blue);
  114.       }
  115.    }
  116. }
  117. random_source& operator>>(random_source& R, point& p)
  118. { double x,y;
  119.   R >> x >>y;
  120.   p = point(100*x,100*y);
  121.   return R;
  122. }
  123. main()
  124. {
  125.    int N = 100;
  126.    bool grid = false;
  127.    panel P;
  128.    P.int_item("speed",speed,1,100);
  129.    P.bool_item("animate",animate);
  130.    P.bool_item("grid",grid);
  131.    P.int_item("#points",N,0,500);
  132.    P.open();
  133.    list<point> L;
  134.    random_source ran(0,1000);
  135. //window W;
  136. W.init(-5,105,-5);
  137. if (grid) W.set_grid_mode(2);
  138. W.set_node_width(2);
  139. L.append(point(0,0));
  140. L.append(point(100,0));
  141. L.append(point(50,100));
  142. point p;
  143. for(int i=0; i<N; i++) 
  144. { ran >> p;
  145.   L.append(p);
  146.  }
  147. forall(p,L) W.draw_filled_node(p);
  148. GRAPH<point,edge> G;
  149. TRIANGULATE_POINTS(L,G);
  150. W.set_mode(xor_mode);
  151. flipping(G);
  152. W.set_mode(src_mode);
  153. W.set_flush(false);
  154. edge e;
  155. forall_edges(e,G) W.draw_edge(G[source(e)],G[target(e)],blue);
  156. W.flush();
  157. W.set_mode(xor_mode);
  158. while (W >> p)
  159. {
  160.   forall_edges(e,G)
  161.   { edge e1 = e;
  162.     edge e2 = G.cyclic_adj_pred(G[e1]);
  163.     edge e3 = G.cyclic_adj_pred(G[e2]);
  164.     point a = G[source(e1)];
  165.     point b = G[source(e2)];
  166.     point c = G[source(e3)];
  167.     if ( left_turn(a,b,p) && left_turn(b,c,p) && left_turn(c,a,p) )
  168.     {
  169.       W.draw_filled_node(p);
  170.       //W.draw_edge(p,a,red);
  171.       //W.draw_edge(p,b,red);
  172.       //W.draw_edge(p,c,red);
  173.       node v = G.new_node(p);
  174.       edge x = G.new_edge(e1,v,nil);
  175.       G[x] = G.new_edge(v,source(e1),x);
  176.       x = G.new_edge(e2,v,nil);
  177.       G[x] = G.new_edge(v,source(e2),x);
  178.       x = G.new_edge(e3,v,nil);
  179.       G[x] = G.new_edge(v,source(e3),x);
  180.       break;
  181.     }
  182.   }
  183.   W.clear();
  184.   node v;
  185.   forall_nodes(v,G) W.draw_filled_node(G[v]);
  186.   animate = true;
  187.   flipping(G);
  188. }
  189. return 0;
  190. }