KWStyle - itkAffineTransform.h
 
Matrix View
Description

1 HRD /*
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkAffineTransform.h.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
18 #ifndef __itkAffineTransform_h
19 #define __itkAffineTransform_h
20
21 #include <iostream>
22
23 #include "itkMatrix.h"
24 #include "itkMatrixOffsetTransformBase.h"
25 #include "itkExceptionObject.h"
26 #include "itkMacro.h"
27
28 namespace itk
29 {
30
31
32 /**
33  * Affine transformation of a vector space (e.g. space coordinates)
34  *
35  * This class allows the definition and manipulation of affine
36  * transformations of an n-dimensional affine space (and its
37  * associated vector space) onto itself.  One common use is to define
38  * and manipulate Euclidean coordinate transformations in two and
39  * three dimensions, but other uses are possible as well.
40  *
41  * An affine transformation is defined mathematically as a linear
42  * transformation plus a constant offset.  If A is a constant n x n
43  * matrix and b is a constant n-vector, then y = Ax+b defines an
44  * affine transformation from the n-vector x to the n-vector y.
45  *
46  * The difference between two points is a vector and transforms
47  * linearly, using the matrix only.  That is, (y1-y2) = A*(x1-x2).
48  *
49  * The AffineTransform class determines whether to transform an object
50  * as a point or a vector by examining its type.  An object of type
51  * Point transforms as a point; an object of type Vector transforms as
52  * a vector.
53  *
54  * One common use of affine transformations is to define coordinate
55  * conversions in two- and three-dimensional space.  In this
56  * application, x is a two- or three-dimensional vector containing the
57  * "source" coordinates of a point, y is a vector containing the
58  * "target" coordinates, the matrix A defines the scaling and rotation
59  * of the coordinate systems from the source to the target, and b
60  * defines the translation of the origin from the source to the
61  * target.  More generally, A can also define anisotropic scaling and
62  * shearing transformations.  Any good textbook on computer graphics
63  * will discuss coordinate transformations in more detail.  Several of
64  * the methods in this class are designed for this purpose and use the
65  * language appropriate to coordinate conversions.
66  *
67  * Any two affine transformations may be composed and the result is
68  * another affine transformation.  However, the order is important.
69  * Given two affine transformations T1 and T2, we will say that
70  * "precomposing T1 with T2" yields the transformation which applies
71  * T1 to the source, and then applies T2 to that result to obtain the
72  * target.  Conversely, we will say that "postcomposing T1 with T2"
73  * yields the transformation which applies T2 to the source, and then
74  * applies T1 to that result to obtain the target.  (Whether T1 or T2
75  * comes first lexicographically depends on whether you choose to
76  * write mappings from right-to-left or vice versa; we avoid the whole
77  * problem by referring to the order of application rather than the
78  * textual order.)
79  *
80  * There are two template parameters for this class:
81  *
82  * ScalarT       The type to be used for scalar numeric values.  Either
83  *               float or double.
84  *
85  * NDimensions   The number of dimensions of the vector space.
86  *
87  * This class provides several methods for setting the matrix and vector
88  * defining the transform. To support the registration framework, the 
89  * transform parameters can also be set as an Array<double> of size
90  * (NDimension + 1) * NDimension using method SetParameters(). 
91  * The first (NDimension x NDimension) parameters defines the matrix in 
92  * column-major order (where the column index) varies the fastest). 
93  * The last NDimension parameters defines the translation 
94  * in each dimensions.
95  *
96  * This class also supports the specification of a center of rotation (center)
97  * and a translation that is applied with respect to that centered rotation.
98  * By default the center of rotation is set to the origin.
99  *
100  * \ingroup Transforms
101  *
102  **/
103
104 template <
105  class TScalarType=double,         // Data type for scalars 
106                                    //    (e.g. float or double)
107  unsigned int NDimensions=3>       // Number of dimensions in the input space
108 class AffineTransform 
109 : public MatrixOffsetTransformBase< TScalarType, NDimensions, NDimensions >
110 {
111 public:
112   /** Standard typedefs   */
113   typedef AffineTransform                           Self;
114   typedef MatrixOffsetTransformBase< TScalarType,
115                                      NDimensions,
116                                      NDimensions >  Superclass;
117   typedef SmartPointer<Self>                        Pointer;
118   typedef SmartPointer<const Self>                  ConstPointer;
119   
120   /** Run-time type information (and related methods).   */
121   itkTypeMacro( AffineTransform, MatrixOffsetTransformBase );
122
123   /** New macro for creation of through a Smart Pointer   */
124   itkNewMacro( Self );
125
126   /** Dimension of the domain space. */
127   itkStaticConstMacro(InputSpaceDimension, unsigned int, NDimensions);
128   itkStaticConstMacro(OutputSpaceDimension, unsigned int, NDimensions);
129   itkStaticConstMacro(SpaceDimension, unsigned int, NDimensions);
130   itkStaticConstMacro(ParametersDimension, unsigned int,
131                                            NDimensions*(NDimensions+1));
132
133   
134   /** Parameters Type   */
135   typedef typename Superclass::ParametersType         ParametersType;
136   typedef typename Superclass::JacobianType           JacobianType;
137   typedef typename Superclass::ScalarType             ScalarType;
138   typedef typename Superclass::InputPointType         InputPointType;
139   typedef typename Superclass::OutputPointType        OutputPointType;
140   typedef typename Superclass::InputVectorType        InputVectorType;
141   typedef typename Superclass::OutputVectorType       OutputVectorType;
142   typedef typename Superclass::InputVnlVectorType     InputVnlVectorType;
143   typedef typename Superclass::OutputVnlVectorType    OutputVnlVectorType;
144   typedef typename Superclass::InputCovariantVectorType 
145 IND ******************************************************InputCovariantVectorType;
146   typedef typename Superclass::OutputCovariantVectorType      
147 IND ******************************************************OutputCovariantVectorType;
148   typedef typename Superclass::MatrixType             MatrixType;
149   typedef typename Superclass::InverseMatrixType      InverseMatrixType;
150   typedef typename Superclass::CenterType             CenterType;
151   typedef typename Superclass::OffsetType             OffsetType;
152   typedef typename Superclass::TranslationType        TranslationType;
153
154   /** Compose affine transformation with a translation
155    *
156    * This method modifies self to include a translation of the
157    * origin.  The translation is precomposed with self if pre is
158    * true, and postcomposed otherwise. 
159    * This updates Translation based on current center. */
160   void Translate(const OutputVectorType &offset, bool pre=0);
161
162   /** Compose affine transformation with a scaling
163    *
164    * This method modifies self to magnify the source by a given
165    * factor along each axis.  If all factors are the same, or only a
166    * single factor is given, then the scaling is isotropic;
167    * otherwise it is anisotropic.  If an odd number of factors are
168    * negative, then the parity of the image changes.  If any of the
169    * factors is zero, then the transformation becomes a projection
170    * and is not invertible.  The scaling is precomposed with self if
171    * pre is true, and postcomposed otherwise. 
172    * Note that the scaling is applied centered at the origin. */
173   void Scale(const OutputVectorType &factor, bool pre=0);
174   void Scale(const TScalarType &factor, bool pre=0);
175
176   /** Compose affine transformation with an elementary rotation
177    *
178    * This method composes self with a rotation that affects two
179    * specified axes, replacing the current value of self.  The
180    * rotation angle is in radians.  The axis of rotation goes
181    * through the origin.  The transformation is given by
182    *
183    * y[axis1] =  cos(angle)*x[axis1] + sin(angle)*x[axis2]
184    * y[axis2] = -sin(angle)*x[axis1] + cos(angle)*x[axis2].
185    *
186    * All coordinates other than axis1 and axis2 are unchanged;
187    * a rotation of pi/2 radians will carry +axis1 into +axis2.
188    * The rotation is precomposed with self if pre is true, and
189    * postcomposed otherwise. 
190    * Note that the rotation is applied centered at the origin. */
191   void Rotate(int axis1, int axis2, TScalarType angle, bool pre=0);
192
193   /** Compose 2D affine transformation with a rotation
194    *
195    * This method composes self, which must be a 2D affine
196    * transformation, with a clockwise rotation through a given angle
197    * in radians.  The center of rotation is the origin.  The
198    * rotation is precomposed with self if pre is true, and
199    * postcomposed otherwise.
200    * Note that the rotation is applied centered at the origin.
201    *
202    * \warning Only to be use in two dimensions
203    *
204    * \todo Find a way to generate a compile-time error
205    *       is this is used with NDimensions != 2. */
206   void Rotate2D(TScalarType angle, bool pre=0);
207
208   /** Compose 3D affine transformation with a rotation
209    *
210    * This method composes self, which must be a 3D affine
211    * transformation, with a clockwise rotation around a specified
212    * axis.  The rotation angle is in radians; the axis of rotation
213    * goes through the origin.  The rotation is precomposed with self
214    * if pre is true, and postcomposed otherwise.
215    * Note that the rotation is applied centered at the origin.
216    *
217    * \warning Only to be used in dimension 3
218    *
219    * \todo Find a way to generate a compile-time error
220    * is this is used with NDimensions != 3. */
221   void Rotate3D(const OutputVectorType &axis, TScalarType angle, bool pre=0);
222
223   /** Compose affine transformation with a shear
224    *
225    * This method composes self with a shear transformation,
226    * replacing the original contents of self.  The shear is
227    * precomposed with self if pre is true, and postcomposed
228    * otherwise.  The transformation is given by
229    *
230    * y[axis1] = x[axis1] + coef*x[axis2]
231    * y[axis2] =                 x[axis2]. 
232    *
233    * Note that the shear is applied centered at the origin. */
234   void Shear(int axis1, int axis2, TScalarType coef, bool pre=0);
235
236   /** Back transform by an affine transformation
237    *
238    * This method finds the point or vector that maps to a given
239    * point or vector under the affine transformation defined by
240    * self.  If no such point exists, an exception is thrown.   
241    *
242    * \deprecated Please use GetInverseTransform and then call the
243    *   forward transform function **/
244   inline InputPointType   BackTransform(const OutputPointType  &point ) const;
245   inline InputVectorType  BackTransform(const OutputVectorType &vector) const;
246   inline InputVnlVectorType BackTransform(
247                                      const OutputVnlVectorType &vector) const;
248   inline InputCovariantVectorType BackTransform(
249                               const OutputCovariantVectorType &vector) const;
250
251   /** Back transform a point by an affine transform
252    *
253    * This method finds the point that maps to a given point under
254    * the affine transformation defined by self.  If no such point
255    * exists, an exception is thrown.  The returned value is (a
256    * pointer to) a brand new point created with new. 
257    *
258    * \deprecated Please use GetInverseTransform and then call the
259    *   forward transform function **/
260   InputPointType  BackTransformPoint(const OutputPointType  &point) const;
261
262   /** Compute distance between two affine transformations
263    *
264    * This method computes a ``distance'' between two affine
265    * transformations.  This distance is guaranteed to be a metric,
266    * but not any particular metric.  (At the moment, the algorithm
267    * is to collect all the elements of the matrix and offset into a
268    * vector, and compute the euclidean (L2) norm of that vector.
269    * Some metric which could be used to estimate the distance between
270    * two points transformed by the affine transformation would be
271    * more useful, but I don't have time right now to work out the
272    * mathematical details.) */
273   ScalarType Metric(const Self * other) const;
274
275   /** This method computes the distance from self to the identity
276    * transformation, using the same metric as the one-argument form
277    * of the Metric() method. **/
278   ScalarType Metric(void) const;
279
280 protected:
281   /** Construct an AffineTransform object
282    *
283    * This method constructs a new AffineTransform object and
284    * initializes the matrix and offset parts of the transformation
285    * to values specified by the caller.  If the arguments are
286    * omitted, then the AffineTransform is initialized to an identity
287    * transformation in the appropriate number of dimensions.   **/
288   AffineTransform(const MatrixType &matrix,
289                   const OutputVectorType &offset);
290   AffineTransform(unsigned int outputDims,
291                   unsigned int paramDims);
292   AffineTransform();      
293   
294   /** Destroy an AffineTransform object   **/
295   virtual ~AffineTransform();
296
297   /** Print contents of an AffineTransform */
298   void PrintSelf(std::ostream &s, Indent indent) const;
299
300 private:
301
302   AffineTransform(const Self & other);
303   const Self & operator=( const Self & );
304
305 }; //class AffineTransform
306
307 }  // namespace itk
308
309
310 #ifndef ITK_MANUAL_INSTANTIATION
311 #include "itkAffineTransform.txx"
312 #endif
313
314 #endif /* __itkAffineTransform_h */
315
316 EOF
317 EOF,EML
318 EOF,EML
319 EOF,EML
320 EOF,EML

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