VTK  9.7.1
vtkMath.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-FileCopyrightText: Copyright 2011 Sandia Corporation
3 // SPDX-License-Identifier: LicenseRef-BSD-3-Clause-Sandia-USGov
24 #ifndef vtkMath_h
25 #define vtkMath_h
26 
27 #include "vtkCommonCoreModule.h" // For export macro
28 #include "vtkMathPrivate.hxx" // For Matrix meta-class helpers
29 #include "vtkMatrixUtilities.h" // For Matrix wrapping / mapping
30 #include "vtkObject.h"
31 #include "vtkSmartPointer.h" // For vtkSmartPointer.
32 #include "vtkTypeTraits.h" // For type traits
33 
34 #include "vtkMathConfigure.h" // For <cmath> and VTK_HAS_ISNAN etc.
35 
36 #include <algorithm> // for std::clamp
37 #include <cassert> // assert() in inline implementations.
38 #include <type_traits> // for type_traits
39 
40 #ifndef DBL_MIN
41 #define VTK_DBL_MIN 2.2250738585072014e-308
42 #else // DBL_MIN
43 #define VTK_DBL_MIN DBL_MIN
44 #endif // DBL_MIN
45 
46 #ifndef DBL_EPSILON
47 #define VTK_DBL_EPSILON 2.2204460492503131e-16
48 #else // DBL_EPSILON
49 #define VTK_DBL_EPSILON DBL_EPSILON
50 #endif // DBL_EPSILON
51 
52 #ifndef VTK_DBL_EPSILON
53 #ifndef DBL_EPSILON
54 #define VTK_DBL_EPSILON 2.2204460492503131e-16
55 #else // DBL_EPSILON
56 #define VTK_DBL_EPSILON DBL_EPSILON
57 #endif // DBL_EPSILON
58 #endif // VTK_DBL_EPSILON
59 
60 VTK_ABI_NAMESPACE_BEGIN
61 class vtkDataArray;
62 class vtkPoints;
63 class vtkMathInternal;
66 VTK_ABI_NAMESPACE_END
67 
68 namespace vtk_detail
69 {
70 VTK_ABI_NAMESPACE_BEGIN
71 // forward declaration
72 template <typename OutT>
73 void RoundDoubleToIntegralIfNecessary(double val, OutT* ret);
74 VTK_ABI_NAMESPACE_END
75 } // end namespace vtk_detail
76 
77 VTK_ABI_NAMESPACE_BEGIN
78 class VTKCOMMONCORE_EXPORT vtkMath : public vtkObject
79 {
80 public:
81  static vtkMath* New();
82  vtkTypeMacro(vtkMath, vtkObject);
83  void PrintSelf(ostream& os, vtkIndent indent) override;
84 
85 private:
86  template <class VectorT, class = void>
87  struct VectorImplementsSize : std::false_type
88  {
89  };
90 
91  template <class VectorT>
92  struct VectorImplementsSize<VectorT, decltype((void)std::declval<VectorT>().size(), void())>
93  : std::true_type
94  {
95  };
96 
100  template <class VectorT>
101  using EnableIfVectorImplementsSize =
103 
104 public:
113  static constexpr int DYNAMIC_VECTOR_SIZE() { return 0; }
114 
118  static constexpr double Pi() { return 3.141592653589793; }
119 
121 
124  static float RadiansFromDegrees(float degrees);
125  static double RadiansFromDegrees(double degrees);
127 
129 
132  static float DegreesFromRadians(float radians);
133  static double DegreesFromRadians(double radians);
135 
139 #if 1
140  static int Round(float f) { return static_cast<int>(f + (f >= 0.0 ? 0.5 : -0.5)); }
141  static int Round(double f) { return static_cast<int>(f + (f >= 0.0 ? 0.5 : -0.5)); }
142 #endif
143 
148  template <typename OutT>
149  static void RoundDoubleToIntegralIfNecessary(double val, OutT* ret)
150  {
151  // Can't specialize template methods in a template class, so we move the
152  // implementations to a external namespace.
154  }
155 
161  static int Floor(double x);
162 
168  static int Ceil(double x);
169 
175  static int CeilLog2(vtkTypeUInt64 x);
176 
181  template <class T>
182  static T Min(const T& a, const T& b);
183 
188  template <class T>
189  static T Max(const T& a, const T& b);
190 
194  static bool IsPowerOfTwo(vtkTypeUInt64 x);
195 
201  static int NearestPowerOfTwo(int x);
202 
207  static vtkTypeInt64 Factorial(int N);
208 
214  static vtkTypeInt64 Binomial(int m, int n);
215 
227  static int* BeginCombination(int m, int n);
228 
239  static int NextCombination(int m, int n, int* combination);
240 
244  static void FreeCombination(int* combination);
245 
261  static void RandomSeed(int s);
262 
274  static int GetSeed();
275 
289  static double Random();
290 
303  static double Random(double min, double max);
304 
317  static double Gaussian();
318 
331  static double Gaussian(double mean, double std);
332 
337  template <class VectorT1, class VectorT2>
338  static void Assign(const VectorT1& a, VectorT2&& b)
339  {
340  b[0] = a[0];
341  b[1] = a[1];
342  b[2] = a[2];
343  }
344 
348  static void Assign(const double a[3], double b[3]) { vtkMath::Assign<>(a, b); }
349 
353  static void Add(const float a[3], const float b[3], float c[3])
354  {
355  for (int i = 0; i < 3; ++i)
356  {
357  c[i] = a[i] + b[i];
358  }
359  }
360 
364  static void Add(const double a[3], const double b[3], double c[3])
365  {
366  for (int i = 0; i < 3; ++i)
367  {
368  c[i] = a[i] + b[i];
369  }
370  }
371 
377  template <class VectorT1, class VectorT2, class VectorT3>
378  static void Add(VectorT1&& a, VectorT2&& b, VectorT3& c)
379  {
380  for (int i = 0; i < 3; ++i)
381  {
382  c[i] = a[i] + b[i];
383  }
384  }
385 
389  static void Subtract(const float a[3], const float b[3], float c[3])
390  {
391  for (int i = 0; i < 3; ++i)
392  {
393  c[i] = a[i] - b[i];
394  }
395  }
396 
400  static void Subtract(const double a[3], const double b[3], double c[3])
401  {
402  for (int i = 0; i < 3; ++i)
403  {
404  c[i] = a[i] - b[i];
405  }
406  }
407 
413  template <class VectorT1, class VectorT2, class VectorT3>
414  static void Subtract(const VectorT1& a, const VectorT2& b, VectorT3&& c)
415  {
416  c[0] = a[0] - b[0];
417  c[1] = a[1] - b[1];
418  c[2] = a[2] - b[2];
419  }
420 
425  static void MultiplyScalar(float a[3], float s)
426  {
427  for (int i = 0; i < 3; ++i)
428  {
429  a[i] *= s;
430  }
431  }
432 
437  static void MultiplyScalar2D(float a[2], float s)
438  {
439  for (int i = 0; i < 2; ++i)
440  {
441  a[i] *= s;
442  }
443  }
444 
449  static void MultiplyScalar(double a[3], double s)
450  {
451  for (int i = 0; i < 3; ++i)
452  {
453  a[i] *= s;
454  }
455  }
456 
461  static void MultiplyScalar2D(double a[2], double s)
462  {
463  for (int i = 0; i < 2; ++i)
464  {
465  a[i] *= s;
466  }
467  }
468 
472  static float Dot(const float a[3], const float b[3])
473  {
474  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
475  }
476 
480  static double Dot(const double a[3], const double b[3])
481  {
482  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
483  }
484 
500  template <typename ReturnTypeT = double, typename TupleRangeT1, typename TupleRangeT2,
501  typename EnableT = typename std::conditional<!std::is_pointer<TupleRangeT1>::value &&
503  TupleRangeT1, TupleRangeT2>::type::value_type>
504  static ReturnTypeT Dot(const TupleRangeT1& a, const TupleRangeT2& b)
505  {
506  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
507  }
508 
512  static void Outer(const float a[3], const float b[3], float c[3][3])
513  {
514  for (int i = 0; i < 3; ++i)
515  {
516  for (int j = 0; j < 3; ++j)
517  {
518  c[i][j] = a[i] * b[j];
519  }
520  }
521  }
522 
526  static void Outer(const double a[3], const double b[3], double c[3][3])
527  {
528  for (int i = 0; i < 3; ++i)
529  {
530  for (int j = 0; j < 3; ++j)
531  {
532  c[i][j] = a[i] * b[j];
533  }
534  }
535  }
536 
542  template <class VectorT1, class VectorT2, class VectorT3>
543  static void Cross(VectorT1&& a, VectorT2&& b, VectorT3& c);
544 
549  static void Cross(const float a[3], const float b[3], float c[3]);
550 
555  static void Cross(const double a[3], const double b[3], double c[3]);
556 
558 
561  static float Norm(const float* x, int n);
562  static double Norm(const double* x, int n);
564 
568  static float Norm(const float v[3]) { return std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); }
569 
573  static double Norm(const double v[3])
574  {
575  return std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
576  }
577 
587  template <typename ReturnTypeT = double, typename TupleRangeT>
588  static ReturnTypeT SquaredNorm(const TupleRangeT& v)
589  {
590  return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
591  }
592 
597  static inline float Normalize(float v[3]);
598 
603  static inline double Normalize(double v[3]);
604 
606 
613  static void Perpendiculars(const double v1[3], double v2[3], double v3[3], double theta);
614  static void Perpendiculars(const float v1[3], float v2[3], float v3[3], double theta);
616 
618 
623  static bool ProjectVector(const float a[3], const float b[3], float projection[3]);
624  static bool ProjectVector(const double a[3], const double b[3], double projection[3]);
626 
628 
634  static bool ProjectVector2D(const float a[2], const float b[2], float projection[2]);
635  static bool ProjectVector2D(const double a[2], const double b[2], double projection[2]);
637 
653  template <typename ReturnTypeT = double, typename TupleRangeT1, typename TupleRangeT2,
654  typename EnableT = typename std::conditional<!std::is_pointer<TupleRangeT1>::value &&
656  TupleRangeT1, TupleRangeT2>::type::value_type>
657  static ReturnTypeT Distance2BetweenPoints(const TupleRangeT1& p1, const TupleRangeT2& p2);
658 
663  static float Distance2BetweenPoints(const float p1[3], const float p2[3]);
664 
669  static double Distance2BetweenPoints(const double p1[3], const double p2[3]);
670 
675  static double Distance2BetweenPoints2D(const double p1[2], const double p2[2]);
676 
680  static double AngleBetweenVectors(const double v1[3], const double v2[3]);
681 
685  static double SignedAngleBetweenVectors(
686  const double v1[3], const double v2[3], const double vn[3]);
687 
692  static double GaussianAmplitude(double variance, double distanceFromMean);
693 
698  static double GaussianAmplitude(double mean, double variance, double position);
699 
705  static double GaussianWeight(double variance, double distanceFromMean);
706 
712  static double GaussianWeight(double mean, double variance, double position);
713 
717  static float Dot2D(const float x[2], const float y[2]) { return x[0] * y[0] + x[1] * y[1]; }
718 
722  static double Dot2D(const double x[2], const double y[2]) { return x[0] * y[0] + x[1] * y[1]; }
723 
727  static void Outer2D(const float x[2], const float y[2], float A[2][2])
728  {
729  for (int i = 0; i < 2; ++i)
730  {
731  for (int j = 0; j < 2; ++j)
732  {
733  A[i][j] = x[i] * y[j];
734  }
735  }
736  }
737 
741  static void Outer2D(const double x[2], const double y[2], double A[2][2])
742  {
743  for (int i = 0; i < 2; ++i)
744  {
745  for (int j = 0; j < 2; ++j)
746  {
747  A[i][j] = x[i] * y[j];
748  }
749  }
750  }
751 
756  static float Norm2D(const float x[2]) { return std::sqrt(x[0] * x[0] + x[1] * x[1]); }
757 
762  static double Norm2D(const double x[2]) { return std::sqrt(x[0] * x[0] + x[1] * x[1]); }
763 
768  static float Normalize2D(float v[2]);
769 
774  static double Normalize2D(double v[2]);
775 
779  static float Determinant2x2(const float c1[2], const float c2[2])
780  {
781  return c1[0] * c2[1] - c2[0] * c1[1];
782  }
783 
785 
788  static double Determinant2x2(double a, double b, double c, double d) { return a * d - b * c; }
789  static double Determinant2x2(const double c1[2], const double c2[2])
790  {
791  return c1[0] * c2[1] - c2[0] * c1[1];
792  }
794 
796 
799  static void LUFactor3x3(float A[3][3], int index[3]);
800  static void LUFactor3x3(double A[3][3], int index[3]);
802 
804 
807  static void LUSolve3x3(const float A[3][3], const int index[3], float x[3]);
808  static void LUSolve3x3(const double A[3][3], const int index[3], double x[3]);
810 
812 
816  static void LinearSolve3x3(const float A[3][3], const float x[3], float y[3]);
817  static void LinearSolve3x3(const double A[3][3], const double x[3], double y[3]);
819 
821 
824  static void Multiply3x3(const float A[3][3], const float v[3], float u[3]);
825  static void Multiply3x3(const double A[3][3], const double v[3], double u[3]);
827 
829 
832  static void Multiply3x3(const float A[3][3], const float B[3][3], float C[3][3]);
833  static void Multiply3x3(const double A[3][3], const double B[3][3], double C[3][3]);
835 
859  template <int RowsT, int MidDimT, int ColsT,
860  class LayoutT1 = vtkMatrixUtilities::Layout::Identity,
861  class LayoutT2 = vtkMatrixUtilities::Layout::Identity, class MatrixT1, class MatrixT2,
862  class MatrixT3>
863  static void MultiplyMatrix(MatrixT1&& M1, MatrixT2&& M2, MatrixT3&& M3)
864  {
865  vtkMathPrivate::MultiplyMatrix<RowsT, MidDimT, ColsT, LayoutT1, LayoutT2>::Compute(
866  std::forward<MatrixT1>(M1), std::forward<MatrixT2>(M2), std::forward<MatrixT3>(M3));
867  }
868 
889  template <int RowsT, int ColsT, class LayoutT = vtkMatrixUtilities::Layout::Identity,
890  class MatrixT, class VectorT1, class VectorT2>
891  static void MultiplyMatrixWithVector(MatrixT&& M, VectorT1&& X, VectorT2&& Y)
892  {
893  vtkMathPrivate::MultiplyMatrix<RowsT, ColsT, 1, LayoutT>::Compute(
894  std::forward<MatrixT>(M), std::forward<VectorT1>(X), std::forward<VectorT2>(Y));
895  }
896 
902  template <class ScalarT, int SizeT, class VectorT1, class VectorT2,
904  static ScalarT Dot(VectorT1&& x, VectorT2&& y)
905  {
906  return vtkMathPrivate::ContractRowWithCol<ScalarT, 1, SizeT, 1, 0, 0,
907  vtkMatrixUtilities::Layout::Identity,
908  vtkMatrixUtilities::Layout::Transpose>::Compute(std::forward<VectorT1>(x),
909  std::forward<VectorT2>(y));
910  }
911 
918  template <class ScalarT, int SizeT, class VectorT1, class VectorT2,
920  class = EnableIfVectorImplementsSize<VectorT1>>
921  static ScalarT Dot(VectorT1&& x, VectorT2&& y)
922  {
923  ScalarT dot = 0.0;
924  using SizeType = decltype(std::declval<VectorT1>().size());
925  for (SizeType dim = 0; dim < x.size(); ++dim)
926  {
927  dot += x[dim] * y[dim];
928  }
929  return dot;
930  }
931 
939  template <int SizeT, class VectorT>
941  VectorT&& x)
942  {
944  return vtkMath::Dot<Scalar, SizeT>(std::forward<VectorT>(x), std::forward<VectorT>(x));
945  }
946 
963  template <int SizeT, class LayoutT = vtkMatrixUtilities::Layout::Identity, class MatrixT>
965  MatrixT&& M)
966  {
967  return vtkMathPrivate::Determinant<SizeT, LayoutT>::Compute(std::forward<MatrixT>(M));
968  }
969 
985  template <int SizeT, class LayoutT = vtkMatrixUtilities::Layout::Identity, class MatrixT1,
986  class MatrixT2>
987  static void InvertMatrix(MatrixT1&& M1, MatrixT2&& M2)
988  {
989  vtkMathPrivate::InvertMatrix<SizeT, LayoutT>::Compute(
990  std::forward<MatrixT1>(M1), std::forward<MatrixT2>(M2));
991  }
992 
1006  template <int RowsT, int ColsT, class LayoutT = vtkMatrixUtilities::Layout::Identity,
1007  class MatrixT, class VectorT1, class VectorT2>
1008  static void LinearSolve(MatrixT&& M, VectorT1&& x, VectorT2&& y)
1009  {
1010  vtkMathPrivate::LinearSolve<RowsT, ColsT, LayoutT>::Compute(
1011  std::forward<MatrixT>(M), std::forward<VectorT1>(x), std::forward<VectorT2>(y));
1012  }
1013 
1028  template <class ScalarT, int SizeT, class LayoutT = vtkMatrixUtilities::Layout::Identity,
1029  class VectorT1, class MatrixT, class VectorT2,
1031  static ScalarT Dot(VectorT1&& x, MatrixT&& M, VectorT2&& y)
1032  {
1033  ScalarT tmp[SizeT];
1034  vtkMathPrivate::MultiplyMatrix<SizeT, SizeT, 1, LayoutT>::Compute(
1035  std::forward<MatrixT>(M), std::forward<VectorT2>(y), tmp);
1036  return vtkMathPrivate::ContractRowWithCol<ScalarT, 1, SizeT, 1, 0, 0,
1037  vtkMatrixUtilities::Layout::Identity,
1038  vtkMatrixUtilities::Layout::Transpose>::Compute(std::forward<VectorT1>(x), tmp);
1039  }
1040 
1046  static void MultiplyMatrix(const double* const* A, const double* const* B, unsigned int rowA,
1047  unsigned int colA, unsigned int rowB, unsigned int colB, double** C);
1048 
1050 
1054  static void Transpose3x3(const float A[3][3], float AT[3][3]);
1055  static void Transpose3x3(const double A[3][3], double AT[3][3]);
1057 
1059 
1063  static void Invert3x3(const float A[3][3], float AI[3][3]);
1064  static void Invert3x3(const double A[3][3], double AI[3][3]);
1066 
1068 
1071  static void Identity3x3(float A[3][3]);
1072  static void Identity3x3(double A[3][3]);
1074 
1076 
1079  static double Determinant3x3(const float A[3][3]);
1080  static double Determinant3x3(const double A[3][3]);
1082 
1086  static float Determinant3x3(const float c1[3], const float c2[3], const float c3[3]);
1087 
1091  static double Determinant3x3(const double c1[3], const double c2[3], const double c3[3]);
1092 
1099  static double Determinant3x3(double a1, double a2, double a3, double b1, double b2, double b3,
1100  double c1, double c2, double c3);
1101 
1103 
1110  static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]);
1111  static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]);
1112  template <class QuaternionT, class MatrixT,
1113  class EnableT = typename std::enable_if<!vtkMatrixUtilities::MatrixIs2DArray<MatrixT>()>::type>
1114  static void QuaternionToMatrix3x3(QuaternionT&& q, MatrixT&& A);
1116 
1118 
1127  static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
1128  static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
1129  template <class MatrixT, class QuaternionT,
1130  class EnableT = typename std::enable_if<!vtkMatrixUtilities::MatrixIs2DArray<MatrixT>()>::type>
1131  static void Matrix3x3ToQuaternion(MatrixT&& A, QuaternionT&& q);
1133 
1135 
1141  static void MultiplyQuaternion(const float q1[4], const float q2[4], float q[4]);
1142  static void MultiplyQuaternion(const double q1[4], const double q2[4], double q[4]);
1144 
1146 
1150  static void RotateVectorByNormalizedQuaternion(const float v[3], const float q[4], float r[3]);
1151  static void RotateVectorByNormalizedQuaternion(const double v[3], const double q[4], double r[3]);
1153 
1155 
1159  static void RotateVectorByWXYZ(const float v[3], const float q[4], float r[3]);
1160  static void RotateVectorByWXYZ(const double v[3], const double q[4], double r[3]);
1162 
1164 
1169  static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
1170  static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
1172 
1174 
1180  static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
1181  static void Diagonalize3x3(const double A[3][3], double w[3], double V[3][3]);
1183 
1185 
1194  static void SingularValueDecomposition3x3(
1195  const float A[3][3], float U[3][3], float w[3], float VT[3][3]);
1196  static void SingularValueDecomposition3x3(
1197  const double A[3][3], double U[3][3], double w[3], double VT[3][3]);
1199 
1207  static vtkTypeBool SolveLinearSystemGEPP2x2(
1208  double a00, double a01, double a10, double a11, double b0, double b1, double& x0, double& x1);
1209 
1218  static vtkTypeBool SolveLinearSystem(double** A, double* x, int size);
1219 
1226  static vtkTypeBool InvertMatrix(double** A, double** AI, int size);
1227 
1233  static vtkTypeBool InvertMatrix(
1234  double** A, double** AI, int size, int* tmp1Size, double* tmp2Size);
1235 
1258  static vtkTypeBool LUFactorLinearSystem(double** A, int* index, int size);
1259 
1265  static vtkTypeBool LUFactorLinearSystem(double** A, int* index, int size, double* tmpSize);
1266 
1275  static void LUSolveLinearSystem(double** A, int* index, double* x, int size);
1276 
1285  static double EstimateMatrixCondition(const double* const* A, int size);
1286 
1288 
1296  static vtkTypeBool Jacobi(float** a, float* w, float** v);
1297  static vtkTypeBool Jacobi(double** a, double* w, double** v);
1299 
1301 
1310  static vtkTypeBool JacobiN(float** a, int n, float* w, float** v);
1311  static vtkTypeBool JacobiN(double** a, int n, double* w, double** v);
1313 
1327  static vtkTypeBool SolveHomogeneousLeastSquares(
1328  int numberOfSamples, double** xt, int xOrder, double** mt);
1329 
1344  static vtkTypeBool SolveLeastSquares(int numberOfSamples, double** xt, int xOrder, double** yt,
1345  int yOrder, double** mt, int checkHomogeneous = 1);
1346 
1348 
1355  static void RGBToHSV(const float rgb[3], float hsv[3])
1356  {
1357  RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
1358  }
1359  static void RGBToHSV(float r, float g, float b, float* h, float* s, float* v);
1360  static void RGBToHSV(const double rgb[3], double hsv[3])
1361  {
1362  RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
1363  }
1364  static void RGBToHSV(double r, double g, double b, double* h, double* s, double* v);
1366 
1368 
1375  static void HSVToRGB(const float hsv[3], float rgb[3])
1376  {
1377  HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
1378  }
1379  static void HSVToRGB(float h, float s, float v, float* r, float* g, float* b);
1380  static void HSVToRGB(const double hsv[3], double rgb[3])
1381  {
1382  HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
1383  }
1384  static void HSVToRGB(double h, double s, double v, double* r, double* g, double* b);
1386 
1388 
1392  static void ProLabToXYZ(const double prolab[3], double xyz[3])
1393  {
1394  ProLabToXYZ(prolab[0], prolab[1], prolab[2], xyz + 0, xyz + 1, xyz + 2);
1395  }
1396  static void ProLabToXYZ(double L, double a, double b, double* x, double* y, double* z);
1398 
1400 
1404  static void XYZToProLab(const double xyz[3], double prolab[3])
1405  {
1406  XYZToProLab(xyz[0], xyz[1], xyz[2], prolab + 0, prolab + 1, prolab + 2);
1407  }
1408  static void XYZToProLab(double x, double y, double z, double* L, double* a, double* b);
1410 
1412 
1415  static void LabToXYZ(const double lab[3], double xyz[3])
1416  {
1417  LabToXYZ(lab[0], lab[1], lab[2], xyz + 0, xyz + 1, xyz + 2);
1418  }
1419  static void LabToXYZ(double L, double a, double b, double* x, double* y, double* z);
1421 
1423 
1426  static void XYZToLab(const double xyz[3], double lab[3])
1427  {
1428  XYZToLab(xyz[0], xyz[1], xyz[2], lab + 0, lab + 1, lab + 2);
1429  }
1430  static void XYZToLab(double x, double y, double z, double* L, double* a, double* b);
1432 
1434 
1437  static void XYZToRGB(const double xyz[3], double rgb[3])
1438  {
1439  XYZToRGB(xyz[0], xyz[1], xyz[2], rgb + 0, rgb + 1, rgb + 2);
1440  }
1441  static void XYZToRGB(double x, double y, double z, double* r, double* g, double* b);
1443 
1445 
1448  static void RGBToXYZ(const double rgb[3], double xyz[3])
1449  {
1450  RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz + 0, xyz + 1, xyz + 2);
1451  }
1452  static void RGBToXYZ(double r, double g, double b, double* x, double* y, double* z);
1454 
1456 
1463  static void RGBToLab(const double rgb[3], double lab[3])
1464  {
1465  RGBToLab(rgb[0], rgb[1], rgb[2], lab + 0, lab + 1, lab + 2);
1466  }
1467  static void RGBToLab(double red, double green, double blue, double* L, double* a, double* b);
1469 
1471 
1474  static void ProLabToRGB(const double prolab[3], double rgb[3])
1475  {
1476  ProLabToRGB(prolab[0], prolab[1], prolab[2], rgb + 0, rgb + 1, rgb + 2);
1477  }
1478  static void ProLabToRGB(double L, double a, double b, double* red, double* green, double* blue);
1480 
1482 
1489  static void RGBToProLab(const double rgb[3], double prolab[3])
1490  {
1491  RGBToProLab(rgb[0], rgb[1], rgb[2], prolab + 0, prolab + 1, prolab + 2);
1492  }
1493  static void RGBToProLab(double red, double green, double blue, double* L, double* a, double* b);
1495 
1497 
1500  static void LabToRGB(const double lab[3], double rgb[3])
1501  {
1502  LabToRGB(lab[0], lab[1], lab[2], rgb + 0, rgb + 1, rgb + 2);
1503  }
1504  static void LabToRGB(double L, double a, double b, double* red, double* green, double* blue);
1506 
1508 
1511  static void UninitializeBounds(double bounds[6])
1512  {
1513  bounds[0] = 1.0;
1514  bounds[1] = -1.0;
1515  bounds[2] = 1.0;
1516  bounds[3] = -1.0;
1517  bounds[4] = 1.0;
1518  bounds[5] = -1.0;
1519  }
1521 
1523 
1526  static vtkTypeBool AreBoundsInitialized(const double bounds[6])
1527  {
1528  if (bounds[1] - bounds[0] < 0.0)
1529  {
1530  return 0;
1531  }
1532  return 1;
1533  }
1535 
1540  template <class T>
1541  static T ClampValue(const T& value, const T& min, const T& max);
1542 
1544 
1548  static void ClampValue(double* value, const double range[2]);
1549  static void ClampValue(double value, const double range[2], double* clamped_value);
1550  static void ClampValues(double* values, int nb_values, const double range[2]);
1551  static void ClampValues(
1552  const double* values, int nb_values, const double range[2], double* clamped_values);
1554 
1561  static double ClampAndNormalizeValue(double value, const double range[2]);
1562 
1567  template <class T1, class T2>
1568  static void TensorFromSymmetricTensor(const T1 symmTensor[6], T2 tensor[9]);
1569 
1575  template <class T>
1576  static void TensorFromSymmetricTensor(T tensor[9]);
1577 
1586  static int GetScalarTypeFittingRange(
1587  double range_min, double range_max, double scale = 1.0, double shift = 0.0);
1588 
1597  static vtkTypeBool GetAdjustedScalarRange(vtkDataArray* array, int comp, double range[2]);
1598 
1603  static vtkTypeBool ExtentIsWithinOtherExtent(const int extent1[6], const int extent2[6]);
1604 
1610  static vtkTypeBool BoundsIsWithinOtherBounds(
1611  const double bounds1[6], const double bounds2[6], const double delta[3]);
1612 
1618  static vtkTypeBool PointIsWithinBounds(
1619  const double point[3], const double bounds[6], const double delta[3]);
1620 
1630  static int PlaneIntersectsAABB(
1631  const double bounds[6], const double normal[3], const double point[3]);
1632 
1642  static double Solve3PointCircle(
1643  const double p1[3], const double p2[3], const double p3[3], double center[3]);
1644 
1648  static double Inf();
1649 
1653  static double NegInf();
1654 
1658  static double Nan();
1659 
1663  static vtkTypeBool IsInf(double x);
1664 
1668  static inline vtkTypeBool IsNan(double x);
1669 
1674  static bool IsFinite(double x);
1675 
1680  static int QuadraticRoot(double a, double b, double c, double min, double max, double* u);
1681 
1687  static vtkIdType ComputeGCD(vtkIdType m, vtkIdType n) { return (n ? ComputeGCD(n, m % n) : m); }
1688 
1692  enum class ConvolutionMode
1693  {
1694  FULL,
1695  SAME,
1696  VALID
1697  };
1698 
1721  template <class Iter1, class Iter2, class Iter3>
1722  static void Convolve1D(Iter1 beginSample, Iter1 endSample, Iter2 beginKernel, Iter2 endKernel,
1723  Iter3 beginOut, Iter3 endOut, ConvolutionMode mode = ConvolutionMode::FULL)
1724  {
1725  int sampleSize = std::distance(beginSample, endSample);
1726  int kernelSize = std::distance(beginKernel, endKernel);
1727  int outSize = std::distance(beginOut, endOut);
1728 
1729  if (sampleSize <= 0 || kernelSize <= 0 || outSize <= 0)
1730  {
1731  return;
1732  }
1733 
1734  int begin = 0;
1735  int end = outSize;
1736 
1737  switch (mode)
1738  {
1739  case ConvolutionMode::SAME:
1740  begin = static_cast<int>(std::ceil((std::min)(sampleSize, kernelSize) / 2.0)) - 1;
1741  end = begin + (std::max)(sampleSize, kernelSize);
1742  break;
1743  case ConvolutionMode::VALID:
1744  begin = (std::min)(sampleSize, kernelSize) - 1;
1745  end = begin + std::abs(sampleSize - kernelSize) + 1;
1746  break;
1747  case ConvolutionMode::FULL:
1748  default:
1749  break;
1750  }
1751 
1752  for (int i = begin; i < end; i++)
1753  {
1754  Iter3 out = beginOut + i - begin;
1755  *out = 0;
1756  for (int j = (std::max)(i - sampleSize + 1, 0); j <= (std::min)(i, kernelSize - 1); j++)
1757  {
1758  *out += *(beginSample + (i - j)) * *(beginKernel + j);
1759  }
1760  }
1761  }
1762 
1767  static void GetPointAlongLine(double result[3], double p1[3], double p2[3], const double offset)
1768  {
1769  double directionVector[3] = { p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2] };
1770  vtkMath::Normalize(directionVector);
1771  result[0] = p2[0] + (offset * directionVector[0]);
1772  result[1] = p2[1] + (offset * directionVector[1]);
1773  result[2] = p2[2] + (offset * directionVector[2]);
1774  }
1775 
1776 protected:
1777  vtkMath() = default;
1778  ~vtkMath() override = default;
1779 
1781 
1782 private:
1783  vtkMath(const vtkMath&) = delete;
1784  void operator=(const vtkMath&) = delete;
1785 };
1786 
1787 //----------------------------------------------------------------------------
1788 inline float vtkMath::RadiansFromDegrees(float x)
1789 {
1790  return x * 0.017453292f;
1791 }
1792 
1793 //----------------------------------------------------------------------------
1794 inline double vtkMath::RadiansFromDegrees(double x)
1795 {
1796  return x * 0.017453292519943295;
1797 }
1798 
1799 //----------------------------------------------------------------------------
1800 inline float vtkMath::DegreesFromRadians(float x)
1801 {
1802  return x * 57.2957795131f;
1803 }
1804 
1805 //----------------------------------------------------------------------------
1806 inline double vtkMath::DegreesFromRadians(double x)
1807 {
1808  return x * 57.29577951308232;
1809 }
1810 
1811 //----------------------------------------------------------------------------
1812 inline bool vtkMath::IsPowerOfTwo(vtkTypeUInt64 x)
1813 {
1814  return ((x != 0) & ((x & (x - 1)) == 0));
1815 }
1816 
1817 //----------------------------------------------------------------------------
1818 // Credit goes to Peter Hart and William Lewis on comp.lang.python 1997
1820 {
1821  unsigned int z = static_cast<unsigned int>(((x > 0) ? x - 1 : 0));
1822  z |= z >> 1;
1823  z |= z >> 2;
1824  z |= z >> 4;
1825  z |= z >> 8;
1826  z |= z >> 16;
1827  return static_cast<int>(z + 1);
1828 }
1829 
1830 //----------------------------------------------------------------------------
1831 // Modify the trunc() operation provided by static_cast<int>() to get floor(),
1832 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
1833 inline int vtkMath::Floor(double x)
1834 {
1835  int i = static_cast<int>(x);
1836  return i - (i > x);
1837 }
1838 
1839 //----------------------------------------------------------------------------
1840 // Modify the trunc() operation provided by static_cast<int>() to get ceil(),
1841 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
1842 inline int vtkMath::Ceil(double x)
1843 {
1844  int i = static_cast<int>(x);
1845  return i + (i < x);
1846 }
1847 
1848 //----------------------------------------------------------------------------
1849 template <class T>
1850 inline T vtkMath::Min(const T& a, const T& b)
1851 {
1852  return (b <= a ? b : a);
1853 }
1854 
1855 //----------------------------------------------------------------------------
1856 template <class T>
1857 inline T vtkMath::Max(const T& a, const T& b)
1858 {
1859  return (b > a ? b : a);
1860 }
1861 
1862 //----------------------------------------------------------------------------
1863 float vtkMath::Normalize(float v[3])
1864 {
1865  float den = vtkMath::Norm(v);
1866  if (den != 0.0)
1867  {
1868  for (int i = 0; i < 3; ++i)
1869  {
1870  v[i] /= den;
1871  }
1872  }
1873  return den;
1874 }
1875 
1876 //----------------------------------------------------------------------------
1877 double vtkMath::Normalize(double v[3])
1878 {
1879  double den = vtkMath::Norm(v);
1880  if (den != 0.0)
1881  {
1882  for (int i = 0; i < 3; ++i)
1883  {
1884  v[i] /= den;
1885  }
1886  }
1887  return den;
1888 }
1889 
1890 //----------------------------------------------------------------------------
1891 inline float vtkMath::Normalize2D(float v[2])
1892 {
1893  float den = vtkMath::Norm2D(v);
1894  if (den != 0.0)
1895  {
1896  for (int i = 0; i < 2; ++i)
1897  {
1898  v[i] /= den;
1899  }
1900  }
1901  return den;
1902 }
1903 
1904 //----------------------------------------------------------------------------
1905 inline double vtkMath::Normalize2D(double v[2])
1906 {
1907  double den = vtkMath::Norm2D(v);
1908  if (den != 0.0)
1909  {
1910  for (int i = 0; i < 2; ++i)
1911  {
1912  v[i] /= den;
1913  }
1914  }
1915  return den;
1916 }
1917 
1918 //----------------------------------------------------------------------------
1919 inline float vtkMath::Determinant3x3(const float c1[3], const float c2[3], const float c3[3])
1920 {
1921  return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
1922  c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
1923 }
1924 
1925 //----------------------------------------------------------------------------
1926 inline double vtkMath::Determinant3x3(const double c1[3], const double c2[3], const double c3[3])
1927 {
1928  return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
1929  c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
1930 }
1931 
1932 //----------------------------------------------------------------------------
1934  double a1, double a2, double a3, double b1, double b2, double b3, double c1, double c2, double c3)
1935 {
1936  return (a1 * vtkMath::Determinant2x2(b2, b3, c2, c3) -
1937  b1 * vtkMath::Determinant2x2(a2, a3, c2, c3) + c1 * vtkMath::Determinant2x2(a2, a3, b2, b3));
1938 }
1939 
1940 //----------------------------------------------------------------------------
1941 inline float vtkMath::Distance2BetweenPoints(const float p1[3], const float p2[3])
1942 {
1943  return ((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]) +
1944  (p1[2] - p2[2]) * (p1[2] - p2[2]));
1945 }
1946 
1947 //----------------------------------------------------------------------------
1948 inline double vtkMath::Distance2BetweenPoints(const double p1[3], const double p2[3])
1949 {
1950  return ((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]) +
1951  (p1[2] - p2[2]) * (p1[2] - p2[2]));
1952 }
1953 
1954 //----------------------------------------------------------------------------
1955 template <typename ReturnTypeT, typename TupleRangeT1, typename TupleRangeT2, typename EnableT>
1956 inline ReturnTypeT vtkMath::Distance2BetweenPoints(const TupleRangeT1& p1, const TupleRangeT2& p2)
1957 {
1958  return ((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]) +
1959  (p1[2] - p2[2]) * (p1[2] - p2[2]));
1960 }
1961 
1962 //------------------------------------------------------------------------------
1963 inline double vtkMath::Distance2BetweenPoints2D(const double p1[2], const double p2[2])
1964 {
1965  return ((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]));
1966 }
1967 
1968 //----------------------------------------------------------------------------
1969 template <class VectorT1, class VectorT2, class VectorT3>
1970 void vtkMath::Cross(VectorT1&& a, VectorT2&& b, VectorT3& c)
1971 {
1973  ValueType Cx = a[1] * b[2] - a[2] * b[1];
1974  ValueType Cy = a[2] * b[0] - a[0] * b[2];
1975  ValueType Cz = a[0] * b[1] - a[1] * b[0];
1976  c[0] = Cx;
1977  c[1] = Cy;
1978  c[2] = Cz;
1979 }
1980 
1981 //----------------------------------------------------------------------------
1982 // Cross product of two 3-vectors. Result (a x b) is stored in c[3].
1983 inline void vtkMath::Cross(const float a[3], const float b[3], float c[3])
1984 {
1985  float Cx = a[1] * b[2] - a[2] * b[1];
1986  float Cy = a[2] * b[0] - a[0] * b[2];
1987  float Cz = a[0] * b[1] - a[1] * b[0];
1988  c[0] = Cx;
1989  c[1] = Cy;
1990  c[2] = Cz;
1991 }
1992 
1993 //----------------------------------------------------------------------------
1994 // Cross product of two 3-vectors. Result (a x b) is stored in c[3].
1995 inline void vtkMath::Cross(const double a[3], const double b[3], double c[3])
1996 {
1997  double Cx = a[1] * b[2] - a[2] * b[1];
1998  double Cy = a[2] * b[0] - a[0] * b[2];
1999  double Cz = a[0] * b[1] - a[1] * b[0];
2000  c[0] = Cx;
2001  c[1] = Cy;
2002  c[2] = Cz;
2003 }
2004 
2005 //----------------------------------------------------------------------------
2006 template <class T>
2007 inline double vtkDeterminant3x3(const T A[3][3])
2008 {
2009  return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] + A[2][0] * A[0][1] * A[1][2] -
2010  A[0][0] * A[2][1] * A[1][2] - A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2];
2011 }
2012 
2013 //----------------------------------------------------------------------------
2014 inline double vtkMath::Determinant3x3(const float A[3][3])
2015 {
2016  return vtkDeterminant3x3(A);
2017 }
2018 
2019 //----------------------------------------------------------------------------
2020 inline double vtkMath::Determinant3x3(const double A[3][3])
2021 {
2022  return vtkDeterminant3x3(A);
2023 }
2024 
2025 //----------------------------------------------------------------------------
2026 template <class T>
2027 inline T vtkMath::ClampValue(const T& value, const T& min, const T& max)
2028 {
2029  assert("pre: valid_range" && min <= max);
2030  return std::clamp(value, min, max);
2031 }
2032 
2033 //----------------------------------------------------------------------------
2034 inline void vtkMath::ClampValue(double* value, const double range[2])
2035 {
2036  if (value && range)
2037  {
2038  assert("pre: valid_range" && range[0] <= range[1]);
2039 
2040  *value = vtkMath::ClampValue(*value, range[0], range[1]);
2041  }
2042 }
2043 
2044 //----------------------------------------------------------------------------
2045 inline void vtkMath::ClampValue(double value, const double range[2], double* clamped_value)
2046 {
2047  if (range && clamped_value)
2048  {
2049  assert("pre: valid_range" && range[0] <= range[1]);
2050 
2051  *clamped_value = vtkMath::ClampValue(value, range[0], range[1]);
2052  }
2053 }
2054 
2055 // ---------------------------------------------------------------------------
2056 inline double vtkMath::ClampAndNormalizeValue(double value, const double range[2])
2057 {
2058  assert("pre: valid_range" && range[0] <= range[1]);
2059 
2060  double result;
2061  if (range[0] == range[1])
2062  {
2063  result = 0.0;
2064  }
2065  else
2066  {
2067  // clamp
2068  result = vtkMath::ClampValue(value, range[0], range[1]);
2069 
2070  // normalize
2071  result = (result - range[0]) / (range[1] - range[0]);
2072  }
2073 
2074  assert("post: valid_result" && result >= 0.0 && result <= 1.0);
2075 
2076  return result;
2077 }
2078 
2079 //-----------------------------------------------------------------------------
2080 template <class T1, class T2>
2081 inline void vtkMath::TensorFromSymmetricTensor(const T1 symmTensor[9], T2 tensor[9])
2082 {
2083  for (int i = 0; i < 3; ++i)
2084  {
2085  tensor[4 * i] = symmTensor[i];
2086  }
2087  tensor[1] = tensor[3] = symmTensor[3];
2088  tensor[2] = tensor[6] = symmTensor[5];
2089  tensor[5] = tensor[7] = symmTensor[4];
2090 }
2091 
2092 //-----------------------------------------------------------------------------
2093 template <class T>
2094 inline void vtkMath::TensorFromSymmetricTensor(T tensor[9])
2095 {
2096  tensor[6] = tensor[5]; // XZ
2097  tensor[7] = tensor[4]; // YZ
2098  tensor[8] = tensor[2]; // ZZ
2099  tensor[4] = tensor[1]; // YY
2100  tensor[5] = tensor[7]; // YZ
2101  tensor[2] = tensor[6]; // XZ
2102  tensor[1] = tensor[3]; // XY
2103 }
2104 VTK_ABI_NAMESPACE_END
2105 
2106 namespace
2107 {
2108 template <class QuaternionT, class MatrixT>
2109 inline void vtkQuaternionToMatrix3x3(QuaternionT&& quat, MatrixT&& A)
2110 {
2112 
2113  Scalar ww = quat[0] * quat[0];
2114  Scalar wx = quat[0] * quat[1];
2115  Scalar wy = quat[0] * quat[2];
2116  Scalar wz = quat[0] * quat[3];
2117 
2118  Scalar xx = quat[1] * quat[1];
2119  Scalar yy = quat[2] * quat[2];
2120  Scalar zz = quat[3] * quat[3];
2121 
2122  Scalar xy = quat[1] * quat[2];
2123  Scalar xz = quat[1] * quat[3];
2124  Scalar yz = quat[2] * quat[3];
2125 
2126  Scalar rr = xx + yy + zz;
2127  // normalization factor, just in case quaternion was not normalized
2128  Scalar f = 1 / (ww + rr);
2129  Scalar s = (ww - rr) * f;
2130  f *= 2;
2131 
2133 
2134  MatrixT& Ar = A;
2135  Wrapper::template Get<0, 0>(Ar) = xx * f + s;
2136  Wrapper::template Get<1, 0>(Ar) = (xy + wz) * f;
2137  Wrapper::template Get<2, 0>(Ar) = (xz - wy) * f;
2138 
2139  Wrapper::template Get<0, 1>(Ar) = (xy - wz) * f;
2140  Wrapper::template Get<1, 1>(Ar) = yy * f + s;
2141  Wrapper::template Get<2, 1>(Ar) = (yz + wx) * f;
2142 
2143  Wrapper::template Get<0, 2>(Ar) = (xz + wy) * f;
2144  Wrapper::template Get<1, 2>(Ar) = (yz - wx) * f;
2145  Wrapper::template Get<2, 2>(Ar) = zz * f + s;
2146 }
2147 } // anonymous namespace
2148 
2149 VTK_ABI_NAMESPACE_BEGIN
2150 //------------------------------------------------------------------------------
2151 inline void vtkMath::QuaternionToMatrix3x3(const float quat[4], float A[3][3])
2152 {
2153  vtkQuaternionToMatrix3x3(quat, A);
2154 }
2155 
2156 //------------------------------------------------------------------------------
2157 inline void vtkMath::QuaternionToMatrix3x3(const double quat[4], double A[3][3])
2158 {
2159  vtkQuaternionToMatrix3x3(quat, A);
2160 }
2161 
2162 //-----------------------------------------------------------------------------
2163 template <class QuaternionT, class MatrixT, class EnableT>
2164 inline void vtkMath::QuaternionToMatrix3x3(QuaternionT&& q, MatrixT&& A)
2165 {
2166  vtkQuaternionToMatrix3x3(std::forward<QuaternionT>(q), std::forward<MatrixT>(A));
2167 }
2168 VTK_ABI_NAMESPACE_END
2169 
2170 namespace
2171 {
2172 //------------------------------------------------------------------------------
2173 // The solution is based on
2174 // Berthold K. P. Horn (1987),
2175 // "Closed-form solution of absolute orientation using unit quaternions,"
2176 // Journal of the Optical Society of America A, 4:629-642
2177 template <class MatrixT, class QuaternionT>
2178 inline void vtkMatrix3x3ToQuaternion(MatrixT&& A, QuaternionT&& quat)
2179 {
2181 
2182  Scalar N[4][4];
2183 
2185 
2186  MatrixT& Ar = A;
2187 
2188  // on-diagonal elements
2189  N[0][0] = Wrapper::template Get<0, 0>(Ar) + Wrapper::template Get<1, 1>(Ar) +
2190  Wrapper::template Get<2, 2>(Ar);
2191  N[1][1] = Wrapper::template Get<0, 0>(Ar) - Wrapper::template Get<1, 1>(Ar) -
2192  Wrapper::template Get<2, 2>(Ar);
2193  N[2][2] = -Wrapper::template Get<0, 0>(Ar) + Wrapper::template Get<1, 1>(Ar) -
2194  Wrapper::template Get<2, 2>(Ar);
2195  N[3][3] = -Wrapper::template Get<0, 0>(Ar) - Wrapper::template Get<1, 1>(Ar) +
2196  Wrapper::template Get<2, 2>(Ar);
2197 
2198  // off-diagonal elements
2199  N[0][1] = N[1][0] = Wrapper::template Get<2, 1>(Ar) - Wrapper::template Get<1, 2>(Ar);
2200  N[0][2] = N[2][0] = Wrapper::template Get<0, 2>(Ar) - Wrapper::template Get<2, 0>(Ar);
2201  N[0][3] = N[3][0] = Wrapper::template Get<1, 0>(Ar) - Wrapper::template Get<0, 1>(Ar);
2202 
2203  N[1][2] = N[2][1] = Wrapper::template Get<1, 0>(Ar) + Wrapper::template Get<0, 1>(Ar);
2204  N[1][3] = N[3][1] = Wrapper::template Get<0, 2>(Ar) + Wrapper::template Get<2, 0>(Ar);
2205  N[2][3] = N[3][2] = Wrapper::template Get<2, 1>(Ar) + Wrapper::template Get<1, 2>(Ar);
2206 
2207  Scalar eigenvectors[4][4], eigenvalues[4];
2208 
2209  // convert into format that JacobiN can use,
2210  // then use Jacobi to find eigenvalues and eigenvectors
2211  Scalar *NTemp[4], *eigenvectorsTemp[4];
2212  for (int i = 0; i < 4; ++i)
2213  {
2214  NTemp[i] = N[i];
2215  eigenvectorsTemp[i] = eigenvectors[i];
2216  }
2217  vtkMath::JacobiN(NTemp, 4, eigenvalues, eigenvectorsTemp);
2218 
2219  // the first eigenvector is the one we want
2220  quat[0] = eigenvectors[0][0];
2221  quat[1] = eigenvectors[1][0];
2222  quat[2] = eigenvectors[2][0];
2223  quat[3] = eigenvectors[3][0];
2224 }
2225 } // anonymous namespace
2226 
2227 VTK_ABI_NAMESPACE_BEGIN
2228 //------------------------------------------------------------------------------
2229 inline void vtkMath::Matrix3x3ToQuaternion(const float A[3][3], float quat[4])
2230 {
2231  vtkMatrix3x3ToQuaternion(A, quat);
2232 }
2233 
2234 //------------------------------------------------------------------------------
2235 inline void vtkMath::Matrix3x3ToQuaternion(const double A[3][3], double quat[4])
2236 {
2237  vtkMatrix3x3ToQuaternion(A, quat);
2238 }
2239 
2240 //-----------------------------------------------------------------------------
2241 template <class MatrixT, class QuaternionT, class EnableT>
2242 inline void vtkMath::Matrix3x3ToQuaternion(MatrixT&& A, QuaternionT&& q)
2243 {
2244  vtkMatrix3x3ToQuaternion(std::forward<MatrixT>(A), std::forward<QuaternionT>(q));
2245 }
2246 VTK_ABI_NAMESPACE_END
2247 
2248 namespace vtk_detail
2249 {
2250 VTK_ABI_NAMESPACE_BEGIN
2251 // Can't specialize templates inside a template class, so we move the impl here.
2252 template <typename OutT>
2253 void RoundDoubleToIntegralIfNecessary(double val, OutT* ret)
2254 { // OutT is integral -- clamp and round
2255  if (!vtkMath::IsNan(val))
2256  {
2257  double min = static_cast<double>(vtkTypeTraits<OutT>::Min());
2258  double max = static_cast<double>(vtkTypeTraits<OutT>::Max());
2259  val = vtkMath::ClampValue(val, min, max);
2260  *ret = static_cast<OutT>((val >= 0.0) ? (val + 0.5) : (val - 0.5));
2261  }
2262  else
2263  *ret = 0;
2264 }
2265 template <>
2266 inline void RoundDoubleToIntegralIfNecessary(double val, double* retVal)
2267 { // OutT is double: passthrough
2268  *retVal = val;
2269 }
2270 template <>
2271 inline void RoundDoubleToIntegralIfNecessary(double val, float* retVal)
2272 { // OutT is float -- just clamp (as doubles, then the cast to float is well-defined.)
2273  if (!vtkMath::IsNan(val))
2274  {
2275  double min = static_cast<double>(vtkTypeTraits<float>::Min());
2276  double max = static_cast<double>(vtkTypeTraits<float>::Max());
2277  val = vtkMath::ClampValue(val, min, max);
2278  }
2279 
2280  *retVal = static_cast<float>(val);
2281 }
2282 VTK_ABI_NAMESPACE_END
2283 } // end namespace vtk_detail
2284 
2285 VTK_ABI_NAMESPACE_BEGIN
2286 //-----------------------------------------------------------------------------
2287 #if defined(VTK_HAS_ISINF) || defined(VTK_HAS_STD_ISINF)
2288 #define VTK_MATH_ISINF_IS_INLINE
2289 inline vtkTypeBool vtkMath::IsInf(double x)
2290 {
2291 #if defined(VTK_HAS_STD_ISINF)
2292  return std::isinf(x);
2293 #else
2294  return (isinf(x) != 0); // Force conversion to bool
2295 #endif
2296 }
2297 #endif
2298 
2299 //-----------------------------------------------------------------------------
2300 #if defined(VTK_HAS_ISNAN) || defined(VTK_HAS_STD_ISNAN)
2301 #define VTK_MATH_ISNAN_IS_INLINE
2302 vtkTypeBool vtkMath::IsNan(double x)
2303 {
2304 #if defined(VTK_HAS_STD_ISNAN)
2305  return std::isnan(x);
2306 #else
2307  return (isnan(x) != 0); // Force conversion to bool
2308 #endif
2309 }
2310 #endif
2311 
2312 //-----------------------------------------------------------------------------
2313 #if defined(VTK_HAS_ISFINITE) || defined(VTK_HAS_STD_ISFINITE) || defined(VTK_HAS_FINITE)
2314 #define VTK_MATH_ISFINITE_IS_INLINE
2315 inline bool vtkMath::IsFinite(double x)
2316 {
2317 #if defined(VTK_HAS_STD_ISFINITE)
2318  return std::isfinite(x);
2319 #elif defined(VTK_HAS_ISFINITE)
2320  return (isfinite(x) != 0); // Force conversion to bool
2321 #else
2322  return (finite(x) != 0); // Force conversion to bool
2323 #endif
2324 }
2325 #endif
2326 
2327 VTK_ABI_NAMESPACE_END
2328 #endif
static void MultiplyScalar2D(float a[2], float s)
Multiplies a 2-vector by a scalar (float version).
Definition: vtkMath.h:437
static bool IsFinite(double x)
Test if a number has finite value i.e.
static float Dot2D(const float x[2], const float y[2])
Dot product of two 2-vectors.
Definition: vtkMath.h:717
static float Dot(const float a[3], const float b[3])
Dot product of two 3-vectors (float version).
Definition: vtkMath.h:472
static void ProLabToRGB(const double prolab[3], double rgb[3])
Convert color from the ProLab system to RGB.
Definition: vtkMath.h:1474
static void TensorFromSymmetricTensor(const T1 symmTensor[6], T2 tensor[9])
Convert a 6-Component symmetric tensor into a 9-Component tensor, no allocation performed.
static void GetPointAlongLine(double result[3], double p1[3], double p2[3], const double offset)
Get the coordinates of a point along a line defined by p1 and p2, at a specified offset relative to p...
Definition: vtkMath.h:1767
abstract base class for most VTK objects
Definition: vtkObject.h:52
static void LabToXYZ(const double lab[3], double xyz[3])
Convert color from the CIE-L*ab system to CIE XYZ.
Definition: vtkMath.h:1415
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
static bool IsPowerOfTwo(vtkTypeUInt64 x)
Returns true if integer is a power of two.
Definition: vtkMath.h:1812
static void RGBToProLab(const double rgb[3], double prolab[3])
Convert color from the RGB system to Prolab The input RGB must be values in the range [0...
Definition: vtkMath.h:1489
static void Outer(const double a[3], const double b[3], double c[3][3])
Outer product of two 3-vectors (double version).
Definition: vtkMath.h:526
void RoundDoubleToIntegralIfNecessary(double val, OutT *ret)
Definition: vtkMath.h:2253
static void MultiplyMatrixWithVector(MatrixT &&M, VectorT1 &&X, VectorT2 &&Y)
Multiply matrix M with vector Y such that Y = M x X.
Definition: vtkMath.h:891
static float Determinant2x2(const float c1[2], const float c2[2])
Compute determinant of 2x2 matrix.
Definition: vtkMath.h:779
static vtkSmartPointer< vtkMathInternal > Internal
Definition: vtkMath.h:1780
static vtkMatrixUtilities::ScalarTypeExtractor< MatrixT >::value_type Determinant(MatrixT &&M)
Computes the determinant of input square SizeT x SizeT matrix M.
Definition: vtkMath.h:964
static double Distance2BetweenPoints2D(const double p1[2], const double p2[2])
Compute distance squared between two 2D points p1 and p2.
Definition: vtkMath.h:1963
static void QuaternionToMatrix3x3(const float quat[4], float A[3][3])
Convert a quaternion to a 3x3 rotation matrix.
Definition: vtkMath.h:2151
static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4])
Convert a 3x3 matrix into a quaternion.
Definition: vtkMath.h:2229
static vtkTypeBool IsInf(double x)
Test if a number is equal to the special floating point value infinity.
static void InvertMatrix(MatrixT1 &&M1, MatrixT2 &&M2)
Computes the inverse of input matrix M1 into M2.
Definition: vtkMath.h:987
static constexpr double Pi()
A mathematical constant.
Definition: vtkMath.h:118
static void RGBToHSV(const double rgb[3], double hsv[3])
Convert color in RGB format (Red, Green, Blue) to HSV format (Hue, Saturation, Value).
Definition: vtkMath.h:1360
static vtkTypeBool IsNan(double x)
Test if a number is equal to the special floating point value Not-A-Number (Nan). ...
static int Round(float f)
Rounds a float to the nearest integer.
Definition: vtkMath.h:140
static void RGBToHSV(const float rgb[3], float hsv[3])
Convert color in RGB format (Red, Green, Blue) to HSV format (Hue, Saturation, Value).
Definition: vtkMath.h:1355
int vtkIdType
Definition: vtkType.h:363
static double ClampAndNormalizeValue(double value, const double range[2])
Clamp a value against a range and then normalize it between 0 and 1.
Definition: vtkMath.h:2056
static void ProLabToXYZ(const double prolab[3], double xyz[3])
Convert color from the ProLAB system to CIE XYZ.
Definition: vtkMath.h:1392
static void MultiplyMatrix(MatrixT1 &&M1, MatrixT2 &&M2, MatrixT3 &&M3)
Multiply matrices such that M3 = M1 x M2.
Definition: vtkMath.h:863
static void Outer(const float a[3], const float b[3], float c[3][3])
Outer product of two 3-vectors (float version).
Definition: vtkMath.h:512
static ScalarT Dot(VectorT1 &&x, VectorT2 &&y)
Computes the dot product between 2 vectors x and y.
Definition: vtkMath.h:904
int vtkTypeBool
Definition: vtkABI.h:64
static void Add(const double a[3], const double b[3], double c[3])
Addition of two 3-vectors (double version).
Definition: vtkMath.h:364
static double Dot(const double a[3], const double b[3])
Dot product of two 3-vectors (double version).
Definition: vtkMath.h:480
static void XYZToRGB(const double xyz[3], double rgb[3])
Convert color from the CIE XYZ system to RGB.
Definition: vtkMath.h:1437
static float Norm2D(const float x[2])
Compute the norm of a 2-vector.
Definition: vtkMath.h:756
static void UninitializeBounds(double bounds[6])
Set the bounds to an uninitialized state.
Definition: vtkMath.h:1511
static constexpr int DYNAMIC_VECTOR_SIZE()
When this value is passed to a select templated functions in vtkMath, the computation can be performe...
Definition: vtkMath.h:113
double vtkDeterminant3x3(const T A[3][3])
Definition: vtkMath.h:2007
static int NearestPowerOfTwo(int x)
Compute the nearest power of two that is not less than x.
Definition: vtkMath.h:1819
RealT ww
Definition: PyrI2Basis.h:13
static void RGBToXYZ(const double rgb[3], double xyz[3])
Convert color from the RGB system to CIE XYZ.
Definition: vtkMath.h:1448
static T Min(const T &a, const T &b)
Returns the minimum of the two arguments provided.
Definition: vtkMath.h:1850
a simple class to control print indentation
Definition: vtkIndent.h:28
static float Normalize2D(float v[2])
Normalize (in place) a 2-vector.
Definition: vtkMath.h:1891
#define Distance2BetweenPoints2D(p1, p2)
static void Subtract(const float a[3], const float b[3], float c[3])
Subtraction of two 3-vectors (float version).
Definition: vtkMath.h:389
static void Subtract(const double a[3], const double b[3], double c[3])
Subtraction of two 3-vectors (double version).
Definition: vtkMath.h:400
static int Floor(double x)
Rounds a double to the nearest integer not greater than itself.
Definition: vtkMath.h:1833
static double Determinant3x3(const float A[3][3])
Return the determinant of a 3x3 matrix.
Definition: vtkMath.h:2014
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:44
static ReturnTypeT SquaredNorm(const TupleRangeT &v)
Compute the squared norm of a 3-vector.
Definition: vtkMath.h:588
static void Convolve1D(Iter1 beginSample, Iter1 endSample, Iter2 beginKernel, Iter2 endKernel, Iter3 beginOut, Iter3 endOut, ConvolutionMode mode=ConvolutionMode::FULL)
Compute the convolution of a sampled 1D signal by a given kernel.
Definition: vtkMath.h:1722
static double Determinant2x2(double a, double b, double c, double d)
Calculate the determinant of a 2x2 matrix: | a b | | c d |.
Definition: vtkMath.h:788
static float RadiansFromDegrees(float degrees)
Convert degrees into radians.
Definition: vtkMath.h:1788
typename detail::ScalarTypeExtractor< std::is_array< DerefContainer >::value||std::is_pointer< DerefContainer >::value, ContainerT >::value_type value_type
value_type is the underlying arithmetic type held in ContainerT
static void HSVToRGB(const double hsv[3], double rgb[3])
Convert color in HSV format (Hue, Saturation, Value) to RGB format (Red, Green, Blue).
Definition: vtkMath.h:1380
RealT mt
Definition: PyrC2Basis.h:39
Park and Miller Sequence of pseudo random numbers.
static void MultiplyScalar(double a[3], double s)
Multiplies a 3-vector by a scalar (double version).
Definition: vtkMath.h:449
static void RGBToLab(const double rgb[3], double lab[3])
Convert color from the RGB system to CIE-L*ab.
Definition: vtkMath.h:1463
static float DegreesFromRadians(float radians)
Convert radians into degrees.
Definition: vtkMath.h:1800
static float Normalize(float v[3])
Normalize (in place) a 3-vector.
Definition: vtkMath.h:1863
static void Outer2D(const double x[2], const double y[2], double A[2][2])
Outer product of two 2-vectors (double version).
Definition: vtkMath.h:741
static void Outer2D(const float x[2], const float y[2], float A[2][2])
Outer product of two 2-vectors (float version).
Definition: vtkMath.h:727
static int Ceil(double x)
Rounds a double to the nearest integer not less than itself.
Definition: vtkMath.h:1842
static void Cross(VectorT1 &&a, VectorT2 &&b, VectorT3 &c)
Cross product of two 3-vectors.
Definition: vtkMath.h:1970
static ScalarT Dot(VectorT1 &&x, MatrixT &&M, VectorT2 &&y)
Computes the dot product x^T M y, where x and y are vectors and M is a metric matrix.
Definition: vtkMath.h:1031
performs common math operations
Definition: vtkMath.h:78
static double Dot2D(const double x[2], const double y[2])
Dot product of two 2-vectors.
Definition: vtkMath.h:722
static void RoundDoubleToIntegralIfNecessary(double val, OutT *ret)
Round a double to type OutT if OutT is integral, otherwise simply clamp the value to the output range...
Definition: vtkMath.h:149
static vtkTypeBool JacobiN(float **a, int n, float *w, float **v)
JacobiN iteration for the solution of eigenvectors/eigenvalues of a nxn real symmetric matrix...
static float Norm(const float v[3])
Compute the norm of 3-vector (float version).
Definition: vtkMath.h:568
static ScalarT Dot(VectorT1 &&x, VectorT2 &&y)
Computes the dot product between 2 vectors x and y.
Definition: vtkMath.h:921
static void MultiplyScalar(float a[3], float s)
Multiplies a 3-vector by a scalar (float version).
Definition: vtkMath.h:425
static void HSVToRGB(const float hsv[3], float rgb[3])
Convert color in HSV format (Hue, Saturation, Value) to RGB format (Red, Green, Blue).
Definition: vtkMath.h:1375
static void Subtract(const VectorT1 &a, const VectorT2 &b, VectorT3 &&c)
Subtraction of two 3-vectors (templated version).
Definition: vtkMath.h:414
static T ClampValue(const T &value, const T &min, const T &max)
Clamp some value against a range, return the result.
Definition: vtkMath.h:2027
static void LinearSolve(MatrixT &&M, VectorT1 &&x, VectorT2 &&y)
This method solves linear systems M * x = y.
Definition: vtkMath.h:1008
static double Norm2D(const double x[2])
Compute the norm of a 2-vector.
Definition: vtkMath.h:762
static int Round(double f)
Definition: vtkMath.h:141
static void Add(VectorT1 &&a, VectorT2 &&b, VectorT3 &c)
Addition of two 3-vectors (double version).
Definition: vtkMath.h:378
static ReturnTypeT Dot(const TupleRangeT1 &a, const TupleRangeT2 &b)
Compute dot product between two points p1 and p2.
Definition: vtkMath.h:504
static double Norm(const double v[3])
Compute the norm of 3-vector (double version).
Definition: vtkMath.h:573
static void MultiplyScalar2D(double a[2], double s)
Multiplies a 2-vector by a scalar (double version).
Definition: vtkMath.h:461
static void LabToRGB(const double lab[3], double rgb[3])
Convert color from the CIE-L*ab system to RGB.
Definition: vtkMath.h:1500
static vtkObject * New()
Create an object with Debug turned off, modified time initialized to zero, and reference counting on...
static float Norm(const float *x, int n)
Compute the norm of n-vector.
static vtkIdType ComputeGCD(vtkIdType m, vtkIdType n)
Compute the greatest common divisor (GCD) of two positive integers m and n.
Definition: vtkMath.h:1687
static ReturnTypeT Distance2BetweenPoints(const TupleRangeT1 &p1, const TupleRangeT2 &p2)
Compute distance squared between two points p1 and p2.
Definition: vtkMath.h:1956
ConvolutionMode
Support the convolution operations.
Definition: vtkMath.h:1692
Gaussian sequence of pseudo random numbers implemented with the Box-Mueller transform.
static double Determinant2x2(const double c1[2], const double c2[2])
Calculate the determinant of a 2x2 matrix: | a b | | c d |.
Definition: vtkMath.h:789
static void Add(const float a[3], const float b[3], float c[3])
Addition of two 3-vectors (float version).
Definition: vtkMath.h:353
Matrix wrapping class.
Template defining traits of native types used by VTK.
Definition: vtkTypeTraits.h:25
static vtkTypeBool AreBoundsInitialized(const double bounds[6])
Are the bounds initialized?
Definition: vtkMath.h:1526
#define max(a, b)
represent and manipulate 3D points
Definition: vtkPoints.h:30
static void Assign(const VectorT1 &a, VectorT2 &&b)
Assign values to a 3-vector (templated version).
Definition: vtkMath.h:338
static T Max(const T &a, const T &b)
Returns the maximum of the two arguments provided.
Definition: vtkMath.h:1857
static void XYZToProLab(const double xyz[3], double prolab[3])
Convert Color from the CIE XYZ system to ProLAB.
Definition: vtkMath.h:1404
static vtkMatrixUtilities::ScalarTypeExtractor< VectorT >::value_type SquaredNorm(VectorT &&x)
Computes the dot product between 2 vectors x and y.
Definition: vtkMath.h:940
static void Assign(const double a[3], double b[3])
Assign values to a 3-vector (double version).
Definition: vtkMath.h:348
static void XYZToLab(const double xyz[3], double lab[3])
Convert Color from the CIE XYZ system to CIE-L*ab.
Definition: vtkMath.h:1426