00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _IRTKFREEFORMTRANSFORMATION3D_H
00014
00015 #define _IRTKFREEFORMTRANSFORMATION3D_H
00016
00017 #include <irtkGeometry.h>
00018
00019 #define FFDLOOKUPTABLESIZE 1000
00020
00028 class irtkFreeFormTransformation3D : public irtkFreeFormTransformation
00029 {
00030
00031 protected:
00032
00034 int _x;
00035
00037 int _y;
00038
00040 int _z;
00041
00043 double _dx;
00044
00046 double _dy;
00047
00049 double _dz;
00050
00052 double _xaxis[3];
00053
00055 double _yaxis[3];
00056
00058 double _zaxis[3];
00059
00061 irtkPoint _origin;
00062
00064 irtkMatrix _matL2W;
00065
00067 irtkMatrix _matW2L;
00068
00070 double ***_xdata;
00071
00073 double ***_ydata;
00074
00076 double ***_zdata;
00077
00079 static double ***Allocate (double ***, int, int, int);
00080
00082 static double ***Deallocate(double ***, int, int, int);
00083
00085 virtual void UpdateMatrix();
00086
00087 public:
00088
00090 virtual int GetX() const;
00091
00093 virtual int GetY() const;
00094
00096 virtual int GetZ() const;
00097
00099 virtual int NumberOfDOFs() const;
00100
00102 virtual void GetSpacing(double &, double &, double &) const;
00103
00105 virtual void PutOrientation(double *, double *, double *);
00106
00108 virtual void GetOrientation(double *, double *, double *) const;
00109
00111 virtual void Put(int, double);
00112
00114 virtual void Put(int, int, int, double, double, double);
00115
00117 virtual double Get(int) const;
00118
00120 virtual void Get(int, int, int, double &, double &, double &) const;
00121
00123 virtual void PutStatus(int, int, int, _Status);
00124
00126 virtual void PutStatus(int, int, int, _Status, _Status, _Status);
00127
00129 virtual void PutStatus(int, _Status);
00130
00132 virtual void GetStatus(int, int, int, _Status &, _Status &, _Status &);
00133
00135 virtual _Status GetStatus(int);
00136
00138 virtual double Bending(double x, double y, double z) = 0;
00139
00141 virtual void WorldToLattice(double &, double &, double &) const;
00142
00144 virtual void WorldToLattice(irtkPoint &) const;
00145
00147 virtual void LatticeToWorld(double &, double &, double &) const;
00148
00150 virtual void LatticeToWorld(irtkPoint &) const;
00151
00153 virtual void IndexToLattice(int index, int& i, int& j, int& k) const;
00154
00156 virtual int LatticeToIndex(int i, int j, int k) const;
00157
00159 virtual void ControlPointLocation(int, double &, double &, double &) const;
00160
00162 virtual irtkPoint ControlPointLocation(int) const;
00163
00165 virtual void PutBoundingBox(irtkPoint, irtkPoint);
00166
00168 virtual void PutBoundingBox(double, double, double,
00169 double, double, double);
00170
00172 virtual void BoundingBox(irtkPoint &, irtkPoint &) const;
00173
00175 virtual void BoundingBox(double &, double &, double &,
00176 double &, double &, double &) const;
00177
00182 virtual void BoundingBox(int, irtkPoint &, irtkPoint &, double = 1) const = 0;
00183
00188 virtual void BoundingBox(int, double &, double &, double &,
00189 double &, double &, double &, double = 1) const = 0;
00190
00195 virtual void BoundingBox(irtkGreyImage *, int, int &, int &, int &,
00196 int &, int &, int &, double = 1) const = 0;
00197
00202 virtual double Approximate(double *, double *, double *,
00203 double *, double *, double *, int) = 0;
00204
00211 virtual void Interpolate(double* dxs, double* dys, double* dzs) = 0;
00212
00214 virtual double Inverse(double &, double &, double &, double, double = 0.01);
00215
00217 virtual Bool IsIdentity();
00218
00220 virtual const char *NameOfClass();
00221
00222 };
00223
00224 inline int irtkFreeFormTransformation3D::GetX() const
00225 {
00226 return _x;
00227 }
00228
00229 inline int irtkFreeFormTransformation3D::GetY() const
00230 {
00231 return _y;
00232 }
00233
00234 inline int irtkFreeFormTransformation3D::GetZ() const
00235 {
00236 return _z;
00237 }
00238
00239 inline int irtkFreeFormTransformation3D::NumberOfDOFs() const
00240 {
00241 return 3*_x*_y*_z;
00242 }
00243
00244 inline double irtkFreeFormTransformation3D::Get(int index) const
00245 {
00246 int i, j, k;
00247
00248 if (index >= 3*_x*_y*_z) {
00249 cerr << "irtkFreeFormTransformation3D::Get: No such dof" << endl;
00250 exit(1);
00251 }
00252 if (index < _x*_y*_z) {
00253 i = index/(_y*_z);
00254 j = index%(_y*_z)/_z;
00255 k = index%(_y*_z)%_z;
00256 return _xdata[k][j][i];
00257 } else {
00258 if (index < 2*_x*_y*_z) {
00259 index -= _x*_y*_z;
00260 i = index/(_y*_z);
00261 j = index%(_y*_z)/_z;
00262 k = index%(_y*_z)%_z;
00263 return _ydata[k][j][i];
00264 } else {
00265 index -= 2*_x*_y*_z;
00266 i = index/(_y*_z);
00267 j = index%(_y*_z)/_z;
00268 k = index%(_y*_z)%_z;
00269 return _zdata[k][j][i];
00270 }
00271 }
00272 }
00273
00274 inline void irtkFreeFormTransformation3D::Get(int i, int j, int k, double &x, double &y, double &z) const
00275 {
00276 if ((i < 0) || (i >= _x) || (j < 0) || (j >= _y) || (k < 0) || (k >= _z)) {
00277 cerr << "irtkFreeFormTransformation3D::Get: No such dof" << endl;
00278 exit(1);
00279 }
00280 x = _xdata[k][j][i];
00281 y = _ydata[k][j][i];
00282 z = _zdata[k][j][i];
00283 }
00284
00285 inline void irtkFreeFormTransformation3D::Put(int index, double x)
00286 {
00287 irtkPoint p;
00288 int i, j, k;
00289
00290 if (index >= 3*_x*_y*_z) {
00291 cerr << "irtkFreeFormTransformation3D::Put: No such dof" << endl;
00292 exit(1);
00293 }
00294 if (index < _x*_y*_z) {
00295 i = index/(_y*_z);
00296 j = index%(_y*_z)/_z;
00297 k = index%(_y*_z)%_z;
00298 _xdata[k][j][i] = x;
00299 } else {
00300 if (index < 2*_x*_y*_z) {
00301 index -= _x*_y*_z;
00302 i = index/(_y*_z);
00303 j = index%(_y*_z)/_z;
00304 k = index%(_y*_z)%_z;
00305 _ydata[k][j][i] = x;
00306 } else {
00307 index -= 2*_x*_y*_z;
00308 i = index/(_y*_z);
00309 j = index%(_y*_z)/_z;
00310 k = index%(_y*_z)%_z;
00311 _zdata[k][j][i] = x;
00312 }
00313 }
00314 }
00315
00316 inline void irtkFreeFormTransformation3D::Put(int i, int j, int k, double x, double y, double z)
00317 {
00318 if ((i < 0) || (i >= _x) || (j < 0) || (j >= _y) || (k < 0) || (k >= _z)) {
00319 cerr << "irtkFreeFormTransformation3D::Put: No such dof" << endl;
00320 exit(1);
00321 }
00322 _xdata[k][j][i] = x;
00323 _ydata[k][j][i] = y;
00324 _zdata[k][j][i] = z;
00325 }
00326
00327 inline void irtkFreeFormTransformation3D::GetSpacing(double &dx, double &dy, double &dz) const
00328 {
00329 dx = _dx;
00330 dy = _dy;
00331 dz = _dz;
00332 }
00333
00334 inline void irtkFreeFormTransformation3D::PutOrientation(double *xaxis, double *yaxis, double *zaxis)
00335 {
00336 _xaxis[0] = xaxis[0];
00337 _xaxis[1] = xaxis[1];
00338 _xaxis[2] = xaxis[2];
00339 _yaxis[0] = yaxis[0];
00340 _yaxis[1] = yaxis[1];
00341 _yaxis[2] = yaxis[2];
00342 _zaxis[0] = zaxis[0];
00343 _zaxis[1] = zaxis[1];
00344 _zaxis[2] = zaxis[2];
00345
00346 this->UpdateMatrix();
00347 }
00348
00349 inline void irtkFreeFormTransformation3D::GetOrientation(double *xaxis, double *yaxis, double *zaxis) const
00350 {
00351 xaxis[0] = _xaxis[0];
00352 xaxis[1] = _xaxis[1];
00353 xaxis[2] = _xaxis[2];
00354 yaxis[0] = _yaxis[0];
00355 yaxis[1] = _yaxis[1];
00356 yaxis[2] = _yaxis[2];
00357 zaxis[0] = _zaxis[0];
00358 zaxis[1] = _zaxis[1];
00359 zaxis[2] = _zaxis[2];
00360 }
00361
00362 inline void irtkFreeFormTransformation3D::PutBoundingBox(double x1, double y1, double z1, double x2, double y2, double z2)
00363 {
00364
00365 _origin._x = (x2 + x1) / 2.0;
00366 _origin._y = (y2 + y1) / 2.0;
00367 _origin._z = (z2 + z1) / 2.0;
00368
00369 double a = x1 * _xaxis[0] + y1 * _xaxis[1] + z1 * _xaxis[2];
00370 double b = x1 * _yaxis[0] + y1 * _yaxis[1] + z1 * _yaxis[2];
00371 double c = x1 * _zaxis[0] + y1 * _zaxis[1] + z1 * _zaxis[2];
00372 x1 = a;
00373 y1 = b;
00374 z1 = c;
00375 a = x2 * _xaxis[0] + y2 * _xaxis[1] + z2 * _xaxis[2];
00376 b = x2 * _yaxis[0] + y2 * _yaxis[1] + z2 * _yaxis[2];
00377 c = x2 * _zaxis[0] + y2 * _zaxis[1] + z2 * _zaxis[2];
00378 x2 = a;
00379 y2 = b;
00380 z2 = c;
00381
00382
00383 _dx = (x2 - x1) / (_x - 1);
00384 _dy = (y2 - y1) / (_y - 1);
00385 if (z2 > z1) {
00386 _dz = (z2 - z1) / (_z - 1);
00387 } else {
00388 _dz = 1;
00389 }
00390
00391 this->UpdateMatrix();
00392 }
00393
00394 inline void irtkFreeFormTransformation3D::PutBoundingBox(irtkPoint p1, irtkPoint p2)
00395 {
00396 this->PutBoundingBox(p1._x, p1._y, p1._z, p2._x, p2._y, p2._z);
00397 }
00398
00399 inline void irtkFreeFormTransformation3D::WorldToLattice(double &x, double &y, double &z) const
00400 {
00401 double a, b, c;
00402
00403
00404 a = _matW2L(0, 0)*x+_matW2L(0, 1)*y+_matW2L(0, 2)*z+_matW2L(0, 3);
00405 b = _matW2L(1, 0)*x+_matW2L(1, 1)*y+_matW2L(1, 2)*z+_matW2L(1, 3);
00406 c = _matW2L(2, 0)*x+_matW2L(2, 1)*y+_matW2L(2, 2)*z+_matW2L(2, 3);
00407
00408
00409 x = a;
00410 y = b;
00411 z = c;
00412 }
00413
00414 inline void irtkFreeFormTransformation3D::WorldToLattice(irtkPoint &p) const
00415 {
00416 this->WorldToLattice(p._x, p._y, p._z);
00417 }
00418
00419 inline void irtkFreeFormTransformation3D::LatticeToWorld(double &x, double &y, double &z) const
00420 {
00421 double a, b, c;
00422
00423
00424 a = _matL2W(0, 0)*x+_matL2W(0, 1)*y+_matL2W(0, 2)*z+_matL2W(0, 3);
00425 b = _matL2W(1, 0)*x+_matL2W(1, 1)*y+_matL2W(1, 2)*z+_matL2W(1, 3);
00426 c = _matL2W(2, 0)*x+_matL2W(2, 1)*y+_matL2W(2, 2)*z+_matL2W(2, 3);
00427
00428
00429 x = a;
00430 y = b;
00431 z = c;
00432 }
00433
00434 inline void irtkFreeFormTransformation3D::LatticeToWorld(irtkPoint &p) const
00435 {
00436 this->LatticeToWorld(p._x, p._y, p._z);
00437 }
00438
00439 inline void irtkFreeFormTransformation3D::IndexToLattice(int index, int& i, int& j, int& k) const
00440 {
00441
00442 if (index >= _x*_y*_z) {
00443 index -= _x*_y*_z;
00444 if (index >= _x*_y*_z) {
00445 index -= _x*_y*_z;
00446 }
00447 }
00448 i = index/(_y*_z);
00449 j = index%(_y*_z)/_z;
00450 k = index%(_y*_z)%_z;
00451 }
00452
00453 inline int irtkFreeFormTransformation3D::LatticeToIndex(int i, int j, int k) const
00454 {
00455 return i * _y * _z + j * _z + k;
00456 }
00457
00458 inline const char *irtkFreeFormTransformation3D::NameOfClass()
00459 {
00460 return "irtkFreeFormTransformation3D";
00461 }
00462
00463 #endif