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 #include "cmtkParametricPlane.h"
00034
00035 #include <Base/cmtkMathUtil.h>
00036
00037 #include <math.h>
00038
00039 namespace
00040 cmtk
00041 {
00042
00045
00046 ParametricPlane::ParametricPlane()
00047 : Rho( 0 ),
00048 Theta( 0 ),
00049 Phi( 0 )
00050 {
00051 this->m_Origin = Self::CoordinateVectorType( Self::CoordinateVectorType::Init( 0 ) );
00052 this->Update();
00053 }
00054
00055 void
00056 ParametricPlane::Update()
00057 {
00058 Normal[0] = MathUtil::Cos( Theta ) * MathUtil::Sin( Phi );
00059 Normal[1] = MathUtil::Sin( Theta ) * MathUtil::Sin( Phi );
00060 Normal[2] = MathUtil::Cos( Phi );
00061
00062 this->SquareNormal = Normal * Normal;
00063 }
00064
00065 void
00066 ParametricPlane::SetNormal( const Self::CoordinateVectorType& normal )
00067 {
00068 this->Normal = (1.0 / normal.RootSumOfSquares()) * normal;
00069
00070 this->Phi = MathUtil::ArcCos( this->Normal[2] );
00071
00072 const Types::Coordinate sinPhi = MathUtil::Sin( this->Phi );
00073 if ( sinPhi != 0 )
00074 this->Theta = MathUtil::ArcSin( this->Normal[1] / sinPhi );
00075 else
00076 this->Theta = Units::Degrees( 0 );
00077
00078 this->SquareNormal = this->Normal * this->Normal;
00079 }
00080
00081 AffineXform*
00082 ParametricPlane::GetAlignmentXform( const byte normalAxis ) const
00083 {
00084 Types::Coordinate angles[3] = { 0, 0, 0 };
00085 Types::Coordinate xlate[3] = { 0, 0, 0 };
00086
00087 AffineXform *alignment = new AffineXform;
00088
00089 switch ( normalAxis )
00090 {
00091
00092 case 0:
00093 {
00094
00095 angles[2] = -1.0 * Units::Degrees( MathUtil::ArcTan2( Normal[1], Normal[0] ) ).Value();
00096
00097
00098 const Types::Coordinate newNormal0 = MathUtil::Sign( Normal[0] ) * sqrt( 1 - Normal[2]*Normal[2] );
00099 angles[1] = -1.0 * Units::Degrees( MathUtil::ArcTan2( Normal[2], newNormal0 ) ).Value();
00100 break;
00101 }
00102
00103
00104 case 1:
00105 {
00106
00107 angles[2] = -1.0 * Units::Degrees( MathUtil::ArcTan2( Normal[0], Normal[1] ) ).Value();
00108
00109
00110 const Types::Coordinate newNormal1 = MathUtil::Sign( Normal[1] ) * sqrt( 1 - Normal[2]*Normal[2] );
00111 angles[0] = -1.0 * Units::Degrees( MathUtil::ArcTan2( Normal[2], newNormal1 ) ).Value();
00112 break;
00113 }
00114
00115
00116 case 2:
00117 {
00118
00119 angles[1] = -1.0 * Units::Degrees( MathUtil::ArcTan2( Normal[0], Normal[2] ) ).Value();
00120
00121
00122 const Types::Coordinate newNormal2 = MathUtil::Sign( Normal[2] ) * sqrt( 1 - Normal[1]*Normal[1] );
00123 angles[0] = -1.0 * Units::Degrees( MathUtil::ArcTan2( Normal[1], newNormal2 ) ).Value();
00124 break;
00125 }
00126 }
00127
00128 alignment->ChangeCenter( this->GetOrigin() );
00129 alignment->SetAngles( angles );
00130
00131 xlate[normalAxis] = Rho;
00132 alignment->SetXlate( xlate );
00133
00134 return alignment;
00135 }
00136
00137 AffineXform::MatrixType
00138 ParametricPlane::GetMirrorXformMatrix() const
00139 {
00140
00141 AffineXform::MatrixType M = AffineXform::MatrixType::IdentityMatrix;
00142
00143 for ( int i = 0; i < 3; ++i )
00144 {
00145 for ( int j = 0; j < 3; ++j )
00146 {
00147 M[i][j] -= 2.0 * this->Normal[i]*this->Normal[j] / this->SquareNormal;
00148 }
00149 }
00150
00151 FixedVector<3,Types::Coordinate> mo = this->m_Origin;
00152 mo *= M;
00153
00154 for ( int j = 0; j < 3; ++j )
00155 {
00156 M[3][j] = this->m_Origin[j] - mo[j] + 2 * this->Rho * this->Normal[j] / this->SquareNormal;
00157 }
00158
00159 return M;
00160 }
00161
00162 }