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

MultiPlatform

  1. #include <LEDA/plane_alg.h>
  2. template <class Point>
  3. struct ch_edge {
  4. Point   source;
  5. Point   target;
  6. ch_edge* succ;
  7. ch_edge* pred;
  8. ch_edge* link;
  9. bool     outside;
  10. ch_edge(const Point& a, const Point& b) : source(a), target(b) 
  11. { outside = true; }
  12. ~ch_edge() {}
  13. };
  14. template <class Point>
  15. list<Point>  C_HULL1(list<Point>& L)
  16.   // move the four extreme points to the front of |L|
  17.   list_item it;
  18.   list_item xmax_it = L.first();
  19.   list_item xmin_it = L.first();
  20.   list_item ymax_it = L.first();
  21.   list_item ymin_it = L.first();
  22.   forall_items(it,L) 
  23.   { if (L[it].xcoord() > L[xmax_it].xcoord()) xmax_it = it;
  24.     if (L[it].xcoord() < L[xmin_it].xcoord()) xmin_it = it;
  25.     if (L[it].ycoord() > L[ymax_it].ycoord()) ymax_it = it;
  26.     if (L[it].ycoord() > L[ymin_it].ycoord()) ymin_it = it;
  27.    }
  28.   L.push(L[xmax_it]); L.del(xmax_it);
  29.   L.push(L[xmin_it]); L.del(xmin_it);
  30.   L.push(L[ymax_it]); L.del(ymax_it);
  31.   L.push(L[ymin_it]); L.del(ymin_it);
  32.   it = L.first();
  33.   Point A = L[it];
  34.   it = L.succ(it);
  35.   Point B = L[it];
  36.   it = L.succ(it);
  37.   ch_edge<Point>* T1 = new ch_edge<Point>(A,B);
  38.   ch_edge<Point>* T2 = new ch_edge<Point>(B,A);
  39.   ch_edge<Point>* last_edge = T2;
  40.   T2->link = T1;
  41.   T1->link = nil;
  42.   T1->succ = T2;
  43.   T1->pred = T2;
  44.   T2->succ = T1;
  45.   T2->pred = T1;
  46.   // scan remaining points
  47.   while (it != nil)
  48.   { Point P = L[it];
  49.     it = L.succ(it);
  50.     ch_edge<Point>* p = (right_turn(A,B,P)) ?  T1 : T2;
  51.     while ( ! p->outside) //(p->succ->pred != p) 
  52.     { ch_edge<Point>* r0 = p->pred;
  53.       if (right_turn(r0->source,r0->target,P)) p = r0;
  54.       else { ch_edge<Point>* r1 = p->succ;
  55.              if (right_turn(r1->source,r1->target,P)) p = r1;
  56.              else { p =  nil; break; }
  57.             }
  58.      }
  59.     if (p==nil) continue;  // P lies inside convex hull
  60.     // compute "upper" tangent (p,high->source)
  61.     ch_edge<Point>* high = p->succ;
  62.     while (right_turn(high->source,high->target,P)) high = high->succ;
  63.     // compute "lower" tangent (p,low->target)
  64.     ch_edge<Point>* low = p->pred;
  65.     while (right_turn(low->source,low->target,P)) low = low->pred;
  66.     p = low->succ;  // p = successor of low edge
  67.     // insert two edges between "low" and "high"
  68.     ch_edge<Point>* e_l = new ch_edge<Point>(low->target,P);
  69.     ch_edge<Point>* e_h = new ch_edge<Point>(P,high->source);
  70.     e_h->link = e_l;
  71.     e_l->link = last_edge;
  72.     last_edge = e_h;
  73.     e_h->succ = high;
  74.     e_l->pred = low;
  75.     high->pred = e_l->succ = e_h;
  76.     low->succ  = e_h->pred = e_l;
  77.     // mark edges between low and high as "inside" and define refinements
  78.     while (p != high)
  79.     { ch_edge<Point>* q = p->succ;
  80.       p->pred = e_l;
  81.       p->succ = e_h;
  82.       p->outside = false;
  83.       p = q;
  84.      }
  85.      
  86.    }
  87.   // return list of vertices
  88.   list<Point> CH;
  89.   CH.append(last_edge->source);
  90.   for(ch_edge<Point>* p = last_edge->succ; p != last_edge; p = p->succ) 
  91.      CH.append(p->source);
  92.  // clean up 
  93.   while (last_edge)
  94.   { ch_edge<Point>* p = last_edge;
  95.     last_edge = last_edge->link;
  96.     delete p;
  97.    }
  98.   return CH;
  99. }
  100. main()
  101. {
  102.   int N = read_int("N = ");
  103.   int k = read_int("k = ");
  104.   list<point>      L1;
  105.   list<rat_point>  L2;
  106.   rand_int.set_seed(N*N);
  107.   for(int i = 0; i<N; i++) 
  108.   { integer x = integer::random(k);
  109.     integer y = integer::random(k);
  110.     L1.append(point(x.todouble(),y.todouble()));
  111.     L2.append(rat_point(x,y,1));
  112.    }
  113.   
  114.  { cout << "C_HULL1(point)      " << flush;
  115.    float T = used_time();
  116.    list<point> C = C_HULL1(L1);
  117.    cout << string("|C| = %d   time = %.2f",C.length(),used_time(T)) << endl;
  118.   }
  119.  { cout << "CONVEX_HULL(point) " << flush;
  120.    float T = used_time();
  121.    list<point> C = CONVEX_HULL(L1);
  122.    cout << string("|C| = %d   time = %.2f",C.length(),used_time(T)) << endl;
  123.   }
  124.  { cout << "C_HULL1(rat_point)  " << flush;
  125.    float T = used_time();
  126.    list<rat_point> C = C_HULL1(L2);
  127.    cout << string("|C| = %d   time = %.2f",C.length(),used_time(T)) << endl;
  128.   }
  129.   return 0;
  130. }