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

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _planar_map.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. #include <LEDA/planar_map.h>
  17.  
  18.  
  19. declare(edge_array,edge)
  20. declare(edge_array,bool)
  21. declare(node_array,bool)
  22.  
  23. extern bool compute_correspondence(const graph&, edge_array(edge)&);
  24.  
  25. list(edge) planar_map::adj_edges(face f) const
  26. { list(edge) result(f->head);
  27.   edge e1 = succ_face_edge(f->head);
  28.   while (e1!=f->head)
  29.   { result.append(e1);
  30.     e1 = succ_face_edge(e1);
  31.    }
  32.   return result;
  33.  }
  34.  
  35. list(node) planar_map::adj_nodes(face f) const
  36. { list(node) result(source(f->head));
  37.   edge e1 = succ_face_edge(f->head);
  38.   while (e1!=f->head)
  39.   { result.append(source(e1));
  40.     e1 = succ_face_edge(e1);
  41.    }
  42.   return result;
  43.  }
  44.  
  45. list(face) planar_map::adj_faces(node v) const
  46. { list(face) result;
  47.   edge e;
  48.   forall_adj_edges(e,v) result.append(adj_face(e));
  49.   return result;
  50.  }
  51.  
  52. face  planar_map::new_face(ent i) 
  53.   //copy_face_entry(i);
  54.  
  55.   face f=new i_face(i,this);
  56.   f->loc=F_list.append(f);
  57.   return f;
  58.  }
  59.  
  60. /*
  61. node planar_map::split_edge(edge e)
  62. { edge r = get_rev(e);
  63.  
  64.   node v = source(e);
  65.   node w = target(e);
  66.  
  67.   node u = graph::new_node();
  68.  
  69. }
  70. */
  71.  
  72. edge planar_map::new_edge(edge e1, edge e2, ent face_i)
  73. /*
  74.     cout << "NEW_EDGE:\n";
  75.     print_edge(e1); cout << " F = " << int(adj_face(e1)->inf) << "\n";
  76.     print_edge(e2); cout << " F = " << int(adj_face(e2)->inf) << "\n";
  77.     newline;
  78. */
  79.  
  80.   if (adj_face(e1) != adj_face(e2)) 
  81.     error_handler(1,"planar_map::new_edge: new edge must split a face."); 
  82.  
  83.   face F = adj_face(e1);
  84.   face f = new_face(face_i);
  85.  
  86.   edge y = graph::new_edge(e1,source(e2),before);
  87.   F->head = y;
  88.   get_face(y) = F;
  89.   
  90.  
  91.   edge x = graph::new_edge(e2,source(e1),before);
  92.   f->head = x;
  93.  
  94.   get_rev(x) = y;
  95.   get_rev(y) = x;
  96.  
  97.   node v = source(x);
  98.   while (target(x) != v) 
  99.   { get_face(x) = f;
  100.     x = succ_face_edge(x);
  101.    }
  102.  
  103.   return y;
  104. }
  105.  
  106. void planar_map::del_edge(edge x, ent face_i)
  107. {
  108.   edge y  = reverse(x);
  109.   face F1 = adj_face(x);
  110.   face F2 = adj_face(y);
  111.  
  112.   edge e = succ_face_edge(y);
  113.  
  114.   F1->inf = face_i;
  115.  
  116.   if (F1!=F2)
  117.   { edge e = succ_face_edge(y);
  118.     F1->head = e;
  119.     while (e!=y)
  120.     { get_face(e) = F1;
  121.       e = succ_face_edge(e);
  122.      }
  123.  
  124.     del_face(F2);
  125.    }
  126.   else
  127.   { e = succ_face_edge(e);
  128.  
  129.     if (e!=y) // no isolated edge
  130.       F1->head = e;   
  131.     else 
  132.       del_face(F1);
  133.  
  134.    }
  135.  
  136.     graph::del_edge(x);
  137.     graph::del_edge(y);
  138.  
  139. }
  140.  
  141. /*
  142. void planar_map::init_entries()
  143. { node v;
  144.   forall_nodes(v,*this) init_node_entry(entry(v));
  145.   face f;
  146.   forall(f,F_list) init_face_entry(f->inf);
  147.  }
  148. */
  149.  
  150.  
  151. planar_map::~planar_map() 
  152. { face f;
  153.   forall(f,F_list) 
  154.   { clear_face_entry(f->inf);
  155.     delete f;
  156.    }
  157.  
  158.  }
  159.  
  160.  
  161. planar_map::planar_map(const graph& G) : graph(G)
  162.  
  163. // input planar embedded graph  represented by a directed graph G 
  164. // i.e., for each node v of G the adjacent edges are sorted 
  165. // counter-clockwise, 
  166. // computes planar map representation (faces!)
  167. // For each face F, one of its edge entries is copied into F
  168.  
  169.   edge e,e1;
  170.  
  171. /*
  172.   if (!PLANAR(*this)) error_handler(1,"planar_map: Graph is not planar."); 
  173. */
  174.  
  175.   edge_array(edge) Rev(*this);
  176.  
  177.   if (compute_correspondence(*this,Rev) == false)
  178.    { print();
  179.      error_handler(999,"planar_map: cannot find reversal edges");;
  180.     }
  181.  
  182.   forall_edges(e,*this) get_rev(e) = Rev[e];
  183.  
  184.  
  185.   Rev.clear();
  186.  
  187.   // compute faces
  188.  
  189.   edge_array(bool) F(*this,false);
  190.  
  191.   forall_edges(e,*this)
  192.    if (!F[e])
  193.     { F[e] = true;
  194.       face f = new_face(e->contents);  // copy entry of first edge into face
  195.       e->contents =  f;
  196.       f->head = e;
  197.       e1 = succ_face_edge(e);
  198.       while (e1 != e)
  199.       { G.clear_edge_entry(e1->contents);
  200.         e1->contents = f;
  201.         F[e1] = true;
  202.         e1 = succ_face_edge(e1);
  203.        }
  204.      } 
  205.  
  206.  
  207.  
  208. list(edge) planar_map::triangulate()
  209. {
  210.   node v,w;
  211.   edge e,e1,e2,e3;
  212.  
  213.   list(edge) L;
  214.  
  215.   node_array(bool) marked(*this,false);
  216.  
  217.   forall_nodes(v,*this)
  218.   {
  219.     edgelist El = adj_edges(v);
  220.  
  221.     forall(e,El) marked[target(e)] = true;
  222.  
  223.     forall(e,El)
  224.     { 
  225.       e1 = e;
  226.       e2 = succ_face_edge(e1);
  227.       e3 = succ_face_edge(e2);
  228.  
  229.       face F = get_face(e1);
  230.  
  231.       while (target(e3) != v)
  232.       { 
  233.  
  234.         // e1,e2 and e3 are the first three edges in a clockwise 
  235.         // traversal of a face incident to v and t(e3) is not equal
  236.         // to v.
  237.  
  238.         if ( !marked[target(e2)] )
  239.         { 
  240.           // we mark w and add the edge {v,w} inside F, i.e., after
  241.           // dart e1 at v and after dart e3 at w.
  242.  
  243.           marked[target(e2)] = true;
  244.   
  245.           e1 = new_edge(e1,e3,F->inf);
  246.           e2 = e3;
  247.           e3 = succ_face_edge(e2);
  248.  
  249.           L.append(e1);
  250.         }
  251.         else
  252.         { // we add the edge {source(e2),target(e3)} inside F, i.e.,
  253.           // after dart e2 at source(e2) and before dart 
  254.           // reversal_of[e3] at target(e3).
  255.  
  256.           e3 = succ_face_edge(e3); 
  257.  
  258.           e2 = new_edge(e2,e3,F->inf);
  259.  
  260.           L.append(e2);
  261.  
  262.         }
  263.       } //end of while
  264.  
  265.     } //end of stepping through incident faces
  266.  
  267.    forall_adj_nodes(w,v) marked[w] = false;
  268.  
  269.   } // end of stepping through nodes
  270.  
  271. return L;
  272.  
  273. } //end of triangulation
  274.  
  275.