cmtkAffineXform.h

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2011 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2752 $
00026 //
00027 //  $LastChangedDate: 2011-01-17 11:33:31 -0800 (Mon, 17 Jan 2011) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #ifndef __cmtkAffineXform_h_included_
00034 #define __cmtkAffineXform_h_included_
00035 
00036 #include <cmtkconfig.h>
00037 
00038 #include <Base/cmtkTypes.h>
00039 #include <Base/cmtkVector.h>
00040 #include <Base/cmtkXform.h>
00041 #include <Base/cmtkMatrix4x4.h>
00042 
00043 #include <System/cmtkSmartPtr.h>
00044 
00045 #include <Base/cmtkUnits.h>
00046 
00047 namespace
00048 cmtk
00049 {
00050 
00053 
00063 class AffineXform : 
00065   public Xform 
00066 {
00067 public:
00069   typedef AffineXform Self;
00070 
00072   typedef Xform Superclass;
00073 
00075   typedef SmartPointer<Self> SmartPtr;
00076 
00078   typedef SmartConstPointer<Self> SmartConstPtr;
00079 
00081   typedef Matrix4x4<Types::Coordinate> MatrixType;
00082 
00084   void MakeIdentityXform ();
00085 
00090   Self::MatrixType Matrix;
00091 
00099   static const size_t TotalNumberOfParameters = 15;
00100 
00109   Self::SpaceVectorType RotateScaleShear ( const Self::SpaceVectorType& v ) const;
00110 
00113   AffineXform () :
00114     m_LogScaleFactors( false )
00115   {
00116     this->AllocateParameterVector( TotalNumberOfParameters );
00117     this->NumberDOFs = this->DefaultNumberOfDOFs();
00118     this->MakeIdentityXform();
00119   }
00120 
00124   AffineXform ( const CoordinateVector& v , 
00125                 const bool logScaleFactors = false  ) :
00126     m_LogScaleFactors( logScaleFactors )
00127   {
00128     this->AllocateParameterVector( TotalNumberOfParameters );
00129     this->NumberDOFs = this->DefaultNumberOfDOFs();
00130     this->SetParamVector( v );
00131   }
00132 
00136   AffineXform ( const Types::Coordinate v[15] , 
00137                 const bool logScaleFactors = false  ) :
00138     m_LogScaleFactors( logScaleFactors )
00139   {
00140     this->AllocateParameterVector( TotalNumberOfParameters );
00141     this->NumberDOFs = this->DefaultNumberOfDOFs();
00142     memcpy( this->m_Parameters, v, 15 * sizeof(Types::Coordinate) );
00143     this->ComposeMatrix();
00144     this->CanonicalRotationRange();
00145   }
00146 
00154   AffineXform ( const Types::Coordinate matrix[4][4], const Types::Coordinate* center = NULL );
00155 
00163   AffineXform ( const MatrixType& matrix, const Types::Coordinate* center = NULL );
00164 
00173   AffineXform ( const Types::Coordinate matrix[4][4], const Types::Coordinate xlate[3], const Types::Coordinate center[3] );
00174   
00176   AffineXform ( const AffineXform& other );
00177   
00181   virtual ~AffineXform() 
00182   { 
00183     InverseXform = Self::SmartPtr::Null; 
00184   }
00185   
00187   Self::SmartPtr Clone () const 
00188   {
00189     return Self::SmartPtr( this->CloneVirtual() );
00190   }
00191 
00193   virtual Self* MakeInverse () const;
00194 
00198   virtual Self::SmartPtr GetDifference( const AffineXform& other ) const;
00199 
00201   const Self::SmartPtr GetInverse() const;
00202 
00204   virtual Types::Coordinate GetGlobalScaling() const 
00205   { 
00206     if ( this->m_LogScaleFactors )
00207       {
00208       return exp( this->m_Parameters[6] + this->m_Parameters[7] + this->m_Parameters[8] );
00209       }
00210     else
00211       {
00212       return this->m_Parameters[6] * this->m_Parameters[7] * this->m_Parameters[8];
00213       }
00214   }
00215 
00220   virtual Types::Coordinate GetJacobianDeterminant ( const Self::SpaceVectorType& ) const
00221   { 
00222     return this->GetGlobalScaling(); 
00223   }
00224 
00226   void Concat( const AffineXform& other );
00227 
00229   void Insert( const AffineXform& other );
00230 
00243   void RotateWXYZ( const Units::Radians angle, const Self::SpaceVectorType& direction, const Types::Coordinate* origin = NULL, Self::MatrixType *const accumulate = NULL );
00244 
00246   void ChangeCoordinateSystem
00247   ( const Self::SpaceVectorType& newX, const Self::SpaceVectorType& newY )
00248   {
00249     this->Matrix.ChangeCoordinateSystem( newX, newY );
00250     this->DecomposeMatrix();
00251   }
00252 
00254   virtual Self::SpaceVectorType Apply ( const Self::SpaceVectorType& vec ) const 
00255   {
00256     Self::SpaceVectorType Result( vec );
00257     this->ApplyInPlace( Result );
00258     return Result;
00259   }
00260   
00262   void ApplyInPlace( Self::SpaceVectorType& vec ) const 
00263   {
00264     vec *= this->Matrix;
00265   }
00266 
00269   virtual bool ApplyInverse ( const Self::SpaceVectorType& v, Self::SpaceVectorType& u, const Types::Coordinate = 0.01  ) const
00270   {
00271     u = this->GetInverse()->Apply( v );
00272     return true;
00273   }
00274 
00277   virtual bool ApplyInverseInPlace( Self::SpaceVectorType& v, const Types::Coordinate = 0.01  ) const
00278   {
00279     this->GetInverse()->ApplyInPlace( v );
00280     return true;
00281   }
00282 
00286 
00287   const Types::Coordinate* RetXlate () const  { return this->m_Parameters; }
00289   const Types::Coordinate* RetAngles () const { return this->m_Parameters+3; }
00291   const Types::Coordinate* RetScales () const { return this->m_Parameters+6; }
00293   const Types::Coordinate* RetShears () const { return this->m_Parameters+9; }
00295   const Types::Coordinate* RetCenter () const { return this->m_Parameters+12; }
00297 
00301 
00302   Types::Coordinate* RetXlate ()  { return this->m_Parameters; }
00304   Types::Coordinate* RetAngles () { return this->m_Parameters+3; }
00306   Types::Coordinate* RetScales () { return this->m_Parameters+6; }
00308   Types::Coordinate* RetShears () { return this->m_Parameters+9; }
00310   Types::Coordinate* RetCenter () { return this->m_Parameters+12; }
00312 
00316 
00317   void SetXlate ( const Types::Coordinate* xlate ) 
00318   { 
00319     if ( this->RetXlate() != xlate )
00320       memcpy( this->RetXlate(), xlate, 3 * sizeof(Types::Coordinate) );
00321     this->ComposeMatrix();
00322   }
00323 
00325   void SetXlate ( const Types::Coordinate dx, const Types::Coordinate dy, const Types::Coordinate dz ) 
00326   { 
00327     this->m_Parameters[0] = dx; this->m_Parameters[1] = dy; this->m_Parameters[2] = dz;
00328     this->ComposeMatrix(); 
00329   }
00330 
00332   void Translate( const Types::Coordinate dx, const Types::Coordinate dy, const Types::Coordinate dz ) 
00333   {
00334     this->m_Parameters[0] += dx; this->m_Parameters[1] += dy; this->m_Parameters[2] += dz; 
00335     this->ComposeMatrix(); 
00336   }
00337   
00339   void Translate( const Self::SpaceVectorType& delta ) 
00340   { 
00341     for ( int dim = 0; dim < 3; ++dim ) 
00342       this->m_Parameters[dim] += delta[dim];
00343     this->ComposeMatrix();
00344   }
00345 
00347   void SetAngles ( const Types::Coordinate* angles ) 
00348   {
00349     if ( angles != this->RetAngles() )
00350       memcpy( this->RetAngles(), angles, 3 * sizeof(Types::Coordinate) );
00351     this->ComposeMatrix();
00352   }
00353 
00355   template<class T> void GetScales( T (&scales)[3] ) const
00356   { 
00357     if ( this->m_LogScaleFactors )
00358       {
00359       for ( size_t i = 0; i < 3; ++i )
00360         {
00361         scales[i] = exp( this->m_Parameters[6+i] );
00362         }
00363       }
00364     else
00365       {
00366       for ( size_t i = 0; i < 3; ++i )
00367         {
00368         scales[i] = this->m_Parameters[6+i];
00369         }
00370       }
00371   }
00372 
00374   void SetScales ( const Types::Coordinate* scales ) 
00375   { 
00376     if ( this->RetScales() != scales )
00377       memcpy( this->RetScales(), scales, 3 * sizeof(Types::Coordinate) );
00378     this->ComposeMatrix();
00379   }
00380   
00382   void SetScales ( const Types::Coordinate sx, const Types::Coordinate sy, const Types::Coordinate sz )
00383   { 
00384     this->m_Parameters[6] = sx; 
00385     this->m_Parameters[7] = sy; 
00386     this->m_Parameters[8] = sz; }
00387 
00389   void SetShears ( const Types::Coordinate* shears ) 
00390   { 
00391     if ( this->RetShears() != shears )
00392       memcpy( this->RetShears(), shears, 3 * sizeof(Types::Coordinate) );
00393     this->ComposeMatrix();
00394   }
00395 
00397   void SetCenter ( const Types::Coordinate* center ) 
00398   {
00399     if ( this->RetCenter() != center )
00400       memcpy( RetCenter(), center, 3 * sizeof(Types::Coordinate) );
00401     this->ComposeMatrix();
00402   }
00404   
00408 
00410   const Types::Coordinate* RetMatrix () const { return &Matrix[0][0]; }
00411     
00413   Types::Coordinate* RetMatrix () { return &Matrix[0][0]; }
00414 
00416   void SetMatrix( const float matrix[4][4] );
00417   void SetMatrix( const double matrix[4][4] );
00418   void SetMatrix( const MatrixType& matrix );
00419 
00421   template<class T> void GetMatrix( T (&matrix)[4][4] ) const;
00423 
00429   void ChangeCenter ( const Self::SpaceVectorType& center );
00430 
00432   virtual size_t ParamVectorDim () const { return 15; }
00433 
00437   virtual size_t VariableParamVectorDim () const { return std::min( 12, NumberDOFs ); }
00438 
00440   virtual void SetNumberDOFs ( const int numberDOFs = 12 );
00441 
00443   virtual unsigned int GetNumberDOFs () const { return NumberDOFs; }
00444 
00446   bool GetUseLogScaleFactors() const
00447   {
00448     return this->m_LogScaleFactors;
00449   }
00450 
00452   void SetUseLogScaleFactors( const bool logScaleFactors );
00453 
00455   virtual void SetParamVector ( CoordinateVector& v );
00456 
00464   virtual void SetParamVector ( const CoordinateVector& v );
00465 
00467   virtual void SetParameter ( const size_t idx, const Types::Coordinate p );
00468 
00470   virtual Types::Coordinate GetParamStep( const size_t idx, const Self::SpaceVectorType& volSize, const Types::Coordinate step_mm = 1 ) const;
00471   
00473   AffineXform& operator=( const AffineXform& other );
00474 
00476   virtual void Print() const;
00477 
00478 protected:
00480   virtual Self* CloneVirtual() const
00481   {
00482     return new AffineXform( *this );
00483   }
00484   
00487   void ComposeMatrix();
00488 
00491   bool DecomposeMatrix();
00492 
00500   int NumberDOFs;
00501 
00502 private:
00504   bool m_LogScaleFactors;
00505 
00507   static int DefaultNumberOfDOFs() { return 12; }
00508 
00510   mutable Self::SmartPtr InverseXform;
00511 
00513   void UpdateInverse() const;
00514 
00521   void SetMatrixDirect ( const Types::Coordinate* matrix ) 
00522   {
00523     Matrix.Set( matrix );
00524     this->DecomposeMatrix();
00525   }
00526 
00528   void CanonicalRotationRange();
00529 };
00530 
00532 
00533 } // namespace cmtk
00534 
00535 #endif // #define __cmtkAffineXform_h_included_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines