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

MultiPlatform

  1. #include <LEDA/plane_alg.h>
  2. #include <LEDA/point.h>
  3. #include <LEDA/matrix.h>
  4. bool incircle(const point& a, const point& b, const point& c, const point& d)
  5. {
  6.    double ax = a.xcoord();
  7.    double ay = a.ycoord();
  8.    double bx = b.xcoord() - ax;
  9.    double by = b.ycoord() - ay;
  10.    double bw = bx*bx + by*by;
  11.    double cx = c.xcoord() - ax;
  12.    double cy = c.ycoord() - ay;
  13.    double cw = cx*cx + cy*cy;
  14.    double dx = d.xcoord() - ax;
  15.    double dy = d.ycoord() - ay;
  16.    double dw = dx*dx + dy*dy;
  17.    //return (by*cw-cy*bw) * (bx*dw-dx*bw) > (bx*cw-cx*bw) * (by*dw-dy*bw);
  18.    return ((by*cx-bx*cy)*dw + (cy*bw-by*cw)*dx  + (bx*cw-cx*bw)*dy)  > 0;
  19.  }
  20. static int flip_count = 0;
  21. inline bool flip_test(const GRAPH<point,edge>& G, edge e)
  22. { point a = G[source(e)];
  23.   point b = G[target(G.cyclic_adj_pred(e))];
  24.   point c = G[target(e)];
  25.   point d = G[target(G.cyclic_adj_succ(e))];
  26.   return right_turn(b,a,d) && right_turn(b,d,c) && incircle(a,b,c,d);
  27.  }
  28. void DELAUNAY_FLIPPING(GRAPH<point,edge>& G)
  29. {
  30.   edge_map<list_item> It(G,nil);
  31.   list<edge> L;
  32.   edge E[4];
  33. #define next_face_edge(x)  G.cyclic_adj_pred(G[x])
  34.   edge e;
  35.   forall_edges(e,G) 
  36.     if (It[e] == nil && flip_test(G,e)) It[G[e]] = It[e] = L.append(e);
  37.   while ( !L.empty() )
  38.   { flip_count++;
  39.     edge e = L.pop();
  40.     edge x = G.cyclic_adj_pred(e); 
  41.     // delete diagonal
  42.     G.del_edge(G[e]);
  43.     G.del_edge(e);
  44.     // collect face edges of quadriliteral
  45.     for(int i = 0; i < 4; i++) 
  46.     { E[i] = x; 
  47.       x = next_face_edge(x); 
  48.      }
  49.     // insert new diagonal
  50.     e = G.new_edge(E[1],source(E[3]),nil);
  51.     G[e] = G.new_edge(E[3],source(E[1]),e);
  52.     // test collected edges 
  53.     for(int j=0; j<4; j++)
  54.     { edge e = E[j];
  55.       if (flip_test(G,e))
  56.         { if (It[e] == nil) 
  57.           It[G[e]] = It[e] = L.push(e); 
  58.          }
  59.       else
  60.           if (It[e] != nil)
  61.           { L.del_item(It[e]);
  62.             It[G[e]] = It[e] = nil;
  63.            }
  64.      }
  65.    }
  66.  }
  67. random_source& operator>>(random_source& R, point& p)
  68. { double x,y;
  69.   R >> x >>y;
  70.   p = point(x,y);
  71.   return R;
  72. }
  73. main()
  74. {
  75.    int N = read_int("N = ");
  76.    list<point> L;
  77.    random_source ran(0,1000);
  78.    ran.set_seed(12345*N);
  79.    for(int i=0; i<N; i++) 
  80.    { point p;
  81.      ran >> p;
  82.      L.append(p);
  83.     }
  84.    GRAPH<point,edge> G;
  85.    float T = used_time();
  86.    flip_count = 0;
  87.    TRIANGULATE_POINTS(L,G);
  88.    DELAUNAY_FLIPPING(G);
  89.    cout << string("flips = %d   time = %.2f", flip_count,used_time(T)) << endl;
  90.    return 0;
  91. }