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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _subdivision.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/segment.h>
  12. #include <LEDA/subdivision.h>
  13. #include <LEDA/p_dictionary.h>
  14. #include <LEDA/sortseq.h>
  15. #include <LEDA/p_queue.h>
  16. static double x_sweep;
  17. #if defined(__GNUC__)
  18. inline
  19. #else
  20. static
  21. #endif
  22. int compare(const segment& s1,const segment& s2)
  23. {
  24.   if (s1 == s2) return 0;
  25.   double sl1 = s1.slope();
  26.   double sl2 = s2.slope();
  27.   if (s1.start() == s2.start()) return compare(sl1,sl2);
  28.   if (s1.end() == s2.end()) return compare(sl2,sl1);
  29.   double y1 = sl1*x_sweep+s1.y_abs();
  30.   double y2 = sl2*x_sweep+s2.y_abs();
  31.   return (y1 > y2) ? 1 : -1;
  32. }
  33. typedef p_dictionary<segment,face> strip;
  34. typedef p_dictionary<segment,face>* Strip_Ptr;
  35. typedef sortseq<double,Strip_Ptr> strip_list;
  36. typedef p_queue<point,edge> X_structure;
  37. SubDivision::SubDivision(const graph& G) : planar_map(G)
  38.   edge e;
  39.   segment s;
  40.   point p;
  41.   strip sp;
  42.   // compute strips
  43.   strip_list* strips = new strip_list;
  44.   strip_ptr = (void*)strips;
  45.   X_structure X;
  46.   // initialize X-structure
  47.   forall_edges(e,*this) 
  48.   { point p = position(source(e));
  49.     point q = position(target(e));
  50.     if (p.xcoord() < q.xcoord()) 
  51.     { X.insert(p,e);
  52.       X.insert(q,e);
  53.      }
  54.    }
  55.   // sweep
  56.   strip Y;
  57.   x_sweep = -MAXDOUBLE;
  58.   strips->insert(x_sweep, new strip(Y));    
  59.   while( !X.empty() )
  60.   { point    p = X.prio(X.find_min());
  61.     list<edge> L,R;
  62.     while ( !X.empty() )
  63.     { pq_item it = X.find_min();
  64.       point    q = X.prio(it);
  65.       edge     e = X.inf(it);
  66.       if (q != p) break;
  67.       if (q == position(source(e)))  // left  end
  68.           L.append(e);    
  69.       else                           // right end
  70.           R.append(e);    
  71.       X.del_item(it);
  72.      }
  73.     // Insert new strip into version List
  74.     x_sweep = p.xcoord();
  75.     edge e;
  76.     forall(e,R) 
  77.        Y = Y.del(segment(position(source(e)),position(target(e))));
  78.     forall(e,L) 
  79.        Y = Y.insert(segment(position(source(e)), position(target(e))), adj_face(e));
  80.     L.clear();
  81.     R.clear();
  82.     strips->insert(x_sweep, new strip(Y));    
  83.     }
  84.    strips->insert(MAXDOUBLE, new strip(Y));    
  85.    // compute outer face
  86.    seq_item sit = strips->min();
  87.    sit = strips->succ(sit);
  88.    outer_face = Y.inf(strips->inf(sit)->min());
  89. }
  90. face SubDivision::locate_point(point p) const
  91. {
  92.   strip_list* strips = (strip_list*)strip_ptr;
  93.   seq_item sit = strips->locate(p.xcoord()); 
  94.   Strip_Ptr Y = strips->inf(strips->pred(sit));
  95.   x_sweep = p.xcoord();
  96.   p_dic_item it = Y->locate(segment(p,0,1));
  97.   return (it == nil) ? outer_face : Y->inf(it);
  98.  }
  99. void SubDivision::print_stripes() const
  100. { seq_item it1;
  101.   p_dic_item it2;
  102.   strip_list* strips = (strip_list*)strip_ptr;
  103.   forall_items(it1,*strips)
  104.   { Strip_Ptr sp = strips->inf(it1);
  105.     forall_items(it2,*sp) 
  106.       cout << sp->key(it2) << " f = " << sp->inf(it2) << "n";
  107.     newline;
  108.   }
  109.   newline;
  110.  }
  111. SubDivision::~SubDivision() 
  112. { strip_list* strips = (strip_list*)strip_ptr;
  113.   seq_item it;
  114.   forall_items(it,*strips) delete strips->inf(it);
  115.   delete strips; 
  116. }