1 // This is oxl/mvl/LineSegSet.cxx
2 //:
3 // \file
4
5 #include <iostream>
6 #include <fstream>
7 #include <vector>
8 #include "LineSegSet.h"
9
10 #ifdef _MSC_VER
11 # include "vcl_msvc_warnings.h"
12 #endif
13
14 #include <mvl/ImageMetric.h>
15 #include <mvl/HomgPoint2D.h>
16
17 // Default ctor
LineSegSet()18 LineSegSet::LineSegSet():
19 hlines_(0)
20 {
21 conditioner_ = nullptr;
22 }
23
24 // Copy ctor
LineSegSet(const LineSegSet & that)25 LineSegSet::LineSegSet(const LineSegSet& that):
26 hlines_(0)
27 {
28 operator=(that);
29 }
30
31 // Assignment
32 LineSegSet& LineSegSet::operator=(const LineSegSet& that) = default;
33
34 // Destructor
35 LineSegSet::~LineSegSet() = default;
36
37 //: Construct from ascii file
LineSegSet(const char * filename,const HomgMetric & c)38 LineSegSet::LineSegSet(const char* filename, const HomgMetric& c)
39 {
40 std::ifstream f(filename);
41 load_ascii(f, c);
42 }
43
44 //: Load lines from ASCII file
load_ascii(std::istream & f,HomgMetric const & c)45 bool LineSegSet::load_ascii(std::istream& f, HomgMetric const& c)
46 {
47 vnl_matrix<double> L;
48 f >> L;
49
50 int cols = L.columns();
51 if (cols != 6 && cols != 4) {
52 std::cerr << "Load failed -- there are " << L.columns() << " data per row\n";
53 return false;
54 }
55
56 conditioner_ = c;
57 hlines_.resize(0);
58 for (unsigned i = 0; i < L.rows(); ++i) {
59 double x1 = L(i,0);
60 double y1 = L(i,1);
61 double x2 = L(i,2);
62 double y2 = L(i,3);
63 #if 0
64 double theta;
65 double avemag;
66 if (cols == 6) {
67 theta = L(i,4);
68 avemag = L(i,5);
69 } else {
70 theta = 0;
71 avemag = 0;
72 }
73 #endif
74 HomgPoint2D p1(x1, y1);
75 HomgPoint2D p2(x2, y2);
76 HomgLineSeg2D line(p1, p2);
77 hlines_.push_back(c.image_to_homg_line(line));
78 }
79
80 std::cerr << "Loaded " << size() << " line segments\n";
81 return true;
82 }
83
FindNearestLineIndex(double,double)84 int LineSegSet::FindNearestLineIndex(double /*x*/, double /*y*/)
85 {
86 std::cerr <<"LineSegSet::FindNearestLineIndex not yet implemented\n";
87 return -1;
88 #if 0 // commented out
89 double mindist=-1.0f;
90 int mini=-1;
91 for (unsigned int i=0; i<size(); ++i)
92 {
93 HomgLineSeg2D& dl = get_homg(i);
94 double t = ( dl.get_point1().x() - x ) * ( dl.get_point2() - x )
95 + ( dl.get_point1().y() - y ) * ( dl.get_point2() - y );
96 // i.e.: t = dot_product ( startpt - pt , endpt - pt ) ;
97
98 double dist;
99 if (t<0) // P lies inbetween the two end points
100 dist = vgl_distance(dl.get_line(),vgl_point_2d<double>(x,y)); // distance to the support line
101 else
102 dist = std::min(// closest distance with endpoints
103 vgl_distance(dl.get_point1(),vgl_point_2d<double>(x,y)),
104 vgl_distance(dl.get_point2(),vgl_point_2d<double>(x,y)));
105 if (mini<0 || dist<mindist){ mindist = dist; mini = i; }
106 }
107 return mini;
108 #endif
109 }
110
111 //: Save lines to ASCII file
save_ascii(std::ostream & f) const112 bool LineSegSet::save_ascii(std::ostream& f) const
113 {
114 for (const auto & l : hlines_) {
115 vnl_double_2 p1 = conditioner_.homg_to_image(l.get_point1());
116 vnl_double_2 p2 = conditioner_.homg_to_image(l.get_point2());
117
118 f << p1[0] << " " << p1[1] << "\t"
119 << p2[0] << " " << p2[1] << std::endl;
120 }
121 std::cerr << "LineSegSet: Saved " << hlines_.size() << " line segments\n";
122 return true;
123 }
124
125 //: Return line selected by mouse click at (x,y) in image coordinates.
pick_line_index(double x,double y)126 int LineSegSet::pick_line_index(double x, double y)
127 {
128 HomgPoint2D p(x, y);
129 HomgMetric metric(conditioner_);
130
131 double dmin = 1e20;
132 int imin = -1;
133 int nlines = hlines_.size();
134 for (int i = 0; i < nlines; ++i) {
135 const HomgLineSeg2D& l = hlines_[i];
136 HomgLineSeg2D l_decond = metric.homg_line_to_image(l);
137
138 double d = l_decond.picking_distance(p);
139
140 if (d < dmin) {
141 dmin = d;
142 imin = i;
143 }
144 }
145
146 return imin;
147 }
148
149 //: Return line selected by mouse click at (x,y) in image coordinates.
pick_line(double x,double y)150 HomgLineSeg2D* LineSegSet::pick_line(double x, double y)
151 {
152 int i = pick_line_index(x,y);
153 if (i >= 0)
154 return &hlines_[i];
155 else
156 return nullptr;
157 }
158