proj home

Files   Classes   Functions   Hierarchy  

mazematrixD3.h

Go to the documentation of this file.
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 

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