ANIMA  4.0
animaVectorOperations.hxx
Go to the documentation of this file.
2 #include <cmath>
3 
5 
6 #include <vnl/vnl_diag_matrix.h>
7 #include <itkMacro.h>
8 
9 namespace anima
10 {
11 
12 /******* Main function ComputeEuclideanDistance *******/
13 // Main
14 template <class VectorType> double ComputeEuclideanDistance(const VectorType &x1, const VectorType &x2, const unsigned int NDimension)
15 {
16  double resVal = 0;
17 
18  for (unsigned int i = 0;i < NDimension;++i)
19  {
20  resVal += (x1[i] - x2[i]) * (x1[i] - x2[i]);
21  }
22 
23  return std::sqrt(resVal);
24 }
25 // For itkVector
26 template <class ScalarType, unsigned int NDimension> double ComputeEuclideanDistance(const itk::Vector <ScalarType,NDimension> &x1, const itk::Vector <ScalarType,NDimension> &x2)
27 {
28  return ComputeEuclideanDistance(x1, x2, NDimension);
29 }
30 // For itkVariableLengthVector
31 template <class ScalarType> double ComputeEuclideanDistance(const itk::VariableLengthVector <ScalarType> &x1, const itk::VariableLengthVector <ScalarType> &x2)
32 {
33  unsigned int NDimension = x1.GetSize();
34 
35  if (x2.GetSize() != NDimension)
36  throw itk::ExceptionObject(__FILE__, __LINE__,"Euclidean distance can only be computed on same size vectors.",ITK_LOCATION);
37 
38  return ComputeEuclideanDistance(x1, x2, NDimension);
39 }
40 // For itkPoint
41 template <class ScalarType, unsigned int NDimension> double ComputeEuclideanDistance(const itk::Point<ScalarType,NDimension> &x1, const itk::Point<ScalarType,NDimension> &x2)
42 {
43  return ComputeEuclideanDistance(x1, x2, NDimension);
44 }
45 // For vnl_vector
46 template <class ScalarType> double ComputeEuclideanDistance(const vnl_vector <ScalarType> &x1, const vnl_vector <ScalarType> &x2)
47 {
48  unsigned int NDimension = x1.size();
49 
50  if (x2.size() != NDimension)
51  throw itk::ExceptionObject(__FILE__, __LINE__,"Euclidean distance can only be computed on same size vectors.",ITK_LOCATION);
52 
53  return ComputeEuclideanDistance(x1, x2, NDimension);
54 }
55 // For vnl_vector_fixed
56 template <class ScalarType, unsigned int NDimension>
57 double ComputeEuclideanDistance(const vnl_vector_fixed <ScalarType,NDimension> &x1, const vnl_vector_fixed <ScalarType,NDimension> &x2)
58 {
59  return ComputeEuclideanDistance(x1,x2,NDimension);
60 }
61 // For std::vector
62 template <class ScalarType> double ComputeEuclideanDistance(const std::vector <ScalarType> &x1, const std::vector <ScalarType> &x2)
63 {
64  unsigned int NDimension = x1.size();
65 
66  if (x2.size() != NDimension)
67  throw itk::ExceptionObject(__FILE__, __LINE__,"Euclidean distance can only be computed on same size vectors.",ITK_LOCATION);
68 
69  return ComputeEuclideanDistance(x1, x2, NDimension);
70 }
71 /******************************************************/
72 
73 // Function ComputePointToSetDistance
74 template <class VectorType> double ComputePointToSetDistance(const VectorType &x, const std::vector <VectorType> &s)
75 {
76  unsigned int NDimension = s.size();
77 
78  double resVal = ComputeEuclideanDistance(x, s[0]);
79 
80  for (unsigned int i = 1;i < NDimension;++i)
81  {
82  double tmpVal = ComputeEuclideanDistance(x, s[i]);
83 
84  if (tmpVal < resVal)
85  resVal = tmpVal;
86  }
87 
88  return resVal;
89 }
90 
91 // Function ComputeDirectedHausdorffDistance
92 template <class VectorType> double ComputeDirectedHausdorffDistance(const std::vector <VectorType> &s1, const std::vector <VectorType> &s2)
93 {
94  unsigned int NDimension = s1.size();
95 
96  double resVal = ComputePointToSetDistance(s1[0], s2);
97 
98  for (unsigned int i = 1;i < NDimension;++i)
99  {
100  double tmpVal = ComputePointToSetDistance(s1[i], s2);
101 
102  if (tmpVal > resVal)
103  resVal = tmpVal;
104  }
105 
106  return resVal;
107 }
108 
109 // Function ComputeHausdorffDistance
110 template <class VectorType> double ComputeHausdorffDistance(const std::vector <VectorType> &s1, const std::vector <VectorType> &s2)
111 {
112  double forward = ComputeDirectedHausdorffDistance(s1, s2);
113  double backward = ComputeDirectedHausdorffDistance(s2, s1);
114 
115  return std::max(forward, backward);
116 }
117 
118 // Function ComputeModifiedDirectedHausdorffDistance
119 template <class VectorType> double ComputeModifiedDirectedHausdorffDistance(const std::vector <VectorType> &s1, const std::vector <VectorType> &s2)
120 {
121  unsigned int NDimension = s1.size();
122 
123  double resVal = ComputePointToSetDistance(s1[0], s2);
124 
125  for (unsigned int i = 1;i < NDimension;++i)
126  resVal += ComputePointToSetDistance(s1[i], s2);
127 
128  return resVal / NDimension;
129 }
130 
131 // Function ComputeModifiedHausdorffDistance
132 template <class VectorType> double ComputeModifiedHausdorffDistance(const std::vector <VectorType> &s1, const std::vector <VectorType> &s2)
133 {
134  double forward = ComputeModifiedDirectedHausdorffDistance(s1, s2);
135  double backward = ComputeModifiedDirectedHausdorffDistance(s2, s1);
136 
137  return std::max(forward, backward);
138 }
139 
140 /******* Function ExponentialSum *******/
141 // Main
142 template <class VectorType> double ExponentialSum(const VectorType &x, const unsigned int NDimension)
143 {
144  double maxVal = x[0];
145 
146  for (unsigned int i = 1;i < NDimension;++i)
147  if (x[i] > maxVal)
148  maxVal = x[i];
149 
150  double sum = 0;
151  for (unsigned int i = 0;i < NDimension;++i)
152  sum += std::exp(x[i] - maxVal);
153 
154  if (sum < 1.0e-6)
155  throw itk::ExceptionObject(__FILE__, __LINE__,"Exponential sum cannot be computed because requires to take the log of a non-positive value.",ITK_LOCATION);
156 
157  return maxVal + std::log(sum);
158 }
159 // For itkVector
160 template <class ScalarType, unsigned int NDimension> double ExponentialSum(const itk::Vector <ScalarType,NDimension> &x)
161 {
162  return ExponentialSum(x, NDimension);
163 }
164 // For itkVariableLengthVector
165 template <class ScalarType> double ExponentialSum(const itk::VariableLengthVector <ScalarType> &x)
166 {
167  unsigned int NDimension = x.GetSize();
168  return ExponentialSum(x, NDimension);
169 }
170 // For itkPoint
171 template <class ScalarType, unsigned int NDimension> double ExponentialSum(const itk::Point <ScalarType,NDimension> &x)
172 {
173  return ExponentialSum(x, NDimension);
174 }
175 // For vnl_vector
176 template <class ScalarType> double ExponentialSum(const vnl_vector <ScalarType> &x)
177 {
178  unsigned int NDimension = x.size();
179  return ExponentialSum(x, NDimension);
180 }
181 // For vnl_vector_fixed
182 template <class ScalarType, unsigned int NDimension> double ExponentialSum(const vnl_vector_fixed <ScalarType,NDimension> &x)
183 {
184  return ExponentialSum(x, NDimension);
185 }
186 // For std::vector
187 template <class ScalarType> double ExponentialSum(const std::vector <ScalarType> &x)
188 {
189  unsigned int NDimension = x.size();
190  return ExponentialSum(x, NDimension);
191 }
192 /***************************************/
193 
194 /******* Main function ComputeScalarProduct *******/
195 // Main
196 template <class VectorType> double ComputeScalarProduct(const VectorType &v1, const VectorType &v2, const unsigned int NDimension)
197 {
198  double resVal = 0;
199 
200  for (unsigned int i = 0;i < NDimension;++i)
201  resVal += v1[i] * v2[i];
202 
203  return resVal;
204 }
205 // For itkVector
206 template <class ScalarType, unsigned int NDimension> double ComputeScalarProduct(const itk::Vector <ScalarType,NDimension> &v1, const itk::Vector <ScalarType,NDimension> &v2)
207 {
208  return ComputeScalarProduct(v1, v2, NDimension);
209 }
210 // For itkVariableLengthVector
211 template <class ScalarType> double ComputeScalarProduct(const itk::VariableLengthVector <ScalarType> &v1, const itk::VariableLengthVector <ScalarType> &v2)
212 {
213  unsigned int NDimension = v1.GetSize();
214 
215  if (v2.GetSize() != NDimension)
216  throw itk::ExceptionObject(__FILE__, __LINE__,"Scalar product can only be computed on same size vectors.",ITK_LOCATION);
217 
218  return ComputeScalarProduct(v1, v2, NDimension);
219 }
220 // For itkPoint
221 template <class ScalarType, unsigned int NDimension> double ComputeScalarProduct(const itk::Point <ScalarType,NDimension> &v1, const itk::Point <ScalarType,NDimension> &v2)
222 {
223  return ComputeScalarProduct(v1, v2, NDimension);
224 }
225 // For vnl_vector
226 template <class ScalarType> double ComputeScalarProduct(const vnl_vector <ScalarType> &v1, const vnl_vector <ScalarType> &v2)
227 {
228  unsigned int NDimension = v1.size();
229 
230  if (v2.size() != NDimension)
231  throw itk::ExceptionObject(__FILE__, __LINE__,"Scalar product can only be computed on same size vectors.",ITK_LOCATION);
232 
233  return ComputeScalarProduct(v1, v2, NDimension);
234 }
235 // For vnl_vector_fixed
236 template <class ScalarType, unsigned int NDimension> double ComputeScalarProduct(const vnl_vector_fixed <ScalarType,NDimension> &v1, const vnl_vector_fixed <ScalarType,NDimension> &v2)
237 {
238  return ComputeScalarProduct(v1, v2, NDimension);
239 }
240 // For std::vector
241 template <class ScalarType> double ComputeScalarProduct(const std::vector <ScalarType> &v1, const std::vector <ScalarType> &v2)
242 {
243  unsigned int NDimension = v1.size();
244 
245  if (v2.size() != NDimension)
246  throw itk::ExceptionObject(__FILE__, __LINE__,"Scalar product can only be computed on same size vectors.",ITK_LOCATION);
247 
248  return ComputeScalarProduct(v1, v2, NDimension);
249 }
250 /**************************************************/
251 
252 /******* Function ComputeCrossProduct *******/
253 // Main
254 template <class VectorType> void ComputeCrossProduct(const VectorType &v1, const VectorType &v2, const unsigned int NDimension, VectorType &resVec)
255 {
256  if (NDimension != 3)
257  throw itk::ExceptionObject(__FILE__, __LINE__,"Cross product requires 3D vectors.",ITK_LOCATION);
258 
259  resVec[0] = v1[1] * v2[2] - v2[1] * v1[2];
260  resVec[1] = v1[2] * v2[0] - v2[2] * v1[0];
261  resVec[2] = v1[0] * v2[1] - v2[0] * v1[1];
262 }
263 // For itkVector
264 template <class ScalarType, unsigned int NDimension> void ComputeCrossProduct(const itk::Vector <ScalarType,NDimension> &v1, const itk::Vector <ScalarType,NDimension> &v2, itk::Vector <ScalarType,NDimension> &resVec)
265 {
266  return ComputeCrossProduct(v1, v2, NDimension, resVec);
267 }
268 // For itkVariableLengthVector
269 template <class ScalarType> void ComputeCrossProduct(const itk::VariableLengthVector <ScalarType> &v1, const itk::VariableLengthVector <ScalarType> &v2, itk::VariableLengthVector <ScalarType> &resVec)
270 {
271  unsigned int NDimension = v1.GetSize();
272 
273  if (v2.GetSize() != NDimension)
274  throw itk::ExceptionObject(__FILE__, __LINE__,"Cross product can only be computed on same size vectors.",ITK_LOCATION);
275 
276  resVec.SetSize(NDimension);
277  return ComputeCrossProduct(v1, v2, NDimension, resVec);
278 }
279 // For itkPoint
280 template <class ScalarType, unsigned int NDimension> void ComputeCrossProduct(const itk::Point <ScalarType,NDimension> &v1, const itk::Point <ScalarType,NDimension> &v2, itk::Point <ScalarType,NDimension> &resVec)
281 {
282  return ComputeCrossProduct(v1, v2, NDimension, resVec);
283 }
284 // For vnl_vector
285 template <class ScalarType> void ComputeCrossProduct(const vnl_vector <ScalarType> &v1, const vnl_vector <ScalarType> &v2, vnl_vector <ScalarType> &resVec)
286 {
287  unsigned int NDimension = v1.size();
288 
289  if (v2.size() != NDimension)
290  throw itk::ExceptionObject(__FILE__, __LINE__,"Cross product can only be computed on same size vectors.",ITK_LOCATION);
291 
292  resVec.set_size(NDimension);
293  return ComputeCrossProduct(v1, v2, NDimension, resVec);
294 }
295 // For vnl_vector_fixed
296 template <class ScalarType, unsigned int NDimension> void ComputeCrossProduct(const vnl_vector_fixed <ScalarType,NDimension> &v1, const vnl_vector_fixed <ScalarType,NDimension> &v2, vnl_vector_fixed <ScalarType,NDimension> &resVec)
297 {
298  return ComputeCrossProduct(v1, v2, NDimension, resVec);
299 }
300 // For std::vector
301 template <class ScalarType> void ComputeCrossProduct(const std::vector <ScalarType> &v1, const std::vector <ScalarType> &v2, std::vector <ScalarType> &resVec)
302 {
303  unsigned int NDimension = v1.size();
304 
305  if (v2.size() != NDimension)
306  throw itk::ExceptionObject(__FILE__, __LINE__,"Cross product can only be computed on same size vectors.",ITK_LOCATION);
307 
308  resVec.resize(NDimension);
309  return ComputeCrossProduct(v1, v2, NDimension, resVec);
310 }
311 /********************************************/
312 
313 // Function ComputeNorm
314 template <class VectorType> double ComputeNorm(const VectorType &v)
315 {
316  double n = ComputeScalarProduct(v, v);
317 
318  if (n < 1.0e-6)
319  return 0;
320 
321  return std::sqrt(n);
322 }
323 
324 /******* Function Normalize *******/
325 // Main
326 template <class VectorType> void Normalize(const VectorType &v, const unsigned int NDimension, VectorType &resVec)
327 {
328  resVec = v;
329 
330  double n = ComputeNorm(v);
331 
332  if (n < 1.0e-6)
333  return;
334 
335  for (unsigned int i = 0;i < NDimension;++i)
336  resVec[i] /= n;
337 }
338 // For itkVector
339 template <class ScalarType, unsigned int NDimension> void Normalize(const itk::Vector <ScalarType,NDimension> &v, itk::Vector <ScalarType,NDimension> &resVec)
340 {
341  Normalize(v, NDimension, resVec);
342 }
343 // For itkVariableLengthVector
344 template <class ScalarType> void Normalize(const itk::VariableLengthVector <ScalarType> &v, itk::VariableLengthVector <ScalarType> &resVec)
345 {
346  unsigned int NDimension = v.GetSize();
347  Normalize(v, NDimension, resVec);
348 }
349 // For itkPoint
350 template <class ScalarType, unsigned int NDimension> void Normalize(const itk::Point <ScalarType,NDimension> &v, itk::Point <ScalarType,NDimension> &resVec)
351 {
352  Normalize(v, NDimension, resVec);
353 }
354 // For vnl_vector
355 template <class ScalarType> void Normalize(const vnl_vector <ScalarType> &v, vnl_vector <ScalarType> &resVec)
356 {
357  unsigned int NDimension = v.size();
358  Normalize(v, NDimension, resVec);
359 }
360 // For vnl_vector_fixed
361 template <class ScalarType, unsigned int NDimension> void Normalize(const vnl_vector_fixed <ScalarType, NDimension> &v, vnl_vector_fixed <ScalarType, NDimension> &resVec)
362 {
363  Normalize(v, NDimension, resVec);
364 }
365 // For std::vector
366 template <class ScalarType> void Normalize(const std::vector <ScalarType> &v, std::vector <ScalarType> &resVec)
367 {
368  unsigned int NDimension = v.size();
369  Normalize(v, NDimension, resVec);
370 }
371 /**********************************/
372 
373 /******* Householder vector functions *******/
374 
375 // Main
376 template <class VectorType> void ComputeHouseholderVector(const VectorType &inputVector, VectorType &outputVector, double &beta, unsigned int dimension)
377 {
378  double sigma = 0.0;
379  outputVector[0] = 1.0;
380  for (unsigned int i = 1;i < dimension;++i)
381  {
382  sigma += inputVector[i] * inputVector[i];
383  outputVector[i] = inputVector[i];
384  }
385 
386  if (sigma == 0.0)
387  beta = 0.0;
388  else
389  {
390  double mu = std::sqrt(inputVector[0] * inputVector[0] + sigma);
391  if (inputVector[0] <= 0.0)
392  outputVector[0] = inputVector[0] - mu;
393  else
394  outputVector[0] = - sigma / (inputVector[0] + mu);
395 
396  beta = 2 * outputVector[0] * outputVector[0] / (sigma + outputVector[0] * outputVector[0]);
397 
398  for (unsigned int i = 1;i < dimension;++i)
399  outputVector[i] /= outputVector[0];
400 
401  outputVector[0] = 1.0;
402  }
403 }
404 
405 // for std vector
406 template <class ScalarType> void ComputeHouseholderVector(const std::vector <ScalarType> &inputVector, std::vector <ScalarType> &outputVector, double &beta)
407 {
408  unsigned int dimension = inputVector.size();
409  outputVector.resize(dimension);
410 
411  ComputeHouseholderVector(inputVector,outputVector,beta,dimension);
412 }
413 
414 // for std vector in place
415 template <class ScalarType> void ComputeHouseholderVector(std::vector <ScalarType> &vector, double &beta)
416 {
417  ComputeHouseholderVector(vector,vector,beta);
418 }
419 
420 /**********************************/
421 
422 template <class VectorType> double ComputeAngle(const VectorType &v1, const VectorType &v2)
423 {
424  double normV1 = ComputeNorm(v1);
425  double normV2 = ComputeNorm(v2);
426 
427  double t = ComputeScalarProduct(v1, v2) / (normV1 * normV2);
428 
429  if (t < -1.0)
430  t = -1.0;
431  if (t > 1.0)
432  t = 1.0;
433 
434  return std::acos(t) * 180.0 / M_PI;
435 }
436 
437 template <class VectorType> double ComputeOrientationAngle(const VectorType &v1, const VectorType &v2)
438 {
439  double normV1 = ComputeNorm(v1);
440  double normV2 = ComputeNorm(v2);
441 
442  double t = std::abs(ComputeScalarProduct(v1, v2)) / (normV1 * normV2);
443 
444  if (t > 1.0)
445  t = 1.0;
446 
447  return std::acos(t) * 180.0 / M_PI;
448 }
449 
450 template <class VectorType> void Revert(const VectorType &v, const unsigned int vSize, VectorType &resVec)
451 {
452  for (unsigned int i = 0;i < vSize;++i)
453  resVec[i] = -v[i];
454 }
455 
456 template <class ScalarType> void Revert(const std::vector <ScalarType> &v, std::vector<ScalarType> &resVec)
457 {
458  unsigned int length = v.size();
459  Revert(v, length, resVec);
460 }
461 
462 template <class ScalarType> void Revert(const itk::Point <ScalarType> &v, itk::Point <ScalarType> &resVec)
463 {
464  unsigned int length = v.GetPointDimension();
465  Revert(v, length, resVec);
466 }
467 
468 template <class ScalarType, unsigned int NDimension>
469 void Revert(const vnl_vector_fixed <ScalarType, NDimension> &v, vnl_vector_fixed <ScalarType, NDimension> &resVec)
470 {
471  Revert(v, NDimension, resVec);
472 }
473 
474 template <class VectorType> void TransformCartesianToSphericalCoordinates(const VectorType &v, VectorType &resVec)
475 {
476  double normV = ComputeNorm(v);
477  Normalize(v, resVec);
478 
479  if (resVec[2] >= 1.0)
480  {
481  resVec[0] = 0;
482  resVec[1] = 0;
483  }
484  else if (resVec[2] <= -1.0)
485  {
486  resVec[0] = M_PI;
487  resVec[1] = 0;
488  }
489  else
490  {
491  double theta = std::acos(resVec[2]);
492  double phi = std::atan2(resVec[1],resVec[0]);
493 
494  if (phi < 0.0)
495  phi += (2.0 * M_PI);
496 
497  resVec[0] = theta;
498  resVec[1] = phi;
499  }
500 
501  resVec[2] = normV;
502 }
503 
504 template <class VectorType> void TransformSphericalToCartesianCoordinates(const VectorType &v, VectorType &resVec)
505 {
507 }
508 
509 template <class VectorType> void TransformSphericalToCartesianCoordinates(double theta, double phi, double vectorNorm, VectorType &resVec)
510 {
511  double tmpVal = std::cos(theta);
512  if (std::abs(tmpVal) < 1e-4)
513  {
514  resVec[0] = std::cos(phi);
515  resVec[1] = std::sin(phi);
516  resVec[2] = 0;
517  }
518  else
519  {
520  resVec[0] = std::sin(theta) * std::cos(phi);
521  resVec[1] = std::sin(theta) * std::sin(phi);
522  resVec[2] = tmpVal;
523  }
524 
525  for (unsigned int i = 0;i < 3;++i)
526  resVec[i] *= vectorNorm;
527 }
528 
529 template <class T1, class T2, class T3> void ProjectOnOrthogonalPlane(const std::vector <T1> &v, const std::vector <T2> &normalVec, std::vector <T3> &resVec)
530 {
531  unsigned int length = v.size();
532 
533  if (normalVec.size() != length)
534  throw itk::ExceptionObject(__FILE__, __LINE__,"Projection on orthogonal plane requires a normal vector of the same size as the input vector.",ITK_LOCATION);
535 
536  resVec.resize(length);
537 
538  double t = ComputeScalarProduct(normalVec, v);
539 
540  for (unsigned int i = 0;i < length;++i)
541  resVec[i] = v[i] - t * normalVec[i];
542 
543  Normalize(resVec, resVec);
544 }
545 
546 template <class T1, class T2, class T3, class T4> void RotateAroundAxis(const std::vector <T1> &v, const T2 &phi, const std::vector <T3> &normalVec, std::vector <T4> &resVec)
547 {
548  unsigned int length = v.size();
549 
550  if (length != 3)
551  throw itk::ExceptionObject(__FILE__, __LINE__,"Rotation around axis requires 3D input vector.",ITK_LOCATION);
552 
553  if (normalVec.size() != length)
554  throw itk::ExceptionObject(__FILE__, __LINE__,"Rotation around axis requires a normal vector of the same size as the input vector.",ITK_LOCATION);
555 
556  resVec.resize(3);
557  fill(resVec.begin(),resVec.end(),0);
558 
559  vnl_matrix <double> A(3,3);
560  A.fill(0);
561  A(0,1) = -normalVec[2];
562  A(0,2) = normalVec[1];
563  A(1,2) = -normalVec[0];
564  A -= A.transpose();
565 
566  vnl_matrix <double> N(3,3);
567  for (unsigned int i = 0; i < 3; ++i)
568  for (unsigned int j = 0; j < 3; ++j)
569  N(i,j) = normalVec[i] * normalVec[j];
570 
571  vnl_matrix <double> R(3,3);
572  R.fill(0.0);
573  R.fill_diagonal(cos(phi));
574 
575  R += N * (1.0 - cos(phi)) + A * sin(phi);
576 
577  for (unsigned int i = 0;i < 3;++i)
578  for (unsigned int j = 0; j < 3; ++j)
579  resVec[i] += R(i,j) * v[j];
580 }
581 
582 template <class Vector3DType, class ScalarType> void RotateAroundAxis(const Vector3DType &v, const ScalarType &phi, const Vector3DType &normalVec, Vector3DType &resVec)
583 {
584  vnl_matrix_fixed <ScalarType,3,3> A;
585  A.fill(0.0);
586  A(0,1) = -normalVec[2];
587  A(0,2) = normalVec[1];
588  A(1,2) = -normalVec[0];
589  A -= A.transpose();
590 
591  vnl_matrix_fixed <ScalarType,3,3> N;
592  for (unsigned int i = 0; i < 3; ++i)
593  for (unsigned int j = 0; j < 3; ++j)
594  N(i,j) = normalVec[i] * normalVec[j];
595 
596  vnl_matrix_fixed <ScalarType,3,3> R;
597  R.fill(0.0);
598  R.fill_diagonal(std::cos(phi));
599 
600  R += N * (1.0 - std::cos(phi)) + A * std::sin(phi);
601 
602  for (unsigned int i = 0;i < 3;++i)
603  {
604  resVec[i] = 0;
605  for (unsigned int j = 0;j < 3;++j)
606  resVec[i] += R(i, j) * v[j];
607  }
608 }
609 
610 } // end of namespace anima
void Revert(const VectorType &v, const unsigned int vSize, VectorType &resVec)
double ExponentialSum(const VectorType &x, const unsigned int NDimension)
void TransformSphericalToCartesianCoordinates(const VectorType &v, VectorType &resVec)
double ComputeEuclideanDistance(const VectorType &x1, const VectorType &x2, const unsigned int NDimension)
double ComputeNorm(const VectorType &v)
void RotateAroundAxis(const std::vector< T1 > &v, const T2 &phi, const std::vector< T3 > &normalVec, std::vector< T4 > &resVec)
double ComputeAngle(const VectorType &v1, const VectorType &v2)
double ComputeModifiedHausdorffDistance(const std::vector< VectorType > &s1, const std::vector< VectorType > &s2)
double ComputeHausdorffDistance(const std::vector< VectorType > &s1, const std::vector< VectorType > &s2)
double ComputePointToSetDistance(const VectorType &x, const std::vector< VectorType > &s)
double ComputeOrientationAngle(const VectorType &v1, const VectorType &v2)
void Normalize(const VectorType &v, const unsigned int NDimension, VectorType &resVec)
double ComputeModifiedDirectedHausdorffDistance(const std::vector< VectorType > &s1, const std::vector< VectorType > &s2)
double ComputeDirectedHausdorffDistance(const std::vector< VectorType > &s1, const std::vector< VectorType > &s2)
double ComputeScalarProduct(const VectorType &v1, const VectorType &v2, const unsigned int NDimension)
void ComputeHouseholderVector(const VectorType &inputVector, VectorType &outputVector, double &beta, unsigned int dimension)
void ProjectOnOrthogonalPlane(const std::vector< T1 > &v, const std::vector< T2 > &normalVec, std::vector< T3 > &resVec)
void TransformCartesianToSphericalCoordinates(const VectorType &v, VectorType &resVec)
void ComputeCrossProduct(const VectorType &v1, const VectorType &v2, const unsigned int NDimension, VectorType &resVec)