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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _voronoi.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/impl/delaunay_tree.h>
  13. #include <LEDA/d_array.h>
  14. static d_array<point,node>* VP;
  15. static GRAPH<point,point>*  G;
  16. static double infi_length;
  17. static point* XP;
  18. static void trace_segment(double x1, double y1, double x2, double y2, 
  19.                    double sx0, double sy0)
  20. {
  21.   point p(x1,y1);
  22.   point q(x2,y2);
  23.   point s(sx0,sy0);
  24.   node v,w;
  25.   if ((v = (*VP)[p]) == nil) (*VP)[p] = v = G->new_node(p);
  26.     
  27.   if ((w = (*VP)[q]) == nil) (*VP)[q] = w = G->new_node(q);
  28.   G->new_edge(v,w,s);
  29. }
  30. static void infi_point(double x1, double y1, double x2, double y2, double* x, double* y)
  31. {
  32.   vector v(x2,y2);
  33.   v = v.norm();
  34.   *x = x1 + infi_length * v[0];
  35.   *y = y1 + infi_length * v[1];
  36. }
  37. static int cmp_infi_pts(const point& p, const point& q)
  38. { // used to sort infi points clockwise around XP
  39.   segment  s1(*XP,p);
  40.   segment  s2(*XP,q);
  41.   return compare(s2.angle(),s1.angle());
  42. }
  43. void VORONOI(list<point>& site_list, double R, GRAPH<point,point>& VD)
  44.    if (site_list.empty()) return;
  45.    d_array<point,node> V(nil);
  46.    point X = site_list.head();
  47.    VP = &V;
  48.    XP = &X;
  49.    delaunay_tree DT;
  50.    point p,q;
  51.    node v;
  52.    list<point> infi_list;
  53.    forall(p,site_list) DT.insert(p,0);
  54.    infi_length = R;
  55.    G = &VD;
  56.    DT.trace_voronoi_edges(trace_segment, infi_point, 1);
  57.    // sort & link infinite points
  58.    forall_nodes(v,VD) 
  59.      if (VD.outdeg(v) == 1) infi_list.append(VD[v]);
  60.    infi_list.sort(cmp_infi_pts);
  61.    point INFI(MAXDOUBLE,MAXDOUBLE);  
  62.    list_item it;
  63.    forall_items(it,infi_list)
  64.    {  node p = V[infi_list[it]];
  65.       node q = V[infi_list[infi_list.cyclic_succ(it)]];
  66.       point s = VD[VD.first_adj_edge(q)];
  67.       VD.new_edge(p,q,s); 
  68.     }
  69.    forall_items(it,infi_list)
  70.    {  node p = V[infi_list[it]];
  71.       node q = V[infi_list[infi_list.cyclic_pred(it)]];
  72.       VD.new_edge(p,q,INFI);  
  73.     }
  74.    V.clear();
  75. }