Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
line.cpp
1 
2 /***************************************************************************
3  * line.cpp - Implementation of a line shape finder
4  *
5  * Created: Thu May 16 00:00:00 2005
6  * Copyright 2005 Tim Niemueller [www.niemueller.de]
7  * Martin Heracles <Martin.Heracles@rwth-aachen.de>
8  * Hu Yuxiao <Yuxiao.Hu@rwth-aachen.de>
9  *
10  ****************************************************************************/
11 
12 /* This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version. A runtime exception applies to
16  * this software (see LICENSE.GPL_WRE file mentioned below for details).
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Library General Public License for more details.
22  *
23  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
24  */
25 
26 #include <utils/math/angle.h>
27 #include <fvmodels/shape/line.h>
28 
29 // #include <utils/geometry/line.h>
30 // #include <utils/geometry/point.h>
31 
32 using namespace std;
33 
34 namespace firevision {
35 #if 0 /* just to make Emacs auto-indent happy */
36 }
37 #endif
38 
39 /** @class LineShape <fvmodels/shape/line.h>
40  * Line shape.
41  */
42 
43 /** Constructor.
44  * @param roi_width ROI width
45  * @param roi_height ROI height
46  */
47 LineShape::LineShape(unsigned int roi_width, unsigned int roi_height)
48 {
49  r = 0;
50  phi = 0;
51  count = 0;
52 
53  max_length = (int)sqrt( roi_width * roi_width + roi_height * roi_height );
54  last_calc_r = last_calc_phi = 0.f;
55 
56  this->roi_width = roi_width;
57  this->roi_height = roi_height;
58 
59 }
60 
61 
62 /** Destructor. */
63 LineShape::~LineShape()
64 {
65 }
66 
67 
68 /** Print line.
69  * @param stream stream to print to
70  */
71 void
72 LineShape::printToStream(std::ostream &stream)
73 {
74  stream << "r=" << r << " phi=" << phi
75  << " count= " << count;
76 }
77 
78 void
79 LineShape::setMargin(unsigned int margin)
80 {
81  this->margin = margin;
82 }
83 
84 
85 bool
86 LineShape::isClose(unsigned int in_roi_x, unsigned int in_roi_y)
87 {
88  return false;
89  /*
90  Point p1(x1, y1);
91  Point p2(x2, y2);
92 
93  Line cl(p1, p2);
94 
95  Point p(x, y);
96  /
97  cout << "LineShape (" << x1 << ", " << y1 << ") <-> (" << x2 << ", " << y2 << ")" << endl
98  << "Point (" << x << ", " << y << ")" << endl
99  << "Distance: " << cl.getDistanceTo(p) << endl;
100  /
101  return (cl.GetDistanceTo(p) <= margin);
102  */
103 }
104 
105 /** Calc points for line. */
106 void
107 LineShape::calcPoints()
108 {
109 
110  if ((last_calc_r == r) && (last_calc_phi == phi)) return;
111  last_calc_r = r;
112  last_calc_phi = phi;
113 
114  float rad_angle = fawkes::deg2rad(phi);
115 
116  // if true, point (x1, y1) will be moved the opposite direction
117  bool reverse_direction = false;
118 
119  /* compute two points on the line.
120  (x1, y1) will be somewhere inside or outside of ROI,
121  (x2, y2) will be on a ROI edge (or on a prolongation thereof) */
122  if ( rad_angle < M_PI/4 ) {
123  x1 = (int)round( r * cos( rad_angle ) );
124  y1 = (int)round( r * sin( rad_angle ) );
125  y2 = 0;
126  x2 = (int)round( r / cos( rad_angle ) );
127  } else if ( rad_angle < M_PI/2 ) {
128  x1 = (int)round( r * cos( rad_angle ) );
129  y1 = (int)round( r * sin( rad_angle ) );
130  x2 = 0;
131  y2 = (int)round( r / cos( M_PI/2 - rad_angle ) );
132  } else if ( rad_angle < 3.0/4.0 * M_PI ) {
133  x1 = (int)round(-r * cos( M_PI - rad_angle ) );
134  y1 = (int)round( r * sin( M_PI - rad_angle ) );
135  x2 = 0;
136  y2 = (int)round( r / cos( rad_angle - M_PI/2 ) );
137 
138  // the direction in which (x1, y1) has to be moved
139  // depends on the sign of r
140  if (r >= 0.0) {
141  reverse_direction = true;
142  }
143  } else {
144  // rad_angle <= M_PI
145  x1 = (int)round(-r * cos( M_PI - rad_angle ) );
146  y1 = (int)round( r * sin( M_PI - rad_angle ) );
147  y2 = 0;
148  x2 = (int)round(-r / cos( M_PI - rad_angle ) );
149 
150  // the direction in which (x1, y1) has to be moved
151  // depends on the sign of r
152  if (r < 0.0) {
153  reverse_direction = true;
154  }
155  }
156 
157  if ( ! (x1 == x2 &&
158  y1 == y2 ) ) {
159  // move (x1, y1) away from (x2, y2)
160  // such that line (x1, y1)<->(x2, y2) spans the whole ROI
161  float vx, vy, length;
162  vx = x1 - x2 ;
163  vy = y1 - y2 ;
164  length = sqrt( vx * vx + vy * vy );
165 
166  vx /= length;
167  vy /= length;
168  vx *= max_length;
169  vy *= max_length;
170 
171  if ( ! reverse_direction) {
172  x1 += (int)vx;
173  y1 += (int)vy;
174  } else {
175  x1 -= (int)vx;
176  y1 -= (int)vy;
177  }
178 
179  } else {
180  // special case: both points are identical, hence could not be moved apart
181  // (re-define first point "by hand")
182  if (x2 == 0) {
183  x1 = roi_width;
184  y1 = y2;
185  } else if (y2 == 0) {
186  x1 = x2;
187  y1 = roi_height;
188  } else {
189  cout << "ERROR!" << endl
190  << " This case should not have occurred. Please have a look at method" << endl
191  << " \"LineShape::calc()\". Treatment of special case is not correct." << endl;
192  //exit(-1);
193  }
194  }
195 }
196 
197 
198 /** Get two points that define the line.
199  * @param x1 contains x coordinate of first point upon return
200  * @param y1 contains y coordinate of first point upon return
201  * @param x2 contains x coordinate of second point upon return
202  * @param y2 contains y coordinate of second point upon return
203  */
204 void
205 LineShape::getPoints(int *x1, int *y1, int *x2, int *y2)
206 {
207  calcPoints();
208 
209  *x1 = this->x1;
210  *y1 = this->y1;
211  *x2 = this->x2;
212  *y2 = this->y2;
213 }
214 
215 } // end namespace firevision