Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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 }
00534
00535 #endif // #define __cmtkAffineXform_h_included_