Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * line.cpp - Implementation of a line shape finder 00004 * 00005 * Created: Thu May 16 00:00:00 2005 00006 * Copyright 2005 Tim Niemueller [www.niemueller.de] 00007 * Martin Heracles <Martin.Heracles@rwth-aachen.de> 00008 * Hu Yuxiao <Yuxiao.Hu@rwth-aachen.de> 00009 * 00010 ****************************************************************************/ 00011 00012 /* This program is free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU General Public License as published by 00014 * the Free Software Foundation; either version 2 of the License, or 00015 * (at your option) any later version. A runtime exception applies to 00016 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00017 * 00018 * This program is distributed in the hope that it will be useful, 00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 * GNU Library General Public License for more details. 00022 * 00023 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00024 */ 00025 00026 #include <utils/math/angle.h> 00027 #include <fvmodels/shape/line.h> 00028 00029 // #include <utils/geometry/line.h> 00030 // #include <utils/geometry/point.h> 00031 00032 using namespace std; 00033 00034 namespace firevision { 00035 #if 0 /* just to make Emacs auto-indent happy */ 00036 } 00037 #endif 00038 00039 /** @class LineShape <fvmodels/shape/line.h> 00040 * Line shape. 00041 */ 00042 00043 /** Constructor. 00044 * @param roi_width ROI width 00045 * @param roi_height ROI height 00046 */ 00047 LineShape::LineShape(unsigned int roi_width, unsigned int roi_height) 00048 { 00049 r = 0; 00050 phi = 0; 00051 count = 0; 00052 00053 max_length = (int)sqrt( roi_width * roi_width + roi_height * roi_height ); 00054 last_calc_r = last_calc_phi = 0.f; 00055 00056 this->roi_width = roi_width; 00057 this->roi_height = roi_height; 00058 00059 } 00060 00061 00062 /** Destructor. */ 00063 LineShape::~LineShape() 00064 { 00065 } 00066 00067 00068 /** Print line. 00069 * @param stream stream to print to 00070 */ 00071 void 00072 LineShape::printToStream(std::ostream &stream) 00073 { 00074 stream << "r=" << r << " phi=" << phi 00075 << " count= " << count; 00076 } 00077 00078 void 00079 LineShape::setMargin(unsigned int margin) 00080 { 00081 this->margin = margin; 00082 } 00083 00084 00085 bool 00086 LineShape::isClose(unsigned int in_roi_x, unsigned int in_roi_y) 00087 { 00088 return false; 00089 /* 00090 Point p1(x1, y1); 00091 Point p2(x2, y2); 00092 00093 Line cl(p1, p2); 00094 00095 Point p(x, y); 00096 / 00097 cout << "LineShape (" << x1 << ", " << y1 << ") <-> (" << x2 << ", " << y2 << ")" << endl 00098 << "Point (" << x << ", " << y << ")" << endl 00099 << "Distance: " << cl.getDistanceTo(p) << endl; 00100 / 00101 return (cl.GetDistanceTo(p) <= margin); 00102 */ 00103 } 00104 00105 /** Calc points for line. */ 00106 void 00107 LineShape::calcPoints() 00108 { 00109 00110 if ((last_calc_r == r) && (last_calc_phi == phi)) return; 00111 last_calc_r = r; 00112 last_calc_phi = phi; 00113 00114 float rad_angle = fawkes::deg2rad(phi); 00115 00116 // if true, point (x1, y1) will be moved the opposite direction 00117 bool reverse_direction = false; 00118 00119 /* compute two points on the line. 00120 (x1, y1) will be somewhere inside or outside of ROI, 00121 (x2, y2) will be on a ROI edge (or on a prolongation thereof) */ 00122 if ( rad_angle < M_PI/4 ) { 00123 x1 = (int)round( r * cos( rad_angle ) ); 00124 y1 = (int)round( r * sin( rad_angle ) ); 00125 y2 = 0; 00126 x2 = (int)round( r / cos( rad_angle ) ); 00127 } else if ( rad_angle < M_PI/2 ) { 00128 x1 = (int)round( r * cos( rad_angle ) ); 00129 y1 = (int)round( r * sin( rad_angle ) ); 00130 x2 = 0; 00131 y2 = (int)round( r / cos( M_PI/2 - rad_angle ) ); 00132 } else if ( rad_angle < 3.0/4.0 * M_PI ) { 00133 x1 = (int)round(-r * cos( M_PI - rad_angle ) ); 00134 y1 = (int)round( r * sin( M_PI - rad_angle ) ); 00135 x2 = 0; 00136 y2 = (int)round( r / cos( rad_angle - M_PI/2 ) ); 00137 00138 // the direction in which (x1, y1) has to be moved 00139 // depends on the sign of r 00140 if (r >= 0.0) { 00141 reverse_direction = true; 00142 } 00143 } else { 00144 // rad_angle <= M_PI 00145 x1 = (int)round(-r * cos( M_PI - rad_angle ) ); 00146 y1 = (int)round( r * sin( M_PI - rad_angle ) ); 00147 y2 = 0; 00148 x2 = (int)round(-r / cos( M_PI - rad_angle ) ); 00149 00150 // the direction in which (x1, y1) has to be moved 00151 // depends on the sign of r 00152 if (r < 0.0) { 00153 reverse_direction = true; 00154 } 00155 } 00156 00157 if ( ! (x1 == x2 && 00158 y1 == y2 ) ) { 00159 // move (x1, y1) away from (x2, y2) 00160 // such that line (x1, y1)<->(x2, y2) spans the whole ROI 00161 float vx, vy, length; 00162 vx = x1 - x2 ; 00163 vy = y1 - y2 ; 00164 length = sqrt( vx * vx + vy * vy ); 00165 00166 vx /= length; 00167 vy /= length; 00168 vx *= max_length; 00169 vy *= max_length; 00170 00171 if ( ! reverse_direction) { 00172 x1 += (int)vx; 00173 y1 += (int)vy; 00174 } else { 00175 x1 -= (int)vx; 00176 y1 -= (int)vy; 00177 } 00178 00179 } else { 00180 // special case: both points are identical, hence could not be moved apart 00181 // (re-define first point "by hand") 00182 if (x2 == 0) { 00183 x1 = roi_width; 00184 y1 = y2; 00185 } else if (y2 == 0) { 00186 x1 = x2; 00187 y1 = roi_height; 00188 } else { 00189 cout << "ERROR!" << endl 00190 << " This case should not have occurred. Please have a look at method" << endl 00191 << " \"LineShape::calc()\". Treatment of special case is not correct." << endl; 00192 //exit(-1); 00193 } 00194 } 00195 } 00196 00197 00198 /** Get two points that define the line. 00199 * @param x1 contains x coordinate of first point upon return 00200 * @param y1 contains y coordinate of first point upon return 00201 * @param x2 contains x coordinate of second point upon return 00202 * @param y2 contains y coordinate of second point upon return 00203 */ 00204 void 00205 LineShape::getPoints(int *x1, int *y1, int *x2, int *y2) 00206 { 00207 calcPoints(); 00208 00209 *x1 = this->x1; 00210 *y1 = this->y1; 00211 *x2 = this->x2; 00212 *y2 = this->y2; 00213 } 00214 00215 } // end namespace firevision