contrib/mul/fhs/fhs_arc.cxx
Go to the documentation of this file.
00001 #include "fhs_arc.h"
00002 //:
00003 // \file
00004 // \author Tim Cootes
00005 // \brief Link between one node and another
00006 
00007 #include <vcl_algorithm.h>
00008 
00009     //: Write to binary stream
00010 void fhs_arc::b_write(vsl_b_ostream& bfs) const
00011 {
00012   vsl_b_write(bfs,i_);
00013   vsl_b_write(bfs,j_);
00014   vsl_b_write(bfs,dx_);
00015   vsl_b_write(bfs,dy_);
00016   vsl_b_write(bfs,var_x_);
00017   vsl_b_write(bfs,var_y_);
00018 }
00019 
00020 //: Read from binary stream
00021 void fhs_arc::b_read(vsl_b_istream& bfs)
00022 {
00023   vsl_b_read(bfs,i_);
00024   vsl_b_read(bfs,j_);
00025   vsl_b_read(bfs,dx_);
00026   vsl_b_read(bfs,dy_);
00027   vsl_b_read(bfs,var_x_);
00028   vsl_b_read(bfs,var_y_);
00029 }
00030 
00031 //: Print
00032 vcl_ostream& operator<<(vcl_ostream& os, const fhs_arc& a)
00033 {
00034   os<<'('<<a.i()<<"->"<<a.j()<<" Offset: ("<<a.dx()<<','<<a.dy()
00035     <<") var: ("<<a.var_x()<<','<<a.var_y()<<')';
00036   return os;
00037 }
00038 
00039 //: Print set
00040 vcl_ostream& operator<<(vcl_ostream& os, const vcl_vector<fhs_arc>& arc)
00041 {
00042   os<<arc.size()<<" arcs:"<<'\n';
00043   for (unsigned i=0;i<arc.size();++i)
00044     os<<i<<") "<<arc[i]<<'\n';
00045   return os;
00046 }
00047 
00048 //: Print
00049 void vsl_print_summary(vcl_ostream& os, const fhs_arc& a)
00050 {
00051   os<<a;
00052 }
00053 
00054 //: Find children of node p_node
00055 //  Add relevant arcs to new_arc, and fill children list
00056 static void fhs_find_children(const vcl_vector<fhs_arc>& arc0,
00057                          vcl_vector<bool>& used,
00058                          vcl_vector<fhs_arc>& new_arc,
00059                          vcl_vector<unsigned>& children,
00060                          unsigned p_node)
00061 {
00062   children.resize(0);
00063   for (unsigned i=0;i<arc0.size();++i)
00064   {
00065     if (used[i]) continue;
00066     if (arc0[i].i()==p_node)
00067     {
00068       new_arc.push_back(arc0[i]);
00069       used[i]=true;
00070       children.push_back(arc0[i].j());
00071     }
00072     else
00073     if (arc0[i].j()==p_node)
00074     {
00075       new_arc.push_back(arc0[i].flipped());
00076       used[i]=true;
00077       children.push_back(arc0[i].i());
00078     }
00079   }
00080 }
00081 
00082 //: Re-order list of arcs so that parents precede their children
00083 //  Assumes that there are n nodes (indexed 0..n-1),
00084 //  thus n-1 arcs defining a tree.
00085 //  On exit children[i] gives list of children of node i
00086 bool fhs_order_tree_from_root(const vcl_vector<fhs_arc>& arc0,
00087                          vcl_vector<fhs_arc>& new_arc,
00088                          vcl_vector<vcl_vector<unsigned> >& children,
00089                          unsigned new_root)
00090 {
00091   // Number of nodes is one more than number of arcs for a tree
00092   unsigned n=arc0.size()+1;
00093   // Check that all nodes are in range [0,n-1]
00094   for (unsigned i=0;i<arc0.size();++i)
00095     if (arc0[i].i()>=n || arc0[i].j()>=n)
00096     {
00097       vcl_cerr<<"Arc index outside range [0,"<<n-1<<']'<<'\n'
00098               <<"Arc = "<<arc0[i]<<'\n';
00099       return false;
00100     }
00101 
00102   children.resize(n);
00103   for (unsigned i=0;i<n;++i) children[i].resize(0);
00104 
00105   vcl_vector<bool> used(n);
00106   vcl_fill(used.begin(),used.end(),false);
00107 
00108   new_arc.resize(0);
00109 
00110   // Find children of root node
00111   fhs_find_children(arc0,used,new_arc,children[new_root],new_root);
00112 
00113   // Now find children of each child node recursively
00114   unsigned p=0;
00115   while (p<new_arc.size() && new_arc.size()!=(n-1))
00116   {
00117     unsigned p_node = new_arc[p].j();
00118     fhs_find_children(arc0,used,new_arc,children[p_node],p_node);
00119     p++;
00120   }
00121 
00122   return new_arc.size()==arc0.size();
00123 }