VTK  9.3.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 
88  static constexpr double Pi() { return 3.141592653589793; }
89 
91 
94  static float RadiansFromDegrees(float degrees);
95  static double RadiansFromDegrees(double degrees);
97 
99 
102  static float DegreesFromRadians(float radians);
103  static double DegreesFromRadians(double radians);
105 
109 #if 1
110  static int Round(float f) { return static_cast<int>(f + (f >= 0.0 ? 0.5 : -0.5)); }
111  static int Round(double f) { return static_cast<int>(f + (f >= 0.0 ? 0.5 : -0.5)); }
112 #endif
113 
118  template <typename OutT>
119  static void RoundDoubleToIntegralIfNecessary(double val, OutT* ret)
120  {
121  // Can't specialize template methods in a template class, so we move the
122  // implementations to a external namespace.
124  }
125 
131  static int Floor(double x);
132 
138  static int Ceil(double x);
139 
145  static int CeilLog2(vtkTypeUInt64 x);
146 
151  template <class T>
152  static T Min(const T& a, const T& b);
153 
158  template <class T>
159  static T Max(const T& a, const T& b);
160 
164  static bool IsPowerOfTwo(vtkTypeUInt64 x);
165 
171  static int NearestPowerOfTwo(int x);
172 
177  static vtkTypeInt64 Factorial(int N);
178 
184  static vtkTypeInt64 Binomial(int m, int n);
185 
197  static int* BeginCombination(int m, int n);
198 
209  static int NextCombination(int m, int n, int* combination);
210 
214  static void FreeCombination(int* combination);
215 
231  static void RandomSeed(int s);
232 
244  static int GetSeed();
245 
259  static double Random();
260 
273  static double Random(double min, double max);
274 
287  static double Gaussian();
288 
301  static double Gaussian(double mean, double std);
302 
307  template <class VectorT1, class VectorT2>
308  static void Assign(const VectorT1& a, VectorT2&& b)
309  {
310  b[0] = a[0];
311  b[1] = a[1];
312  b[2] = a[2];
313  }
314 
318  static void Assign(const double a[3], double b[3]) { vtkMath::Assign<>(a, b); }
319 
323  static void Add(const float a[3], const float b[3], float c[3])
324  {
325  for (int i = 0; i < 3; ++i)
326  {
327  c[i] = a[i] + b[i];
328  }
329  }
330 
334  static void Add(const double a[3], const double b[3], double c[3])
335  {
336  for (int i = 0; i < 3; ++i)
337  {
338  c[i] = a[i] + b[i];
339  }
340  }
341 
347  template <class VectorT1, class VectorT2, class VectorT3>
348  static void Add(VectorT1&& a, VectorT2&& b, VectorT3& c)
349  {
350  for (int i = 0; i < 3; ++i)
351  {
352  c[i] = a[i] + b[i];
353  }
354  }
355 
359  static void Subtract(const float a[3], const float b[3], float c[3])
360  {
361  for (int i = 0; i < 3; ++i)
362  {
363  c[i] = a[i] - b[i];
364  }
365  }
366 
370  static void Subtract(const double a[3], const double b[3], double c[3])
371  {
372  for (int i = 0; i < 3; ++i)
373  {
374  c[i] = a[i] - b[i];
375  }
376  }
377 
383  template <class VectorT1, class VectorT2, class VectorT3>
384  static void Subtract(const VectorT1& a, const VectorT2& b, VectorT3&& c)
385  {
386  c[0] = a[0] - b[0];
387  c[1] = a[1] - b[1];
388  c[2] = a[2] - b[2];
389  }
390 
395  static void MultiplyScalar(float a[3], float s)
396  {
397  for (int i = 0; i < 3; ++i)
398  {
399  a[i] *= s;
400  }
401  }
402 
407  static void MultiplyScalar2D(float a[2], float s)
408  {
409  for (int i = 0; i < 2; ++i)
410  {
411  a[i] *= s;
412  }
413  }
414 
419  static void MultiplyScalar(double a[3], double s)
420  {
421  for (int i = 0; i < 3; ++i)
422  {
423  a[i] *= s;
424  }
425  }
426 
431  static void MultiplyScalar2D(double a[2], double s)
432  {
433  for (int i = 0; i < 2; ++i)
434  {
435  a[i] *= s;
436  }
437  }
438 
442  static float Dot(const float a[3], const float b[3])
443  {
444  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
445  }
446 
450  static double Dot(const double a[3], const double b[3])
451  {
452  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
453  }
454 
470  template <typename ReturnTypeT = double, typename TupleRangeT1, typename TupleRangeT2,
471  typename EnableT = typename std::conditional<!std::is_pointer<TupleRangeT1>::value &&
473  TupleRangeT1, TupleRangeT2>::type::value_type>
474  static ReturnTypeT Dot(const TupleRangeT1& a, const TupleRangeT2& b)
475  {
476  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
477  }
478 
482  static void Outer(const float a[3], const float b[3], float c[3][3])
483  {
484  for (int i = 0; i < 3; ++i)
485  {
486  for (int j = 0; j < 3; ++j)
487  {
488  c[i][j] = a[i] * b[j];
489  }
490  }
491  }
492 
496  static void Outer(const double a[3], const double b[3], double c[3][3])
497  {
498  for (int i = 0; i < 3; ++i)
499  {
500  for (int j = 0; j < 3; ++j)
501  {
502  c[i][j] = a[i] * b[j];
503  }
504  }
505  }
506 
512  template <class VectorT1, class VectorT2, class VectorT3>
513  static void Cross(VectorT1&& a, VectorT2&& b, VectorT3& c);
514 
519  static void Cross(const float a[3], const float b[3], float c[3]);
520 
525  static void Cross(const double a[3], const double b[3], double c[3]);
526 
528 
531  static float Norm(const float* x, int n);
532  static double Norm(const double* x, int n);
534 
538  static float Norm(const float v[3]) { return std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); }
539 
543  static double Norm(const double v[3])
544  {
545  return std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
546  }
547 
557  template <typename ReturnTypeT = double, typename TupleRangeT>
558  static ReturnTypeT SquaredNorm(const TupleRangeT& v)
559  {
560  return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
561  }
562 
567  static float Normalize(float v[3]);
568 
573  static double Normalize(double v[3]);
574 
576 
583  static void Perpendiculars(const double v1[3], double v2[3], double v3[3], double theta);
584  static void Perpendiculars(const float v1[3], float v2[3], float v3[3], double theta);
586 
588 
593  static bool ProjectVector(const float a[3], const float b[3], float projection[3]);
594  static bool ProjectVector(const double a[3], const double b[3], double projection[3]);
596 
598 
604  static bool ProjectVector2D(const float a[2], const float b[2], float projection[2]);
605  static bool ProjectVector2D(const double a[2], const double b[2], double projection[2]);
607 
623  template <typename ReturnTypeT = double, typename TupleRangeT1, typename TupleRangeT2,
624  typename EnableT = typename std::conditional<!std::is_pointer<TupleRangeT1>::value &&
626  TupleRangeT1, TupleRangeT2>::type::value_type>
627  static ReturnTypeT Distance2BetweenPoints(const TupleRangeT1& p1, const TupleRangeT2& p2);
628 
633  static float Distance2BetweenPoints(const float p1[3], const float p2[3]);
634 
639  static double Distance2BetweenPoints(const double p1[3], const double p2[3]);
640 
644  static double AngleBetweenVectors(const double v1[3], const double v2[3]);
645 
649  static double SignedAngleBetweenVectors(
650  const double v1[3], const double v2[3], const double vn[3]);
651 
656  static double GaussianAmplitude(double variance, double distanceFromMean);
657 
662  static double GaussianAmplitude(double mean, double variance, double position);
663 
669  static double GaussianWeight(double variance, double distanceFromMean);
670 
676  static double GaussianWeight(double mean, double variance, double position);
677 
681  static float Dot2D(const float x[2], const float y[2]) { return x[0] * y[0] + x[1] * y[1]; }
682 
686  static double Dot2D(const double x[2], const double y[2]) { return x[0] * y[0] + x[1] * y[1]; }
687 
691  static void Outer2D(const float x[2], const float y[2], float A[2][2])
692  {
693  for (int i = 0; i < 2; ++i)
694  {
695  for (int j = 0; j < 2; ++j)
696  {
697  A[i][j] = x[i] * y[j];
698  }
699  }
700  }
701 
705  static void Outer2D(const double x[2], const double y[2], double A[2][2])
706  {
707  for (int i = 0; i < 2; ++i)
708  {
709  for (int j = 0; j < 2; ++j)
710  {
711  A[i][j] = x[i] * y[j];
712  }
713  }
714  }
715 
720  static float Norm2D(const float x[2]) { return std::sqrt(x[0] * x[0] + x[1] * x[1]); }
721 
726  static double Norm2D(const double x[2]) { return std::sqrt(x[0] * x[0] + x[1] * x[1]); }
727 
732  static float Normalize2D(float v[2]);
733 
738  static double Normalize2D(double v[2]);
739 
743  static float Determinant2x2(const float c1[2], const float c2[2])
744  {
745  return c1[0] * c2[1] - c2[0] * c1[1];
746  }
747 
749 
752  static double Determinant2x2(double a, double b, double c, double d) { return a * d - b * c; }
753  static double Determinant2x2(const double c1[2], const double c2[2])
754  {
755  return c1[0] * c2[1] - c2[0] * c1[1];
756  }
758 
760 
763  static void LUFactor3x3(float A[3][3], int index[3]);
764  static void LUFactor3x3(double A[3][3], int index[3]);
766 
768 
771  static void LUSolve3x3(const float A[3][3], const int index[3], float x[3]);
772  static void LUSolve3x3(const double A[3][3], const int index[3], double x[3]);
774 
776 
780  static void LinearSolve3x3(const float A[3][3], const float x[3], float y[3]);
781  static void LinearSolve3x3(const double A[3][3], const double x[3], double y[3]);
783 
785 
788  static void Multiply3x3(const float A[3][3], const float v[3], float u[3]);
789  static void Multiply3x3(const double A[3][3], const double v[3], double u[3]);
791 
793 
796  static void Multiply3x3(const float A[3][3], const float B[3][3], float C[3][3]);
797  static void Multiply3x3(const double A[3][3], const double B[3][3], double C[3][3]);
799 
823  template <int RowsT, int MidDimT, int ColsT,
824  class LayoutT1 = vtkMatrixUtilities::Layout::Identity,
825  class LayoutT2 = vtkMatrixUtilities::Layout::Identity, class MatrixT1, class MatrixT2,
826  class MatrixT3>
827  static void MultiplyMatrix(const MatrixT1& M1, const MatrixT2& M2, MatrixT3&& M3)
828  {
829  vtkMathPrivate::MultiplyMatrix<RowsT, MidDimT, ColsT, LayoutT1, LayoutT2>::Compute(M1, M2, M3);
830  }
831 
852  template <int RowsT, int ColsT, class LayoutT = vtkMatrixUtilities::Layout::Identity,
853  class MatrixT, class VectorT1, class VectorT2>
854  static void MultiplyMatrixWithVector(const MatrixT& M, const VectorT1& X, VectorT2&& Y)
855  {
856  vtkMathPrivate::MultiplyMatrix<RowsT, ColsT, 1, LayoutT>::Compute(M, X, Y);
857  }
858 
864  template <class ScalarT, int SizeT, class VectorT1, class VectorT2>
865  static ScalarT Dot(const VectorT1& x, const VectorT2& y)
866  {
867  return vtkMathPrivate::ContractRowWithCol<ScalarT, 1, SizeT, 1, 0, 0,
868  vtkMatrixUtilities::Layout::Identity, vtkMatrixUtilities::Layout::Transpose>::Compute(x, y);
869  }
870 
887  template <int SizeT, class LayoutT = vtkMatrixUtilities::Layout::Identity, class MatrixT>
889  const MatrixT& M)
890  {
891  return vtkMathPrivate::Determinant<SizeT, LayoutT>::Compute(M);
892  }
893 
909  template <int SizeT, class LayoutT = vtkMatrixUtilities::Layout::Identity, class MatrixT1,
910  class MatrixT2>
911  static void InvertMatrix(const MatrixT1& M1, MatrixT2&& M2)
912  {
913  vtkMathPrivate::InvertMatrix<SizeT, LayoutT>::Compute(M1, M2);
914  }
915 
929  template <int RowsT, int ColsT, class LayoutT = vtkMatrixUtilities::Layout::Identity,
930  class MatrixT, class VectorT1, class VectorT2>
931  static void LinearSolve(const MatrixT& M, const VectorT1& x, VectorT2& y)
932  {
933  vtkMathPrivate::LinearSolve<RowsT, ColsT, LayoutT>::Compute(M, x, y);
934  }
935 
950  template <class ScalarT, int SizeT, class LayoutT = vtkMatrixUtilities::Layout::Identity,
951  class VectorT1, class MatrixT, class VectorT2>
952  static ScalarT Dot(const VectorT1& x, const MatrixT& M, const VectorT2& y)
953  {
954  ScalarT tmp[SizeT];
955  vtkMathPrivate::MultiplyMatrix<SizeT, SizeT, 1, LayoutT>::Compute(M, y, tmp);
956  return vtkMathPrivate::ContractRowWithCol<ScalarT, 1, SizeT, 1, 0, 0,
957  vtkMatrixUtilities::Layout::Identity, vtkMatrixUtilities::Layout::Transpose>::Compute(x, tmp);
958  }
959 
965  static void MultiplyMatrix(const double* const* A, const double* const* B, unsigned int rowA,
966  unsigned int colA, unsigned int rowB, unsigned int colB, double** C);
967 
969 
973  static void Transpose3x3(const float A[3][3], float AT[3][3]);
974  static void Transpose3x3(const double A[3][3], double AT[3][3]);
976 
978 
982  static void Invert3x3(const float A[3][3], float AI[3][3]);
983  static void Invert3x3(const double A[3][3], double AI[3][3]);
985 
987 
990  static void Identity3x3(float A[3][3]);
991  static void Identity3x3(double A[3][3]);
993 
995 
998  static double Determinant3x3(const float A[3][3]);
999  static double Determinant3x3(const double A[3][3]);
1001 
1005  static float Determinant3x3(const float c1[3], const float c2[3], const float c3[3]);
1006 
1010  static double Determinant3x3(const double c1[3], const double c2[3], const double c3[3]);
1011 
1018  static double Determinant3x3(double a1, double a2, double a3, double b1, double b2, double b3,
1019  double c1, double c2, double c3);
1020 
1022 
1029  static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]);
1030  static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]);
1031  template <class QuaternionT, class MatrixT,
1032  class EnableT = typename std::enable_if<!vtkMatrixUtilities::MatrixIs2DArray<MatrixT>()>::type>
1033  static void QuaternionToMatrix3x3(const QuaternionT& q, MatrixT&& A);
1035 
1037 
1046  static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
1047  static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
1048  template <class MatrixT, class QuaternionT,
1049  class EnableT = typename std::enable_if<!vtkMatrixUtilities::MatrixIs2DArray<MatrixT>()>::type>
1050  static void Matrix3x3ToQuaternion(const MatrixT& A, QuaternionT&& q);
1052 
1054 
1060  static void MultiplyQuaternion(const float q1[4], const float q2[4], float q[4]);
1061  static void MultiplyQuaternion(const double q1[4], const double q2[4], double q[4]);
1063 
1065 
1069  static void RotateVectorByNormalizedQuaternion(const float v[3], const float q[4], float r[3]);
1070  static void RotateVectorByNormalizedQuaternion(const double v[3], const double q[4], double r[3]);
1072 
1074 
1078  static void RotateVectorByWXYZ(const float v[3], const float q[4], float r[3]);
1079  static void RotateVectorByWXYZ(const double v[3], const double q[4], double r[3]);
1081 
1083 
1088  static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
1089  static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
1091 
1093 
1099  static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
1100  static void Diagonalize3x3(const double A[3][3], double w[3], double V[3][3]);
1102 
1104 
1113  static void SingularValueDecomposition3x3(
1114  const float A[3][3], float U[3][3], float w[3], float VT[3][3]);
1115  static void SingularValueDecomposition3x3(
1116  const double A[3][3], double U[3][3], double w[3], double VT[3][3]);
1118 
1126  static vtkTypeBool SolveLinearSystemGEPP2x2(
1127  double a00, double a01, double a10, double a11, double b0, double b1, double& x0, double& x1);
1128 
1137  static vtkTypeBool SolveLinearSystem(double** A, double* x, int size);
1138 
1145  static vtkTypeBool InvertMatrix(double** A, double** AI, int size);
1146 
1152  static vtkTypeBool InvertMatrix(
1153  double** A, double** AI, int size, int* tmp1Size, double* tmp2Size);
1154 
1177  static vtkTypeBool LUFactorLinearSystem(double** A, int* index, int size);
1178 
1184  static vtkTypeBool LUFactorLinearSystem(double** A, int* index, int size, double* tmpSize);
1185 
1194  static void LUSolveLinearSystem(double** A, int* index, double* x, int size);
1195 
1204  static double EstimateMatrixCondition(const double* const* A, int size);
1205 
1207 
1215  static vtkTypeBool Jacobi(float** a, float* w, float** v);
1216  static vtkTypeBool Jacobi(double** a, double* w, double** v);
1218 
1220 
1229  static vtkTypeBool JacobiN(float** a, int n, float* w, float** v);
1230  static vtkTypeBool JacobiN(double** a, int n, double* w, double** v);
1232 
1246  static vtkTypeBool SolveHomogeneousLeastSquares(
1247  int numberOfSamples, double** xt, int xOrder, double** mt);
1248 
1263  static vtkTypeBool SolveLeastSquares(int numberOfSamples, double** xt, int xOrder, double** yt,
1264  int yOrder, double** mt, int checkHomogeneous = 1);
1265 
1267 
1274  static void RGBToHSV(const float rgb[3], float hsv[3])
1275  {
1276  RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
1277  }
1278  static void RGBToHSV(float r, float g, float b, float* h, float* s, float* v);
1279  static void RGBToHSV(const double rgb[3], double hsv[3])
1280  {
1281  RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
1282  }
1283  static void RGBToHSV(double r, double g, double b, double* h, double* s, double* v);
1285 
1287 
1294  static void HSVToRGB(const float hsv[3], float rgb[3])
1295  {
1296  HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
1297  }
1298  static void HSVToRGB(float h, float s, float v, float* r, float* g, float* b);
1299  static void HSVToRGB(const double hsv[3], double rgb[3])
1300  {
1301  HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
1302  }
1303  static void HSVToRGB(double h, double s, double v, double* r, double* g, double* b);
1305 
1307 
1310  static void LabToXYZ(const double lab[3], double xyz[3])
1311  {
1312  LabToXYZ(lab[0], lab[1], lab[2], xyz + 0, xyz + 1, xyz + 2);
1313  }
1314  static void LabToXYZ(double L, double a, double b, double* x, double* y, double* z);
1316 
1318 
1321  static void XYZToLab(const double xyz[3], double lab[3])
1322  {
1323  XYZToLab(xyz[0], xyz[1], xyz[2], lab + 0, lab + 1, lab + 2);
1324  }
1325  static void XYZToLab(double x, double y, double z, double* L, double* a, double* b);
1327 
1329 
1332  static void XYZToRGB(const double xyz[3], double rgb[3])
1333  {
1334  XYZToRGB(xyz[0], xyz[1], xyz[2], rgb + 0, rgb + 1, rgb + 2);
1335  }
1336  static void XYZToRGB(double x, double y, double z, double* r, double* g, double* b);
1338 
1340 
1343  static void RGBToXYZ(const double rgb[3], double xyz[3])
1344  {
1345  RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz + 0, xyz + 1, xyz + 2);
1346  }
1347  static void RGBToXYZ(double r, double g, double b, double* x, double* y, double* z);
1349 
1351 
1357  static void RGBToLab(const double rgb[3], double lab[3])
1358  {
1359  RGBToLab(rgb[0], rgb[1], rgb[2], lab + 0, lab + 1, lab + 2);
1360  }
1361  static void RGBToLab(double red, double green, double blue, double* L, double* a, double* b);
1363 
1365 
1368  static void LabToRGB(const double lab[3], double rgb[3])
1369  {
1370  LabToRGB(lab[0], lab[1], lab[2], rgb + 0, rgb + 1, rgb + 2);
1371  }
1372  static void LabToRGB(double L, double a, double b, double* red, double* green, double* blue);
1374 
1376 
1379  static void UninitializeBounds(double bounds[6])
1380  {
1381  bounds[0] = 1.0;
1382  bounds[1] = -1.0;
1383  bounds[2] = 1.0;
1384  bounds[3] = -1.0;
1385  bounds[4] = 1.0;
1386  bounds[5] = -1.0;
1387  }
1389 
1391 
1394  static vtkTypeBool AreBoundsInitialized(const double bounds[6])
1395  {
1396  if (bounds[1] - bounds[0] < 0.0)
1397  {
1398  return 0;
1399  }
1400  return 1;
1401  }
1403 
1408  template <class T>
1409  static T ClampValue(const T& value, const T& min, const T& max);
1410 
1412 
1416  static void ClampValue(double* value, const double range[2]);
1417  static void ClampValue(double value, const double range[2], double* clamped_value);
1418  static void ClampValues(double* values, int nb_values, const double range[2]);
1419  static void ClampValues(
1420  const double* values, int nb_values, const double range[2], double* clamped_values);
1422 
1429  static double ClampAndNormalizeValue(double value, const double range[2]);
1430 
1435  template <class T1, class T2>
1436  static void TensorFromSymmetricTensor(const T1 symmTensor[6], T2 tensor[9]);
1437 
1443  template <class T>
1444  static void TensorFromSymmetricTensor(T tensor[9]);
1445 
1454  static int GetScalarTypeFittingRange(
1455  double range_min, double range_max, double scale = 1.0, double shift = 0.0);
1456 
1465  static vtkTypeBool GetAdjustedScalarRange(vtkDataArray* array, int comp, double range[2]);
1466 
1471  static vtkTypeBool ExtentIsWithinOtherExtent(const int extent1[6], const int extent2[6]);
1472 
1478  static vtkTypeBool BoundsIsWithinOtherBounds(
1479  const double bounds1[6], const double bounds2[6], const double delta[3]);
1480 
1486  static vtkTypeBool PointIsWithinBounds(
1487  const double point[3], const double bounds[6], const double delta[3]);
1488 
1498  static int PlaneIntersectsAABB(
1499  const double bounds[6], const double normal[3], const double point[3]);
1500 
1510  static double Solve3PointCircle(
1511  const double p1[3], const double p2[3], const double p3[3], double center[3]);
1512 
1516  static double Inf();
1517 
1521  static double NegInf();
1522 
1526  static double Nan();
1527 
1531  static vtkTypeBool IsInf(double x);
1532 
1536  static vtkTypeBool IsNan(double x);
1537 
1542  static bool IsFinite(double x);
1543 
1548  static int QuadraticRoot(double a, double b, double c, double min, double max, double* u);
1549 
1555  static vtkIdType ComputeGCD(vtkIdType m, vtkIdType n) { return (n ? ComputeGCD(n, m % n) : m); }
1556 
1560  enum class ConvolutionMode
1561  {
1562  FULL,
1563  SAME,
1564  VALID
1565  };
1566 
1589  template <class Iter1, class Iter2, class Iter3>
1590  static void Convolve1D(Iter1 beginSample, Iter1 endSample, Iter2 beginKernel, Iter2 endKernel,
1591  Iter3 beginOut, Iter3 endOut, ConvolutionMode mode = ConvolutionMode::FULL)
1592  {
1593  int sampleSize = std::distance(beginSample, endSample);
1594  int kernelSize = std::distance(beginKernel, endKernel);
1595  int outSize = std::distance(beginOut, endOut);
1596 
1597  if (sampleSize <= 0 || kernelSize <= 0 || outSize <= 0)
1598  {
1599  return;
1600  }
1601 
1602  int begin = 0;
1603  int end = outSize;
1604 
1605  switch (mode)
1606  {
1607  case ConvolutionMode::SAME:
1608  begin = static_cast<int>(std::ceil((std::min)(sampleSize, kernelSize) / 2.0)) - 1;
1609  end = begin + (std::max)(sampleSize, kernelSize);
1610  break;
1611  case ConvolutionMode::VALID:
1612  begin = (std::min)(sampleSize, kernelSize) - 1;
1613  end = begin + std::abs(sampleSize - kernelSize) + 1;
1614  break;
1615  case ConvolutionMode::FULL:
1616  default:
1617  break;
1618  }
1619 
1620  for (int i = begin; i < end; i++)
1621  {
1622  Iter3 out = beginOut + i - begin;
1623  *out = 0;
1624  for (int j = (std::max)(i - sampleSize + 1, 0); j <= (std::min)(i, kernelSize - 1); j++)
1625  {
1626  *out += *(beginSample + (i - j)) * *(beginKernel + j);
1627  }
1628  }
1629  }
1630 
1635  static void GetPointAlongLine(double result[3], double p1[3], double p2[3], const double offset)
1636  {
1637  double directionVector[3] = { p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2] };
1638  vtkMath::Normalize(directionVector);
1639  result[0] = p2[0] + (offset * directionVector[0]);
1640  result[1] = p2[1] + (offset * directionVector[1]);
1641  result[2] = p2[2] + (offset * directionVector[2]);
1642  }
1643 
1644 protected:
1645  vtkMath() = default;
1646  ~vtkMath() override = default;
1647 
1649 
1650 private:
1651  vtkMath(const vtkMath&) = delete;
1652  void operator=(const vtkMath&) = delete;
1653 };
1654 
1655 //----------------------------------------------------------------------------
1656 inline float vtkMath::RadiansFromDegrees(float x)
1657 {
1658  return x * 0.017453292f;
1659 }
1660 
1661 //----------------------------------------------------------------------------
1662 inline double vtkMath::RadiansFromDegrees(double x)
1663 {
1664  return x * 0.017453292519943295;
1665 }
1666 
1667 //----------------------------------------------------------------------------
1668 inline float vtkMath::DegreesFromRadians(float x)
1669 {
1670  return x * 57.2957795131f;
1671 }
1672 
1673 //----------------------------------------------------------------------------
1674 inline double vtkMath::DegreesFromRadians(double x)
1675 {
1676  return x * 57.29577951308232;
1677 }
1678 
1679 //----------------------------------------------------------------------------
1680 inline bool vtkMath::IsPowerOfTwo(vtkTypeUInt64 x)
1681 {
1682  return ((x != 0) & ((x & (x - 1)) == 0));
1683 }
1684 
1685 //----------------------------------------------------------------------------
1686 // Credit goes to Peter Hart and William Lewis on comp.lang.python 1997
1688 {
1689  unsigned int z = static_cast<unsigned int>(((x > 0) ? x - 1 : 0));
1690  z |= z >> 1;
1691  z |= z >> 2;
1692  z |= z >> 4;
1693  z |= z >> 8;
1694  z |= z >> 16;
1695  return static_cast<int>(z + 1);
1696 }
1697 
1698 //----------------------------------------------------------------------------
1699 // Modify the trunc() operation provided by static_cast<int>() to get floor(),
1700 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
1701 inline int vtkMath::Floor(double x)
1702 {
1703  int i = static_cast<int>(x);
1704  return i - (i > x);
1705 }
1706 
1707 //----------------------------------------------------------------------------
1708 // Modify the trunc() operation provided by static_cast<int>() to get ceil(),
1709 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
1710 inline int vtkMath::Ceil(double x)
1711 {
1712  int i = static_cast<int>(x);
1713  return i + (i < x);
1714 }
1715 
1716 //----------------------------------------------------------------------------
1717 template <class T>
1718 inline T vtkMath::Min(const T& a, const T& b)
1719 {
1720  return (b <= a ? b : a);
1721 }
1722 
1723 //----------------------------------------------------------------------------
1724 template <class T>
1725 inline T vtkMath::Max(const T& a, const T& b)
1726 {
1727  return (b > a ? b : a);
1728 }
1729 
1730 //----------------------------------------------------------------------------
1731 inline float vtkMath::Normalize(float v[3])
1732 {
1733  float den = vtkMath::Norm(v);
1734  if (den != 0.0)
1735  {
1736  for (int i = 0; i < 3; ++i)
1737  {
1738  v[i] /= den;
1739  }
1740  }
1741  return den;
1742 }
1743 
1744 //----------------------------------------------------------------------------
1745 inline double vtkMath::Normalize(double v[3])
1746 {
1747  double den = vtkMath::Norm(v);
1748  if (den != 0.0)
1749  {
1750  for (int i = 0; i < 3; ++i)
1751  {
1752  v[i] /= den;
1753  }
1754  }
1755  return den;
1756 }
1757 
1758 //----------------------------------------------------------------------------
1759 inline float vtkMath::Normalize2D(float v[2])
1760 {
1761  float den = vtkMath::Norm2D(v);
1762  if (den != 0.0)
1763  {
1764  for (int i = 0; i < 2; ++i)
1765  {
1766  v[i] /= den;
1767  }
1768  }
1769  return den;
1770 }
1771 
1772 //----------------------------------------------------------------------------
1773 inline double vtkMath::Normalize2D(double v[2])
1774 {
1775  double den = vtkMath::Norm2D(v);
1776  if (den != 0.0)
1777  {
1778  for (int i = 0; i < 2; ++i)
1779  {
1780  v[i] /= den;
1781  }
1782  }
1783  return den;
1784 }
1785 
1786 //----------------------------------------------------------------------------
1787 inline float vtkMath::Determinant3x3(const float c1[3], const float c2[3], const float c3[3])
1788 {
1789  return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
1790  c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
1791 }
1792 
1793 //----------------------------------------------------------------------------
1794 inline double vtkMath::Determinant3x3(const double c1[3], const double c2[3], const double c3[3])
1795 {
1796  return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
1797  c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
1798 }
1799 
1800 //----------------------------------------------------------------------------
1802  double a1, double a2, double a3, double b1, double b2, double b3, double c1, double c2, double c3)
1803 {
1804  return (a1 * vtkMath::Determinant2x2(b2, b3, c2, c3) -
1805  b1 * vtkMath::Determinant2x2(a2, a3, c2, c3) + c1 * vtkMath::Determinant2x2(a2, a3, b2, b3));
1806 }
1807 
1808 //----------------------------------------------------------------------------
1809 inline float vtkMath::Distance2BetweenPoints(const float p1[3], const float p2[3])
1810 {
1811  return ((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]) +
1812  (p1[2] - p2[2]) * (p1[2] - p2[2]));
1813 }
1814 
1815 //----------------------------------------------------------------------------
1816 inline double vtkMath::Distance2BetweenPoints(const double p1[3], const double p2[3])
1817 {
1818  return ((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]) +
1819  (p1[2] - p2[2]) * (p1[2] - p2[2]));
1820 }
1821 
1822 //----------------------------------------------------------------------------
1823 template <typename ReturnTypeT, typename TupleRangeT1, typename TupleRangeT2, typename EnableT>
1824 inline ReturnTypeT vtkMath::Distance2BetweenPoints(const TupleRangeT1& p1, const TupleRangeT2& p2)
1825 {
1826  return ((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]) +
1827  (p1[2] - p2[2]) * (p1[2] - p2[2]));
1828 }
1829 
1830 //----------------------------------------------------------------------------
1831 template <class VectorT1, class VectorT2, class VectorT3>
1832 void vtkMath::Cross(VectorT1&& a, VectorT2&& b, VectorT3& c)
1833 {
1835  ValueType Cx = a[1] * b[2] - a[2] * b[1];
1836  ValueType Cy = a[2] * b[0] - a[0] * b[2];
1837  ValueType Cz = a[0] * b[1] - a[1] * b[0];
1838  c[0] = Cx;
1839  c[1] = Cy;
1840  c[2] = Cz;
1841 }
1842 
1843 //----------------------------------------------------------------------------
1844 // Cross product of two 3-vectors. Result (a x b) is stored in c[3].
1845 inline void vtkMath::Cross(const float a[3], const float b[3], float c[3])
1846 {
1847  float Cx = a[1] * b[2] - a[2] * b[1];
1848  float Cy = a[2] * b[0] - a[0] * b[2];
1849  float Cz = a[0] * b[1] - a[1] * b[0];
1850  c[0] = Cx;
1851  c[1] = Cy;
1852  c[2] = Cz;
1853 }
1854 
1855 //----------------------------------------------------------------------------
1856 // Cross product of two 3-vectors. Result (a x b) is stored in c[3].
1857 inline void vtkMath::Cross(const double a[3], const double b[3], double c[3])
1858 {
1859  double Cx = a[1] * b[2] - a[2] * b[1];
1860  double Cy = a[2] * b[0] - a[0] * b[2];
1861  double Cz = a[0] * b[1] - a[1] * b[0];
1862  c[0] = Cx;
1863  c[1] = Cy;
1864  c[2] = Cz;
1865 }
1866 
1867 //----------------------------------------------------------------------------
1868 template <class T>
1869 inline double vtkDeterminant3x3(const T A[3][3])
1870 {
1871  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] -
1872  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];
1873 }
1874 
1875 //----------------------------------------------------------------------------
1876 inline double vtkMath::Determinant3x3(const float A[3][3])
1877 {
1878  return vtkDeterminant3x3(A);
1879 }
1880 
1881 //----------------------------------------------------------------------------
1882 inline double vtkMath::Determinant3x3(const double A[3][3])
1883 {
1884  return vtkDeterminant3x3(A);
1885 }
1886 
1887 //----------------------------------------------------------------------------
1888 template <class T>
1889 inline T vtkMath::ClampValue(const T& value, const T& min, const T& max)
1890 {
1891  assert("pre: valid_range" && min <= max);
1892 
1893 #if __cplusplus >= 201703L
1894  return std::clamp(value, min, max);
1895 #else
1896  // compilers are good at optimizing the ternary operator,
1897  // use '<' since it is preferred by STL for custom types
1898  T v = (min < value ? value : min);
1899  return (v < max ? v : max);
1900 #endif
1901 }
1902 
1903 //----------------------------------------------------------------------------
1904 inline void vtkMath::ClampValue(double* value, const double range[2])
1905 {
1906  if (value && range)
1907  {
1908  assert("pre: valid_range" && range[0] <= range[1]);
1909 
1910  *value = vtkMath::ClampValue(*value, range[0], range[1]);
1911  }
1912 }
1913 
1914 //----------------------------------------------------------------------------
1915 inline void vtkMath::ClampValue(double value, const double range[2], double* clamped_value)
1916 {
1917  if (range && clamped_value)
1918  {
1919  assert("pre: valid_range" && range[0] <= range[1]);
1920 
1921  *clamped_value = vtkMath::ClampValue(value, range[0], range[1]);
1922  }
1923 }
1924 
1925 // ---------------------------------------------------------------------------
1926 inline double vtkMath::ClampAndNormalizeValue(double value, const double range[2])
1927 {
1928  assert("pre: valid_range" && range[0] <= range[1]);
1929 
1930  double result;
1931  if (range[0] == range[1])
1932  {
1933  result = 0.0;
1934  }
1935  else
1936  {
1937  // clamp
1938  result = vtkMath::ClampValue(value, range[0], range[1]);
1939 
1940  // normalize
1941  result = (result - range[0]) / (range[1] - range[0]);
1942  }
1943 
1944  assert("post: valid_result" && result >= 0.0 && result <= 1.0);
1945 
1946  return result;
1947 }
1948 
1949 //-----------------------------------------------------------------------------
1950 template <class T1, class T2>
1951 inline void vtkMath::TensorFromSymmetricTensor(const T1 symmTensor[9], T2 tensor[9])
1952 {
1953  for (int i = 0; i < 3; ++i)
1954  {
1955  tensor[4 * i] = symmTensor[i];
1956  }
1957  tensor[1] = tensor[3] = symmTensor[3];
1958  tensor[2] = tensor[6] = symmTensor[5];
1959  tensor[5] = tensor[7] = symmTensor[4];
1960 }
1961 
1962 //-----------------------------------------------------------------------------
1963 template <class T>
1964 inline void vtkMath::TensorFromSymmetricTensor(T tensor[9])
1965 {
1966  tensor[6] = tensor[5]; // XZ
1967  tensor[7] = tensor[4]; // YZ
1968  tensor[8] = tensor[2]; // ZZ
1969  tensor[4] = tensor[1]; // YY
1970  tensor[5] = tensor[7]; // YZ
1971  tensor[2] = tensor[6]; // XZ
1972  tensor[1] = tensor[3]; // XY
1973 }
1974 VTK_ABI_NAMESPACE_END
1975 
1976 namespace
1977 {
1978 template <class QuaternionT, class MatrixT>
1979 inline void vtkQuaternionToMatrix3x3(const QuaternionT& quat, MatrixT& A)
1980 {
1982 
1983  Scalar ww = quat[0] * quat[0];
1984  Scalar wx = quat[0] * quat[1];
1985  Scalar wy = quat[0] * quat[2];
1986  Scalar wz = quat[0] * quat[3];
1987 
1988  Scalar xx = quat[1] * quat[1];
1989  Scalar yy = quat[2] * quat[2];
1990  Scalar zz = quat[3] * quat[3];
1991 
1992  Scalar xy = quat[1] * quat[2];
1993  Scalar xz = quat[1] * quat[3];
1994  Scalar yz = quat[2] * quat[3];
1995 
1996  Scalar rr = xx + yy + zz;
1997  // normalization factor, just in case quaternion was not normalized
1998  Scalar f = 1 / (ww + rr);
1999  Scalar s = (ww - rr) * f;
2000  f *= 2;
2001 
2003 
2004  Wrapper::template Get<0, 0>(A) = xx * f + s;
2005  Wrapper::template Get<1, 0>(A) = (xy + wz) * f;
2006  Wrapper::template Get<2, 0>(A) = (xz - wy) * f;
2007 
2008  Wrapper::template Get<0, 1>(A) = (xy - wz) * f;
2009  Wrapper::template Get<1, 1>(A) = yy * f + s;
2010  Wrapper::template Get<2, 1>(A) = (yz + wx) * f;
2011 
2012  Wrapper::template Get<0, 2>(A) = (xz + wy) * f;
2013  Wrapper::template Get<1, 2>(A) = (yz - wx) * f;
2014  Wrapper::template Get<2, 2>(A) = zz * f + s;
2015 }
2016 } // anonymous namespace
2017 
2018 VTK_ABI_NAMESPACE_BEGIN
2019 //------------------------------------------------------------------------------
2020 inline void vtkMath::QuaternionToMatrix3x3(const float quat[4], float A[3][3])
2021 {
2022  vtkQuaternionToMatrix3x3(quat, A);
2023 }
2024 
2025 //------------------------------------------------------------------------------
2026 inline void vtkMath::QuaternionToMatrix3x3(const double quat[4], double A[3][3])
2027 {
2028  vtkQuaternionToMatrix3x3(quat, A);
2029 }
2030 
2031 //-----------------------------------------------------------------------------
2032 template <class QuaternionT, class MatrixT, class EnableT>
2033 inline void vtkMath::QuaternionToMatrix3x3(const QuaternionT& q, MatrixT&& A)
2034 {
2035  vtkQuaternionToMatrix3x3(q, A);
2036 }
2037 VTK_ABI_NAMESPACE_END
2038 
2039 namespace
2040 {
2041 //------------------------------------------------------------------------------
2042 // The solution is based on
2043 // Berthold K. P. Horn (1987),
2044 // "Closed-form solution of absolute orientation using unit quaternions,"
2045 // Journal of the Optical Society of America A, 4:629-642
2046 template <class MatrixT, class QuaternionT>
2047 inline void vtkMatrix3x3ToQuaternion(const MatrixT& A, QuaternionT& quat)
2048 {
2050 
2051  Scalar N[4][4];
2052 
2054 
2055  // on-diagonal elements
2056  N[0][0] = Wrapper::template Get<0, 0>(A) + Wrapper::template Get<1, 1>(A) +
2057  Wrapper::template Get<2, 2>(A);
2058  N[1][1] = Wrapper::template Get<0, 0>(A) - Wrapper::template Get<1, 1>(A) -
2059  Wrapper::template Get<2, 2>(A);
2060  N[2][2] = -Wrapper::template Get<0, 0>(A) + Wrapper::template Get<1, 1>(A) -
2061  Wrapper::template Get<2, 2>(A);
2062  N[3][3] = -Wrapper::template Get<0, 0>(A) - Wrapper::template Get<1, 1>(A) +
2063  Wrapper::template Get<2, 2>(A);
2064 
2065  // off-diagonal elements
2066  N[0][1] = N[1][0] = Wrapper::template Get<2, 1>(A) - Wrapper::template Get<1, 2>(A);
2067  N[0][2] = N[2][0] = Wrapper::template Get<0, 2>(A) - Wrapper::template Get<2, 0>(A);
2068  N[0][3] = N[3][0] = Wrapper::template Get<1, 0>(A) - Wrapper::template Get<0, 1>(A);
2069 
2070  N[1][2] = N[2][1] = Wrapper::template Get<1, 0>(A) + Wrapper::template Get<0, 1>(A);
2071  N[1][3] = N[3][1] = Wrapper::template Get<0, 2>(A) + Wrapper::template Get<2, 0>(A);
2072  N[2][3] = N[3][2] = Wrapper::template Get<2, 1>(A) + Wrapper::template Get<1, 2>(A);
2073 
2074  Scalar eigenvectors[4][4], eigenvalues[4];
2075 
2076  // convert into format that JacobiN can use,
2077  // then use Jacobi to find eigenvalues and eigenvectors
2078  Scalar *NTemp[4], *eigenvectorsTemp[4];
2079  for (int i = 0; i < 4; ++i)
2080  {
2081  NTemp[i] = N[i];
2082  eigenvectorsTemp[i] = eigenvectors[i];
2083  }
2084  vtkMath::JacobiN(NTemp, 4, eigenvalues, eigenvectorsTemp);
2085 
2086  // the first eigenvector is the one we want
2087  quat[0] = eigenvectors[0][0];
2088  quat[1] = eigenvectors[1][0];
2089  quat[2] = eigenvectors[2][0];
2090  quat[3] = eigenvectors[3][0];
2091 }
2092 } // anonymous namespace
2093 
2094 VTK_ABI_NAMESPACE_BEGIN
2095 //------------------------------------------------------------------------------
2096 inline void vtkMath::Matrix3x3ToQuaternion(const float A[3][3], float quat[4])
2097 {
2098  vtkMatrix3x3ToQuaternion(A, quat);
2099 }
2100 
2101 //------------------------------------------------------------------------------
2102 inline void vtkMath::Matrix3x3ToQuaternion(const double A[3][3], double quat[4])
2103 {
2104  vtkMatrix3x3ToQuaternion(A, quat);
2105 }
2106 
2107 //-----------------------------------------------------------------------------
2108 template <class MatrixT, class QuaternionT, class EnableT>
2109 inline void vtkMath::Matrix3x3ToQuaternion(const MatrixT& A, QuaternionT&& q)
2110 {
2111  vtkMatrix3x3ToQuaternion(A, q);
2112 }
2113 VTK_ABI_NAMESPACE_END
2114 
2115 namespace vtk_detail
2116 {
2117 VTK_ABI_NAMESPACE_BEGIN
2118 // Can't specialize templates inside a template class, so we move the impl here.
2119 template <typename OutT>
2120 void RoundDoubleToIntegralIfNecessary(double val, OutT* ret)
2121 { // OutT is integral -- clamp and round
2122  if (!vtkMath::IsNan(val))
2123  {
2124  double min = static_cast<double>(vtkTypeTraits<OutT>::Min());
2125  double max = static_cast<double>(vtkTypeTraits<OutT>::Max());
2126  val = vtkMath::ClampValue(val, min, max);
2127  *ret = static_cast<OutT>((val >= 0.0) ? (val + 0.5) : (val - 0.5));
2128  }
2129  else
2130  *ret = 0;
2131 }
2132 template <>
2133 inline void RoundDoubleToIntegralIfNecessary(double val, double* retVal)
2134 { // OutT is double: passthrough
2135  *retVal = val;
2136 }
2137 template <>
2138 inline void RoundDoubleToIntegralIfNecessary(double val, float* retVal)
2139 { // OutT is float -- just clamp (as doubles, then the cast to float is well-defined.)
2140  if (!vtkMath::IsNan(val))
2141  {
2142  double min = static_cast<double>(vtkTypeTraits<float>::Min());
2143  double max = static_cast<double>(vtkTypeTraits<float>::Max());
2144  val = vtkMath::ClampValue(val, min, max);
2145  }
2146 
2147  *retVal = static_cast<float>(val);
2148 }
2149 VTK_ABI_NAMESPACE_END
2150 } // end namespace vtk_detail
2151 
2152 VTK_ABI_NAMESPACE_BEGIN
2153 //-----------------------------------------------------------------------------
2154 #if defined(VTK_HAS_ISINF) || defined(VTK_HAS_STD_ISINF)
2155 #define VTK_MATH_ISINF_IS_INLINE
2156 inline vtkTypeBool vtkMath::IsInf(double x)
2157 {
2158 #if defined(VTK_HAS_STD_ISINF)
2159  return std::isinf(x);
2160 #else
2161  return (isinf(x) != 0); // Force conversion to bool
2162 #endif
2163 }
2164 #endif
2165 
2166 //-----------------------------------------------------------------------------
2167 #if defined(VTK_HAS_ISNAN) || defined(VTK_HAS_STD_ISNAN)
2168 #define VTK_MATH_ISNAN_IS_INLINE
2169 inline vtkTypeBool vtkMath::IsNan(double x)
2170 {
2171 #if defined(VTK_HAS_STD_ISNAN)
2172  return std::isnan(x);
2173 #else
2174  return (isnan(x) != 0); // Force conversion to bool
2175 #endif
2176 }
2177 #endif
2178 
2179 //-----------------------------------------------------------------------------
2180 #if defined(VTK_HAS_ISFINITE) || defined(VTK_HAS_STD_ISFINITE) || defined(VTK_HAS_FINITE)
2181 #define VTK_MATH_ISFINITE_IS_INLINE
2182 inline bool vtkMath::IsFinite(double x)
2183 {
2184 #if defined(VTK_HAS_STD_ISFINITE)
2185  return std::isfinite(x);
2186 #elif defined(VTK_HAS_ISFINITE)
2187  return (isfinite(x) != 0); // Force conversion to bool
2188 #else
2189  return (finite(x) != 0); // Force conversion to bool
2190 #endif
2191 }
2192 #endif
2193 
2194 VTK_ABI_NAMESPACE_END
2195 #endif
static void MultiplyScalar2D(float a[2], float s)
Multiplies a 2-vector by a scalar (float version).
Definition: vtkMath.h:407
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:681
static float Dot(const float a[3], const float b[3])
Dot product of two 3-vectors (float version).
Definition: vtkMath.h:442
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:1635
abstract base class for most VTK objects
Definition: vtkObject.h:51
static void LabToXYZ(const double lab[3], double xyz[3])
Convert color from the CIE-L*ab system to CIE XYZ.
Definition: vtkMath.h:1310
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:1680
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:496
void RoundDoubleToIntegralIfNecessary(double val, OutT *ret)
Definition: vtkMath.h:2120
static float Determinant2x2(const float c1[2], const float c2[2])
Compute determinant of 2x2 matrix.
Definition: vtkMath.h:743
static vtkSmartPointer< vtkMathInternal > Internal
Definition: vtkMath.h:1648
static void QuaternionToMatrix3x3(const float quat[4], float A[3][3])
Convert a quaternion to a 3x3 rotation matrix.
Definition: vtkMath.h:2020
static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4])
Convert a 3x3 matrix into a quaternion.
Definition: vtkMath.h:2096
static vtkTypeBool IsInf(double x)
Test if a number is equal to the special floating point value infinity.
static ScalarT Dot(const VectorT1 &x, const VectorT2 &y)
Computes the dot product between 2 vectors x and y.
Definition: vtkMath.h:865
static constexpr double Pi()
A mathematical constant.
Definition: vtkMath.h:88
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:1279
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:110
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:1274
int vtkIdType
Definition: vtkType.h:315
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:1926
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:482
static void MultiplyMatrixWithVector(const MatrixT &M, const VectorT1 &X, VectorT2 &&Y)
Multiply matrix M with vector Y such that Y = M x X.
Definition: vtkMath.h:854
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:334
static double Dot(const double a[3], const double b[3])
Dot product of two 3-vectors (double version).
Definition: vtkMath.h:450
static void XYZToRGB(const double xyz[3], double rgb[3])
Convert color from the CIE XYZ system to RGB.
Definition: vtkMath.h:1332
static float Norm2D(const float x[2])
Compute the norm of a 2-vector.
Definition: vtkMath.h:720
detail::ScalarTypeExtractor< std::is_array< DerefContainer >::value||std::is_pointer< DerefContainer >::value, ContainerT >::value_type value_type
static void UninitializeBounds(double bounds[6])
Set the bounds to an uninitialized state.
Definition: vtkMath.h:1379
double vtkDeterminant3x3(const T A[3][3])
Definition: vtkMath.h:1869
static int NearestPowerOfTwo(int x)
Compute the nearest power of two that is not less than x.
Definition: vtkMath.h:1687
static void RGBToXYZ(const double rgb[3], double xyz[3])
Convert color from the RGB system to CIE XYZ.
Definition: vtkMath.h:1343
static void LinearSolve(const MatrixT &M, const VectorT1 &x, VectorT2 &y)
This method solves linear systems M * x = y.
Definition: vtkMath.h:931
static T Min(const T &a, const T &b)
Returns the minimum of the two arguments provided.
Definition: vtkMath.h:1718
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:1759
static void Subtract(const float a[3], const float b[3], float c[3])
Subtraction of two 3-vectors (float version).
Definition: vtkMath.h:359
static void Subtract(const double a[3], const double b[3], double c[3])
Subtraction of two 3-vectors (double version).
Definition: vtkMath.h:370
static int Floor(double x)
Rounds a double to the nearest integer not greater than itself.
Definition: vtkMath.h:1701
static double Determinant3x3(const float A[3][3])
Return the determinant of a 3x3 matrix.
Definition: vtkMath.h:1876
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:558
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:1590
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:752
static float RadiansFromDegrees(float degrees)
Convert degrees into radians.
Definition: vtkMath.h:1656
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:1299
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:419
static void RGBToLab(const double rgb[3], double lab[3])
Convert color from the RGB system to CIE-L*ab.
Definition: vtkMath.h:1357
static float DegreesFromRadians(float radians)
Convert radians into degrees.
Definition: vtkMath.h:1668
static float Normalize(float v[3])
Normalize (in place) a 3-vector.
Definition: vtkMath.h:1731
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:705
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:691
static int Ceil(double x)
Rounds a double to the nearest integer not less than itself.
Definition: vtkMath.h:1710
static void Cross(VectorT1 &&a, VectorT2 &&b, VectorT3 &c)
Cross product of two 3-vectors.
Definition: vtkMath.h:1832
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:686
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:119
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:538
static void MultiplyScalar(float a[3], float s)
Multiplies a 3-vector by a scalar (float version).
Definition: vtkMath.h:395
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:1294
static void Subtract(const VectorT1 &a, const VectorT2 &b, VectorT3 &&c)
Subtraction of two 3-vectors (templated version).
Definition: vtkMath.h:384
static T ClampValue(const T &value, const T &min, const T &max)
Clamp some value against a range, return the result.
Definition: vtkMath.h:1889
static double Norm2D(const double x[2])
Compute the norm of a 2-vector.
Definition: vtkMath.h:726
static void InvertMatrix(const MatrixT1 &M1, MatrixT2 &&M2)
Computes the inverse of input matrix M1 into M2.
Definition: vtkMath.h:911
static int Round(double f)
Definition: vtkMath.h:111
static void Add(VectorT1 &&a, VectorT2 &&b, VectorT3 &c)
Addition of two 3-vectors (double version).
Definition: vtkMath.h:348
static ReturnTypeT Dot(const TupleRangeT1 &a, const TupleRangeT2 &b)
Compute dot product between two points p1 and p2.
Definition: vtkMath.h:474
static double Norm(const double v[3])
Compute the norm of 3-vector (double version).
Definition: vtkMath.h:543
static void MultiplyScalar2D(double a[2], double s)
Multiplies a 2-vector by a scalar (double version).
Definition: vtkMath.h:431
static void LabToRGB(const double lab[3], double rgb[3])
Convert color from the CIE-L*ab system to RGB.
Definition: vtkMath.h:1368
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 ScalarT Dot(const VectorT1 &x, const MatrixT &M, const 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:952
static vtkIdType ComputeGCD(vtkIdType m, vtkIdType n)
Compute the greatest common divisor (GCD) of two positive integers m and n.
Definition: vtkMath.h:1555
static ReturnTypeT Distance2BetweenPoints(const TupleRangeT1 &p1, const TupleRangeT2 &p2)
Compute distance squared between two points p1 and p2.
Definition: vtkMath.h:1824
ConvolutionMode
Support the convolution operations.
Definition: vtkMath.h:1560
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:753
static void Add(const float a[3], const float b[3], float c[3])
Addition of two 3-vectors (float version).
Definition: vtkMath.h:323
Matrix wrapping class.
static void MultiplyMatrix(const MatrixT1 &M1, const MatrixT2 &M2, MatrixT3 &&M3)
Multiply matrices such that M3 = M1 x M2.
Definition: vtkMath.h:827
Template defining traits of native types used by VTK.
Definition: vtkTypeTraits.h:23
static vtkTypeBool AreBoundsInitialized(const double bounds[6])
Are the bounds initialized?
Definition: vtkMath.h:1394
#define max(a, b)
represent and manipulate 3D points
Definition: vtkPoints.h:28
static void Assign(const VectorT1 &a, VectorT2 &&b)
Assign values to a 3-vector (templated version).
Definition: vtkMath.h:308
static T Max(const T &a, const T &b)
Returns the maximum of the two arguments provided.
Definition: vtkMath.h:1725
static vtkMatrixUtilities::ScalarTypeExtractor< MatrixT >::value_type Determinant(const MatrixT &M)
Computes the determinant of input square SizeT x SizeT matrix M.
Definition: vtkMath.h:888
static void Assign(const double a[3], double b[3])
Assign values to a 3-vector (double version).
Definition: vtkMath.h:318
static void XYZToLab(const double xyz[3], double lab[3])
Convert Color from the CIE XYZ system to CIE-L*ab.
Definition: vtkMath.h:1321