proj home

Files   Classes   Functions   Hierarchy  

spiralindex.h

Go to the documentation of this file.
00001 #ifndef SPIRALINDEX_H
00002 #define SPIRALINDEX_H
00003 
00004 #include <point.h>
00005 #include <typedefs.h>
00006 
00021 template< typename T = int >
00022 class spiralindex
00023 {
00025   T count;
00027   T const countend;
00029   point2<T> current;
00031   point2<T> start;
00032 
00034   point2<T> xrange;
00036   point2<T> yrange;
00037 
00039   void directionclockwise();
00041   void directionanticlockwise();
00042 public:
00043 
00045   T const rows;
00047   T const columns;
00049   point2<T> di[4];
00051   uint direction;
00052 
00054   spiralindex
00055   (
00056     T const _rows, 
00057     T const _columns, 
00058     boolc anticlockwise=true
00059   );
00060 
00062   void reset();
00064   boolc operator !() const
00065     { return count < countend; }
00067   void operator ++ ();
00069   void pos(T & row, T & col) const
00070     { row=current.x; col=current.y; }
00072   void pos(T & k2) const
00073     { k2 = current.x*columns+current.y; }
00075   boolc valid(point2<T> const & p) const;
00076 
00078   void indexsequence(T* seq);
00079 
00080 };
00081 
00092 template< typename T = int >
00093 class spiralindex3D
00094 {
00096   T* square0;
00098   T* square1;
00100   T* squarei;
00103   T zcount;
00105   T icount;
00106 public:
00107 
00109   T const rows;
00111   T const columns;
00113   T const rectanglelength;
00114 
00116   spiralindex3D
00117   (
00118     T const _rows, 
00119     T const _columns, 
00120     T const _rectanglelength,
00121     boolc anticlockwise=true
00122   );
00124   ~spiralindex3D();
00125 
00127   void reset();
00129   boolc operator !() const
00130     { if (zcount<rectanglelength) return true; return false; }
00132   void pos(T & row, T & col, T & z) const;
00134   void pos(T & k2) const
00135     { k2 = zcount*rows*columns + icount; }
00136 
00138   void operator ++ ();
00139 
00140 };
00141 
00142 //---------------------------------------------------------
00143 // Implementation
00144 
00145 
00146 template< typename T >
00147 void spiralindex3D<T>::pos(T & row, T & col, T & z) const
00148 {
00149   T k(*squarei);
00150   col = k % columns;
00151   row = (k-col)/columns;
00152   z = zcount;
00153 }
00154 
00155 template< typename T >
00156 void spiralindex3D<T>::operator ++ ()
00157 {
00158   ++icount;
00159 
00160   // Reverse spiral incrementation.
00161   if ((zcount % 2)==1)
00162   {
00163     --squarei;
00164     if (squarei+1==square0)
00165     {
00166       ++zcount;
00167       icount=0;
00168       ++squarei;
00169     }
00170 
00171     return;
00172   }
00173 
00174   ++squarei;
00175   if (squarei==square1)
00176   {
00177     ++zcount;
00178     icount=0;
00179     --squarei;
00180   }
00181 }
00182 
00183 
00184 template< typename T >
00185 void spiralindex3D<T>::reset()
00186 {
00187   icount=0;
00188   zcount=0;
00189   squarei = square0;
00190 }
00191 
00192 template< typename T >
00193 spiralindex3D<T>::~spiralindex3D()
00194 {
00195   delete[] square0;
00196 }
00197 
00198 
00199 template< typename T >
00200 spiralindex3D<T>::spiralindex3D
00201 (
00202   T const _rows, 
00203   T const _columns, 
00204   T const _rectanglelength,
00205   boolc anticlockwise
00206 )
00207   : rows(_rows), columns(_columns),
00208   rectanglelength(_rectanglelength)
00209 {
00210   assert(rows>0);
00211   assert(columns>0);
00212 
00213   square0 = new T[rows*columns];
00214   square1 = square0 + rows*columns;
00215   spiralindex<T> spi(rows,columns,anticlockwise);
00216   spi.indexsequence(square0);
00217 
00218 /*
00219 cout << "square" << endl;
00220 for (int i=0; i<rows*columns; ++i)
00221   cout << square0[i] << " ";
00222 cout << endl << endl;
00223 */
00224 }
00225 
00226 
00227 
00228 
00229 
00230 template< typename T >
00231 void spiralindex<T>::indexsequence(T* seq)
00232 {
00233   //T k2;
00234   for ( reset(); operator !(); operator++() )
00235   {
00236     pos(*seq);
00237     ++seq;
00238   }
00239 }
00240 
00241 template< typename T >
00242 void spiralindex<T>::directionclockwise()
00243 {
00244   di[0] = point2<T>(0,1);
00245   di[1] = point2<T>(1,0);
00246   di[2] = point2<T>(0,-1);
00247   di[3] = point2<T>(-1,0);
00248 }
00249 
00250 template< typename T >
00251 void spiralindex<T>::directionanticlockwise()
00252 {
00253   di[0] = point2<T>(1,0);
00254   di[1] = point2<T>(0,1);
00255   di[2] = point2<T>(-1,0);
00256   di[3] = point2<T>(0,-1);
00257 }
00258 
00259 template< typename T >
00260 spiralindex<T>::spiralindex
00261 (
00262   T const _rows, 
00263   T const _columns, 
00264   boolc anticlockwise
00265 )
00266   : count(0), countend(_rows*_columns), current(0,0), 
00267     rows(_rows), columns(_columns)
00268 {
00269   assert(rows>0);
00270   assert(columns>0);
00271 
00272   if (anticlockwise)
00273     directionanticlockwise();
00274   else
00275     directionclockwise();
00276 }
00277 
00278 template< typename T >
00279 boolc spiralindex<T>::valid(point2<T> const & p) const
00280 {
00281   if (p.x==start.x)
00282   {
00283     if (p.y==start.y)
00284       return false;
00285   }
00286 
00287   if (p.x<yrange.x)
00288     return false;
00289 
00290   if (p.y<xrange.x)
00291     return false;
00292 
00293   if (p.x>yrange.y)
00294     return false;
00295 
00296   if (p.y>xrange.y)
00297     return false;
00298 
00299   return true;
00300 }
00301 
00302 template< typename T >
00303 void spiralindex<T>::reset()
00304 {
00305   current.x = 0;
00306   current.y = 0;
00307   count = 0;
00308 
00309   direction=0;
00310 
00311   start.x = 0;
00312   start.y = 0;
00313 
00314   xrange.x = 0;
00315   xrange.y = columns-1;
00316   yrange.x = 0;
00317   yrange.y = rows-1;
00318 }
00319 
00320 template< typename T >
00321 void spiralindex<T>::operator ++ ()
00322 {
00323   ++count;
00324 
00325   point2<T> c2 = current + di[direction];
00326   if (valid(c2)==false)
00327   {
00328     if (c2==start)
00329     {
00330       ++direction;
00331       direction %= 4;
00332 
00333       current += di[direction];
00334       start = current;
00335 
00336       ++xrange.x;
00337       --xrange.y;
00338       ++yrange.x;
00339       --yrange.y;
00340     }
00341     else
00342     {
00343       ++direction;
00344       direction %= 4;
00345 
00346       //start = current;
00347       current += di[direction];
00348     }
00349   }
00350   else
00351     current = c2;
00352 }
00353 
00354 
00355 
00356 #endif
00357 
00358 

Generated on Fri Mar 4 00:49:31 2011 for Chelton Evans Source by  doxygen 1.5.8