VTK
vtkMath.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkMath.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================
15  Copyright 2011 Sandia Corporation.
16  Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
17  license for use of this work by or on behalf of the
18  U.S. Government. Redistribution and use in source and binary forms, with
19  or without modification, are permitted provided that this Notice and any
20  statement of authorship are reproduced on all copies.
21 
22  Contact: pppebay@sandia.gov,dcthomp@sandia.gov
23 
24 =========================================================================*/
43 #ifndef __vtkMath_h
44 #define __vtkMath_h
45 
46 #include "vtkCommonCoreModule.h" // For export macro
47 #include "vtkObject.h"
48 
49 #include <assert.h> // assert() in inline implementations.
50 
51 #ifndef DBL_MIN
52 # define VTK_DBL_MIN 2.2250738585072014e-308
53 #else // DBL_MIN
54 # define VTK_DBL_MIN DBL_MIN
55 #endif // DBL_MIN
56 
57 #ifndef DBL_EPSILON
58 # define VTK_DBL_EPSILON 2.2204460492503131e-16
59 #else // DBL_EPSILON
60 # define VTK_DBL_EPSILON DBL_EPSILON
61 #endif // DBL_EPSILON
62 #include "vtkMathConfigure.h" // For VTK_HAS_ISINF and VTK_HAS_ISNAN
63 
64 #ifndef VTK_DBL_EPSILON
65 # ifndef DBL_EPSILON
66 # define VTK_DBL_EPSILON 2.2204460492503131e-16
67 # else // DBL_EPSILON
68 # define VTK_DBL_EPSILON DBL_EPSILON
69 # endif // DBL_EPSILON
70 #endif // VTK_DBL_EPSILON
71 
72 class vtkDataArray;
73 class vtkPoints;
74 class vtkMathInternal;
77 
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);
84 
86  static float Pi() { return 3.14159265358979f; };
87 
90  static double DoubleTwoPi() { return 6.283185307179586; };
91 
94  static double DoublePi() { return 3.1415926535897932384626; };
95 
97 
98  static float RadiansFromDegrees( float degrees);
99  static double RadiansFromDegrees( double degrees);
101 
103 
104  static float DegreesFromRadians( float radians);
105  static double DegreesFromRadians( double radians);
107 
109 
110  static int Round(float f) {
111  return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
112  static int Round(double f) {
113  return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
115 
118  static int Floor(double x);
119 
122  static int Ceil(double x);
123 
126  static vtkTypeInt64 Factorial( int N );
127 
131  static vtkTypeInt64 Binomial( int m, int n );
132 
139  static int* BeginCombination( int m, int n );
140 
147  static int NextCombination( int m, int n, int* combination );
148 
150  static void FreeCombination( int* combination);
151 
163  static void RandomSeed(int s);
164 
173  static int GetSeed();
174 
184  static double Random();
185 
194  static double Random( double min, double max );
195 
204  static double Gaussian();
205 
215  static double Gaussian( double mean, double std );
216 
218 
219  static void Add(const float a[3], const float b[3], float c[3]) {
220  for (int i = 0; i < 3; ++i)
221  c[i] = a[i] + b[i];
222  }
224 
226 
227  static void Add(const double a[3], const double b[3], double c[3]) {
228  for (int i = 0; i < 3; ++i)
229  c[i] = a[i] + b[i];
230  }
232 
234 
236  static void Subtract(const float a[3], const float b[3], float c[3]) {
237  for (int i = 0; i < 3; ++i)
238  c[i] = a[i] - b[i];
239  }
241 
243 
245  static void Subtract(const double a[3], const double b[3], double c[3]) {
246  for (int i = 0; i < 3; ++i)
247  c[i] = a[i] - b[i];
248  }
250 
252 
254  static void MultiplyScalar(float a[3], float s) {
255  for (int i = 0; i < 3; ++i)
256  a[i] *= s;
257  }
259 
261 
263  static void MultiplyScalar2D(float a[2], float s) {
264  for (int i = 0; i < 2; ++i)
265  a[i] *= s;
266  }
268 
270 
272  static void MultiplyScalar(double a[3], double s) {
273  for (int i = 0; i < 3; ++i)
274  a[i] *= s;
275  }
277 
279 
281  static void MultiplyScalar2D(double a[2], double s) {
282  for (int i = 0; i < 2; ++i)
283  a[i] *= s;
284  }
286 
288 
289  static float Dot(const float x[3], const float y[3]) {
290  return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
292 
294 
295  static double Dot(const double x[3], const double y[3]) {
296  return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
298 
300 
301  static void Outer(const float x[3], const float y[3], float A[3][3]) {
302  for (int i=0; i < 3; i++)
303  for (int j=0; j < 3; j++)
304  A[i][j] = x[i] * y[j];
305  }
307 
308 
309  static void Outer(const double x[3], const double y[3], double A[3][3]) {
310  for (int i=0; i < 3; i++)
311  for (int j=0; j < 3; j++)
312  A[i][j] = x[i] * y[j];
313  }
315 
317  static void Cross(const float x[3], const float y[3], float z[3]);
318 
321  static void Cross(const double x[3], const double y[3], double z[3]);
322 
324 
325  static float Norm(const float* x, int n);
326  static double Norm(const double* x, int n);
328 
330 
331  static float Norm(const float x[3]) {
332  return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ) );};
334 
336 
337  static double Norm(const double x[3]) {
338  return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );};
340 
342  static float Normalize(float x[3]);
343 
346  static double Normalize(double x[3]);
347 
349 
354  static void Perpendiculars(const double x[3], double y[3], double z[3],
355  double theta);
356  static void Perpendiculars(const float x[3], float y[3], float z[3],
357  double theta);
359 
361 
364  static bool ProjectVector(const float a[3], const float b[3], float projection[3]);
365  static bool ProjectVector(const double a[3], const double b[3], double projection[3]);
367 
369 
373  static bool ProjectVector2D(const float a[2], const float b[2], float projection[2]);
374  static bool ProjectVector2D(const double a[2], const double b[2], double projection[2]);
376 
378  static float Distance2BetweenPoints(const float x[3], const float y[3]);
379 
382  static double Distance2BetweenPoints(const double x[3], const double y[3]);
383 
387  static double GaussianAmplitude(const double variance, const double distanceFromMean);
388 
392  static double GaussianAmplitude(const double mean, const double variance, const double position);
393 
398  static double GaussianWeight(const double variance, const double distanceFromMean);
399 
404  static double GaussianWeight(const double mean, const double variance, const double position);
405 
407 
408  static float Dot2D(const float x[2], const float y[2]) {
409  return ( x[0] * y[0] + x[1] * y[1] );};
411 
413 
414  static double Dot2D(const double x[2], const double y[2]) {
415  return ( x[0] * y[0] + x[1] * y[1] );};
417 
419 
420  static void Outer2D(const float x[2], const float y[2], float A[2][2])
421  {
422  for (int i=0; i < 2; i++)
423  {
424  for (int j=0; j < 2; j++)
425  {
426  A[i][j] = x[i] * y[j];
427  }
428  }
429  }
431 
432 
433  static void Outer2D(const double x[2], const double y[2], double A[2][2])
434  {
435  for (int i=0; i < 2; i++)
436  {
437  for (int j=0; j < 2; j++)
438  {
439  A[i][j] = x[i] * y[j];
440  }
441  }
442  }
444 
446 
447  static float Norm2D(const float x[2]) {
448  return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] ) );};
450 
452 
453  static double Norm2D(const double x[2]) {
454  return sqrt( x[0] * x[0] + x[1] * x[1] );};
456 
458  static float Normalize2D(float x[2]);
459 
462  static double Normalize2D(double x[2]);
463 
465 
466  static float Determinant2x2(const float c1[2], const float c2[2]) {
467  return (c1[0] * c2[1] - c2[0] * c1[1] );};
469 
471 
472  static double Determinant2x2(double a, double b, double c, double d) {
473  return (a * d - b * c);};
474  static double Determinant2x2(const double c1[2], const double c2[2]) {
475  return (c1[0] * c2[1] - c2[0] * c1[1] );};
477 
479 
480  static void LUFactor3x3(float A[3][3], int index[3]);
481  static void LUFactor3x3(double A[3][3], int index[3]);
483 
485 
486  static void LUSolve3x3(const float A[3][3], const int index[3],
487  float x[3]);
488  static void LUSolve3x3(const double A[3][3], const int index[3],
489  double x[3]);
491 
493 
495  static void LinearSolve3x3(const float A[3][3], const float x[3],
496  float y[3]);
497  static void LinearSolve3x3(const double A[3][3], const double x[3],
498  double y[3]);
500 
502 
503  static void Multiply3x3(const float A[3][3], const float in[3],
504  float out[3]);
505  static void Multiply3x3(const double A[3][3], const double in[3],
506  double out[3]);
508 
510 
511  static void Multiply3x3(const float A[3][3], const float B[3][3],
512  float C[3][3]);
513  static void Multiply3x3(const double A[3][3], const double B[3][3],
514  double C[3][3]);
516 
518 
520  static void MultiplyMatrix(const double **A, const double **B,
521  unsigned int rowA, unsigned int colA,
522  unsigned int rowB, unsigned int colB,
523  double **C);
525 
527 
529  static void Transpose3x3(const float A[3][3], float AT[3][3]);
530  static void Transpose3x3(const double A[3][3], double AT[3][3]);
532 
534 
536  static void Invert3x3(const float A[3][3], float AI[3][3]);
537  static void Invert3x3(const double A[3][3], double AI[3][3]);
539 
541 
542  static void Identity3x3(float A[3][3]);
543  static void Identity3x3(double A[3][3]);
545 
547 
548  static double Determinant3x3(float A[3][3]);
549  static double Determinant3x3(double A[3][3]);
551 
553 
554  static float Determinant3x3(const float c1[3],
555  const float c2[3],
556  const float c3[3]);
558 
560 
561  static double Determinant3x3(const double c1[3],
562  const double c2[3],
563  const double c3[3]);
565 
567 
569  static double Determinant3x3(double a1, double a2, double a3,
570  double b1, double b2, double b3,
571  double c1, double c2, double c3);
573 
575 
577  static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]);
578  static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]);
580 
582 
585  static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
586  static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
588 
590 
591  static void MultiplyQuaternion( const float q1[4], const float q2[4], float q[4] );
592  static void MultiplyQuaternion( const double q1[4], const double q2[4], double q[4] );
594 
596 
599  static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
600  static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
602 
604 
608  static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
609  static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]);
611 
613 
620  static void SingularValueDecomposition3x3(const float A[3][3],
621  float U[3][3], float w[3],
622  float VT[3][3]);
623  static void SingularValueDecomposition3x3(const double A[3][3],
624  double U[3][3], double w[3],
625  double VT[3][3]);
627 
632  static int SolveLinearSystem(double **A, double *x, int size);
633 
637  static int InvertMatrix(double **A, double **AI, int size);
638 
640 
642  static int InvertMatrix(double **A, double **AI, int size,
643  int *tmp1Size, double *tmp2Size);
645 
651  static int LUFactorLinearSystem(double **A, int *index, int size);
652 
654 
656  static int LUFactorLinearSystem(double **A, int *index, int size,
657  double *tmpSize);
659 
661 
667  static void LUSolveLinearSystem(double **A, int *index,
668  double *x, int size);
670 
678  static double EstimateMatrixCondition(double **A, int size);
679 
681 
685  static int Jacobi(float **a, float *w, float **v);
686  static int Jacobi(double **a, double *w, double **v);
688 
690 
695  static int JacobiN(float **a, int n, float *w, float **v);
696  static int JacobiN(double **a, int n, double *w, double **v);
698 
700 
710  static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder,
711  double **mt);
713 
714 
716 
727  static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
728  double **yt, int yOrder, double **mt, int checkHomogeneous=1);
730 
732 
736  static void RGBToHSV(const float rgb[3], float hsv[3])
737  { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
738  static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v);
739  static double* RGBToHSV(const double rgb[3]);
740  static double* RGBToHSV(double r, double g, double b);
741  static void RGBToHSV(const double rgb[3], double hsv[3])
742  { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
743  static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v);
745 
747 
749  static void HSVToRGB(const float hsv[3], float rgb[3])
750  { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
751  static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b);
752  static double* HSVToRGB(const double hsv[3]);
753  static double* HSVToRGB(double h, double s, double v);
754  static void HSVToRGB(const double hsv[3], double rgb[3])
755  { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
756  static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b);
758 
760 
761  static void LabToXYZ(const double lab[3], double xyz[3]) {
762  LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2);
763  }
764  static void LabToXYZ(double L, double a, double b,
765  double *x, double *y, double *z);
766  static double *LabToXYZ(const double lab[3]);
768 
770 
771  static void XYZToLab(const double xyz[3], double lab[3]) {
772  XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2);
773  }
774  static void XYZToLab(double x, double y, double z,
775  double *L, double *a, double *b);
776  static double *XYZToLab(const double xyz[3]);
778 
780 
781  static void XYZToRGB(const double xyz[3], double rgb[3]) {
782  XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2);
783  }
784  static void XYZToRGB(double x, double y, double z,
785  double *r, double *g, double *b);
786  static double *XYZToRGB(const double xyz[3]);
788 
790 
791  static void RGBToXYZ(const double rgb[3], double xyz[3]) {
792  RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2);
793  }
794  static void RGBToXYZ(double r, double g, double b,
795  double *x, double *y, double *z);
796  static double *RGBToXYZ(const double rgb[3]);
798 
800 
803  static void RGBToLab(const double rgb[3], double lab[3]) {
804  RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2);
805  }
806  static void RGBToLab(double red, double green, double blue,
807  double *L, double *a, double *b);
808  static double *RGBToLab(const double rgb[3]);
810 
812 
813  static void LabToRGB(const double lab[3], double rgb[3]) {
814  LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2);
815  }
816  static void LabToRGB(double L, double a, double b,
817  double *red, double *green, double *blue);
818  static double *LabToRGB(const double lab[3]);
820 
822 
823  static void UninitializeBounds(double bounds[6]){
824  bounds[0] = 1.0;
825  bounds[1] = -1.0;
826  bounds[2] = 1.0;
827  bounds[3] = -1.0;
828  bounds[4] = 1.0;
829  bounds[5] = -1.0;
830  }
832 
834 
835  static int AreBoundsInitialized(double bounds[6]){
836  if ( bounds[1]-bounds[0]<0.0 )
837  {
838  return 0;
839  }
840  return 1;
841  }
843 
845 
847  static void ClampValue(double *value, const double range[2]);
848  static void ClampValue(double value, const double range[2], double *clamped_value);
849  static void ClampValues(
850  double *values, int nb_values, const double range[2]);
851  static void ClampValues(
852  const double *values, int nb_values, const double range[2], double *clamped_values);
854 
856 
859  static double ClampAndNormalizeValue(double value,
860  const double range[2]);
862 
864 
870  static int GetScalarTypeFittingRange(
871  double range_min, double range_max,
872  double scale = 1.0, double shift = 0.0);
874 
876 
882  static int GetAdjustedScalarRange(
883  vtkDataArray *array, int comp, double range[2]);
885 
888  static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]);
889 
893  static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]);
894 
898  static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]);
899 
907  static double Solve3PointCircle(const double p1[3], const double p2[3], const double p3[3], double center[3]);
908 
910  static double Inf();
911 
913  static double NegInf();
914 
916  static double Nan();
917 
920  static int IsInf(double x);
921 
924  static int IsNan(double x);
925 
926 protected:
927  vtkMath() {};
928  ~vtkMath() {};
929 
930  static vtkMathInternal Internal;
931 private:
932  vtkMath(const vtkMath&); // Not implemented.
933  void operator=(const vtkMath&); // Not implemented.
934 };
935 
936 //----------------------------------------------------------------------------
937 inline float vtkMath::RadiansFromDegrees( float x )
938 {
939  return x * 0.017453292f;
940 }
941 
942 //----------------------------------------------------------------------------
943 inline double vtkMath::RadiansFromDegrees( double x )
944 {
945  return x * 0.017453292519943295;
946 }
947 
948 //----------------------------------------------------------------------------
949 inline float vtkMath::DegreesFromRadians( float x )
950 {
951  return x * 57.2957795131f;
952 }
953 
954 //----------------------------------------------------------------------------
955 inline double vtkMath::DegreesFromRadians( double x )
956 {
957  return x * 57.29577951308232;
958 }
959 
960 //----------------------------------------------------------------------------
961 inline vtkTypeInt64 vtkMath::Factorial( int N )
962 {
963  vtkTypeInt64 r = 1;
964  while ( N > 1 )
965  {
966  r *= N--;
967  }
968  return r;
969 }
970 
971 //----------------------------------------------------------------------------
972 // Modify the trunc() operation provided by static_cast<int>() to get floor(),
973 // if x<0 (condition g) and x!=trunc(x) (condition n) then floor(x)=trunc(x)-1
974 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
975 inline int vtkMath::Floor(double x)
976 {
977  const int r = static_cast<int>(x);
978  const int n = ( x != static_cast<double>(r) );
979  const int g = ( x < 0 );
980  return r - ( n & g );
981 }
982 
983 //----------------------------------------------------------------------------
984 // Modify the trunc() operation provided by static_cast<int>() to get ceil(),
985 // if x>=0 (condition g) and x!=trunc(x) (condition n) then ceil(x)=trunc(x)+1
986 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
987 inline int vtkMath::Ceil(double x)
988 {
989  const int r = static_cast<int>(x);
990  const int n = ( x != static_cast<double>(r) );
991  const int g = ( x >= 0 );
992  return r + ( n & g );
993 }
994 
995 //----------------------------------------------------------------------------
996 inline float vtkMath::Normalize(float x[3])
997 {
998  float den;
999  if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
1000  {
1001  for (int i=0; i < 3; i++)
1002  {
1003  x[i] /= den;
1004  }
1005  }
1006  return den;
1007 }
1008 
1009 //----------------------------------------------------------------------------
1010 inline double vtkMath::Normalize(double x[3])
1011 {
1012  double den;
1013  if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
1014  {
1015  for (int i=0; i < 3; i++)
1016  {
1017  x[i] /= den;
1018  }
1019  }
1020  return den;
1021 }
1022 
1023 //----------------------------------------------------------------------------
1024 inline float vtkMath::Normalize2D(float x[3])
1025 {
1026  float den;
1027  if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
1028  {
1029  for (int i=0; i < 2; i++)
1030  {
1031  x[i] /= den;
1032  }
1033  }
1034  return den;
1035 }
1036 
1037 //----------------------------------------------------------------------------
1038 inline double vtkMath::Normalize2D(double x[3])
1039 {
1040  double den;
1041  if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
1042  {
1043  for (int i=0; i < 2; i++)
1044  {
1045  x[i] /= den;
1046  }
1047  }
1048  return den;
1049 }
1050 
1051 //----------------------------------------------------------------------------
1052 inline float vtkMath::Determinant3x3(const float c1[3],
1053  const float c2[3],
1054  const float c3[3])
1055 {
1056  return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
1057  c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
1058 }
1059 
1060 //----------------------------------------------------------------------------
1061 inline double vtkMath::Determinant3x3(const double c1[3],
1062  const double c2[3],
1063  const double c3[3])
1064 {
1065  return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
1066  c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
1067 }
1068 
1069 //----------------------------------------------------------------------------
1070 inline double vtkMath::Determinant3x3(double a1, double a2, double a3,
1071  double b1, double b2, double b3,
1072  double c1, double c2, double c3)
1073 {
1074  return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
1075  - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
1076  + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
1077 }
1078 
1079 //----------------------------------------------------------------------------
1080 inline float vtkMath::Distance2BetweenPoints(const float x[3],
1081  const float y[3])
1082 {
1083  return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
1084  + ( x[1] - y[1] ) * ( x[1] - y[1] )
1085  + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
1086 }
1087 
1088 //----------------------------------------------------------------------------
1089 inline double vtkMath::Distance2BetweenPoints(const double x[3],
1090  const double y[3])
1091 {
1092  return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
1093  + ( x[1] - y[1] ) * ( x[1] - y[1] )
1094  + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
1095 }
1096 
1097 //----------------------------------------------------------------------------
1098 // Cross product of two 3-vectors. Result (a x b) is stored in z[3].
1099 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
1100 {
1101  float Zx = x[1] * y[2] - x[2] * y[1];
1102  float Zy = x[2] * y[0] - x[0] * y[2];
1103  float Zz = x[0] * y[1] - x[1] * y[0];
1104  z[0] = Zx; z[1] = Zy; z[2] = Zz;
1105 }
1106 
1107 //----------------------------------------------------------------------------
1108 // Cross product of two 3-vectors. Result (a x b) is stored in z[3].
1109 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3])
1110 {
1111  double Zx = x[1] * y[2] - x[2] * y[1];
1112  double Zy = x[2] * y[0] - x[0] * y[2];
1113  double Zz = x[0] * y[1] - x[1] * y[0];
1114  z[0] = Zx; z[1] = Zy; z[2] = Zz;
1115 }
1116 
1117 //BTX
1118 //----------------------------------------------------------------------------
1119 template<class T>
1120 inline double vtkDeterminant3x3(T A[3][3])
1121 {
1122  return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] +
1123  A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] -
1124  A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2];
1125 }
1126 //ETX
1127 
1128 //----------------------------------------------------------------------------
1129 inline double vtkMath::Determinant3x3(float A[3][3])
1130 {
1131  return vtkDeterminant3x3( A );
1132 }
1133 
1134 //----------------------------------------------------------------------------
1135 inline double vtkMath::Determinant3x3(double A[3][3])
1136 {
1137  return vtkDeterminant3x3( A );
1138 }
1139 
1140 //----------------------------------------------------------------------------
1141 inline void vtkMath::ClampValue(double *value, const double range[2])
1142 {
1143  if (value && range)
1144  {
1145  if (*value < range[0])
1146  {
1147  *value = range[0];
1148  }
1149  else if (*value > range[1])
1150  {
1151  *value = range[1];
1152  }
1153  }
1154 }
1155 
1156 //----------------------------------------------------------------------------
1158  double value, const double range[2], double *clamped_value)
1159 {
1160  if (range && clamped_value)
1161  {
1162  if (value < range[0])
1163  {
1164  *clamped_value = range[0];
1165  }
1166  else if (value > range[1])
1167  {
1168  *clamped_value = range[1];
1169  }
1170  else
1171  {
1172  *clamped_value = value;
1173  }
1174  }
1175 }
1176 
1177 // ---------------------------------------------------------------------------
1179  const double range[2])
1180 {
1181  assert("pre: valid_range" && range[0]<=range[1]);
1182 
1183  double result;
1184  if(range[0]==range[1])
1185  {
1186  result=0.0;
1187  }
1188  else
1189  {
1190  // clamp
1191  if(value<range[0])
1192  {
1193  result=range[0];
1194  }
1195  else
1196  {
1197  if(value>range[1])
1198  {
1199  result=range[1];
1200  }
1201  else
1202  {
1203  result=value;
1204  }
1205  }
1206 
1207  // normalize
1208  result=( result - range[0] ) / ( range[1] - range[0] );
1209  }
1210 
1211  assert("post: valid_result" && result>=0.0 && result<=1.0);
1212 
1213  return result;
1214 }
1215 
1216 #if defined(VTK_HAS_ISINF)
1217 //-----------------------------------------------------------------------------
1218 inline int vtkMath::IsInf(double x)
1219 {
1220  return (isinf(x) ? 1 : 0);
1221 }
1222 #endif
1223 
1224 #if defined(VTK_HAS_ISNAN)
1225 //-----------------------------------------------------------------------------
1226 inline int vtkMath::IsNan(double x)
1227 {
1228  return (isnan(x) ? 1 : 0);
1229 }
1230 #endif
1231 
1232 #endif