grid.cpp

00001 
00002 /***************************************************************************
00003  *  grid.cpp - Implementation of the grid scanline model
00004  *
00005  *  Created: Tue Feb 22 10:36:39 2005
00006  *  Copyright  2005  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #include <models/scanlines/grid.h>
00025 #include <core/exceptions/software.h>
00026 
00027 #include <cstring>
00028 
00029 using fawkes::point_t;
00030 
00031 namespace firevision {
00032 #if 0 /* just to make Emacs auto-indent happy */
00033 }
00034 #endif
00035 
00036 /** @class ScanlineGrid <models/scanlines/grid.h>
00037  * Scanline Grid.
00038  * A grid as scanline points. The crossings of the lines are the scanline
00039  * points.
00040  */
00041 
00042 /** Constructor.
00043  * @param width width of grid
00044  * @param height height of grid
00045  * @param offset_x x offset between lines
00046  * @param offset_y y offset between lines
00047  * @param roi the grid will only be calculated within the roi (if NULL the roi
00048  *            will be from 0,0 to width,height). The object will be deleted by
00049  *            ScanlineGrid!
00050  * @param horizontal_grid if true x will be increased before y
00051  */
00052 ScanlineGrid::ScanlineGrid(unsigned int width, unsigned int height,
00053                            unsigned int offset_x, unsigned int offset_y,
00054                            ROI* roi, bool horizontal_grid)
00055 {
00056   this->roi = NULL;
00057   setGridParams(width, height,
00058                 offset_x, offset_y,
00059                 roi, horizontal_grid);
00060   //reset is done in setGridParams ()
00061 }
00062 
00063 /** Destructor
00064  */
00065 ScanlineGrid::~ScanlineGrid()
00066 {
00067   if (roi) //Has to be set, but still...
00068   {
00069     delete roi;
00070   }
00071 }
00072 
00073 point_t
00074 ScanlineGrid::operator*()
00075 {
00076   return coord;
00077 }
00078 
00079 point_t*
00080 ScanlineGrid::operator->()
00081 {
00082   return &coord;
00083 }
00084 
00085 void
00086 ScanlineGrid::calc_next_coord()
00087 {
00088   if (finished())
00089     return;
00090 
00091   if (horizontal_grid)
00092   {
00093     if (static_cast<int>(coord.x) < static_cast<int>(roi->image_width - offset_x))
00094     {
00095       coord.x += offset_x;
00096     }
00097     else
00098     {
00099       if (static_cast<int>(coord.y) < static_cast<int>(roi->image_height - offset_y))
00100       {
00101         coord.x = roi->start.x;
00102         coord.y += offset_y;
00103       }
00104       else
00105       {
00106         more_to_come = false;
00107       }
00108     }
00109   }
00110   else // vertical grid
00111   {
00112     if (static_cast<int>(coord.y) < static_cast<int>(roi->image_height - offset_y))
00113     {
00114       coord.y += offset_y;
00115     }
00116     else
00117     {
00118       if (static_cast<int>(coord.x) < static_cast<int>(roi->image_width - offset_x))
00119       {
00120         coord.x += offset_x;
00121         coord.y = roi->start.y;
00122       }
00123       else
00124       {
00125         more_to_come = false;
00126       }
00127     }
00128   }
00129 }
00130 
00131 point_t *
00132 ScanlineGrid::operator++()
00133 {
00134   calc_next_coord();
00135   return &coord;
00136 }
00137 
00138 point_t *
00139 ScanlineGrid::operator++(int)
00140 {
00141   memcpy(&tmp_coord, &coord, sizeof(point_t));
00142   calc_next_coord();
00143   return &tmp_coord;
00144 }
00145 
00146 bool
00147 ScanlineGrid::finished()
00148 {
00149   return !more_to_come;
00150 }
00151 
00152 void
00153 ScanlineGrid::reset()
00154 {
00155   coord.x = roi->start.x;
00156   coord.y = roi->start.y;
00157 
00158   more_to_come = true;
00159 }
00160 
00161 const char *
00162 ScanlineGrid::get_name()
00163 {
00164   return "ScanlineModel::Grid";
00165 }
00166 
00167 
00168 unsigned int
00169 ScanlineGrid::get_margin()
00170 {
00171   return (offset_x > offset_y) ? offset_x : offset_y;
00172 }
00173 
00174 
00175 void
00176 ScanlineGrid::set_robot_pose(float x, float y, float ori)
00177 {
00178   // ignored
00179 }
00180 
00181 
00182 void
00183 ScanlineGrid::set_pan_tilt(float pan, float tilt)
00184 {
00185   // ignored
00186 }
00187 
00188 void
00189 ScanlineGrid::set_roi(ROI *roi)
00190 {
00191   delete this->roi;
00192 
00193   if (!roi) this->roi = new ROI(0, 0, this->width, this->height, this->width, this->height);
00194   else
00195   {
00196     this->roi = roi;
00197     //Use roi's image width/height as grid boundary (to simplify the "exceeds-boundaries"-test)
00198     this->roi->image_width  = this->roi->start.x + this->roi->width;
00199     this->roi->image_height = this->roi->start.y + this->roi->height;
00200 
00201     if (this->roi->image_width > this->width)
00202       throw fawkes::OutOfBoundsException("ScanlineGrid: ROI is out of grid bounds!", this->roi->image_width, 0, this->width);
00203     if (this->roi->image_height > this->height)
00204       throw fawkes::OutOfBoundsException("ScanlineGrid: ROI is out of grid bounds!", this->roi->image_height, 0, this->height);
00205   }
00206 
00207   reset();
00208 }
00209 
00210 /** Set dimensions.
00211  * Set width and height of scanline grid. Implicitly resets the grid.
00212  * @param width width
00213  * @param height height
00214  * @param roi the grid will only be calculated within the roi (if NULL the roi
00215  *            will be from 0,0 to width,height). The object will be deleted by
00216  *            ScanlineGrid!
00217  */
00218 void
00219 ScanlineGrid::setDimensions(unsigned int width, unsigned int height, ROI* roi)
00220 {
00221   this->width  = width;
00222   this->height = height;
00223 
00224   set_roi(roi);
00225 }
00226 
00227 
00228 /** Set offset.
00229  * Set X and Y offset by which the pointer in the grid is advanced. Implicitly resets the grid.
00230  * @param offset_x offset_x
00231  * @param offset_y offset_y
00232  */
00233 void
00234 ScanlineGrid::setOffset(unsigned int offset_x, unsigned int offset_y)
00235 {
00236   this->offset_x = offset_x;
00237   this->offset_y = offset_y;
00238 
00239   reset();
00240 }
00241 
00242 
00243 /** Set all grid parameters.
00244  * Set width, height, X and Y offset by which the pointer in the grid is advanced.
00245  * Implicitly resets the grid.
00246  * @param width width
00247  * @param height height
00248  * @param offset_x offset_x
00249  * @param offset_y offset_y
00250  * @param roi the grid will only be calculated within the roi (if NULL the roi
00251  *            will be from 0,0 to width,height). The object will be deleted by
00252  *            ScanlineGrid!
00253  * @param horizontal_grid if true x will be increased before y
00254  */
00255 void
00256 ScanlineGrid::setGridParams(unsigned int width, unsigned int height,
00257                             unsigned int offset_x, unsigned int offset_y,
00258                             ROI* roi, bool horizontal_grid)
00259 {
00260   this->horizontal_grid = horizontal_grid;
00261 
00262   setDimensions(width, height, roi);
00263   setOffset (offset_x, offset_y);
00264 }
00265 
00266 } // end namespace firevision