Files Classes Functions Hierarchy
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
1.5.8