Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Gridder.h

Go to the documentation of this file.
00001 #ifndef GRIDDER_H
00002 #define GRIDDER_H
00003 
00004 #include <algorithm>
00005 #include <iterator>
00006 #include <vector>
00007 
00008 #include "Segment.h"
00009 
00010 namespace AprilTags {
00011 
00012 //! A lookup table in 2D for implementing nearest neighbor.
00013 template <class T>
00014 class Gridder {
00015   private:
00016   Gridder(const Gridder&); //!< don't call
00017   Gridder& operator=(const Gridder&); //!< don't call
00018   
00019   struct Cell {
00020     T* object;
00021     Cell *next;
00022 
00023     Cell() : object(NULL), next(NULL) {}
00024 
00025     Cell(const Cell& c) : object(c.object), next(c.next) {}
00026 
00027     // Destructor
00028     ~Cell() {
00029       delete next;
00030     }
00031 
00032     Cell& operator=(const Cell &other) {
00033       if (this == &other)
00034   return *this;
00035 
00036       object = other.object;
00037       next = other.next;
00038       return *this;
00039     }
00040   };
00041 
00042   //! Initializes Gridder constructor
00043   void gridderInit(float x0Arg, float y0Arg, float x1Arg, float y1Arg, float ppCell) {
00044     width = (int) ((x1Arg - x0Arg)/ppCell + 1);
00045     height = (int) ((y1Arg - y0Arg)/ppCell + 1);
00046     
00047     x1 = x0Arg + ppCell*width;
00048     y1 = y0Arg + ppCell*height;
00049     cells = std::vector< std::vector<Cell*> >(height, std::vector<Cell*>(width,(Cell*)NULL));
00050   }
00051 
00052   float x0,y0,x1,y1;
00053   int width, height;
00054   float pixelsPerCell; //pixels per cell
00055   std::vector< std::vector<Cell*> > cells;
00056  
00057 public:
00058   Gridder(float x0Arg, float y0Arg, float x1Arg, float y1Arg, float ppCell)
00059     : x0(x0Arg), y0(y0Arg), x1(), y1(), width(), height(), pixelsPerCell(ppCell),
00060       cells() { gridderInit(x0Arg, y0Arg, x1Arg, y1Arg, ppCell); }
00061 
00062   // Destructor
00063   ~Gridder() {
00064     for (unsigned int i = 0; i < cells.size(); i++) {
00065       for (unsigned int j = 0; j < cells[i].size(); j++)
00066   delete cells[i][j];
00067     }
00068   }
00069 
00070   void add(float x, float y, T* object) {
00071     int ix = (int) ((x - x0)/pixelsPerCell);
00072     int iy = (int) ((y - y0)/pixelsPerCell);
00073 
00074     if (ix>=0 && iy>=0 && ix<width && iy<height) {
00075       Cell *c = new Cell;
00076       c->object = object;
00077       c->next = cells[iy][ix];
00078       cells[iy][ix] = c;
00079       // cout << "Gridder placed seg " << o->getId() << " at (" << ix << "," << iy << ")" << endl;
00080     }
00081   }
00082   
00083   // iterator begin();
00084   // iterator end();
00085 
00086   //! Iterator for Segment class.
00087   class Iterator {
00088   public:
00089     Iterator(Gridder* grid, float x, float y, float range)
00090       : outer(grid), ix0(), ix1(), iy0(), iy1(), ix(), iy(), c(NULL) { iteratorInit(x,y,range); }
00091     
00092     Iterator(const Iterator& it)
00093     : outer(it.outer), ix0(it.ix0), ix1(it.ix1), iy0(it.iy0), iy1(it.iy1), ix(it.ix), iy(it.iy), c(it.c) {}
00094     
00095     Iterator& operator=(const Iterator& it) {
00096       outer = it.outer;
00097       ix0 = it.ix0;
00098       ix1 = it.ix1;
00099       iy0 = it.iy0;
00100       iy1 = it.iy1;
00101       ix = it.ix;
00102       iy = it.iy;
00103       c = it.c;
00104     }
00105 
00106     bool hasNext() {
00107       if (c == NULL)
00108   findNext();
00109       return (c != NULL);
00110     }
00111 
00112     T& next() {
00113       T* thisObj = c->object;
00114       findNext();
00115       return *thisObj; // return Segment
00116     }
00117 
00118   private:
00119     void findNext() {
00120       if (c != NULL)
00121   c = c->next;
00122       if (c != NULL)
00123   return;
00124 
00125       ix++;
00126       while (true) {
00127   if (ix > ix1) {
00128     iy++;
00129     ix = ix0;
00130   }
00131   if (iy > iy1)
00132     break;
00133 
00134         c = outer->cells[iy][ix];
00135        
00136   if (c != NULL)
00137     break;
00138   ix++;
00139       }
00140     }
00141 
00142     //! Initializes Iterator constructor
00143     void iteratorInit(float x, float y, float range) {
00144       ix0 = (int) ((x - range - outer->x0)/outer->pixelsPerCell);
00145       iy0 = (int) ((y - range - outer->y0)/outer->pixelsPerCell);
00146 
00147       ix1 = (int) ((x + range - outer->x0)/outer->pixelsPerCell);
00148       iy1 = (int) ((y + range - outer->y0)/outer->pixelsPerCell);
00149 
00150       ix0 = std::max(0, ix0);
00151       ix0 = std::min(outer->width-1, ix0);
00152 
00153       ix1 = std::max(0, ix1);
00154       ix1 = std::min(outer->width-1, ix1);
00155 
00156       iy0 = std::max(0, iy0);
00157       iy0 = std::min(outer->height-1, iy0);
00158 
00159       iy1 = std::max(0, iy1);
00160       iy1 = std::min(outer->height-1, iy1);
00161 
00162       ix = ix0;
00163       iy = iy0;
00164 
00165       c = outer->cells[iy][ix];
00166     }
00167 
00168     Gridder* outer;
00169     int ix0, ix1, iy0, iy1;
00170     int ix, iy;
00171     Cell *c;
00172   };
00173 
00174   typedef Iterator iterator;
00175   iterator find(float x, float y, float range) { return Iterator(this,x,y,range); }
00176 };
00177 
00178 } // namespace
00179 
00180 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:41 2016 by Doxygen 1.6.3