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

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _triangulation.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.  
  16. /*******************************************************************************
  17. *                                                                              *
  18. *  TRIANGULATE_PLANAR_MAP  (triangulation)                                     *
  19. *                                                                              *
  20. *******************************************************************************/
  21.  
  22.  
  23.  
  24. #include <LEDA/graph_alg.h>
  25.  
  26. /*
  27. #include <LEDA/d_array.h>
  28.  
  29. declare2(d_array,edge,edge)
  30. */
  31.  
  32.  
  33. #define NEXT_FACE_EDGE(e) G.cyclic_adj_pred(REV[e]) 
  34.  
  35. list(edge) TRIANGULATE_PLANAR_MAP(graph& G)
  36.  
  37. /*
  38.    G is a planar map. This procedure triangulates all faces of G
  39.    without introducing multiple edges. The algorithm was suggested by 
  40.    Christian Uhrig and Torben Hagerup. First implementation 9/5/88
  41.  
  42.    Description:
  43.  
  44.    Triangulating a planar graph G, i.e., adding edges
  45.    to G to obtain a chordal planar graph, in linear time:
  46.    
  47.    1) Compute a (combinatorial) embedding of G.
  48.    
  49.    2) Step through the vertices of G. For each vertex u,
  50.    triangulate those faces incident on u that have not
  51.    already been triangulated. For each vertex u, this
  52.    consists of the following:
  53.    
  54.      a) Mark the neighbours of u. During the processing
  55.    of u, a vertex will be marked exactly if it is a
  56.    neighbour of u.
  57.    
  58.      b) Process in any order those faces incident on u
  59.    that have not already been triangulated. For each such
  60.    face with boundary vertices u=x_1,...,x_n,
  61.         I)   If n=3, do nothing; otherwise
  62.         II)  If x_3 is not marked, add an edge {x_1,x_3},
  63.              mark x_3 and continue triangulating the face
  64.              with boundary vertices x_1,x_3,x_4,...,x_n.
  65.         III) If x_3 is marked, add an edge {x_2,x_4} and
  66.              continue triangulating the face with boundary
  67.              vertices x_1,x_2,x_4,x_5,...,x_n.
  68.    
  69.      c) Unmark the neighbours of x_1.
  70.    
  71.    Proof of correctness:
  72.    
  73.    A) All faces are triangulated.
  74.    This is rather obvious.
  75.    
  76.    B) There will be no multiple edges.
  77.    During the processing of a vertex u, the marks on
  78.    neighbours of u clearly prevent us from adding a multiple
  79.    edge with endpoint u. After the processing of u, such an
  80.    edge is not added because all faces incident on u have
  81.    been triangulated. This takes care of edges added in
  82.    step II).
  83.    Whenever an edge {x_2,x_4} is added in step III), the
  84.    presence of an edge {x_1,x_3} implies, by a topological
  85.    argument, that x_2 and x_4 are incident on exactly one
  86.    common face, namely the face currently being processed.
  87.    Hence we never add another edge {x_2,x_4}.
  88.    
  89. */
  90.    
  91.  
  92.   node v;
  93.   edge x;
  94.   list(edge) L;
  95.  
  96.   node_array(int)  marked(G,0);
  97.  
  98.   edge_array(edge) REV(G, 3*G.number_of_edges(), nil);
  99.  
  100.   compute_correspondence(G,REV);
  101.  
  102. /*
  103.   d_array(edge,edge) reversal;
  104.   forall_edges(x,G) reversal[x] = REV[x]; 
  105. */
  106.  
  107.   forall_nodes(v,G)
  108.   {
  109.     edgelist El = G.adj_edges(v);
  110.     edge e,e1,e2,e3;
  111.  
  112.     forall(e,El) marked[target(e)]=1;
  113.  
  114.     forall(e,El)
  115.     { 
  116.       e1 = e;
  117.       e2 = NEXT_FACE_EDGE(e1);
  118.       e3 = NEXT_FACE_EDGE(e2);
  119.  
  120.       while (target(e3) != v)
  121.       // e1,e2 and e3 are the first three edges in a clockwise 
  122.       // traversal of a face incident to v and t(e3) is not equal
  123.       // to v.
  124.        if ( !marked[target(e2)] )
  125.         { // we mark w and add the edge {v,w} inside F, i.e., after
  126.           // dart e1 at v and after dart e3 at w.
  127.  
  128.           marked[target(e2)] = 1;
  129.           L.append(x  = G.new_edge(e3,source(e1)));
  130.           L.append(e1 = G.new_edge(e1,source(e3)));
  131.           REV[x] = e1;
  132.           REV[e1] = x;
  133.           e2 = e3;
  134.           e3 = NEXT_FACE_EDGE(e2);
  135.         }
  136.         else
  137.         { // we add the edge {source(e2),target(e3)} inside F, i.e.,
  138.           // after dart e2 at source(e2) and before dart 
  139.           // reversal_of[e3] at target(e3).
  140.  
  141.           e3 = NEXT_FACE_EDGE(e3); 
  142.           L.append(x  = G.new_edge(e3,source(e2)));
  143.           L.append(e2 = G.new_edge(e2,source(e3)));
  144.           REV[x] = e2;
  145.           REV[e2] = x;
  146.         }
  147.      //end of while
  148.  
  149.     } //end of stepping through incident faces
  150.  
  151.    node w; forall_adj_nodes(w,v) marked[w] = 0;
  152.  
  153.   } // end of stepping through nodes
  154.  
  155. return L;
  156.  
  157. } //end of triangulation
  158.