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