contrib/brl/bbas/btol/btol_edge_algs.cxx
Go to the documentation of this file.
00001 // This is brl/bbas/btol/btol_edge_algs.cxx
00002 #include "btol_edge_algs.h"
00003 //:
00004 // \file
00005 #include <vcl_algorithm.h> // vcl_find()
00006 #include <vcl_cmath.h>
00007 #include <vdgl/vdgl_digital_curve.h>
00008 #include <vtol/vtol_topology_object_sptr.h>
00009 #include <vtol/vtol_topology_object.h>
00010 #include <vtol/vtol_edge_2d.h>
00011 #include <vcl_iostream.h>
00012 
00013 const double btol_edge_algs::tol = 1e-6;
00014 
00015 // Destructor
00016 btol_edge_algs::~btol_edge_algs()
00017 {
00018 }
00019 
00020 //-----------------------------------------------------------------------------
00021 //: Splits e at v and returns the two edges e1, e2, which are incident at v.
00022 // If v is not within btol_edge_algs::tol (user-settable) of a point on edge e
00023 // then false is returned, and e is not split
00024 //-----------------------------------------------------------------------------
00025 bool btol_edge_algs::split_edge_2d(vtol_vertex_2d_sptr const& /*v*/,
00026                                    vtol_edge_2d_sptr const& /*e*/,
00027                                    vtol_edge_2d_sptr& /*e1*/, vtol_edge_2d_sptr& /*e2*/)
00028 {
00029   vcl_cout << "tol = " << btol_edge_algs::tol << vcl_endl
00030            << "btol_edge_algs::split_edge_2d - not implemented\n";
00031   return true;
00032 }
00033 
00034 bool btol_edge_algs::unlink_all_inferiors_twoway(vtol_edge_2d_sptr const& e)
00035 {
00036   if (!e->v1()||!e->v2())
00037     return false;
00038   vtol_vertex_sptr tv1 = e->v1()->cast_to_vertex();
00039   vtol_vertex_sptr tv2 = e->v2()->cast_to_vertex();
00040 
00041   vtol_edge_sptr toe = e->cast_to_edge();
00042   vcl_vector<vtol_topology_object_sptr>* infs = toe->inferiors();
00043   //this will be the zero_chain for the edge
00044   //Can have an edge with no vertices
00045   if (!infs->size())
00046     return true;
00047   if (infs->size()>1)
00048   {
00049     vcl_cout << " In btol_edge_algs::unlink_all_inferiors_twoway(..) -"
00050              << " inferiors inconsistent size\n";
00051     return false;
00052   }
00053   vtol_zero_chain_sptr inf_zero_chain = infs->front()->cast_to_zero_chain();
00054   if (!inf_zero_chain)
00055   {
00056     vcl_cout << " In btol_edge_algs::unlink_all_inferiors_twoway(..) -"
00057              << " null zero chain\n";
00058     return false;
00059   }
00060   inf_zero_chain->unlink_inferior(tv1);
00061   if (tv1!=tv2)
00062     inf_zero_chain->unlink_inferior(tv2);
00063   toe->unlink_inferior(inf_zero_chain);
00064   return true;
00065 }
00066 
00067 //-----------------------------------------------------------------------------
00068 //: Replaces va by vb on edge e.
00069 //-----------------------------------------------------------------------------
00070 bool btol_edge_algs::subst_vertex_on_edge(vtol_vertex_sptr const& va,
00071                                           vtol_vertex_sptr const& vb,
00072                                           vtol_edge_sptr const& e)
00073 {
00074   if (!va||!vb||!e)
00075     return false;
00076   vtol_vertex_sptr v1 = e->v1();
00077   vtol_vertex_sptr v2 = e->v2();
00078   if (!v1||!v2)
00079     return false;
00080   if (v1==va)
00081   {
00082     e->set_v1(vb);
00083     return true;
00084   }
00085   if (v2==va)
00086   {
00087     e->set_v2(vb);
00088     return true;
00089   }
00090   return false;
00091 }
00092 
00093 //-----------------------------------------------------------------------------
00094 //: Computes the bounding box for a set of edges
00095 //-----------------------------------------------------------------------------
00096 vsol_box_2d btol_edge_algs::bounding_box(vcl_vector<vtol_edge_2d_sptr>& edges)
00097 {
00098   vsol_box_2d b;//default box
00099 
00100   for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
00101        eit != edges.end(); eit++)
00102   {
00103     vsol_curve_2d_sptr c = (*eit)->curve();
00104     if (!c)
00105     {
00106       vcl_cout << "In btol_edge_algs::bounding_box(..) - null curve\n";
00107       continue;
00108     }
00109     if (c->cast_to_vdgl_digital_curve())
00110       b.grow_minmax_bounds(c->cast_to_vdgl_digital_curve()->get_bounding_box());
00111     else
00112       vcl_cout << "In btol_edge_algs::bounding_box(..) -"
00113                << " curve has unknown geometry\n";
00114   }
00115   return b;
00116 }
00117 
00118 //: a bit more convenient interface for finding edges than messing with iterators
00119 void btol_edge_algs::edge_2d_erase(vcl_vector<vtol_edge_2d_sptr>& edges,
00120                                    vtol_edge_2d_sptr const& e)
00121 {
00122   vcl_vector<vtol_edge_2d_sptr>::iterator eit =
00123     vcl_find(edges.begin(), edges.end(), e);
00124   if (eit != edges.end())
00125     edges.erase(eit);
00126   return;
00127 }
00128 
00129 //: find the vertex closest to the given position and return it
00130 vtol_vertex_2d_sptr btol_edge_algs::closest_vertex(vtol_edge_2d_sptr const& e,
00131                                                    const double x,
00132                                                    const double y)
00133 {
00134   double x1 = e->v1()->cast_to_vertex_2d()->x();
00135   double y1 = e->v1()->cast_to_vertex_2d()->y();
00136   double x2 = e->v2()->cast_to_vertex_2d()->x();
00137   double y2 = e->v2()->cast_to_vertex_2d()->y();
00138   double d1 = vcl_sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
00139   double d2 = vcl_sqrt((x2-x)*(x2-x)+(y2-y)*(y2-y));
00140   if (d1<d2)
00141     return e->v1()->cast_to_vertex_2d();
00142   else
00143     return e->v2()->cast_to_vertex_2d();
00144 }