1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkCenteredRigid2DTransform_hxx
19 #define itkCenteredRigid2DTransform_hxx
20 
21 #include "itkCenteredRigid2DTransform.h"
22 
23 namespace itk
24 {
25 
26 template<typename TParametersValueType>
27 CenteredRigid2DTransform<TParametersValueType>
CenteredRigid2DTransform()28 ::CenteredRigid2DTransform() :
29   Superclass(ParametersDimension)
30 {
31 }
32 
33 
34 template<typename TParametersValueType>
CenteredRigid2DTransform(unsigned int spaceDimension,unsigned int parametersDimension)35 CenteredRigid2DTransform<TParametersValueType>::CenteredRigid2DTransform(unsigned int spaceDimension,
36                                                                 unsigned int parametersDimension) :
37   Superclass(spaceDimension, parametersDimension)
38 {
39 }
40 
41 
42 template<typename TParametersValueType>
43 void
44 CenteredRigid2DTransform<TParametersValueType>
SetParameters(const ParametersType & parameters)45 ::SetParameters(const ParametersType & parameters)
46 {
47   itkDebugMacro(<< "Setting parameters " << parameters);
48   // Parameters are ordered as:
49   //
50   // p[0]   = angle
51   // p[1:2} = center of rotation coordinates
52   // p[3:4} = translation components
53   //
54   //
55 
56   // Save parameters
57   if( &parameters != &(this->m_Parameters) )
58     {
59     this->m_Parameters = parameters;
60     }
61 
62   // Set the angle
63   const TParametersValueType angle = parameters[0];
64   this->SetVarAngle(angle);
65   // Set the center
66   InputPointType center;
67   for( unsigned int i = 0; i < SpaceDimension; i++ )
68     {
69     center[i] = parameters[i + 1];
70     }
71   this->SetVarCenter(center);
72 
73   // Set the translation
74   OutputVectorType translation;
75   for( unsigned int j = 0; j < SpaceDimension; j++ )
76     {
77     translation[j] = parameters[j + 1 + SpaceDimension];
78     }
79   this->SetVarTranslation(translation);
80 
81   // Update matrix and offset
82   this->ComputeMatrix();
83   this->ComputeOffset();
84 
85   // Modified is always called since we just have a pointer to the
86   // parameters and cannot know if the parameters have changed.
87   this->Modified();
88 
89   itkDebugMacro(<< "After setting parameters ");
90 }
91 
92 
93 template<typename TParametersValueType>
94 const typename CenteredRigid2DTransform<TParametersValueType>::ParametersType
95 & CenteredRigid2DTransform<TParametersValueType>
GetParameters() const96 ::GetParameters() const
97 {
98   itkDebugMacro(<< "Getting parameters ");
99   // Parameters are ordered as:
100   //
101   // p[0]   = angle
102   // p[1:2} = center of rotation coordinates
103   // p[3:4} = translation components
104   //
105 
106   // Get the angle
107   this->m_Parameters[0] = this->GetAngle();
108   // Get the center
109   for( unsigned int i = 0; i < SpaceDimension; i++ )
110     {
111     this->m_Parameters[i + 1] = this->GetCenter()[i];
112     }
113   // Get the translation
114   for( unsigned int j = 0; j < SpaceDimension; j++ )
115     {
116     this->m_Parameters[j + 1 + SpaceDimension] = this->GetTranslation()[j];
117     }
118 
119   itkDebugMacro(<< "After getting parameters " << this->m_Parameters);
120 
121   return this->m_Parameters;
122 }
123 
124 
125 template<typename TParametersValueType>
126 void
127 CenteredRigid2DTransform<TParametersValueType>
ComputeJacobianWithRespectToParameters(const InputPointType & p,JacobianType & jacobian) const128 ::ComputeJacobianWithRespectToParameters(const InputPointType & p, JacobianType & jacobian) const
129 {
130   const double ca = std::cos( this->GetAngle() );
131   const double sa = std::sin( this->GetAngle() );
132 
133   jacobian.SetSize( 2, this->GetNumberOfLocalParameters() );
134   jacobian.Fill(0.0);
135 
136   const double cx = this->GetCenter()[0];
137   const double cy = this->GetCenter()[1];
138 
139   // derivatives with respect to the angle
140   jacobian[0][0] = -sa * ( p[0] - cx ) - ca * ( p[1] - cy );
141   jacobian[1][0] =  ca * ( p[0] - cx ) - sa * ( p[1] - cy );
142 
143   // compute derivatives with respect to the center part
144   // first with respect to cx
145   jacobian[0][1] = 1.0 - ca;
146   jacobian[1][1] =     -sa;
147   // then with respect to cy
148   jacobian[0][2] =       sa;
149   jacobian[1][2] = 1.0 - ca;
150 
151   // compute derivatives with respect to the translation part
152   // first with respect to tx
153   jacobian[0][3] = 1.0;
154   jacobian[1][3] = 0.0;
155   // first with respect to ty
156   jacobian[0][4] = 0.0;
157   jacobian[1][4] = 1.0;
158 }
159 
160 
161 template<typename TParametersValueType>
162 void
163 CenteredRigid2DTransform<TParametersValueType>
SetFixedParameters(const FixedParametersType & itkNotUsed (parameters))164 ::SetFixedParameters( const FixedParametersType & itkNotUsed(parameters) )
165 {
166   // no fixed parameters
167 }
168 
169 
170 template<typename TParametersValueType>
171 const typename CenteredRigid2DTransform<TParametersValueType>::FixedParametersType &
172 CenteredRigid2DTransform<TParametersValueType>
GetFixedParameters() const173 ::GetFixedParameters() const
174 {
175   // return dummy parameters
176   return this->m_FixedParameters;
177 }
178 
179 
180 template<typename TParametersValueType>
181 void
182 CenteredRigid2DTransform<TParametersValueType>
CloneInverseTo(Pointer & result) const183 ::CloneInverseTo(Pointer & result) const
184 {
185   result = New();
186   this->GetInverse( result );
187 }
188 
189 
190 template<typename TParametersValueType>
191 bool
192 CenteredRigid2DTransform<TParametersValueType>
GetInverse(Self * inverse) const193 ::GetInverse(Self *inverse) const
194 {
195   if( !inverse )
196     {
197     return false;
198     }
199 
200   inverse->SetFixedParameters( this->GetFixedParameters() );
201   inverse->SetCenter( this->GetCenter() );  // inverse have the same center
202   inverse->SetAngle( -this->GetAngle() );
203   inverse->SetTranslation( -( this->GetInverseMatrix()
204                               * this->GetTranslation() ) );
205   return true;
206 }
207 
208 
209 template<typename TParametersValueType>
210 typename CenteredRigid2DTransform<TParametersValueType>::InverseTransformBasePointer
211 CenteredRigid2DTransform<TParametersValueType>
GetInverseTransform() const212 ::GetInverseTransform() const
213 {
214   Pointer inv = New();
215 
216   return GetInverse(inv) ? inv.GetPointer() : nullptr;
217 }
218 
219 
220 template<typename TParametersValueType>
221 void
222 CenteredRigid2DTransform<TParametersValueType>
CloneTo(Pointer & result) const223 ::CloneTo(Pointer & result) const
224 {
225   result = New();
226   result->SetCenter( this->GetCenter() );
227   result->SetAngle( this->GetAngle() );
228   result->SetTranslation( this->GetTranslation() );
229 }
230 
231 
232 template<typename TParametersValueType>
233 void
234 CenteredRigid2DTransform<TParametersValueType>
PrintSelf(std::ostream & os,Indent indent) const235 ::PrintSelf(std::ostream & os, Indent indent) const
236 {
237   this->Superclass::PrintSelf(os, indent);
238 }
239 
240 } // end namespace itk
241 
242 #endif
243