home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / leda / src / plane / _convex_.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  3.0 KB  |  184 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _convex_hull.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/plane.h>
  16. #include <LEDA/graph.h>
  17.  
  18.  
  19. struct p_edge {
  20.  
  21. segment   s;
  22. list_item it;
  23.  
  24. OPERATOR_NEW(2)
  25. OPERATOR_DEL(2)
  26.  
  27.  
  28. };
  29.  
  30. typedef p_edge* p_edge_ptr;
  31.  
  32. void Clear(p_edge_ptr& p) { delete p; }
  33.  
  34.  
  35.  
  36. declare2(GRAPH,p_edge_ptr,int)
  37. GRAPH(p_edge_ptr,int) DAG;
  38. list(node) POL;
  39.  
  40.  
  41.  
  42. node NEW_NODE(segment s)
  43. { p_edge_ptr p = new p_edge;
  44.   p->s =s;
  45.   return DAG.new_node(p);
  46.  }
  47.  
  48.  
  49.  
  50.  
  51. node next_segment(segment s, node v )
  52. { node u = nil;
  53.   node w;
  54.   point Q;
  55.   forall_adj_nodes(w,v)
  56.     if (s.intersection(DAG[w]->s,Q)) 
  57.     { u = w;
  58.       break;
  59.      }
  60.   DAG.init_adj_iterator(v);
  61.   return u;
  62. }
  63.  
  64.  
  65.  
  66. polygon CONVEX_HULL(list(point) L)
  67.  
  68.  
  69.   point A,B,C;
  70.  
  71.   A = L.pop();
  72.   B = L.pop();
  73.   C = L.pop();
  74.  
  75.   segment sa(A,B);
  76.   segment sb(B,C);
  77.   segment sc(C,A);
  78.  
  79.   if (sa.angle(sb) < 0) 
  80.   { sa = segment(A,C);
  81.     sb = segment(C,B);
  82.     sc = segment(B,A);
  83.    }
  84.  
  85.   node root = NEW_NODE(segment(A,A));
  86.   node    a = NEW_NODE(sa);
  87.   node    b = NEW_NODE(sb);
  88.   node    c = NEW_NODE(sc);
  89.  
  90.   //DAG edges
  91.  
  92.   DAG.new_edge(root,a,0);
  93.   DAG.new_edge(root,b,0);
  94.   DAG.new_edge(root,c,0);
  95.  
  96.   //POL is initialized to triangle (A,B,C);
  97.  
  98.   DAG[a]->it = POL.append(a);
  99.   DAG[b]->it = POL.append(b);
  100.   DAG[c]->it = POL.append(c);
  101.  
  102.   double x = (A.xcoord() + B.xcoord() + C.xcoord())/3;
  103.   double y = (A.ycoord() + B.ycoord() + C.ycoord())/3;
  104.  
  105.   point I(x,y);
  106.  
  107.   point P;
  108.  
  109.   while (!L.empty())
  110.   { 
  111.     P = L.pop();
  112.  
  113.     point   Q;
  114.  
  115.     segment S(P,I);
  116.  
  117.     node v = root;
  118.  
  119.     while (v!=nil && DAG.outdeg(v)!=0) v = next_segment(S,v);
  120.  
  121.     if (v==nil) continue;
  122.  
  123.      list_item it;
  124.  
  125.  
  126.      point   rtouch  = DAG[v]->s.start();
  127.      segment rtangent(P,rtouch);
  128.      node    w = v;
  129.  
  130.      it = DAG[w]->it;
  131.      while (rtangent.angle(DAG[w]->s) <= 0) 
  132.      { 
  133.        it = POL.cyclic_succ(it);
  134.        w = POL[it];
  135.        rtouch   = DAG[w]->s.start();
  136.        rtangent = segment(P,rtouch);
  137.       }
  138.  
  139.      point   ltouch   = DAG[v]->s.end();
  140.      segment ltangent(ltouch,P);
  141.      node    u = v;
  142.  
  143.      it = DAG[u]->it;
  144.      while (ltangent.angle(DAG[u]->s) >= 0) 
  145.      { it = POL.cyclic_pred(it);
  146.        u = POL[it];
  147.        ltouch   = DAG[u]->s.end();
  148.        ltangent = segment(ltouch,P);
  149.       }
  150.  
  151.  
  152.      node x = NEW_NODE(ltangent);
  153.      node y = NEW_NODE(rtangent);
  154.  
  155.      it = POL.cyclic_succ(DAG[u]->it);
  156.      
  157.      while (it != DAG[w]->it)
  158.      { list_item i = it;
  159.        it = POL.cyclic_succ(it);
  160.        DAG.new_edge(POL[i],x);
  161.        DAG.new_edge(POL[i],y);
  162.        POL.del(i);
  163.       }
  164.      
  165.      DAG[x]->it = POL.insert(x,it,before);
  166.      DAG[y]->it = POL.insert(y,it,before);
  167.  
  168.  
  169.    }
  170.  
  171.  
  172.  
  173.  
  174.   node v;
  175.  
  176.   forall(v,POL) L.append(DAG[v]->s.start());
  177.  
  178.   return polygon(L);
  179.  
  180. }
  181.  
  182.