00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
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
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
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