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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _delaunay.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #include <LEDA/plane_alg.h>
  12. #include <LEDA/planar_map.h>
  13. typedef point   POINT;
  14. // in the current version we use GRAPH<POINT,edge> for representing
  15. // planar maps ( G[e] = rev(e) )
  16. static int flip_count = 0;
  17. inline bool flip_test(const GRAPH<POINT,edge>& G, edge e)
  18. { POINT a = G[source(e)];
  19.   POINT b = G[target(G.cyclic_adj_pred(e))];
  20.   POINT c = G[target(e)];
  21.   POINT d = G[target(G.cyclic_adj_succ(e))];
  22.   return right_turn(b,a,d) && right_turn(b,d,c) && incircle(a,b,c,d);
  23.  }
  24. static void DELAUNAY_FLIPPING(GRAPH<POINT,edge>& G)
  25. {
  26.   edge_map<list_item> It(G,nil);
  27.   list<edge> L;
  28.   edge E[4];
  29.   edge e;
  30.   forall_edges(e,G) 
  31.     if (It[e] == nil && flip_test(G,e)) It[G[e]] = It[e] = L.append(e);
  32.   while ( !L.empty() )
  33.   { flip_count++;
  34.     edge e = L.pop();
  35.     edge x = G.cyclic_adj_pred(e); 
  36.     // delete diagonal
  37.     G.del_edge(G[e]);
  38.     G.del_edge(e);
  39.     // collect face edges of quadriliteral
  40.     for(int i = 0; i < 4; i++) 
  41.     { E[i] = x; 
  42.       x = G.cyclic_adj_pred(G[x]);
  43.      }
  44.     // insert new diagonal
  45.     e = G.new_edge(E[1],source(E[3]),nil);
  46.     G[e] = G.new_edge(E[3],source(E[1]),e);
  47.     // test collected edges 
  48.     for(int j=0; j<4; j++)
  49.     { edge e = E[j];
  50.       if (flip_test(G,e))
  51.         { if (It[e] == nil) 
  52.           It[G[e]] = It[e] = L.push(e); 
  53.          }
  54.       else
  55.           if (It[e] != nil)
  56.           { L.del_item(It[e]);
  57.             It[G[e]] = It[e] = nil;
  58.            }
  59.      }
  60.    }
  61.  }
  62. void DELAUNAY_TRIANG(const list<POINT>& L, GRAPH<POINT,edge>& T)
  63. {
  64.   TRIANGULATE_POINTS(L,T);
  65.   DELAUNAY_FLIPPING(T);
  66. }
  67. void DELAUNAY_TRIANG(const list<POINT>& L, graph& T, 
  68.                                            node_array<POINT>& pos,
  69.                                            edge_array<edge>&  rev)
  70. { GRAPH<POINT,edge> G;
  71.   DELAUNAY_TRIANG(L,G);
  72.   T = G;
  73.   node v;
  74.   pos.init(T);
  75.   forall_nodes(v,G) pos[v] = G[v];
  76.   edge e;
  77.   rev.init(T);
  78.   forall_edges(e,G) rev[e] = G[e];
  79. }
  80. void DELAUNAY_TRIANG(const list<POINT>& L, planar_map& T, 
  81.                                            node_array<POINT>& pos)
  82. { GRAPH<POINT,edge> G;
  83.   DELAUNAY_TRIANG(L,G);
  84.   T = G;
  85.   node v;
  86.   pos.init(T);
  87.   forall_nodes(v,G) pos[v] = G[v];
  88. }