contrib/oxl/mvl/LineSegSet.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/LineSegSet.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 //  \file
00007 
00008 #include "LineSegSet.h"
00009 
00010 #include <vcl_iostream.h>
00011 #include <vcl_fstream.h>
00012 #include <vcl_vector.h>
00013 #include <vcl_vector.txx>
00014 
00015 #include <mvl/ImageMetric.h>
00016 #include <mvl/HomgPoint2D.h>
00017 
00018 // Default ctor
00019 LineSegSet::LineSegSet():
00020   hlines_(0)
00021 {
00022   conditioner_ = 0;
00023 }
00024 
00025 // Copy ctor
00026 LineSegSet::LineSegSet(const LineSegSet& that):
00027   hlines_(0)
00028 {
00029   operator=(that);
00030 }
00031 
00032 // Assignment
00033 LineSegSet& LineSegSet::operator=(const LineSegSet& that)
00034 {
00035   hlines_ = that.hlines_;
00036   conditioner_ = that.conditioner_;
00037   return *this;
00038 }
00039 
00040 // Destructor
00041 LineSegSet::~LineSegSet()
00042 {
00043 }
00044 
00045 //: Construct from ascii file
00046 LineSegSet::LineSegSet(const char* filename, const HomgMetric& c)
00047 {
00048   vcl_ifstream f(filename);
00049   load_ascii(f, c);
00050 }
00051 
00052 //: Load lines from ASCII file
00053 bool LineSegSet::load_ascii(vcl_istream& f, HomgMetric const& c)
00054 {
00055   vnl_matrix<double> L;
00056   f >> L;
00057 
00058   int cols = L.columns();
00059   if (cols != 6 && cols != 4) {
00060     vcl_cerr << "Load failed -- there are " << L.columns() << " data per row\n";
00061     return false;
00062   }
00063 
00064   conditioner_ = c;
00065   hlines_.resize(0);
00066   for (unsigned i = 0; i < L.rows(); ++i) {
00067     double x1 = L(i,0);
00068     double y1 = L(i,1);
00069     double x2 = L(i,2);
00070     double y2 = L(i,3);
00071 #if 0
00072     double theta;
00073     double avemag;
00074     if (cols == 6) {
00075       theta = L(i,4);
00076       avemag = L(i,5);
00077     } else {
00078       theta = 0;
00079       avemag = 0;
00080     }
00081 #endif
00082     HomgPoint2D p1(x1, y1);
00083     HomgPoint2D p2(x2, y2);
00084     HomgLineSeg2D line(p1, p2);
00085     hlines_.push_back(c.image_to_homg_line(line));
00086   }
00087 
00088   vcl_cerr << "Loaded " << size() << " line segments\n";
00089   return true;
00090 }
00091 
00092 int LineSegSet::FindNearestLineIndex(double /*x*/, double /*y*/)
00093 {
00094   vcl_cerr <<"LineSegSet::FindNearestLineIndex not yet implemented\n";
00095   return -1;
00096 #if 0 // commented out
00097   double mindist=-1.0f;
00098   int mini=-1;
00099   for (unsigned int i=0; i<size(); ++i)
00100   {
00101     HomgLineSeg2D& dl = get_homg(i);
00102     double t = ( dl.get_point1().x() - x ) * ( dl.get_point2() - x )
00103              + ( dl.get_point1().y() - y ) * ( dl.get_point2() - y );
00104     // i.e.: t = dot_product ( startpt - pt , endpt - pt ) ;
00105 
00106     double dist;
00107     if (t<0)     // P lies inbetween the two end points
00108       dist = vgl_distance(dl.get_line(),vgl_point_2d<double>(x,y)); // distance to the support line
00109     else
00110       dist = vcl_min(// closest distance with endpoints
00111                      vgl_distance(dl.get_point1(),vgl_point_2d<double>(x,y)),
00112                      vgl_distance(dl.get_point2(),vgl_point_2d<double>(x,y)));
00113     if (mini<0 || dist<mindist){ mindist = dist; mini = i; }
00114   }
00115   return mini;
00116 #endif
00117 }
00118 
00119 //: Save lines to ASCII file
00120 bool LineSegSet::save_ascii(vcl_ostream& f) const
00121 {
00122   for (unsigned i = 0; i < hlines_.size(); ++i) {
00123     HomgLineSeg2D const& l = hlines_[i];
00124 
00125     vnl_double_2 p1 = conditioner_.homg_to_image(l.get_point1());
00126     vnl_double_2 p2 = conditioner_.homg_to_image(l.get_point2());
00127 
00128     f << p1[0] << " " << p1[1] << "\t"
00129       << p2[0] << " " << p2[1] << vcl_endl;
00130   }
00131   vcl_cerr << "LineSegSet: Saved " << hlines_.size() << " line segments\n";
00132   return true;
00133 }
00134 
00135 //: Return line selected by mouse click at (x,y) in image coordinates.
00136 int LineSegSet::pick_line_index(double x, double y)
00137 {
00138   HomgPoint2D p(x, y);
00139   HomgMetric metric(conditioner_);
00140 
00141   double dmin = 1e20;
00142   int imin = -1;
00143   int nlines = hlines_.size();
00144   for (int i = 0; i < nlines; ++i) {
00145     const HomgLineSeg2D& l = hlines_[i];
00146     HomgLineSeg2D l_decond = metric.homg_line_to_image(l);
00147 
00148     double d = l_decond.picking_distance(p);
00149 
00150     if (d < dmin) {
00151       dmin = d;
00152       imin = i;
00153     }
00154   }
00155 
00156   return imin;
00157 }
00158 
00159 //: Return line selected by mouse click at (x,y) in image coordinates.
00160 HomgLineSeg2D* LineSegSet::pick_line(double x, double y)
00161 {
00162   int i = pick_line_index(x,y);
00163   if (i >= 0)
00164     return &hlines_[i];
00165   else
00166     return 0;
00167 }