ANIMA  4.0
animaDirectionScaleSkewTransform.hxx
Go to the documentation of this file.
1 #pragma once
3 
4 namespace anima
5 {
6 
7 // Set Parameters
8 template <class TScalarType>
9 void
11 ::SetParameters(const ParametersType & parameters)
12 {
13  // Set angles with parameters
14  m_LogScale = parameters[0];
15  m_LogFirstSkew = parameters[1];
16  m_LogSecondSkew = parameters[2];
17  m_UniqueTranslation = parameters[3];
18 
19  this->ComputeMatrix();
20 }
21 
22 
23 // Get Parameters
24 template <class TScalarType>
27 ::GetParameters( void ) const
28 {
29  this->m_Parameters[0] = m_LogScale;
30  this->m_Parameters[1] = m_LogFirstSkew;
31  this->m_Parameters[2] = m_LogSecondSkew;
32  this->m_Parameters[3] = m_UniqueTranslation;
33 
34  return this->m_Parameters;
35 }
36 
37 template <class TScalarType>
38 void
41 {
42  Superclass::SetIdentity();
43  m_LogScale = 0;
44  m_UniqueTranslation = 0;
45  m_LogFirstSkew = 0;
46  m_LogSecondSkew = 0;
47 
48  m_LogTransform.fill(itk::NumericTraits<TScalarType>::Zero);
49  m_ExpTransform.set_identity();
50  m_LogVector.Fill(itk::NumericTraits<TScalarType>::Zero);
51 }
52 
53 template <class TScalarType>
54 void
56 ::SetGeometry(HomogeneousMatrixType &matrix, bool update)
57 {
58  m_Geometry = matrix;
59  m_GeometryInv = m_Geometry.GetInverse();
60 
61  if (update)
62  this->ComputeMatrix();
63 }
64 
65 template <class TScalarType>
66 void
68 ::SetLogScale(ScalarType scale, bool update)
69 {
70  m_LogScale = scale;
71 
72  if (update)
73  this->ComputeMatrix();
74 }
75 
76 template <class TScalarType>
77 void
79 ::SetLogFirstSkew(ScalarType skew, bool update)
80 {
81  m_LogFirstSkew = skew;
82 
83  if (update)
84  this->ComputeMatrix();
85 }
86 
87 template <class TScalarType>
88 void
90 ::SetLogSecondSkew(ScalarType skew, bool update)
91 {
92  m_LogSecondSkew = skew;
93 
94  if (update)
95  this->ComputeMatrix();
96 }
97 
98 template <class TScalarType>
99 void
101 ::SetUniqueTranslation(ScalarType translation, bool update)
102 {
103  m_UniqueTranslation = translation;
104 
105  if (update)
106  this->ComputeMatrix();
107 }
108 
109 template <class TScalarType>
110 void
112 ::SetUniqueDirection(unsigned int direction)
113 {
114  m_UniqueDirection = direction;
115  this->ComputeMatrix();
116 }
117 
118 // Compute angles from the rotation matrix
119 template <class TScalarType>
120 void
123 {
124  // Start by updating log-representations
125  this->GetInternalLogarithm();
126  this->GetInternalExponential();
127 
128  MatrixType linearMatrix;
129  OffsetType off;
130 
131  // Apply geometry to log and exp transforms
132  this->InternalApplyGeometry(linearMatrix,off);
133 
134  this->SetMatrix(linearMatrix);
135  this->SetOffset(off);
136 
137  m_LogVector.Fill(itk::NumericTraits<TScalarType>::Zero);
138  for (unsigned int i = 0;i < 3;++i)
139  for (unsigned int j = 0;j <= 3;++j)
140  m_LogVector[i * 4 + j] = m_LogTransform(i,j);
141 }
142 
143 template <class TScalarType>
144 void
147 {
148  // First update log transform
149  for (unsigned int i = 0;i < 3;++i)
150  offset[i] = m_Geometry(i,m_UniqueDirection) * m_UniqueTranslation;
151 
152  for (unsigned int j = 0;j < 3;++j)
153  {
154  double aRinv = 0.0;
155  for (unsigned int k = 0;k < 3;++k)
156  aRinv += m_LogTransform(m_UniqueDirection,k) * m_GeometryInv(k,j);
157 
158  for (unsigned int i = 0;i < 3;++i)
159  linearMatrix(i,j) = aRinv * m_Geometry(i,m_UniqueDirection);
160  }
161 
162  for (unsigned int i = 0;i < 3;++i)
163  {
164  for (unsigned int j = 0;j < 3;++j)
165  offset[i] -= linearMatrix(i,j) * m_Geometry(j,3);
166 
167  m_LogTransform(i,3) = offset[i];
168  for (unsigned int j = 0;j < 3;++j)
169  m_LogTransform(i,j) = linearMatrix(i,j);
170  }
171 
172  // Then update exp transform and keep linearMatrix and offset there
173  for (unsigned int i = 0;i < 3;++i)
174  offset[i] = m_Geometry(i,m_UniqueDirection) * m_ExpTransform(m_UniqueDirection,3) + m_Geometry(i,3);
175 
176  for (unsigned int j = 0;j < 3;++j)
177  {
178  double aRinv = 0.0;
179  for (unsigned int k = 0;k < 3;++k)
180  aRinv += m_ExpTransform(m_UniqueDirection,k) * m_GeometryInv(k,j);
181 
182  for (unsigned int i = 0;i < 3;++i)
183  {
184  linearMatrix(i,j) = aRinv * m_Geometry(i,m_UniqueDirection);
185  for (unsigned int k = 0;k < 3;++k)
186  {
187  if (k == m_UniqueDirection)
188  continue;
189  linearMatrix(i,j) += m_Geometry(i,k) * m_GeometryInv(k,j);
190  }
191  }
192  }
193 
194  for (unsigned int i = 0;i < 3;++i)
195  {
196  for (unsigned int j = 0;j < 3;++j)
197  offset[i] -= linearMatrix(i,j) * m_Geometry(j,3);
198 
199  m_ExpTransform(i,3) = offset[i];
200  for (unsigned int j = 0;j < 3;++j)
201  m_ExpTransform(i,j) = linearMatrix(i,j);
202  }
203 }
204 
205 template <class TScalarType>
206 void
209 {
210  m_LogTransform.fill(0.0);
211 
212  unsigned int skewLocation = 0;
213  if (m_UniqueDirection == skewLocation)
214  skewLocation++;
215 
216  m_LogTransform(m_UniqueDirection,skewLocation) = m_LogFirstSkew;
217  skewLocation++;
218  if (m_UniqueDirection == skewLocation)
219  skewLocation++;
220 
221  m_LogTransform(m_UniqueDirection,skewLocation) = m_LogSecondSkew;
222 
223  m_LogTransform(m_UniqueDirection,m_UniqueDirection) = m_LogScale;
224  m_LogTransform(m_UniqueDirection,3) = m_UniqueTranslation;
225 }
226 
227 template <class TScalarType>
228 void
231 {
232  m_ExpTransform.set_identity();
233 
234  unsigned int skewLocation = 0;
235  if (m_UniqueDirection == skewLocation)
236  skewLocation++;
237 
238  double expFactor = 1.0;
239  if (m_LogScale != 0.0)
240  {
241  expFactor = std::exp(m_LogScale);
242  m_ExpTransform(m_UniqueDirection,skewLocation) = m_LogFirstSkew * (expFactor - 1.0) / m_LogScale;
243  }
244  else
245  m_ExpTransform(m_UniqueDirection,skewLocation) = m_LogFirstSkew;
246 
247  skewLocation++;
248  if (m_UniqueDirection == skewLocation)
249  skewLocation++;
250 
251  if (m_LogScale != 0.0)
252  m_ExpTransform(m_UniqueDirection,skewLocation) = m_LogSecondSkew * (expFactor - 1.0) / m_LogScale;
253  else
254  m_ExpTransform(m_UniqueDirection,skewLocation) = m_LogSecondSkew;
255 
256  m_ExpTransform(m_UniqueDirection,m_UniqueDirection) = expFactor;
257 
258  if (m_LogScale != 0.0)
259  m_ExpTransform(m_UniqueDirection,3) = m_UniqueTranslation * (expFactor - 1.0) / m_LogScale;
260  else
261  m_ExpTransform(m_UniqueDirection,3) = m_UniqueTranslation;
262 }
263 
264 // Print self
265 template<class TScalarType>
266 void
268 PrintSelf(std::ostream &os, itk::Indent indent) const
269 {
270  Superclass::PrintSelf(os,indent);
271 
272  os << indent << "Direction scale transform parameters: Log scale=" << m_LogScale
273  << " Log first skew=" << m_LogFirstSkew
274  << " Log second skew=" << m_LogSecondSkew
275  << " Log translation=" << m_UniqueTranslation
276  << " Transform direction=" << m_UniqueDirection
277  << " Geometry=" << m_Geometry
278  << std::endl;
279 }
280 
282 
283 // Set Parameters
284 template <class TScalarType>
285 void
287 ::SetParameters(const ParametersType & parameters)
288 {
289  // Set angles with parameters
290  this->SetLogScale(parameters[0],false);
291  this->SetLogFirstSkew(0,false);
292  this->SetLogSecondSkew(0,false);
293  this->SetUniqueTranslation(parameters[1],false);
294 
295  this->ComputeMatrix();
296 }
297 
298 // Get Parameters
299 template <class TScalarType>
302 ::GetParameters( void ) const
303 {
304  this->m_Parameters[0] = this->GetLogScale();
305  this->m_Parameters[1] = this->GetUniqueTranslation();
306 
307  return this->m_Parameters;
308 }
309 
310 template <class TScalarType>
311 void
314 {
315  unsigned int uniqueDirection = this->GetUniqueDirection();
316  // First update log transform
317  for (unsigned int i = 0;i < 3;++i)
318  offset[i] = this->m_Geometry(i,uniqueDirection) * this->GetUniqueTranslation();
319 
320  for (unsigned int j = 0;j < 3;++j)
321  {
322  double aRinv = this->m_LogTransform(uniqueDirection,uniqueDirection) * this->m_GeometryInv(uniqueDirection,j);
323 
324  for (unsigned int i = 0;i < 3;++i)
325  linearMatrix(i,j) = aRinv * this->m_Geometry(i,uniqueDirection);
326  }
327 
328  for (unsigned int i = 0;i < 3;++i)
329  {
330  for (unsigned int j = 0;j < 3;++j)
331  offset[i] -= linearMatrix(i,j) * this->m_Geometry(j,3);
332 
333  this->m_LogTransform(i,3) = offset[i];
334  for (unsigned int j = 0;j < 3;++j)
335  this->m_LogTransform(i,j) = linearMatrix(i,j);
336  }
337 
338  // Then update exp transform and keep linearMatrix and offset there
339  for (unsigned int i = 0;i < 3;++i)
340  offset[i] = this->m_Geometry(i,uniqueDirection) * this->m_ExpTransform(uniqueDirection,3) + this->m_Geometry(i,3);
341 
342  for (unsigned int j = 0;j < 3;++j)
343  {
344  double aRinv = this->m_ExpTransform(uniqueDirection,uniqueDirection) * this->m_GeometryInv(uniqueDirection,j);
345 
346  for (unsigned int i = 0;i < 3;++i)
347  {
348  linearMatrix(i,j) = aRinv * this->m_Geometry(i,uniqueDirection);
349  for (unsigned int k = 0;k < 3;++k)
350  {
351  if (k == uniqueDirection)
352  continue;
353  linearMatrix(i,j) += this->m_Geometry(i,k) * this->m_GeometryInv(k,j);
354  }
355  }
356  }
357 
358  for (unsigned int i = 0;i < 3;++i)
359  {
360  for (unsigned int j = 0;j < 3;++j)
361  offset[i] -= linearMatrix(i,j) * this->m_Geometry(j,3);
362 
363  this->m_ExpTransform(i,3) = offset[i];
364  for (unsigned int j = 0;j < 3;++j)
365  this->m_ExpTransform(i,j) = linearMatrix(i,j);
366  }
367 }
368 
369 template <class TScalarType>
370 void
373 {
374  this->m_LogTransform.fill(0.0);
375 
376  unsigned int uniqueDirection = this->GetUniqueDirection();
377  this->m_LogTransform(uniqueDirection,uniqueDirection) = this->GetLogScale();
378  this->m_LogTransform(uniqueDirection,3) = this->GetUniqueTranslation();
379 }
380 
381 template <class TScalarType>
382 void
385 {
386  this->m_ExpTransform.set_identity();
387 
388  double expFactor = 1.0;
389  double logScale = this->GetLogScale();
390  if (logScale != 0.0)
391  expFactor = std::exp(logScale);
392 
393  unsigned int uniqueDirection = this->GetUniqueDirection();
394  this->m_ExpTransform(uniqueDirection,uniqueDirection) = expFactor;
395 
396  if (logScale != 0.0)
397  this->m_ExpTransform(uniqueDirection,3) = this->GetUniqueTranslation() * (expFactor - 1.0) / logScale;
398  else
399  this->m_ExpTransform(uniqueDirection,3) = this->GetUniqueTranslation();
400 }
401 
403 
404 // Set Parameters
405 template <class TScalarType>
406 void
408 ::SetParameters(const ParametersType & parameters)
409 {
410  // Set angles with parameters
411  this->SetLogScale(0,false);
412  this->SetLogFirstSkew(0,false);
413  this->SetLogSecondSkew(0,false);
414  this->SetUniqueTranslation(parameters[0],false);
415 
416  this->ComputeMatrix();
417 }
418 
419 // Get Parameters
420 template <class TScalarType>
424 {
425  this->m_Parameters[0] = this->GetUniqueTranslation();
426  return this->m_Parameters;
427 }
428 
429 template <class TScalarType>
430 void
433 {
434  unsigned int uniqueDirection = this->GetUniqueDirection();
435  // First update log transform
436  for (unsigned int i = 0;i < 3;++i)
437  offset[i] = this->m_Geometry(i,uniqueDirection) * this->GetUniqueTranslation();
438 
439  for (unsigned int i = 0;i < 3;++i)
440  this->m_LogTransform(i,3) = offset[i];
441 
442  // Then update exp transform and keep linearMatrix and offset there
443  for (unsigned int i = 0;i < 3;++i)
444  offset[i] = this->m_Geometry(i,uniqueDirection) * this->m_ExpTransform(uniqueDirection,3);
445 
446  linearMatrix.SetIdentity();
447 
448  for (unsigned int i = 0;i < 3;++i)
449  {
450  this->m_ExpTransform(i,3) = offset[i];
451  for (unsigned int j = 0;j < 3;++j)
452  this->m_ExpTransform(i,j) = linearMatrix(i,j);
453  }
454 }
455 
456 template <class TScalarType>
457 void
460 {
461  this->m_LogTransform.fill(0.0);
462  this->m_LogTransform(this->GetUniqueDirection(),3) = this->GetUniqueTranslation();
463 }
464 
465 template <class TScalarType>
466 void
469 {
470  this->m_ExpTransform.set_identity();
471  this->m_ExpTransform(this->GetUniqueDirection(),3) = this->GetUniqueTranslation();
472 }
473 
474 } // end namespace anima
virtual void SetParameters(const ParametersType &parameters) override
virtual const ParametersType & GetParameters() const override
virtual void InternalApplyGeometry(MatrixType &linearMatrix, OffsetType &offset) override
void SetLogScale(ScalarType scale, bool update=true)
void SetLogSecondSkew(ScalarType skew, bool update=true)
void SetLogFirstSkew(ScalarType skew, bool update=true)
virtual const ParametersType & GetParameters() const override
void PrintSelf(std::ostream &os, itk::Indent indent) const override
itk::Matrix< ScalarType, 4, 4 > HomogeneousMatrixType
void SetUniqueTranslation(ScalarType translation, bool update=true)
Superclass::ParametersType ParametersType
virtual const ParametersType & GetParameters() const override
virtual void SetParameters(const ParametersType &parameters) override
virtual void InternalApplyGeometry(MatrixType &linearMatrix, OffsetType &offset) override
virtual void SetParameters(const ParametersType &parameters) override
virtual void InternalApplyGeometry(MatrixType &linearMatrix, OffsetType &offset)
virtual void SetGeometry(HomogeneousMatrixType &matrix, bool update=true)