Fawkes API  Fawkes Development Version
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 using namespace std;
30 
31 namespace firevision {
32 #if 0 /* just to make Emacs auto-indent happy */
33 }
34 #endif
35 
36 /** @class LineShape <fvmodels/shape/line.h>
37  * Line shape.
38  */
39 
40 /** Constructor.
41  * @param roi_width ROI width
42  * @param roi_height ROI height
43  */
44 LineShape::LineShape(unsigned int roi_width, unsigned int roi_height)
45 {
46  r = 0;
47  phi = 0;
48  count = 0;
49 
50  max_length = (int)sqrt( roi_width * roi_width + roi_height * roi_height );
51  last_calc_r = last_calc_phi = 0.f;
52 
53  this->roi_width = roi_width;
54  this->roi_height = roi_height;
55 
56 }
57 
58 
59 /** Destructor. */
60 LineShape::~LineShape()
61 {
62 }
63 
64 
65 /** Print line.
66  * @param stream stream to print to
67  */
68 void
69 LineShape::printToStream(std::ostream &stream)
70 {
71  stream << "r=" << r << " phi=" << phi
72  << " count= " << count;
73 }
74 
75 void
76 LineShape::setMargin(unsigned int margin)
77 {
78  this->margin = margin;
79 }
80 
81 
82 bool
83 LineShape::isClose(unsigned int in_roi_x, unsigned int in_roi_y)
84 {
85  return false;
86  /*
87  Point p1(x1, y1);
88  Point p2(x2, y2);
89 
90  Line cl(p1, p2);
91 
92  Point p(x, y);
93  /
94  cout << "LineShape (" << x1 << ", " << y1 << ") <-> (" << x2 << ", " << y2 << ")" << endl
95  << "Point (" << x << ", " << y << ")" << endl
96  << "Distance: " << cl.getDistanceTo(p) << endl;
97  /
98  return (cl.GetDistanceTo(p) <= margin);
99  */
100 }
101 
102 /** Calc points for line. */
103 void
104 LineShape::calcPoints()
105 {
106 
107  if ((last_calc_r == r) && (last_calc_phi == phi)) return;
108  last_calc_r = r;
109  last_calc_phi = phi;
110 
111  float rad_angle = fawkes::deg2rad(phi);
112 
113  // if true, point (x1, y1) will be moved the opposite direction
114  bool reverse_direction = false;
115 
116  /* compute two points on the line.
117  (x1, y1) will be somewhere inside or outside of ROI,
118  (x2, y2) will be on a ROI edge (or on a prolongation thereof) */
119  if ( rad_angle < M_PI/4 ) {
120  x1 = (int)round( r * cos( rad_angle ) );
121  y1 = (int)round( r * sin( rad_angle ) );
122  y2 = 0;
123  x2 = (int)round( r / cos( rad_angle ) );
124  } else if ( rad_angle < M_PI/2 ) {
125  x1 = (int)round( r * cos( rad_angle ) );
126  y1 = (int)round( r * sin( rad_angle ) );
127  x2 = 0;
128  y2 = (int)round( r / cos( M_PI/2 - rad_angle ) );
129  } else if ( rad_angle < 3.0/4.0 * M_PI ) {
130  x1 = (int)round(-r * cos( M_PI - rad_angle ) );
131  y1 = (int)round( r * sin( M_PI - rad_angle ) );
132  x2 = 0;
133  y2 = (int)round( r / cos( rad_angle - M_PI/2 ) );
134 
135  // the direction in which (x1, y1) has to be moved
136  // depends on the sign of r
137  if (r >= 0.0) {
138  reverse_direction = true;
139  }
140  } else {
141  // rad_angle <= M_PI
142  x1 = (int)round(-r * cos( M_PI - rad_angle ) );
143  y1 = (int)round( r * sin( M_PI - rad_angle ) );
144  y2 = 0;
145  x2 = (int)round(-r / cos( M_PI - rad_angle ) );
146 
147  // the direction in which (x1, y1) has to be moved
148  // depends on the sign of r
149  if (r < 0.0) {
150  reverse_direction = true;
151  }
152  }
153 
154  if ( ! (x1 == x2 &&
155  y1 == y2 ) ) {
156  // move (x1, y1) away from (x2, y2)
157  // such that line (x1, y1)<->(x2, y2) spans the whole ROI
158  float vx, vy, length;
159  vx = x1 - x2 ;
160  vy = y1 - y2 ;
161  length = sqrt( vx * vx + vy * vy );
162 
163  vx /= length;
164  vy /= length;
165  vx *= max_length;
166  vy *= max_length;
167 
168  if ( ! reverse_direction) {
169  x1 += (int)vx;
170  y1 += (int)vy;
171  } else {
172  x1 -= (int)vx;
173  y1 -= (int)vy;
174  }
175 
176  } else {
177  // special case: both points are identical, hence could not be moved apart
178  // (re-define first point "by hand")
179  if (x2 == 0) {
180  x1 = roi_width;
181  y1 = y2;
182  } else if (y2 == 0) {
183  x1 = x2;
184  y1 = roi_height;
185  } else {
186  cout << "ERROR!" << endl
187  << " This case should not have occurred. Please have a look at method" << endl
188  << " \"LineShape::calc()\". Treatment of special case is not correct." << endl;
189  //exit(-1);
190  }
191  }
192 }
193 
194 
195 /** Get two points that define the line.
196  * @param x1 contains x coordinate of first point upon return
197  * @param y1 contains y coordinate of first point upon return
198  * @param x2 contains x coordinate of second point upon return
199  * @param y2 contains y coordinate of second point upon return
200  */
201 void
202 LineShape::getPoints(int *x1, int *y1, int *x2, int *y2)
203 {
204  calcPoints();
205 
206  *x1 = this->x1;
207  *y1 = this->y1;
208  *x2 = this->x2;
209  *y2 = this->y2;
210 }
211 
212 } // end namespace firevision
STL namespace.
float deg2rad(float deg)
Convert an angle given in degrees to radians.
Definition: angle.h:37