/vol/vipdata/irtk/packages/transformation/include/irtkFreeFormTransformation4D.h

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkFreeFormTransformation4D.h 2 2008-12-23 12:40:14Z dr $
00005   Copyright : Imperial College, Department of Computing
00006               Visual Information Processing (VIP), 2008 onwards
00007   Date      : $Date: 2008-12-23 12:40:14 +0000 (Tue, 23 Dec 2008) $
00008   Version   : $Revision: 2 $
00009   Changes   : $Author: dr $
00010 
00011 =========================================================================*/
00012 
00013 #ifndef _IRTKFREEFORMTRANSFORMATION4D_H
00014 
00015 #define _IRTKFREEFORMTRANSFORMATION4D_H
00016 
00017 #include <irtkGeometry.h>
00018 
00019 #define FFDLOOKUPTABLESIZE 1000
00020 
00028 class irtkFreeFormTransformation4D : public irtkFreeFormTransformation
00029 {
00030 
00031 protected:
00032 
00034   int _x;
00035 
00037   int _y;
00038 
00040   int _z;
00041 
00043   int _t;
00044 
00046   double _dx;
00047 
00049   double _dy;
00050 
00052   double _dz;
00053 
00055   double _dt;
00056 
00058   double _tMin;
00059 
00061   double _tMax;
00062 
00064   double _xaxis[3];
00065 
00067   double _yaxis[3];
00068 
00070   double _zaxis[3];
00071 
00073   irtkPoint _origin;
00074 
00076   irtkMatrix _matL2W;
00077 
00079   irtkMatrix _matW2L;
00080 
00082   double ****_xdata;
00083 
00085   double ****_ydata;
00086 
00088   double ****_zdata;
00089 
00091   static double ****Allocate  (double ****, int, int, int, int);
00092 
00094   static double ****Deallocate(double ****, int, int, int, int);
00095 
00097   virtual void UpdateMatrix();
00098 
00099 public:
00100 
00102   virtual void Subdivide() = 0;
00103 
00105   virtual int GetX() const;
00106 
00108   virtual int GetY() const;
00109 
00111   virtual int GetZ() const;
00112 
00114   virtual int GetT() const;
00115 
00117   virtual int NumberOfDOFs() const;
00118 
00120   virtual void GetSpacing(double &, double &, double &, double &) const;
00121 
00123   virtual void  PutOrientation(double *, double *, double *);
00124 
00126   virtual void  GetOrientation(double *, double *, double *) const;
00127 
00129   virtual void   Put(int, double);
00130 
00132   virtual void   Put(int, int, int, int, double, double, double);
00133 
00135   virtual double Get(int) const;
00136 
00138   virtual void   Get(int, int, int, int, double &, double &, double &) const;
00139 
00141   virtual double Bending(double, double, double, double) = 0;
00142 
00144   virtual void   PutStatus(int, int, int, int, _Status);
00145 
00147   virtual void   PutStatus(int, int, int, int, _Status, _Status, _Status);
00148 
00150   virtual void   PutStatus(int, _Status);
00151 
00153   virtual void   GetStatus(int, int, int, int, _Status &, _Status &, _Status &);
00154 
00156   virtual _Status GetStatus(int);
00157 
00159   virtual void WorldToLattice(double &, double &, double &) const;
00160 
00162   virtual void WorldToLattice(irtkPoint &) const;
00163 
00165   virtual double TimeToLattice(double) const;
00166 
00168   virtual void LatticeToWorld(double &, double &, double &) const;
00169 
00171   virtual void LatticeToWorld(irtkPoint &) const;
00172 
00174   virtual double LatticeToTime(double) const;
00175 
00177   virtual void IndexToLattice(int index, int& i, int& j, int& k, int& l) const;
00178 
00180   virtual int  LatticeToIndex(int i, int j, int k, int l) const;
00181 
00183   virtual void  ControlPointLocation(int, double &, double &, double &) const;
00184 
00186   virtual irtkPoint ControlPointLocation(int) const;
00187 
00189   virtual void BoundingBox(irtkPoint &, irtkPoint &) const;
00190 
00192   virtual void BoundingBox(double &, double &, double &,
00193                            double &, double &, double &) const;
00194 
00199   virtual void BoundingBox(int, double &, double &, double &, double &,
00200                            double &, double &, double &, double &, double = 1) const = 0;
00201 
00206   virtual void BoundingBox(irtkGreyImage *, int, int &, int &, int &, int &,
00207                            int &, int &, int &, int &, double = 1) const = 0;
00208 
00210   virtual double Inverse(double &, double &, double &, double = 0, double = 0.01);
00211 
00213   virtual Bool IsIdentity();
00214 
00216   virtual const char *NameOfClass();
00217 
00218 };
00219 
00220 inline int irtkFreeFormTransformation4D::GetX() const
00221 {
00222   return _x;
00223 }
00224 
00225 inline int irtkFreeFormTransformation4D::GetY() const
00226 {
00227   return _y;
00228 }
00229 
00230 inline int irtkFreeFormTransformation4D::GetZ() const
00231 {
00232   return _z;
00233 }
00234 
00235 inline int irtkFreeFormTransformation4D::GetT() const
00236 {
00237   return _t;
00238 }
00239 
00240 inline int irtkFreeFormTransformation4D::NumberOfDOFs() const
00241 {
00242   return 3*_x*_y*_z*_t;
00243 }
00244 
00245 inline double irtkFreeFormTransformation4D::Get(int index) const
00246 {
00247   int i, j, k, l;
00248 
00249   if (index >= 3*_x*_y*_z*_t) {
00250     cerr << "irtkFreeFormTransformation4D::Get: No such dof" << endl;
00251     exit(1);
00252   }
00253 
00254   if (index < _x*_y*_z*_t) {
00255     l = index/(_z*_y*_x);
00256     k = index%(_z*_y*_x)/(_y*_x);
00257     j = index%(_z*_y*_x)%(_y*_x)/_x;
00258     i = index%(_z*_y*_x)%(_y*_x)%_x;
00259     cout << "x = " << i << " " << j << " " << k << " " << l << endl;
00260 
00261     return _xdata[l][k][j][i];
00262   } else if (index < 2*_x*_y*_z*_t) {
00263     index -= _x*_y*_z*_t;
00264 
00265     l = index/(_z*_y*_x);
00266     k = index%(_z*_y*_x)/(_y*_x);
00267     j = index%(_z*_y*_x)%(_y*_x)/_x;
00268     i = index%(_z*_y*_x)%(_y*_x)%_x;
00269     cout << "y  = " << i << " " << j << " " << k << " " << l << endl;
00270 
00271     return _ydata[l][k][j][i];
00272   } else {
00273     index -= 2*_x*_y*_z*_t;
00274 
00275     l = index/(_z*_y*_x);
00276     k = index%(_z*_y*_x)/(_y*_x);
00277     j = index%(_z*_y*_x)%(_y*_x)/_x;
00278     i = index%(_z*_y*_x)%(_y*_x)%_x;
00279     cout << "z = " << i << " " << j << " " << k << " " << l << endl;
00280 
00281     return _zdata[l][k][j][i];
00282   }
00283 }
00284 
00285 inline void irtkFreeFormTransformation4D::Get(int i, int j, int k, int l, double &x, double &y, double &z) const
00286 {
00287   if ((i < 0) || (i >= _x) || (j < 0) || (j >= _y) || (k < 0) || (k >= _z) || (l < 0) || (l >= _t)) {
00288     cerr << "irtkFreeFormTransformation4D::Get: No such dof" << endl;
00289     exit(1);
00290   }
00291   x = _xdata[l][k][j][i];
00292   y = _ydata[l][k][j][i];
00293   z = _zdata[l][k][j][i];
00294 }
00295 
00296 inline void irtkFreeFormTransformation4D::Put(int index, double x)
00297 {
00298   int i, j, k, l;
00299 
00300   if (index >= 3*_x*_y*_z*_t) {
00301     cerr << "irtkFreeFormTransformation4D::Put: No such dof" << endl;
00302     exit(1);
00303   }
00304 
00305   if (index < _x*_y*_z*_t) {
00306     l = index/(_z*_y*_x);
00307     k = index%(_z*_y*_x)/(_y*_x);
00308     j = index%(_z*_y*_x)%(_y*_x)/_x;
00309     i = index%(_z*_y*_x)%(_y*_x)%_x;
00310 
00311     _xdata[l][k][j][i] = x;
00312   } else if (index < 2*_x*_y*_z*_t) {
00313     index -= _x*_y*_z*_t;
00314 
00315     l = index/(_z*_y*_x);
00316     k = index%(_z*_y*_x)/(_y*_x);
00317     j = index%(_z*_y*_x)%(_y*_x)/_x;
00318     i = index%(_z*_y*_x)%(_y*_x)%_x;
00319 
00320     _ydata[l][k][j][i] = x;
00321   } else {
00322     index -= 2*_x*_y*_z*_t;
00323 
00324     l = index/(_z*_y*_x) ;
00325     k = index%(_z*_y*_x)/(_y*_x) ;
00326     j = index%(_z*_y*_x)%(_y*_x)/_x;
00327     i = index%(_z*_y*_x)%(_y*_x)%_x;
00328 
00329     _zdata[l][k][j][i] = x;
00330   }
00331 }
00332 
00333 inline void irtkFreeFormTransformation4D::Put(int i, int j, int k, int l, double x, double y, double z)
00334 {
00335   if ((i < 0) || (i >= _x) || (j < 0) || (j >= _y) || (k < 0) || (k >= _z) || (l < 0) || (l >= _t)) {
00336     cerr << "irtkFreeFormTransformation4D::Put: No such dof" << endl;
00337     exit(1);
00338   }
00339   _xdata[l][k][j][i] = x;
00340   _ydata[l][k][j][i] = y;
00341   _zdata[l][k][j][i] = z;
00342 }
00343 
00344 inline void irtkFreeFormTransformation4D::GetSpacing(double &dx, double &dy, double &dz, double &dt) const
00345 {
00346   dx = _dx;
00347   dy = _dy;
00348   dz = _dz;
00349   dt = _dt;
00350 }
00351 
00352 inline void irtkFreeFormTransformation4D::PutOrientation(double *xaxis, double *yaxis, double *zaxis)
00353 {
00354   _xaxis[0] = xaxis[0];
00355   _xaxis[1] = xaxis[1];
00356   _xaxis[2] = xaxis[2];
00357   _yaxis[0] = yaxis[0];
00358   _yaxis[1] = yaxis[1];
00359   _yaxis[2] = yaxis[2];
00360   _zaxis[0] = zaxis[0];
00361   _zaxis[1] = zaxis[1];
00362   _zaxis[2] = zaxis[2];
00363 
00364   this->UpdateMatrix();
00365 }
00366 
00367 inline void irtkFreeFormTransformation4D::GetOrientation(double *xaxis, double *yaxis, double *zaxis) const
00368 {
00369   xaxis[0] = _xaxis[0];
00370   xaxis[1] = _xaxis[1];
00371   xaxis[2] = _xaxis[2];
00372   yaxis[0] = _yaxis[0];
00373   yaxis[1] = _yaxis[1];
00374   yaxis[2] = _yaxis[2];
00375   zaxis[0] = _zaxis[0];
00376   zaxis[1] = _zaxis[1];
00377   zaxis[2] = _zaxis[2];
00378 }
00379 
00380 inline void irtkFreeFormTransformation4D::WorldToLattice(double &x, double &y, double &z) const
00381 {
00382   double a, b, c;
00383 
00384   // Pre-multiply point with transformation matrix
00385   a = _matW2L(0, 0)*x+_matW2L(0, 1)*y+_matW2L(0, 2)*z+_matW2L(0, 3);
00386   b = _matW2L(1, 0)*x+_matW2L(1, 1)*y+_matW2L(1, 2)*z+_matW2L(1, 3);
00387   c = _matW2L(2, 0)*x+_matW2L(2, 1)*y+_matW2L(2, 2)*z+_matW2L(2, 3);
00388 
00389   // Copy result back
00390   x = a;
00391   y = b;
00392   z = c;
00393 }
00394 
00395 inline void irtkFreeFormTransformation4D::WorldToLattice(irtkPoint &p) const
00396 {
00397   this->WorldToLattice(p._x, p._y, p._z);
00398 }
00399 
00400 inline double irtkFreeFormTransformation4D::TimeToLattice(double t) const
00401 {
00402   return (t - _tMin)*(_t - 1)/(_tMax - _tMin);
00403 }
00404 
00405 inline void irtkFreeFormTransformation4D::LatticeToWorld(double &x, double &y, double &z) const
00406 {
00407   double a, b, c;
00408 
00409   // Pre-multiply point with transformation matrix
00410   a = _matL2W(0, 0)*x+_matL2W(0, 1)*y+_matL2W(0, 2)*z+_matL2W(0, 3);
00411   b = _matL2W(1, 0)*x+_matL2W(1, 1)*y+_matL2W(1, 2)*z+_matL2W(1, 3);
00412   c = _matL2W(2, 0)*x+_matL2W(2, 1)*y+_matL2W(2, 2)*z+_matL2W(2, 3);
00413 
00414   // Copy result back
00415   x = a;
00416   y = b;
00417   z = c;
00418 }
00419 
00420 inline void irtkFreeFormTransformation4D::LatticeToWorld(irtkPoint &p) const
00421 {
00422   this->LatticeToWorld(p._x, p._y, p._z);
00423 }
00424 
00425 inline double irtkFreeFormTransformation4D::LatticeToTime(double t) const
00426 {
00427   return t*(_tMax - _tMin)/double(_t - 1)+_tMin;
00428 }
00429 
00430 inline void irtkFreeFormTransformation4D::IndexToLattice(int index, int& i, int& j, int& k, int& l) const
00431 {
00432   if (index > _x*_y*_z*_t) {
00433     index -= _x*_y*_z*_t;
00434     if (index > _x*_y*_z*_t)
00435       index -= _x*_y*_z*_t;
00436   }
00437 
00438   l = index/(_z*_y*_x);
00439   k = index%(_z*_y*_x)/(_y*_x);
00440   j = index%(_z*_y*_x)%(_y*_x)/_x;
00441   i = index%(_z*_y*_x)%(_y*_x)%_x;
00442 }
00443 
00444 inline int irtkFreeFormTransformation4D::LatticeToIndex(int i, int j, int k, int l) const
00445 {
00446   return l*_z*_y*_x + k*_y*_x + j*_x + i;
00447 }
00448 
00449 inline const char *irtkFreeFormTransformation4D::NameOfClass()
00450 {
00451   return "irtkFreeFormTransformation4D";
00452 }
00453 
00454 #endif