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

MultiPlatform

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