6 #include <vnl/vnl_diag_matrix.h> 14 template <
class VectorType>
double ComputeEuclideanDistance(
const VectorType &x1,
const VectorType &x2,
const unsigned int NDimension)
18 for (
unsigned int i = 0;i < NDimension;++i)
20 resVal += (x1[i] - x2[i]) * (x1[i] - x2[i]);
23 return std::sqrt(resVal);
26 template <
class ScalarType,
unsigned int NDimension>
double ComputeEuclideanDistance(
const itk::Vector <ScalarType,NDimension> &x1,
const itk::Vector <ScalarType,NDimension> &x2)
31 template <
class ScalarType>
double ComputeEuclideanDistance(
const itk::VariableLengthVector <ScalarType> &x1,
const itk::VariableLengthVector <ScalarType> &x2)
33 unsigned int NDimension = x1.GetSize();
35 if (x2.GetSize() != NDimension)
36 throw itk::ExceptionObject(__FILE__, __LINE__,
"Euclidean distance can only be computed on same size vectors.",ITK_LOCATION);
41 template <
class ScalarType,
unsigned int NDimension>
double ComputeEuclideanDistance(
const itk::Point<ScalarType,NDimension> &x1,
const itk::Point<ScalarType,NDimension> &x2)
46 template <
class ScalarType>
double ComputeEuclideanDistance(
const vnl_vector <ScalarType> &x1,
const vnl_vector <ScalarType> &x2)
48 unsigned int NDimension = x1.size();
50 if (x2.size() != NDimension)
51 throw itk::ExceptionObject(__FILE__, __LINE__,
"Euclidean distance can only be computed on same size vectors.",ITK_LOCATION);
56 template <
class ScalarType,
unsigned int NDimension>
57 double ComputeEuclideanDistance(
const vnl_vector_fixed <ScalarType,NDimension> &x1,
const vnl_vector_fixed <ScalarType,NDimension> &x2)
62 template <
class ScalarType>
double ComputeEuclideanDistance(
const std::vector <ScalarType> &x1,
const std::vector <ScalarType> &x2)
64 unsigned int NDimension = x1.size();
66 if (x2.size() != NDimension)
67 throw itk::ExceptionObject(__FILE__, __LINE__,
"Euclidean distance can only be computed on same size vectors.",ITK_LOCATION);
76 unsigned int NDimension = s.size();
80 for (
unsigned int i = 1;i < NDimension;++i)
94 unsigned int NDimension = s1.size();
98 for (
unsigned int i = 1;i < NDimension;++i)
110 template <
class VectorType>
double ComputeHausdorffDistance(
const std::vector <VectorType> &s1,
const std::vector <VectorType> &s2)
115 return std::max(forward, backward);
121 unsigned int NDimension = s1.size();
125 for (
unsigned int i = 1;i < NDimension;++i)
128 return resVal / NDimension;
137 return std::max(forward, backward);
142 template <
class VectorType>
double ExponentialSum(
const VectorType &x,
const unsigned int NDimension)
144 double maxVal = x[0];
146 for (
unsigned int i = 1;i < NDimension;++i)
151 for (
unsigned int i = 0;i < NDimension;++i)
152 sum += std::exp(x[i] - maxVal);
155 throw itk::ExceptionObject(__FILE__, __LINE__,
"Exponential sum cannot be computed because requires to take the log of a non-positive value.",ITK_LOCATION);
157 return maxVal + std::log(sum);
160 template <
class ScalarType,
unsigned int NDimension>
double ExponentialSum(
const itk::Vector <ScalarType,NDimension> &x)
165 template <
class ScalarType>
double ExponentialSum(
const itk::VariableLengthVector <ScalarType> &x)
167 unsigned int NDimension = x.GetSize();
171 template <
class ScalarType,
unsigned int NDimension>
double ExponentialSum(
const itk::Point <ScalarType,NDimension> &x)
176 template <
class ScalarType>
double ExponentialSum(
const vnl_vector <ScalarType> &x)
178 unsigned int NDimension = x.size();
182 template <
class ScalarType,
unsigned int NDimension>
double ExponentialSum(
const vnl_vector_fixed <ScalarType,NDimension> &x)
187 template <
class ScalarType>
double ExponentialSum(
const std::vector <ScalarType> &x)
189 unsigned int NDimension = x.size();
196 template <
class VectorType>
double ComputeScalarProduct(
const VectorType &v1,
const VectorType &v2,
const unsigned int NDimension)
200 for (
unsigned int i = 0;i < NDimension;++i)
201 resVal += v1[i] * v2[i];
206 template <
class ScalarType,
unsigned int NDimension>
double ComputeScalarProduct(
const itk::Vector <ScalarType,NDimension> &v1,
const itk::Vector <ScalarType,NDimension> &v2)
211 template <
class ScalarType>
double ComputeScalarProduct(
const itk::VariableLengthVector <ScalarType> &v1,
const itk::VariableLengthVector <ScalarType> &v2)
213 unsigned int NDimension = v1.GetSize();
215 if (v2.GetSize() != NDimension)
216 throw itk::ExceptionObject(__FILE__, __LINE__,
"Scalar product can only be computed on same size vectors.",ITK_LOCATION);
221 template <
class ScalarType,
unsigned int NDimension>
double ComputeScalarProduct(
const itk::Point <ScalarType,NDimension> &v1,
const itk::Point <ScalarType,NDimension> &v2)
226 template <
class ScalarType>
double ComputeScalarProduct(
const vnl_vector <ScalarType> &v1,
const vnl_vector <ScalarType> &v2)
228 unsigned int NDimension = v1.size();
230 if (v2.size() != NDimension)
231 throw itk::ExceptionObject(__FILE__, __LINE__,
"Scalar product can only be computed on same size vectors.",ITK_LOCATION);
236 template <
class ScalarType,
unsigned int NDimension>
double ComputeScalarProduct(
const vnl_vector_fixed <ScalarType,NDimension> &v1,
const vnl_vector_fixed <ScalarType,NDimension> &v2)
241 template <
class ScalarType>
double ComputeScalarProduct(
const std::vector <ScalarType> &v1,
const std::vector <ScalarType> &v2)
243 unsigned int NDimension = v1.size();
245 if (v2.size() != NDimension)
246 throw itk::ExceptionObject(__FILE__, __LINE__,
"Scalar product can only be computed on same size vectors.",ITK_LOCATION);
254 template <
class VectorType>
void ComputeCrossProduct(
const VectorType &v1,
const VectorType &v2,
const unsigned int NDimension, VectorType &resVec)
257 throw itk::ExceptionObject(__FILE__, __LINE__,
"Cross product requires 3D vectors.",ITK_LOCATION);
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];
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)
269 template <
class ScalarType>
void ComputeCrossProduct(
const itk::VariableLengthVector <ScalarType> &v1,
const itk::VariableLengthVector <ScalarType> &v2, itk::VariableLengthVector <ScalarType> &resVec)
271 unsigned int NDimension = v1.GetSize();
273 if (v2.GetSize() != NDimension)
274 throw itk::ExceptionObject(__FILE__, __LINE__,
"Cross product can only be computed on same size vectors.",ITK_LOCATION);
276 resVec.SetSize(NDimension);
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)
285 template <
class ScalarType>
void ComputeCrossProduct(
const vnl_vector <ScalarType> &v1,
const vnl_vector <ScalarType> &v2, vnl_vector <ScalarType> &resVec)
287 unsigned int NDimension = v1.size();
289 if (v2.size() != NDimension)
290 throw itk::ExceptionObject(__FILE__, __LINE__,
"Cross product can only be computed on same size vectors.",ITK_LOCATION);
292 resVec.set_size(NDimension);
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)
301 template <
class ScalarType>
void ComputeCrossProduct(
const std::vector <ScalarType> &v1,
const std::vector <ScalarType> &v2, std::vector <ScalarType> &resVec)
303 unsigned int NDimension = v1.size();
305 if (v2.size() != NDimension)
306 throw itk::ExceptionObject(__FILE__, __LINE__,
"Cross product can only be computed on same size vectors.",ITK_LOCATION);
308 resVec.resize(NDimension);
314 template <
class VectorType>
double ComputeNorm(
const VectorType &v)
326 template <
class VectorType>
void Normalize(
const VectorType &v,
const unsigned int NDimension, VectorType &resVec)
335 for (
unsigned int i = 0;i < NDimension;++i)
339 template <
class ScalarType,
unsigned int NDimension>
void Normalize(
const itk::Vector <ScalarType,NDimension> &v, itk::Vector <ScalarType,NDimension> &resVec)
344 template <
class ScalarType>
void Normalize(
const itk::VariableLengthVector <ScalarType> &v, itk::VariableLengthVector <ScalarType> &resVec)
346 unsigned int NDimension = v.GetSize();
350 template <
class ScalarType,
unsigned int NDimension>
void Normalize(
const itk::Point <ScalarType,NDimension> &v, itk::Point <ScalarType,NDimension> &resVec)
355 template <
class ScalarType>
void Normalize(
const vnl_vector <ScalarType> &v, vnl_vector <ScalarType> &resVec)
357 unsigned int NDimension = v.size();
361 template <
class ScalarType,
unsigned int NDimension>
void Normalize(
const vnl_vector_fixed <ScalarType, NDimension> &v, vnl_vector_fixed <ScalarType, NDimension> &resVec)
366 template <
class ScalarType>
void Normalize(
const std::vector <ScalarType> &v, std::vector <ScalarType> &resVec)
368 unsigned int NDimension = v.size();
376 template <
class VectorType>
void ComputeHouseholderVector(
const VectorType &inputVector, VectorType &outputVector,
double &beta,
unsigned int dimension)
379 outputVector[0] = 1.0;
380 for (
unsigned int i = 1;i < dimension;++i)
382 sigma += inputVector[i] * inputVector[i];
383 outputVector[i] = inputVector[i];
390 double mu = std::sqrt(inputVector[0] * inputVector[0] + sigma);
391 if (inputVector[0] <= 0.0)
392 outputVector[0] = inputVector[0] - mu;
394 outputVector[0] = - sigma / (inputVector[0] + mu);
396 beta = 2 * outputVector[0] * outputVector[0] / (sigma + outputVector[0] * outputVector[0]);
398 for (
unsigned int i = 1;i < dimension;++i)
399 outputVector[i] /= outputVector[0];
401 outputVector[0] = 1.0;
406 template <
class ScalarType>
void ComputeHouseholderVector(
const std::vector <ScalarType> &inputVector, std::vector <ScalarType> &outputVector,
double &beta)
408 unsigned int dimension = inputVector.size();
409 outputVector.resize(dimension);
422 template <
class VectorType>
double ComputeAngle(
const VectorType &v1,
const VectorType &v2)
434 return std::acos(t) * 180.0 / M_PI;
447 return std::acos(t) * 180.0 / M_PI;
450 template <
class VectorType>
void Revert(
const VectorType &v,
const unsigned int vSize, VectorType &resVec)
452 for (
unsigned int i = 0;i < vSize;++i)
456 template <
class ScalarType>
void Revert(
const std::vector <ScalarType> &v, std::vector<ScalarType> &resVec)
458 unsigned int length = v.size();
459 Revert(v, length, resVec);
462 template <
class ScalarType>
void Revert(
const itk::Point <ScalarType> &v, itk::Point <ScalarType> &resVec)
464 unsigned int length = v.GetPointDimension();
465 Revert(v, length, resVec);
468 template <
class ScalarType,
unsigned int NDimension>
469 void Revert(
const vnl_vector_fixed <ScalarType, NDimension> &v, vnl_vector_fixed <ScalarType, NDimension> &resVec)
471 Revert(v, NDimension, resVec);
479 if (resVec[2] >= 1.0)
484 else if (resVec[2] <= -1.0)
491 double theta = std::acos(resVec[2]);
492 double phi = std::atan2(resVec[1],resVec[0]);
511 double tmpVal = std::cos(theta);
512 if (std::abs(tmpVal) < 1e-4)
514 resVec[0] = std::cos(phi);
515 resVec[1] = std::sin(phi);
520 resVec[0] = std::sin(theta) * std::cos(phi);
521 resVec[1] = std::sin(theta) * std::sin(phi);
525 for (
unsigned int i = 0;i < 3;++i)
526 resVec[i] *= vectorNorm;
529 template <
class T1,
class T2,
class T3>
void ProjectOnOrthogonalPlane(
const std::vector <T1> &v,
const std::vector <T2> &normalVec, std::vector <T3> &resVec)
531 unsigned int length = v.size();
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);
536 resVec.resize(length);
540 for (
unsigned int i = 0;i < length;++i)
541 resVec[i] = v[i] - t * normalVec[i];
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)
548 unsigned int length = v.size();
551 throw itk::ExceptionObject(__FILE__, __LINE__,
"Rotation around axis requires 3D input vector.",ITK_LOCATION);
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);
557 fill(resVec.begin(),resVec.end(),0);
559 vnl_matrix <double> A(3,3);
561 A(0,1) = -normalVec[2];
562 A(0,2) = normalVec[1];
563 A(1,2) = -normalVec[0];
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];
571 vnl_matrix <double> R(3,3);
573 R.fill_diagonal(cos(phi));
575 R += N * (1.0 - cos(phi)) + A * sin(phi);
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];
582 template <
class Vector3DType,
class ScalarType>
void RotateAroundAxis(
const Vector3DType &v,
const ScalarType &phi,
const Vector3DType &normalVec, Vector3DType &resVec)
584 vnl_matrix_fixed <ScalarType,3,3> A;
586 A(0,1) = -normalVec[2];
587 A(0,2) = normalVec[1];
588 A(1,2) = -normalVec[0];
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];
596 vnl_matrix_fixed <ScalarType,3,3> R;
598 R.fill_diagonal(std::cos(phi));
600 R += N * (1.0 - std::cos(phi)) + A * std::sin(phi);
602 for (
unsigned int i = 0;i < 3;++i)
605 for (
unsigned int j = 0;j < 3;++j)
606 resVec[i] += R(i, j) * v[j];
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)