line.cpp

00001
00002 /***************************************************************************
00003  *  circle.cpp - Implementation of a circle shape finder
00004  *
00005  *  Generated: Thu May 16 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 <models/shape/line.h>
00028
00029 // #include <utils/geometry/line.h>
00030 // #include <utils/geometry/point.h>
00031
00032 using namespace std;
00033 
00034 /** @class LineShape <models/shape/line.h>
00035  * Line shape.
00036  */
00037 
00038 /** Constructor.
00039  * @param roi_width ROI width
00040  * @param roi_height ROI height
00041  */
00042 LineShape::LineShape(unsigned int roi_width, unsigned int roi_height)
00043 {
00044   r = 0;
00045   phi = 0;
00046   count = 0;
00047
00048   max_length = (int)sqrt( roi_width * roi_width + roi_height * roi_height );
00049   last_calc_r = last_calc_phi = 0.f;
00050
00051   this->roi_width = roi_width;
00052   this->roi_height = roi_height;
00053
00054 }
00055
00056 
00057 /** Destructor. */
00058 LineShape::~LineShape()
00059 {
00060 }
00061
00062 
00063 /** Print line.
00064  * @param stream stream to print to
00065  */
00066 void
00067 LineShape::printToStream(std::ostream &stream)
00068 {
00069   stream << "r=" << r << "  phi=" << phi
00070          << "  count= " << count;
00071 }
00072
00073 void
00074 LineShape::setMargin(unsigned int margin)
00075 {
00076   this->margin = margin;
00077 }
00078
00079
00080 bool
00081 LineShape::isClose(unsigned int in_roi_x, unsigned int in_roi_y)
00082 {
00083   return false;
00084   /*
00085   Point p1(x1, y1);
00086   Point p2(x2, y2);
00087 
00088   Line  cl(p1, p2);
00089 
00090   Point p(x, y);
00091   /
00092   cout << "LineShape     (" << x1 << ", " << y1 << ") <-> (" << x2 << ", " << y2 << ")" << endl
00093        << "Point    (" << x  << ", " << y  << ")" << endl
00094        << "Distance: " << cl.getDistanceTo(p) << endl;
00095   /
00096   return (cl.GetDistanceTo(p) <= margin);
00097   */
00098 }
00099 
00100 /** Calc points for line. */
00101 void
00102 LineShape::calcPoints()
00103 {
00104
00105   if ((last_calc_r == r) && (last_calc_phi == phi)) return;
00106   last_calc_r   = r;
00107   last_calc_phi = phi;
00108
00109   float rad_angle = fawkes::deg2rad(phi);
00110
00111   // if true, point (x1, y1) will be moved the opposite direction
00112   bool reverse_direction = false;
00113
00114   /* compute two points on the line.
00115      (x1, y1) will be somewhere inside or outside of ROI,
00116      (x2, y2) will be on a ROI edge (or on a prolongation thereof) */
00117   if ( rad_angle < M_PI/4 ) {
00118     x1 = (int)round( r * cos( rad_angle ) );
00119     y1 = (int)round( r * sin( rad_angle ) );
00120     y2 = 0;
00121     x2 = (int)round( r / cos( rad_angle ) );
00122   } else if ( rad_angle < M_PI/2 ) {
00123     x1 = (int)round( r * cos( rad_angle ) );
00124     y1 = (int)round( r * sin( rad_angle ) );
00125     x2 = 0;
00126     y2 = (int)round( r / cos( M_PI/2 - rad_angle ) );
00127   } else if ( rad_angle < 3.0/4.0 * M_PI ) {
00128     x1 = (int)round(-r * cos( M_PI - rad_angle ) );
00129     y1 = (int)round( r * sin( M_PI - rad_angle ) );
00130     x2 = 0;
00131     y2 = (int)round( r / cos( rad_angle - M_PI/2 ) );
00132
00133     // the direction in which (x1, y1) has to be moved
00134     // depends on the sign of r
00135     if (r >= 0.0) {
00136       reverse_direction = true;
00137     }
00138   } else {
00139     // rad_angle <= M_PI
00140     x1 = (int)round(-r * cos( M_PI - rad_angle ) );
00141     y1 = (int)round( r * sin( M_PI - rad_angle ) );
00142     y2 = 0;
00143     x2 = (int)round(-r / cos( M_PI - rad_angle ) );
00144
00145     // the direction in which (x1, y1) has to be moved
00146     // depends on the sign of r 
00147     if (r < 0.0) {
00148       reverse_direction = true;
00149     }
00150   }
00151
00152   if ( ! (x1 == x2 &&
00153           y1 == y2   ) ) {
00154     // move (x1, y1) away from (x2, y2) 
00155     // such that line (x1, y1)<->(x2, y2) spans the whole ROI
00156     float vx, vy, length;
00157     vx = x1 - x2 ;
00158     vy = y1 - y2 ;
00159     length = sqrt( vx * vx + vy * vy );
00160
00161     vx /= length;
00162     vy /= length;
00163     vx *= max_length;
00164     vy *= max_length;
00165
00166     if ( ! reverse_direction) {
00167       x1 += (int)vx;
00168       y1 += (int)vy;
00169     } else {
00170       x1 -= (int)vx;
00171       y1 -= (int)vy;
00172     }
00173
00174   } else {
00175     // special case: both points are identical, hence could not be moved apart
00176     // (re-define first point "by hand")
00177     if (x2 == 0) {
00178       x1 = roi_width;
00179       y1 = y2;
00180     } else if (y2 == 0) {
00181       x1 = x2;
00182       y1 = roi_height;
00183     } else {
00184       cout << "ERROR!" << endl
00185            << "  This case should not have occurred. Please have a look at method" << endl
00186            << "  \"LineShape::calc()\". Treatment of special case is not correct." << endl;
00187       //exit(-1);
00188     }
00189   }
00190 }
00191
00192 
00193 /** Get two points that define the line.
00194  * @param x1 contains x coordinate of first point upon return
00195  * @param y1 contains y coordinate of first point upon return
00196  * @param x2 contains x coordinate of second point upon return
00197  * @param y2 contains y coordinate of second point upon return
00198  */
00199 void
00200 LineShape::getPoints(int *x1, int *y1, int *x2, int *y2)
00201 {
00202   calcPoints();
00203
00204   *x1 = this->x1;
00205   *y1 = this->y1;
00206   *x2 = this->x2;
00207   *y2 = this->y2;
00208 }
00209
00210
00211