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

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkBSplineFreeFormTransformation4D.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 _IRTKBSPLINEFREEFORMTRANSFORMATION4D_H
00014 
00015 #define _IRTKBSPLINEFREEFORMTRANSFORMATION4D_H
00016 
00017 #include <irtkGeometry.h>
00018 
00028 class irtkBSplineFreeFormTransformation4D : public irtkFreeFormTransformation4D
00029 {
00030 
00031 protected:
00032 
00034   static double B0(double);
00035 
00037   static double B1(double);
00038 
00040   static double B2(double);
00041 
00043   static double B3(double);
00044 
00046   static double B0_I(double);
00047 
00049   static double B1_I(double);
00050 
00052   static double B2_I(double);
00053 
00055   static double B3_I(double);
00056 
00058   static double B0_II(double);
00059 
00061   static double B1_II(double);
00062 
00064   static double B2_II(double);
00065 
00067   static double B3_II(double);
00068 
00070   virtual void Subdivide2D();
00071 
00073   virtual void Subdivide3D();
00074 
00076   static    double LookupTable[FFDLOOKUPTABLESIZE][4];
00077 
00078   /* Memory for lookup table for first derivatives of B-spline basis
00079    * function values */
00080   static    double LookupTable_I[FFDLOOKUPTABLESIZE][4];
00081 
00082   /* Memory for lookup table for second derivatives of B-spline basis
00083    * function values */
00084   static    double LookupTable_II[FFDLOOKUPTABLESIZE][4];
00085 
00086 public:
00087 
00089   static double B (int, double);
00090 
00092   static double B_I(int, double);
00093 
00095   static double B_II(int, double);
00096 
00098   irtkBSplineFreeFormTransformation4D();
00099 
00101   irtkBSplineFreeFormTransformation4D(irtkBaseImage &, double = 1, double = 1, double = 1, double = 1);
00102 
00104   irtkBSplineFreeFormTransformation4D(double x1, double y1, double z1, double t1,
00105                                       double x2, double y2, double z2, double t2,
00106                                       double dx, double dy, double dz, double dt,
00107                                       double* xaxis, double* yaxis, double* zaxis);
00108 
00110   irtkBSplineFreeFormTransformation4D(const class irtkBSplineFreeFormTransformation4D &);
00111 
00113   virtual ~irtkBSplineFreeFormTransformation4D();
00114 
00119   virtual double Approximate(double *, double *, double *, double *,
00120                              double *, double *, double *, int);
00121 
00128   virtual void Interpolate(double* dxs, double* dys, double* dzs);
00129 
00131   virtual void Subdivide();
00132 
00134   virtual void FFD1(double &, double &, double &, double) const;
00135 
00137   virtual void FFD2(double &, double &, double &, double) const;
00138 
00140   virtual void Transform(double &, double &, double &, double = 0);
00141 
00143   virtual void Transform2(double &, double &, double &, double = 0);
00144 
00146   virtual void GlobalTransform(double &, double &, double &, double = 0);
00147 
00149   virtual void LocalTransform (double &, double &, double &, double = 0);
00150 
00152   virtual void GlobalDisplacement(double &, double &, double &, double = 0);
00153 
00155   virtual void LocalDisplacement(double &, double &, double &, double = 0);
00156 
00158   virtual void Jacobian(irtkMatrix &, double, double, double, double = 0);
00159 
00161   virtual void LocalJacobian(irtkMatrix &, double, double, double, double = 0);
00162 
00164   virtual void GlobalJacobian(irtkMatrix &, double, double, double, double = 0);
00165 
00167   virtual double Bending(double, double, double, double);
00168 
00173   virtual void BoundingBox(int, irtkPoint &, irtkPoint &, double = 1) const;
00174 
00179   virtual void BoundingBox(int, double &, double &, double &, double &, double &,
00180                            double &, double &, double &, double = 1) const;
00181 
00186   virtual void BoundingBox(irtkGreyImage *, int, int &, int &, int &, int &,
00187                            int &, int &, int &, int &, double = 1) const;
00188 
00190   virtual void Print();
00191 
00193   static int CheckHeader(char *);
00194 
00196   virtual const char *NameOfClass();
00197 
00199   virtual irtkCifstream& Read(irtkCifstream&);
00200 
00202   virtual irtkCofstream& Write(irtkCofstream&);
00203 };
00204 
00205 inline double irtkBSplineFreeFormTransformation4D::B(int i, double t)
00206 {
00207   switch (i) {
00208   case 0:
00209     return (1-t)*(1-t)*(1-t)/6.0;
00210   case 1:
00211     return (3*t*t*t - 6*t*t + 4)/6.0;
00212   case 2:
00213     return (-3*t*t*t + 3*t*t + 3*t + 1)/6.0;
00214   case 3:
00215     return (t*t*t)/6.0;
00216   }
00217   return 0;
00218 }
00219 
00220 inline double irtkBSplineFreeFormTransformation4D::B_I(int i, double t)
00221 {
00222   switch (i) {
00223   case 0:
00224     return -(1-t)*(1-t)/2.0;
00225   case 1:
00226     return (9*t*t - 12*t)/6.0;
00227   case 2:
00228     return (-9*t*t + 6*t + 3)/6.0;
00229   case 3:
00230     return (t*t)/2.0;
00231   }
00232   return 0;
00233 }
00234 
00235 inline double irtkBSplineFreeFormTransformation4D::B_II(int i, double t)
00236 {
00237   switch (i) {
00238   case 0:
00239     return 1 - t;
00240   case 1:
00241     return 3*t - 2;
00242   case 2:
00243     return -3*t + 1;
00244   case 3:
00245     return t;
00246   }
00247   return 0;
00248 }
00249 
00250 inline double irtkBSplineFreeFormTransformation4D::B0(double t)
00251 {
00252   return (1-t)*(1-t)*(1-t)/6.0;
00253 }
00254 
00255 inline double irtkBSplineFreeFormTransformation4D::B1(double t)
00256 {
00257   return (3*t*t*t - 6*t*t + 4)/6.0;
00258 }
00259 
00260 inline double irtkBSplineFreeFormTransformation4D::B2(double t)
00261 {
00262   return (-3*t*t*t + 3*t*t + 3*t + 1)/6.0;
00263 }
00264 
00265 inline double irtkBSplineFreeFormTransformation4D::B3(double t)
00266 {
00267   return (t*t*t)/6.0;
00268 }
00269 
00270 inline double irtkBSplineFreeFormTransformation4D::B0_I(double t)
00271 {
00272   return -(1-t)*(1-t)/2.0;
00273 }
00274 
00275 inline double irtkBSplineFreeFormTransformation4D::B1_I(double t)
00276 {
00277   return (9*t*t - 12*t)/6.0;
00278 }
00279 
00280 inline double irtkBSplineFreeFormTransformation4D::B2_I(double t)
00281 {
00282   return (-9*t*t + 6*t + 3)/6.0;
00283 }
00284 
00285 inline double irtkBSplineFreeFormTransformation4D::B3_I(double t)
00286 {
00287   return (t*t)/2.0;
00288 }
00289 
00290 inline double irtkBSplineFreeFormTransformation4D::B0_II(double t)
00291 {
00292   return 1 - t;
00293 }
00294 
00295 inline double irtkBSplineFreeFormTransformation4D::B1_II(double t)
00296 {
00297   return 3*t - 2;
00298 }
00299 
00300 inline double irtkBSplineFreeFormTransformation4D::B2_II(double t)
00301 {
00302   return -3*t + 1;
00303 }
00304 
00305 inline double irtkBSplineFreeFormTransformation4D::B3_II(double t)
00306 {
00307   return t;
00308 }
00309 
00310 inline void irtkBSplineFreeFormTransformation4D::Transform(double &x, double &y, double &z, double t)
00311 {
00312   double u, v, w;
00313 
00314   u = x;
00315   v = y;
00316   w = z;
00317 
00318   // Convert world coordinates in to FFD coordinates
00319   this->WorldToLattice(u, v, w);
00320 
00321   // Calculate FFD
00322   this->FFD1(u, v, w, this->TimeToLattice(t));
00323 
00324   // Add FFD to world coordinates
00325   x += u;
00326   y += v;
00327   z += w;
00328 }
00329 
00330 inline void irtkBSplineFreeFormTransformation4D::Transform2(double &x, double &y, double &z, double t)
00331 {
00332   double u, v, w;
00333 
00334   u = x;
00335   v = y;
00336   w = z;
00337 
00338   // Convert world coordinates in to FFD coordinates
00339   this->WorldToLattice(u, v, w);
00340 
00341   // Calculate FFD
00342   this->FFD2(u, v, w, this->TimeToLattice(t));
00343 
00344   // Add FFD to world coordinates
00345   x += u;
00346   y += v;
00347   z += w;
00348 }
00349 
00350 inline void irtkBSplineFreeFormTransformation4D::GlobalTransform(double &x, double &y, double &z, double t)
00351 {}
00352 
00353 inline void irtkBSplineFreeFormTransformation4D::LocalTransform(double &x, double &y, double &z, double t)
00354 {
00355   double u, v, w;
00356 
00357   u = x;
00358   v = y;
00359   w = z;
00360 
00361   // calculate displacement
00362   this->LocalDisplacement(u, v, w, this->TimeToLattice(t));
00363 
00364   // Add displacement
00365   x += u;
00366   y += v;
00367   z += w;
00368 }
00369 
00370 inline void irtkBSplineFreeFormTransformation4D::GlobalDisplacement(double &x, double &y, double &z, double t)
00371 {
00372   x = 0;
00373   y = 0;
00374   z = 0;
00375 }
00376 
00377 inline void irtkBSplineFreeFormTransformation4D::LocalDisplacement(double &x, double &y, double &z, double t)
00378 {
00379   // Convert world coordinates in to FFD coordinates
00380   this->WorldToLattice(x, y, z);
00381 
00382   // Calculate FFD
00383   this->FFD1(x, y, z, this->TimeToLattice(t));
00384 }
00385 
00386 inline const char *irtkBSplineFreeFormTransformation4D::NameOfClass()
00387 {
00388   return "irtkBSplineFreeFormTransformation4D";
00389 }
00390 
00391 #endif