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_h
19 #define itkCenteredRigid2DTransform_h
20 
21 #include <iostream>
22 #include "itkRigid2DTransform.h"
23 
24 namespace itk
25 {
26 /** \class CenteredRigid2DTransform
27  * \brief CenteredRigid2DTransform of a vector space (e.g. space coordinates)
28  *
29  * This transform applies a rigid transformation is 2D space.
30  * The transform is specified as a rotation around arbitrary center
31  * and is followed by a translation.
32  *
33  * The main difference between this class and its superclass
34  * Rigid2DTransform is that the center of rotation is exposed
35  * for optimization.
36  *
37  * The serialization of the optimizable parameters is an array of 5 elements
38  * ordered as follows:
39  * p[0] = angle
40  * p[1] = x coordinate of the center
41  * p[2] = y coordinate of the center
42  * p[3] = x component of the translation
43  * p[4] = y component of the translation
44  *
45  * There are no fixed parameters.
46  *
47  * \sa Rigid2DTransform
48  *
49  * \ingroup ITKTransform
50  */
51 template<typename TParametersValueType=double>
52 class ITK_TEMPLATE_EXPORT CenteredRigid2DTransform :
53   public Rigid2DTransform<TParametersValueType>
54 {
55 public:
56   ITK_DISALLOW_COPY_AND_ASSIGN(CenteredRigid2DTransform);
57 
58   /** Standard class type aliases. */
59   using Self = CenteredRigid2DTransform;
60   using Superclass = Rigid2DTransform<TParametersValueType>;
61   using Pointer = SmartPointer<Self>;
62   using ConstPointer = SmartPointer<const Self>;
63 
64   /** New macro for creation of through a Smart Pointer. */
65   itkNewMacro(Self);
66 
67   /** Run-time type information (and related methods). */
68   itkTypeMacro(CenteredRigid2DTransform, Rigid2DTransform);
69 
70   /** Dimension of parameters. */
71   static constexpr unsigned int SpaceDimension = 2;
72   static constexpr unsigned int OutputSpaceDimension = 2;
73   static constexpr unsigned int ParametersDimension = 5;
74 
75   /** Parameters type. */
76   using ScalarType = typename Superclass::ScalarType;
77   using FixedParametersType = typename Superclass::FixedParametersType;
78   using FixedParametersValueType = typename Superclass::FixedParametersValueType;
79   using ParametersType = typename Superclass::ParametersType;
80   using ParametersValueType = typename Superclass::ParametersValueType;
81 
82   /** Jacobian type. */
83   using JacobianType = typename Superclass::JacobianType;
84   using JacobianPositionType = typename Superclass::JacobianPositionType;
85   using InverseJacobianPositionType = typename Superclass::InverseJacobianPositionType;
86 
87   /** Offset type. */
88   using OffsetType = typename Superclass::OffsetType;
89 
90   /** Point type. */
91   using InputPointType = typename Superclass::InputPointType;
92   using OutputPointType = typename Superclass::OutputPointType;
93   using InputPointValueType = typename Superclass::InputPointValueType;
94 
95   /** Vector type. */
96   using InputVectorType = typename Superclass::InputVectorType;
97   using OutputVectorType = typename Superclass::OutputVectorType;
98   using OutputVectorValueType = typename Superclass::OutputVectorValueType;
99 
100   /** CovariantVector type. */
101   using InputCovariantVectorType = typename Superclass::InputCovariantVectorType;
102   using OutputCovariantVectorType = typename Superclass::OutputCovariantVectorType;
103 
104   /** VnlVector type. */
105   using InputVnlVectorType = typename Superclass::InputVnlVectorType;
106   using OutputVnlVectorType = typename Superclass::OutputVnlVectorType;
107 
108   /** Base inverse transform type. This type should not be changed to the
109    * concrete inverse transform type or inheritance would be lost. */
110   using InverseTransformBaseType = typename Superclass::InverseTransformBaseType;
111   using InverseTransformBasePointer = typename InverseTransformBaseType::Pointer;
112 
113   /** Set the transformation from a container of parameters
114    * This is typically used by optimizers.
115    * There are 5 parameters. The first one represents the
116    * rotation, the next two the center of rotation and
117    * the last two represents the offset.
118    *
119    * \sa Transform::SetParameters()
120    * \sa Transform::SetFixedParameters() */
121   void SetParameters(const ParametersType & parameters) override;
122 
123   /** Get the parameters that uniquely define the transform
124    * This is typically used by optimizers.
125    * There are 3 parameters. The first one represents the
126    * rotation, the next two the center of rotation and
127    * the last two represents the offset.
128    *
129    * \sa Transform::GetParameters()
130    * \sa Transform::GetFixedParameters() */
131   const ParametersType & GetParameters() const override;
132 
133   /** This method computes the Jacobian matrix of the transformation
134    * at a given input point.
135    */
136   void ComputeJacobianWithRespectToParameters( const InputPointType  & p, JacobianType & jacobian) const override;
137 
138   /** Set the fixed parameters and update internal transformation.
139    * This is a null function as there are no fixed parameters. */
140   void SetFixedParameters(const FixedParametersType &) override;
141 
142   /** Get the Fixed Parameters. An empty array is returned
143    * as there are no fixed parameters. */
144   const FixedParametersType & GetFixedParameters() const override;
145 
146   /**
147    * This method creates and returns a new CenteredRigid2DTransform object
148    * which is the inverse of self. */
149   void CloneInverseTo(Pointer & newinverse) const;
150 
151   /** Get an inverse of this transform. */
152   bool GetInverse(Self *inverse) const;
153 
154   /** Return an inverse of this transform. */
155   InverseTransformBasePointer GetInverseTransform() const override;
156 
157   /**
158    * This method creates and returns a new CenteredRigid2DTransform object
159    * which has the same parameters as self. */
160   void CloneTo(Pointer & clone) const;
161 
162 protected:
163   CenteredRigid2DTransform();
164   ~CenteredRigid2DTransform() override = default;
165 
166   CenteredRigid2DTransform(unsigned int outputSpaceDimension, unsigned int parametersDimension);
167 
168   void PrintSelf(std::ostream & os, Indent indent) const override;
169 };                                        // class CenteredRigid2DTransform
170 }  // namespace itk
171 
172 #ifndef ITK_MANUAL_INSTANTIATION
173 #include "itkCenteredRigid2DTransform.hxx"
174 #endif
175 
176 #endif /* itkCenteredRigid2DTransform_h */
177