Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

mmn_make_tri_tree.cxx

Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \brief Representation of topological arc joining two vertices
00004 // \author Tim Cootes
00005 
00006 #include <mmn/mmn_make_tri_tree.h>
00007 #include <vcl_cassert.h>
00008 
00009 static void  update_best_arcs(const vnl_matrix<double>& D,
00010                               const vcl_vector<bool>& node_free,
00011                               vcl_vector<mmn_arc>& arcs, unsigned a,
00012                               vcl_vector<unsigned>& best_arc,
00013                               vcl_vector<double>& best_d)
00014 {
00015   unsigned v1=arcs[a].v1;
00016   unsigned v2=arcs[a].v2;
00017   for (unsigned i=0;i<node_free.size();++i)
00018   {
00019     if (node_free[i])
00020     {
00021       double d = D(i,v1)+D(i,v2);
00022       if (d<best_d[i])
00023       {
00024         best_d[i]=d;
00025         best_arc[i]=a;
00026       }
00027     }
00028   }
00029 }
00030 
00031 //: Compute arcs defining a graph s.t. triangles form a tree.
00032 //  Compute arc of graph such that point belongs to at least one triangle,
00033 //  and the graph of triangles is a tree (acylcic).
00034 //  Two triangles are neighbours if they share an edge (arc).
00035 //
00036 //  The approach is to select nodes one at a time, at each step
00037 //  choosing the node closest to two nodes ending an existing arc.
00038 //  This gives two new arcs.
00039 //
00040 //  Complexity is approximately O(n^2)
00041 //
00042 //  \param D: a symmetric matrix indicating proximity of two nodes
00043 //  \param arcs: Output 2n-3 arcs defining the graph.
00044 //  \param v0: If input as >=0 then defines one node of the first arc
00045 void mmn_make_tri_tree(const vnl_matrix<double>& D,
00046                        vcl_vector<mmn_arc>& arcs,
00047                        int v0)
00048 {
00049   unsigned n = D.rows();
00050   assert(D.cols()==n);
00051 
00052   vcl_vector<bool> node_free(n,true);
00053 
00054   // Record of index of best arc for each node
00055   // arcs[best_arc[i]] is arc whose nodes are closest to i
00056   // best_d[i] is the sum of D(i,v1)+D(i,v2)
00057   vcl_vector<unsigned> best_arc(n);
00058   vcl_vector<double> best_d(n);
00059 
00060   arcs.resize(0);
00061 
00062   // Deduce the first arc
00063   mmn_arc arc(0,1);
00064 
00065   if (v0>=0 && v0<n)
00066   {
00067     // Find nearest neighbour of v0
00068     double min_d=9e9;
00069     unsigned best_i;
00070     for (unsigned i=0;i<n;++i)
00071       if (i!=v0 && D(v0,i)<min_d)
00072       { best_i=i; min_d=D(v0,i); }
00073     arc = mmn_arc(v0,best_i);
00074   }
00075   else
00076   {
00077     // Find smallest element in D
00078     double min_d = D(arc.v1,arc.v2);
00079     for (unsigned j=1;j<n;++j)
00080       for (unsigned i=0;i<j;++j)
00081       {
00082         if (D(i,j)<min_d)
00083         {
00084           arc=mmn_arc(i,j); min_d=D(i,j);
00085         }
00086       }
00087   }
00088   arcs.push_back(arc);
00089   node_free[arc.v1]=false;
00090   node_free[arc.v2]=false;
00091 
00092   // Initialise list of best arcs and distances
00093   for (unsigned i=0;i<n;++i)
00094   {
00095     best_arc[i]=0;
00096     if (node_free[i]) best_d[i] = D(i,arc.v1)+D(i,arc.v2);
00097   }
00098 
00099   for (unsigned k=2;k<n;++k)
00100   {
00101     // Search for node with lowest distance to an arc end
00102     unsigned best_i=0;
00103     double min_d=9e9;
00104     for (unsigned i=0;i<n;++i)
00105       if (node_free[i] && best_d[i]<min_d)
00106         {min_d=best_d[i]; best_i=i; }
00107 
00108     arc = arcs[best_arc[best_i]];
00109     // Record arcs from node best_i to ends of arc best_arcs[best_i]
00110     node_free[best_i]=false;
00111     arcs.push_back(mmn_arc(best_i,arc.v1));
00112     arcs.push_back(mmn_arc(best_i,arc.v2));
00113 
00114     // Re-evaluate distances to each free point
00115     update_best_arcs(D,node_free,arcs,arcs.size()-2,best_arc,best_d);
00116     update_best_arcs(D,node_free,arcs,arcs.size()-1,best_arc,best_d);
00117   }
00118 }

Generated on Thu Jan 10 14:44:52 2008 for contrib/mul/mmn by  doxygen 1.4.4