⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _planar_map.c

📁 数据类型和算法库LEDA 数据类型和算法库LEDA
💻 C
字号:
/*******************************************************************************
+
+  LEDA  3.0
+
+
+  _planar_map.c
+
+
+  Copyright (c) 1992  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 6600 Saarbruecken, FRG     
+  All rights reserved.
+ 
*******************************************************************************/


#include <LEDA/planar_map.h>


extern bool compute_correspondence(const graph&, edge_array<edge>&);

list<edge> planar_map::adj_edges(face f) const
{ list<edge> result(f->head);
  edge e1 = succ_face_edge(f->head);
  while (e1!=f->head)
  { result.append(e1);
    e1 = succ_face_edge(e1);
   }
  return result;
 }

list<node> planar_map::adj_nodes(face f) const
{ list<node> result(source(f->head));
  edge e1 = succ_face_edge(f->head);
  while (e1!=f->head)
  { result.append(source(e1));
    e1 = succ_face_edge(e1);
   }
  return result;
 }

list<face> planar_map::adj_faces(node v) const
{ list<face> result;
  edge e;
  forall_adj_edges(e,v) result.append(adj_face(e));
  return result;
 }

face  planar_map::new_face(GenPtr i) 
{ 
  face f=new i_face(i,this);
  f->loc=F_list.append(f);
  return f;
 }


edge planar_map::split_edge(edge e, GenPtr node_inf)
{ 
  /* 
     splits edge e and its reversal by inserting a new node u (node_inf) 

              e                          e           rr
        ----------->                --------->   --------->
     (v)            (w)   ====>  (v)          (u)          (w)
        <-----------                <---------   <---------
              r                          er          r

     returns edge rr
  */


  edge r = get_rev(e);

  node v = source(e);
  node w = target(e);

  node u = graph::new_node();

  copy_node_entry(node_inf);

  u->contents = node_inf;

  e->t = u;
  r->t = u;

  v->indegree--;
  w->indegree--;
  u->indegree  = 2;


  edge rr = graph::new_edge(u,w);
  edge er = graph::new_edge(u,v);

  get_face(rr) = get_face(e);
  get_face(er) = get_face(r);

  get_rev(r)  = rr;
  get_rev(rr) = r;

  get_rev(e)  = er;
  get_rev(er) = e;

  return rr;

}


edge planar_map::new_edge(edge e1, edge e2, GenPtr face_i)
{ 
 /* cout << "NEW_EDGE:\n";
    print_edge(e1); cout << " F = " << int(adj_face(e1)) << "\n";
    print_edge(e2); cout << " F = " << int(adj_face(e2)) << "\n";
    newline;
  */

  if (adj_face(e1) != adj_face(e2)) 
    error_handler(1,"planar_map::new_edge: new edge must split a face."); 

  face F = adj_face(e1);
  face f = new_face(face_i);

  edge y = graph::new_edge(e1,source(e2),before);
  F->head = y;
  get_face(y) = F;
  
  edge x = graph::new_edge(e2,source(e1),before);
  f->head = x;
  get_face(x) = f;

  get_rev(x) = y;
  get_rev(y) = x;

  for (edge e = succ_face_edge(x); e != x; e = succ_face_edge(e)) 
     get_face(e) = f;

  return y;
}


node planar_map::new_node(const list<edge>& el, GenPtr node_inf)
{
  if (el.length() < 2)
      error_handler(1,"planar_map::new_node(el,i):  el.length() < 2."); 

  list_item it = el.first();

  edge e0 = el[it];

  it = el.succ(it);

  face f = adj_face(e0);

  edge e;
  forall(e,el)
  { if (adj_face(e) != f)
      error_handler(1,"planar_map::new_node: edges bound different faces."); 
   }

  e = el[it];

  it = el.succ(it);

  GenPtr face_inf = f->inf;

  copy_face_entry(face_inf);
  copy_node_entry(node_inf);

  edge e1 = split_edge(new_edge(e0,e,face_inf),node_inf);

  node u = source(e1);

  while(it)
  { copy_face_entry(face_inf);
    e1 = new_edge(e1,el[it],face_inf);
    it = el.succ(it);
   }

  return u;
}

node planar_map::new_node(face f, GenPtr node_inf)
{ return new_node(adj_edges(f),node_inf);
 }


void planar_map::del_edge(edge x, GenPtr face_i)
{
  edge y  = reverse(x);
  face F1 = adj_face(x);
  face F2 = adj_face(y);

  edge e = succ_face_edge(y);

  F1->inf = face_i;

  if (F1!=F2)
  { edge e = succ_face_edge(y);
    F1->head = e;
    while (e!=y)
    { get_face(e) = F1;
      e = succ_face_edge(e);
     }

    del_face(F2);
   }
  else
  { e = succ_face_edge(e);

    if (e!=y) // no isolated edge
      F1->head = e;   
    else 
      del_face(F1);

   }

  x->adj_loc2 = 0;  // prevent x and y to be considered as an undirected edge
  y->adj_loc2 = 0;

  graph::del_edge(x);
  graph::del_edge(y);

}


void planar_map::clear() 
{ face f;
  forall(f,F_list) 
  { clear_face_entry(f->inf);
    delete f;
   }
  F_list.clear();
  graph::clear();
 }

planar_map::planar_map(const graph& G) : graph(G)

// input planar embedded graph  represented by a directed graph G 
// i.e., for each node v of G the adjacent edges are sorted 
// counter-clockwise, 
// computes planar map representation (faces!)
// For each face F, one of its edge entries is copied into F

{ 
  edge e,e1;

/*
  if (!PLANAR(*this)) error_handler(1,"planar_map: Graph is not planar."); 
*/

  edge_array<edge> Rev(*this);

  if (compute_correspondence(*this,Rev) == false)
     error_handler(999,"planar_map: cannot find reversal edges");

  forall_edges(e,*this) get_rev(e) = Rev[e];


  Rev.clear();

  // compute faces

  edge_array<bool> F(*this,false);

  forall_edges(e,*this)
   if (!F[e])
    { F[e] = true;
      face f = new_face(e->contents);  // copy entry of first edge into face
      G.copy_edge_entry(f->inf);
      e->contents =  f;
      f->head = e;
      e1 = succ_face_edge(e);
      while (e1 != e)
      { e1->contents = f;
        F[e1] = true;
        e1 = succ_face_edge(e1);
       }
     } 

} 


list<edge> planar_map::triangulate()
{
  node v,w;
  edge e,e1,e2,e3;

  list<edge> L;

  node_array<bool> marked(*this,false);
 
  forall_nodes(v,*this)
  {
    list<edge> El = adj_edges(v);
 
    forall(e,El) marked[target(e)] = true;

    forall(e,El)
    { 
      e1 = e;
      e2 = succ_face_edge(e1);
      e3 = succ_face_edge(e2);

      face F = get_face(e1);

      while (target(e3) != v)
      { 

        // e1,e2 and e3 are the first three edges in a clockwise 
        // traversal of a face incident to v and t(e3) is not equal
        // to v.

        if ( !marked[target(e2)] )
        { 
          // we mark w and add the edge {v,w} inside F, i.e., after
          // dart e1 at v and after dart e3 at w.

          marked[target(e2)] = true;
  
          e1 = new_edge(e1,e3,F->inf);
          e2 = e3;
          e3 = succ_face_edge(e2);

          L.append(e1);
        }
        else
        { // we add the edge {source(e2),target(e3)} inside F, i.e.,
          // after dart e2 at source(e2) and before dart 
          // reversal_of[e3] at target(e3).

          e3 = succ_face_edge(e3); 

          e2 = new_edge(e2,e3,F->inf);

          L.append(e2);

        }
      } //end of while

    } //end of stepping through incident faces

   forall_adj_nodes(w,v) marked[w] = false;

  } // end of stepping through nodes

 return L;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -