KWStyle - itkAffineTransform.txx
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkAffineTransform.txx.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:32 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12      This software is distributed WITHOUT ANY WARRANTY; without even 
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14      PURPOSE.  See the above copyright notices for more information.
15
16 =========================================================================*/
17 DEF #ifndef _itkAffineTransform_txx
18 DEF #define _itkAffineTransform_txx
19
20 #include "itkNumericTraits.h"
21 #include "itkAffineTransform.h"
22 #include "vnl/algo/vnl_matrix_inverse.h"
23
24
25 namespace itk
26 {
27
28 // Constructor with default arguments
29 template<class TScalarType, unsigned int NDimensions>
30 AffineTransform<TScalarType, NDimensions>::
31 AffineTransform():
32 IND **Superclass(SpaceDimension,ParametersDimension)
33 {
34 }
35
36
37 // Constructor with default arguments
38 template<class TScalarType, unsigned int NDimensions>
39 AffineTransform<TScalarType, NDimensions>::
40 AffineTransform( unsigned int outputSpaceDimension, 
41                  unsigned int parametersDimension   ):
42 IND **Superclass(outputSpaceDimension,parametersDimension)
43 {
44 }
45
46
47 EML
48 // Constructor with explicit arguments
49 template<class TScalarType, unsigned int NDimensions>
50 AffineTransform<TScalarType, NDimensions>::
51 AffineTransform(const MatrixType & matrix,
52                const OutputVectorType & offset):
53 IND **Superclass(matrix, offset)
54 {
55 }
56
57
58 EML
59 EML
60 // Destructor
61 template<class TScalarType, unsigned int NDimensions>
62 AffineTransform<TScalarType, NDimensions>::
63 ~AffineTransform()
64 {
65   return;
66 }
67
68
69 EML
70 // Print self
71 template<class TScalarType, unsigned int NDimensions>
72 void
73 AffineTransform<TScalarType, NDimensions>::
74 PrintSelf(std::ostream &os, Indent indent) const
75 {
76   Superclass::PrintSelf(os,indent);
77 }
78
79
80 // Compose with a translation
81 template<class TScalarType, unsigned int NDimensions>
82 void
83 AffineTransform<TScalarType, NDimensions>::
84 Translate(const OutputVectorType &trans, bool pre)
85 {
86   OutputVectorType newTranslation = this->GetTranslation();
87   if (pre) 
88     {
89     newTranslation += this->GetMatrix() * trans;
90     }
91   else 
92     {
93     newTranslation += trans;
94     }
95   this->SetVarTranslation(newTranslation);
96   this->ComputeOffset();
97   this->Modified();
98   return;
99 }
100
101
102 // Compose with isotropic scaling
103 template<class TScalarType, unsigned int NDimensions>
104 void
105 AffineTransform<TScalarType, NDimensions>
106 ::Scale(const TScalarType &factor, bool pre) 
107 {
108   if (pre) 
109     {
110     MatrixType newMatrix = this->GetMatrix();
111     newMatrix *= factor;
112     this->SetVarMatrix(newMatrix);
113     }
114   else 
115     {
116     MatrixType newMatrix = this->GetMatrix();
117     newMatrix *= factor;
118     this->SetVarMatrix(newMatrix);
119
120     OutputVectorType newTranslation = this->GetTranslation();
121     newTranslation *= factor;
122     this->SetVarTranslation(newTranslation);
123     }
124   this->ComputeMatrixParameters();
125   this->ComputeOffset();
126   this->Modified();
127   return;
128 }
129
130
131 EML
132 // Compose with anisotropic scaling
133 template<class TScalarType, unsigned int NDimensions>
134 void
135 AffineTransform<TScalarType, NDimensions>
136 ::Scale(const OutputVectorType &factor, bool pre) 
137 {
138   MatrixType trans;
139   unsigned int i, j;
140
141   for (i = 0; i < NDimensions; i++) 
142     {
143     for (j = 0; j < NDimensions; j++) 
144       {
145       trans[i][j] = 0.0;
146       }
147     trans[i][i] = factor[i];
148     }
149   if (pre) 
150     {
151     this->SetVarMatrix( this->GetMatrix() * trans );
152     }
153   else 
154     {
155     this->SetVarMatrix( trans * this->GetMatrix() );
156     this->SetVarTranslation( trans * this->GetTranslation() );
157     }
158   this->ComputeMatrixParameters();
159   this->ComputeOffset();
160   this->Modified();
161   return;
162 }
163
164
165 EML
166 // Compose with elementary rotation
167 template<class TScalarType, unsigned int NDimensions>
168 void
169 AffineTransform<TScalarType, NDimensions>
170 ::Rotate(int axis1, int axis2, TScalarType angle, bool pre) 
171 {
172   MatrixType trans;
173   unsigned int i, j;
174
175   for (i = 0; i < NDimensions; i++) 
176     {
177     for (j = 0; j < NDimensions; j++) 
178       {
179       trans[i][j] = 0.0;
180       }
181     trans[i][i] = 1.0;
182     }
183   trans[axis1][axis1] =  cos(angle);
184   trans[axis1][axis2] =  sin(angle);
185   trans[axis2][axis1] = -sin(angle);
186   trans[axis2][axis2] =  cos(angle);
187   if (pre) 
188     {
189     this->SetVarMatrix( this->GetMatrix() * trans );
190     }
191   else 
192     {
193     this->SetVarMatrix( trans * this->GetMatrix() );
194     this->SetVarTranslation( trans * this->GetTranslation() );
195     }
196   this->ComputeMatrixParameters();
197   this->ComputeOffset();
198   this->Modified();
199   return;
200 }
201
202
203 // Compose with 2D rotation
204 // \todo Find a way to generate a compile-time error
205 // is this is used with NDimensions != 2.
206 template<class TScalarType, unsigned int NDimensions>
207 void
208 AffineTransform<TScalarType, NDimensions>
209 ::Rotate2D(TScalarType angle, bool pre)
210 {
211   MatrixType trans;
212
213   trans[0][0] =  cos(angle);
214   trans[0][1] = -sin(angle);
215   trans[1][0] = sin(angle);
216   trans[1][1] =  cos(angle);
217   if (pre) 
218     {
219     this->SetVarMatrix( this->GetMatrix() * trans );
220     }
221   else 
222     {
223     this->SetVarMatrix( trans * this->GetMatrix() );
224     this->SetVarTranslation( trans * this->GetTranslation() );
225     }
226   this->ComputeMatrixParameters();
227   this->ComputeOffset();
228   this->Modified();
229   return;
230 }
231
232
233 EML
234 // Compose with 3D rotation
235 // \todo Find a way to generate a compile-time error
236 // is this is used with NDimensions != 3.
237 template<class TScalarType, unsigned int NDimensions>
238 void
239 AffineTransform<TScalarType, NDimensions>
240 ::Rotate3D(const OutputVectorType &axis, TScalarType angle, bool pre)
241 {
242   MatrixType trans;
243   ScalarType r, x1, x2, x3;
244   ScalarType q0, q1, q2, q3;
245
246   // Convert the axis to a unit vector
247   r = sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]);
248   x1 = axis[0] / r;
249   x2 = axis[1] / r;
250   x3 = axis[2] / r;
251
252   // Compute quaternion elements
253   q0 = cos(angle/2.0);
254   q1 = x1 * sin(angle/2.0);
255   q2 = x2 * sin(angle/2.0);
256   q3 = x3 * sin(angle/2.0);
257
258   // Compute elements of the rotation matrix
259   trans[0][0] = q0*q0 + q1*q1 - q2*q2 - q3*q3;
260   trans[0][1] = 2.0*(q1*q2 - q0*q3);
261   trans[0][2] = 2.0*(q1*q3 + q0*q2);
262   trans[1][0] = 2.0*(q1*q2 + q0*q3);
263   trans[1][1] = q0*q0 + q2*q2 - q1*q1 - q3*q3;
264   trans[1][2] = 2.0*(q2*q3 - q0*q1);
265   trans[2][0] = 2.0*(q1*q3 - q0*q2);
266   trans[2][1] = 2.0*(q2*q3 + q0*q1);
267   trans[2][2] = q0*q0 + q3*q3 - q1*q1 - q2*q2;
268
269   // Compose rotation matrix with the existing matrix
270   if (pre) 
271     {
272     this->SetVarMatrix( this->GetMatrix() * trans );
273     }
274   else 
275     {
276     this->SetVarMatrix( trans * this->GetMatrix() );
277     this->SetVarTranslation( trans * this->GetTranslation() );
278     }
279   this->ComputeMatrixParameters();
280   this->ComputeOffset();
281   this->Modified();
282   return;
283 }
284
285
286 // Compose with elementary rotation
287 template<class TScalarType, unsigned int NDimensions>
288 void
289 AffineTransform<TScalarType, NDimensions>
290 ::Shear(int axis1, int axis2, TScalarType coef, bool pre)
291 {
292   MatrixType trans;
293   unsigned int i, j;
294
295   for (i = 0; i < NDimensions; i++) 
296     {
297     for (j = 0; j < NDimensions; j++) 
298       {
299       trans[i][j] = 0.0;
300       }
301     trans[i][i] = 1.0;
302     }
303   trans[axis1][axis2] =  coef;
304   if (pre) 
305     {
306     this->SetVarMatrix( this->GetMatrix() * trans );
307     }
308   else 
309     {
310     this->SetVarMatrix( trans * this->GetMatrix() );
311     this->SetVarTranslation( trans * this->GetTranslation() );
312     }
313   this->ComputeMatrixParameters();
314   this->ComputeOffset();
315   this->Modified();
316   return;
317 }
318
319
320 // Compute a distance between two affine transforms
321 template<class TScalarType, unsigned int NDimensions>
322 typename AffineTransform<TScalarType, NDimensions>::ScalarType
323 AffineTransform<TScalarType, NDimensions>
324 ::Metric(const Self * other) const
325 {
326   ScalarType result = 0.0, term;
327
328   for (unsigned int i = 0; i < NDimensions; i++) 
329     {
330     for (unsigned int j = 0; j < NDimensions; j++) 
331       {
332       term = this->GetMatrix()[i][j] - other->GetMatrix()[i][j];
333       result += term * term;
334       }
335     term = this->GetOffset()[i] - other->GetOffset()[i];
336     result += term * term;
337     }
338   return sqrt(result);
339 }
340
341
342 EML
343 // Compute a distance between self and the identity transform
344 template<class TScalarType, unsigned int NDimensions>
345 typename AffineTransform<TScalarType, NDimensions>::ScalarType
346 AffineTransform<TScalarType, NDimensions>
347 ::Metric(void) const
348 {
349   ScalarType result = 0.0, term;
350
351   for (unsigned int i = 0; i < NDimensions; i++) 
352     {
353     for (unsigned int j = 0; j < NDimensions; j++) 
354       {
355       if (i == j)
356         {
357         term = this->GetMatrix()[i][j] - 1.0;
358         }
359       else
360         {
361         term = this->GetMatrix()[i][j];
362         }
363       result += term * term;
364       }
365     term = this->GetOffset()[i];
366     result += term * term;
367     }
368
369   return sqrt(result);
370 }
371
372 // Back transform a point
373 template<class TScalarType, unsigned int NDimensions>
374 typename AffineTransform<TScalarType, NDimensions>::InputPointType
375 AffineTransform<TScalarType, NDimensions>::
376 BackTransform(const OutputPointType &point) const 
377 {
378 LEN   itkWarningMacro(<<"BackTransform(): This method is slated to be removed from ITK.  Instead, please use GetInverse() to generate an inverse transform and then perform the transform using that inverted transform.");
379   InputPointType result;       // Converted point
380   ScalarType temp[NDimensions];
381   unsigned int i, j;
382
383   for (j = 0; j < NDimensions; j++) 
384     {
385     temp[j] = point[j] - this->GetOffset()[j];
386     }
387
388   for (i = 0; i < NDimensions; i++) 
389     {
390     result[i] = 0.0;
391     for (j = 0; j < NDimensions; j++) 
392       {
393       result[i] += this->GetInverseMatrix()[i][j]*temp[j];
394       }
395     }
396   return result;
397 }
398
399
400 // Back transform a vector
401 template<class TScalarType, unsigned int NDimensions>
402 typename AffineTransform<TScalarType, NDimensions>::InputVectorType
403 AffineTransform<TScalarType, NDimensions>::
404 BackTransform(const OutputVectorType &vect ) const 
405 {
406 LEN   itkWarningMacro(<<"BackTransform(): This method is slated to be removed from ITK.  Instead, please use GetInverse() to generate an inverse transform and then perform the transform using that inverted transform.");
407   return this->GetInverseMatrix() * vect;
408 }
409
410
411 EML
412 EML
413 // Back transform a vnl_vector
414 template<class TScalarType, unsigned int NDimensions>
415 typename AffineTransform<TScalarType, NDimensions>::InputVnlVectorType
416 AffineTransform<TScalarType, NDimensions>::
417 BackTransform(const OutputVnlVectorType &vect ) const 
418 {
419 LEN   itkWarningMacro(<<"BackTransform(): This method is slated to be removed from ITK.  Instead, please use GetInverse() to generate an inverse transform and then perform the transform using that inverted transform.");
420   return this->GetInverseMatrix() * vect;
421 }
422
423
424 EML
425 // Back Transform a CovariantVector
426 template<class TScalarType, unsigned int NDimensions>
427 typename AffineTransform<TScalarType, NDimensions>::InputCovariantVectorType
428 AffineTransform<TScalarType, NDimensions>::
429 BackTransform(const OutputCovariantVectorType &vec) const 
430 {
431 LEN   itkWarningMacro(<<"BackTransform(): This method is slated to be removed from ITK.  Instead, please use GetInverse() to generate an inverse transform and then perform the transform using that inverted transform.");
432
433   InputCovariantVectorType result;    // Converted vector
434
435   for (unsigned int i = 0; i < NDimensions; i++) 
436     {
437     result[i] = NumericTraits<ScalarType>::Zero;
438     for (unsigned int j = 0; j < NDimensions; j++) 
439       {
440       result[i] += this->GetMatrix()[j][i]*vec[j]; // Direct matrix transposed
441       }
442     }
443   return result;
444 }
445
446
447 EML
448 EML
449 // Back transform a given point which is represented as type PointType
450 template<class TScalarType, unsigned int NDimensions>
451 typename AffineTransform<TScalarType, NDimensions>::InputPointType
452 AffineTransform<TScalarType, NDimensions>::
453 BackTransformPoint(const OutputPointType &point) const
454 {
455   return this->BackTransform(point);
456 }
457
458 // namespace
459
460 #endif
461
462 EOF

Generated by KWStyle 1.0b on Tuesday January,17 at 02:13:58PM
© Kitware Inc.