Files Classes Functions Hierarchy
00001 #ifndef MAZEMATRIXD3_H 00002 #define MAZEMATRIXD3_H 00003 00004 #include <cassert> 00005 #include <vector> 00006 using namespace std; 00007 00008 #include <cellD3.h> 00009 #include <print.h> 00010 00035 template< typename T > 00036 class mazematrixD3 00037 { 00038 public: 00039 00041 uint dim[4]; 00042 00044 void dimset(uintc rows, uintc columns, uintc depth); 00045 00047 vector< cellD3<T> > vi; 00048 00050 mazematrixD3(); 00051 00053 mazematrixD3(uintc rows, uintc columns, uintc depth); 00054 00056 uintc add(); 00057 00059 T neib(T id, uintc k) const; 00060 00062 void link( T id, uintc k, T id2); 00063 00065 void link(T id, uintc k, T id2, uintc k2); 00066 00068 boolc valid() const; 00069 00071 cellD3<T> & access(uintc r, uintc c, uintc depth) 00072 { return vi[c+r*dim[0]+depth*dim[0]*dim[1]+1]; } 00073 00075 void access(bool & res, cellD3<T>& x, uintc r, uintc c) 00076 { 00077 res=false; 00078 T k=c+r*dim[0]+1; 00079 if (k < dim[2]+1) 00080 { 00081 if (k!=0) 00082 { 00083 x=vi[k]; 00084 res=true; 00085 } 00086 } 00087 } 00088 00090 void move(bool & res, T& k2, uintc mv, T const k) const; 00091 00093 void neighboursunvisited( vector<T> & v, T const k); 00094 00096 void linkadjacent(bool & res, T const id1, T const id2); 00097 00098 }; 00099 00100 00101 //---------------------------------------------------------- 00102 // Implementation 00103 00104 template< typename T > 00105 void mazematrixD3<T>::dimset(uintc rows, uintc columns, uintc depth) 00106 { 00107 dim[0]=rows; 00108 dim[1]=columns; 00109 dim[2]=depth; 00110 dim[3]=rows*columns*depth; 00111 00112 vi.resize(dim[3]+1); 00113 for (T i=0; i<vi.size(); ++i) 00114 vi[i].id=i; 00115 } 00116 00117 00118 template< typename T > 00119 uintc mazematrixD3<T>::add() 00120 { 00121 assert(dim[0]*dim[1]*dim[2]!=0); // dimset must be called 00122 00123 uint k=vi.size(); 00124 cellD3<T> x; 00125 x.id=k; 00126 vi.push_back(x); 00127 00128 return k; 00129 } 00130 00131 00132 template< typename T > 00133 mazematrixD3<T>::mazematrixD3(uintc rows, uintc columns, uintc depth) 00134 { 00135 dimset(rows,columns,depth); 00136 } 00137 00138 00139 template< typename T > 00140 mazematrixD3<T>::mazematrixD3() 00141 { 00142 dim[0]=0; 00143 dim[1]=0; 00144 dim[2]=0; 00145 dim[3]=0; 00146 } 00147 00148 template< typename T > 00149 T mazematrixD3<T>::neib(T id, uintc k) const 00150 { 00151 assert(id!=0); 00152 assert(id<=dim[3]); 00153 assert(k<6); 00154 00155 uint m=dim[0]; 00156 uint n=dim[1]; 00157 00158 uint mn=m*n; 00159 T w=(id-1)%mn; 00160 00161 // Up. 00162 if (k==0) 00163 { 00164 if (w<n) 00165 return 0; 00166 return id-n; 00167 } 00168 00169 // Down. 00170 if (k==2) 00171 { 00172 if (w+n>mn) 00173 return 0; 00174 return id+n; 00175 } 00176 00177 // Right. 00178 if (k==1) 00179 { 00180 if (((id-1)%n)==0) 00181 return 0; 00182 00183 return id+1; 00184 } 00185 00186 // Left. 00187 if (k==3) 00188 { 00189 if (((id+n-1)%n)==0) 00190 return 0; 00191 00192 return id-1; 00193 } 00194 00195 // Forward 00196 if (k==4) 00197 { 00198 if (id-1+mn>=mn*dim[2]) 00199 return 0; 00200 return id+mn; 00201 } 00202 00203 // Back 00204 if (k==5) 00205 { 00206 if (id-1<mn) 00207 return 0; 00208 return id-mn; 00209 } 00210 00211 return 0; 00212 } 00213 00214 template< typename T > 00215 void mazematrixD3<T>::link( T id, uintc k, T id2) 00216 { 00217 assert(dim[0]*dim[1]*dim[3]!=0); // dimset must be called 00218 assert(k<6); 00219 assert(id!=0); 00220 assert(id2!=0); 00221 00222 uint k2; 00223 switch (k) 00224 { 00225 case 0: k2=2; break; 00226 case 1: k2=3; break; 00227 case 2: k2=0; break; 00228 case 3: k2=1; break; 00229 case 4: k2=5; break; 00230 case 5: k2=4; break; 00231 } 00232 00233 vi[id].ni[k] = id2; 00234 vi[id2].ni[k2] = id; 00235 } 00236 00237 00238 template< typename T > 00239 void mazematrixD3<T>::link( T id, uintc k, T id2, uintc k2) 00240 { 00241 assertreturn(dim[0]*dim[1]*dim[2]!=0); // dimset must be called 00242 assert(k<6); 00243 assert(k2<6); 00244 assert(id!=0); 00245 assert(id2!=0); 00246 00247 vi[id].ni[k] = id2; 00248 vi[id2].ni[k2] = id; 00249 } 00250 00251 template< typename T > 00252 boolc mazematrixD3<T>::valid() const 00253 { 00254 assertreturnfalse(dim[0]*dim[1]*dim[2]!=0); // dimset must be called 00255 00256 uint imax=vi.size(); 00257 T nb; 00258 T nb2local; 00259 for (uint i=1; i<imax; ++i) 00260 { 00261 // cout << "error: " << (string)vi[i] << endl; 00262 00263 assertreturnfalse(!(vi[i].id!=i)); 00264 00265 for (uint k=0; k<6; ++k) 00266 { 00267 //cout << SHOW(k) << endl; 00268 nb=vi[i].ni[k]; 00269 //cout << SHOW(nb) << endl; 00270 if (nb!=0) 00271 { 00272 assertreturnfalse(!(nb>=imax)); 00273 00274 nb2local = vi[nb].niInv(i); 00275 assertreturnfalse(!(nb2local==6)); 00276 assertreturnfalse(!(vi[nb].ni[nb2local]!=i)); 00277 } 00278 } 00279 00280 } 00281 00282 return true; 00283 } 00284 00285 template< typename T > 00286 void mazematrixD3<T>::move 00287 ( 00288 bool & res, 00289 T& k2, 00290 uintc mv, 00291 T const k 00292 ) const 00293 { 00294 uintc m=dim[0]; 00295 uintc n=dim[1]; 00296 uintc d=dim[2]; 00297 00298 assert(mv<6); 00299 00300 if (mv==3) 00301 { 00302 res=(((k-1)%n)!=0); 00303 k2=k-1; 00304 return; 00305 } 00306 00307 if (mv==1) 00308 { 00309 res=((k%n)!=0); 00310 k2=k+1; 00311 return; 00312 } 00313 00314 if (mv==0) 00315 { 00316 uint i = (k-1)%(m*n); 00317 res=(i>=n); 00318 k2=k-n; 00319 return; 00320 } 00321 00322 if (mv==2) 00323 { 00324 uint i = (k-1)%(m*n); 00325 res=((i+n)<m*n); 00326 k2=k+n; 00327 return; 00328 } 00329 00330 if (mv==4) 00331 { 00332 res=(k+(m*n)-1<m*n*d); 00333 k2=k+m*n; 00334 return; 00335 } 00336 00337 if (mv==5) 00338 { 00339 res=(k-1>m*n); 00340 k2=k-m*n; 00341 return; 00342 } 00343 } 00344 00345 template< typename T > 00346 void mazematrixD3<T>::neighboursunvisited 00347 ( 00348 vector<T> & v, 00349 T const k 00350 ) 00351 { 00352 //cout << SHOW(k) << endl; 00353 v.clear(); 00354 bool res; 00355 T k2; 00356 for (uint i=0; i<4; ++i) 00357 { 00358 move(res,k2,i,k); 00359 //cout << SHOW(k2) << endl; 00360 if (res) 00361 { 00362 if (vi[k2].unvisited()) 00363 v.push_back(k2); 00364 } 00365 } 00366 } 00367 00368 template< typename T > 00369 void mazematrixD3<T>::linkadjacent 00370 ( 00371 bool & res, 00372 T const id1, 00373 T const id2 00374 ) 00375 { 00376 res=false; 00377 00378 if (id1==id2) 00379 return; 00380 00381 T a; 00382 T b; 00383 00384 if (id1<id2) 00385 { a=id1; b=id2; } 00386 else 00387 { a=id2; b=id1; }; 00388 00389 // Horizontal linkage 00390 if (a+1==b) 00391 { 00392 link(a,1,b,3); 00393 res=true; 00394 return; 00395 } 00396 00397 // Vertical linkage 00398 if (a+dim[1]==b) 00399 { 00400 link(a,2,b,0); 00401 res=true; 00402 return; 00403 } 00404 } 00405 00406 00407 00408 #endif 00409 00410
1.5.8