VTK
dox/Common/Core/vtkMath.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkMath.h
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================
00015   Copyright 2011 Sandia Corporation.
00016   Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00017   license for use of this work by or on behalf of the
00018   U.S. Government. Redistribution and use in source and binary forms, with
00019   or without modification, are permitted provided that this Notice and any
00020   statement of authorship are reproduced on all copies.
00021 
00022   Contact: pppebay@sandia.gov,dcthomp@sandia.gov
00023 
00024 =========================================================================*/
00044 #ifndef __vtkMath_h
00045 #define __vtkMath_h
00046 
00047 #include "vtkCommonCoreModule.h" // For export macro
00048 #include "vtkObject.h"
00049 
00050 #include "vtkMathConfigure.h" // For <cmath> and VTK_HAS_ISNAN etc.
00051 
00052 #include <cassert> // assert() in inline implementations.
00053 
00054 #ifndef DBL_MIN
00055 #  define VTK_DBL_MIN    2.2250738585072014e-308
00056 #else  // DBL_MIN
00057 #  define VTK_DBL_MIN    DBL_MIN
00058 #endif  // DBL_MIN
00059 
00060 #ifndef DBL_EPSILON
00061 #  define VTK_DBL_EPSILON    2.2204460492503131e-16
00062 #else  // DBL_EPSILON
00063 #  define VTK_DBL_EPSILON    DBL_EPSILON
00064 #endif  // DBL_EPSILON
00065 
00066 #ifndef VTK_DBL_EPSILON
00067 #  ifndef DBL_EPSILON
00068 #    define VTK_DBL_EPSILON    2.2204460492503131e-16
00069 #  else  // DBL_EPSILON
00070 #    define VTK_DBL_EPSILON    DBL_EPSILON
00071 #  endif  // DBL_EPSILON
00072 #endif  // VTK_DBL_EPSILON
00073 
00074 class vtkDataArray;
00075 class vtkPoints;
00076 class vtkMathInternal;
00077 class vtkMinimalStandardRandomSequence;
00078 class vtkBoxMuellerRandomSequence;
00079 
00080 class VTKCOMMONCORE_EXPORT vtkMath : public vtkObject
00081 {
00082 public:
00083   static vtkMath *New();
00084   vtkTypeMacro(vtkMath,vtkObject);
00085   void PrintSelf(ostream& os, vtkIndent indent);
00086 
00088   static double Pi() { return 3.141592653589793; };
00089 
00091   VTK_LEGACY(static double DoublePi());
00092 
00094   VTK_LEGACY(static double DoubleTwoPi());
00095 
00097 
00098   static float RadiansFromDegrees( float degrees);
00099   static double RadiansFromDegrees( double degrees);
00101 
00103 
00104   static float DegreesFromRadians( float radians);
00105   static double DegreesFromRadians( double radians);
00107 
00109 
00110   static int Round(float f) {
00111     return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
00112   static int Round(double f) {
00113     return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
00115 
00118   static int Floor(double x);
00119 
00122   static int Ceil(double x);
00123 
00127   static int CeilLog2(vtkTypeUInt64 x);
00128 
00130   static bool IsPowerOfTwo(vtkTypeUInt64 x);
00131 
00135   static int NearestPowerOfTwo(int x);
00136 
00139   static vtkTypeInt64 Factorial( int N );
00140 
00144   static vtkTypeInt64 Binomial( int m, int n );
00145 
00152   static int* BeginCombination( int m, int n );
00153 
00160   static int NextCombination( int m, int n, int* combination );
00161 
00163   static void FreeCombination( int* combination);
00164 
00176   static void RandomSeed(int s);
00177 
00186   static int GetSeed();
00187 
00197   static double Random();
00198 
00207   static double Random( double min, double max );
00208 
00217   static double Gaussian();
00218 
00228   static double Gaussian( double mean, double std );
00229 
00231 
00232   static void Add(const float a[3], const float b[3], float c[3]) {
00233     for (int i = 0; i < 3; ++i)
00234       c[i] = a[i] + b[i];
00235   }
00237 
00239 
00240   static void Add(const double a[3], const double b[3], double c[3]) {
00241     for (int i = 0; i < 3; ++i)
00242       c[i] = a[i] + b[i];
00243   }
00245 
00247 
00249   static void Subtract(const float a[3], const float b[3], float c[3]) {
00250     for (int i = 0; i < 3; ++i)
00251       c[i] = a[i] - b[i];
00252   }
00254 
00256 
00258   static void Subtract(const double a[3], const double b[3], double c[3]) {
00259     for (int i = 0; i < 3; ++i)
00260       c[i] = a[i] - b[i];
00261   }
00263 
00265 
00267   static void MultiplyScalar(float a[3], float s) {
00268     for (int i = 0; i < 3; ++i)
00269       a[i] *= s;
00270   }
00272 
00274 
00276   static void MultiplyScalar2D(float a[2], float s) {
00277     for (int i = 0; i < 2; ++i)
00278       a[i] *= s;
00279   }
00281 
00283 
00285   static void MultiplyScalar(double a[3], double s) {
00286     for (int i = 0; i < 3; ++i)
00287       a[i] *= s;
00288   }
00290 
00292 
00294   static void MultiplyScalar2D(double a[2], double s) {
00295     for (int i = 0; i < 2; ++i)
00296       a[i] *= s;
00297   }
00299 
00301 
00302   static float Dot(const float x[3], const float y[3]) {
00303     return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
00305 
00307 
00308   static double Dot(const double x[3], const double y[3]) {
00309     return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
00311 
00313 
00314   static void Outer(const float x[3], const float y[3], float A[3][3]) {
00315     for (int i=0; i < 3; i++)
00316       for (int j=0; j < 3; j++)
00317         A[i][j] = x[i] * y[j];
00318   }
00320 
00321 
00322   static void Outer(const double x[3], const double y[3], double A[3][3]) {
00323     for (int i=0; i < 3; i++)
00324       for (int j=0; j < 3; j++)
00325         A[i][j] = x[i] * y[j];
00326   }
00328 
00330   static void Cross(const float x[3], const float y[3], float z[3]);
00331 
00334   static void Cross(const double x[3], const double y[3], double z[3]);
00335 
00337 
00338   static float Norm(const float* x, int n);
00339   static double Norm(const double* x, int n);
00341 
00343 
00344   static float Norm(const float x[3]) {
00345     return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ) );};
00347 
00349 
00350   static double Norm(const double x[3]) {
00351     return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );};
00353 
00355   static float Normalize(float x[3]);
00356 
00359   static double Normalize(double x[3]);
00360 
00362 
00367   static void Perpendiculars(const double x[3], double y[3], double z[3],
00368                              double theta);
00369   static void Perpendiculars(const float x[3], float y[3], float z[3],
00370                              double theta);
00372 
00374 
00377   static bool ProjectVector(const float a[3], const float b[3], float projection[3]);
00378   static bool ProjectVector(const double a[3], const double b[3], double projection[3]);
00380 
00382 
00386   static bool ProjectVector2D(const float a[2], const float b[2], float projection[2]);
00387   static bool ProjectVector2D(const double a[2], const double b[2], double projection[2]);
00389 
00391   static float Distance2BetweenPoints(const float x[3], const float y[3]);
00392 
00395   static double Distance2BetweenPoints(const double x[3], const double y[3]);
00396 
00400   static double GaussianAmplitude(const double variance, const double distanceFromMean);
00401 
00405   static double GaussianAmplitude(const double mean, const double variance, const double position);
00406 
00411   static double GaussianWeight(const double variance, const double distanceFromMean);
00412 
00417   static double GaussianWeight(const double mean, const double variance, const double position);
00418 
00420 
00421   static float Dot2D(const float x[2], const float y[2]) {
00422     return ( x[0] * y[0] + x[1] * y[1] );};
00424 
00426 
00427   static double Dot2D(const double x[2], const double y[2]) {
00428     return ( x[0] * y[0] + x[1] * y[1] );};
00430 
00432 
00433   static void Outer2D(const float x[2], const float y[2], float A[2][2])
00434     {
00435     for (int i=0; i < 2; i++)
00436       {
00437       for (int j=0; j < 2; j++)
00438         {
00439         A[i][j] = x[i] * y[j];
00440         }
00441       }
00442     }
00444 
00445 
00446   static void Outer2D(const double x[2], const double y[2], double A[2][2])
00447     {
00448     for (int i=0; i < 2; i++)
00449       {
00450       for (int j=0; j < 2; j++)
00451         {
00452         A[i][j] = x[i] * y[j];
00453         }
00454       }
00455     }
00457 
00459 
00460   static float Norm2D(const float x[2]) {
00461     return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] ) );};
00463 
00465 
00466   static double Norm2D(const double x[2]) {
00467     return sqrt( x[0] * x[0] + x[1] * x[1] );};
00469 
00471   static float Normalize2D(float x[2]);
00472 
00475   static double Normalize2D(double x[2]);
00476 
00478 
00479   static float Determinant2x2(const float c1[2], const float c2[2]) {
00480     return (c1[0] * c2[1] - c2[0] * c1[1] );};
00482 
00484 
00485   static double Determinant2x2(double a, double b, double c, double d) {
00486     return (a * d - b * c);};
00487   static double Determinant2x2(const double c1[2], const double c2[2]) {
00488     return (c1[0] * c2[1] - c2[0] * c1[1] );};
00490 
00492 
00493   static void LUFactor3x3(float A[3][3], int index[3]);
00494   static void LUFactor3x3(double A[3][3], int index[3]);
00496 
00498 
00499   static void LUSolve3x3(const float A[3][3], const int index[3],
00500                          float x[3]);
00501   static void LUSolve3x3(const double A[3][3], const int index[3],
00502                          double x[3]);
00504 
00506 
00508   static void LinearSolve3x3(const float A[3][3], const float x[3],
00509                              float y[3]);
00510   static void LinearSolve3x3(const double A[3][3], const double x[3],
00511                              double y[3]);
00513 
00515 
00516   static void Multiply3x3(const float A[3][3], const float in[3],
00517                           float out[3]);
00518   static void Multiply3x3(const double A[3][3], const double in[3],
00519                           double out[3]);
00521 
00523 
00524   static void Multiply3x3(const float A[3][3], const float B[3][3],
00525                           float C[3][3]);
00526   static void Multiply3x3(const double A[3][3], const double B[3][3],
00527                           double C[3][3]);
00529 
00531 
00533   static void MultiplyMatrix(const double **A, const double **B,
00534                              unsigned int rowA, unsigned int colA,
00535                              unsigned int rowB, unsigned int colB,
00536                              double **C);
00538 
00540 
00542   static void Transpose3x3(const float A[3][3], float AT[3][3]);
00543   static void Transpose3x3(const double A[3][3], double AT[3][3]);
00545 
00547 
00549   static void Invert3x3(const float A[3][3], float AI[3][3]);
00550   static void Invert3x3(const double A[3][3], double AI[3][3]);
00552 
00554 
00555   static void Identity3x3(float A[3][3]);
00556   static void Identity3x3(double A[3][3]);
00558 
00560 
00561   static double Determinant3x3(float A[3][3]);
00562   static double Determinant3x3(double A[3][3]);
00564 
00566 
00567   static float Determinant3x3(const float c1[3],
00568                               const float c2[3],
00569                               const float c3[3]);
00571 
00573 
00574   static double Determinant3x3(const double c1[3],
00575                                const double c2[3],
00576                                const double c3[3]);
00578 
00580 
00582   static double Determinant3x3(double a1, double a2, double a3,
00583                                double b1, double b2, double b3,
00584                                double c1, double c2, double c3);
00586 
00588 
00592   static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]);
00593   static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]);
00595 
00597 
00602   static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
00603   static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
00605 
00607 
00610   static void MultiplyQuaternion( const float q1[4], const float q2[4],  float q[4] );
00611   static void MultiplyQuaternion( const double q1[4], const double q2[4],  double q[4] );
00613 
00615 
00618   static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
00619   static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
00621 
00623 
00627   static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
00628   static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]);
00630 
00632 
00639   static void SingularValueDecomposition3x3(const float A[3][3],
00640                                             float U[3][3], float w[3],
00641                                             float VT[3][3]);
00642   static void SingularValueDecomposition3x3(const double A[3][3],
00643                                             double U[3][3], double w[3],
00644                                             double VT[3][3]);
00646 
00651   static int SolveLinearSystem(double **A, double *x, int size);
00652 
00656   static int InvertMatrix(double **A, double **AI, int size);
00657 
00659 
00661   static int InvertMatrix(double **A, double **AI, int size,
00662                           int *tmp1Size, double *tmp2Size);
00664 
00680   static int LUFactorLinearSystem(double **A, int *index, int size);
00681 
00683 
00685   static int LUFactorLinearSystem(double **A, int *index, int size,
00686                                   double *tmpSize);
00688 
00690 
00696   static void LUSolveLinearSystem(double **A, int *index,
00697                                   double *x, int size);
00699 
00707   static double EstimateMatrixCondition(double **A, int size);
00708 
00710 
00714   static int Jacobi(float **a, float *w, float **v);
00715   static int Jacobi(double **a, double *w, double **v);
00717 
00719 
00724   static int JacobiN(float **a, int n, float *w, float **v);
00725   static int JacobiN(double **a, int n, double *w, double **v);
00727 
00729 
00739   static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder,
00740                                 double **mt);
00742 
00743 
00745 
00756   static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
00757                                double **yt, int yOrder, double **mt, int checkHomogeneous=1);
00759 
00761 
00765   static void RGBToHSV(const float rgb[3], float hsv[3])
00766     { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00767   static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v);
00768   static double* RGBToHSV(const double rgb[3]);
00769   static double* RGBToHSV(double r, double g, double b);
00770   static void RGBToHSV(const double rgb[3], double hsv[3])
00771     { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00772   static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v);
00774 
00776 
00780   static void HSVToRGB(const float hsv[3], float rgb[3])
00781     { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00782   static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b);
00783   static double* HSVToRGB(const double hsv[3]);
00784   static double* HSVToRGB(double h, double s, double v);
00785   static void HSVToRGB(const double hsv[3], double rgb[3])
00786     { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00787   static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b);
00789 
00791 
00792   static void LabToXYZ(const double lab[3], double xyz[3]) {
00793     LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2);
00794   }
00795   static void LabToXYZ(double L, double a, double b,
00796                        double *x, double *y, double *z);
00797   static double *LabToXYZ(const double lab[3]);
00799 
00801 
00802   static void XYZToLab(const double xyz[3], double lab[3]) {
00803     XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2);
00804   }
00805   static void XYZToLab(double x, double y, double z,
00806                        double *L, double *a, double *b);
00807   static double *XYZToLab(const double xyz[3]);
00809 
00811 
00812   static void XYZToRGB(const double xyz[3], double rgb[3]) {
00813     XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2);
00814   }
00815   static void XYZToRGB(double x, double y, double z,
00816                        double *r, double *g, double *b);
00817   static double *XYZToRGB(const double xyz[3]);
00819 
00821 
00822   static void RGBToXYZ(const double rgb[3], double xyz[3]) {
00823     RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2);
00824   }
00825   static void RGBToXYZ(double r, double g, double b,
00826                        double *x, double *y, double *z);
00827   static double *RGBToXYZ(const double rgb[3]);
00829 
00831 
00834   static void RGBToLab(const double rgb[3], double lab[3]) {
00835     RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2);
00836   }
00837   static void RGBToLab(double red, double green, double blue,
00838                        double *L, double *a, double *b);
00839   static double *RGBToLab(const double rgb[3]);
00841 
00843 
00844   static void LabToRGB(const double lab[3], double rgb[3]) {
00845     LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2);
00846   }
00847   static void LabToRGB(double L, double a, double b,
00848                        double *red, double *green, double *blue);
00849   static double *LabToRGB(const double lab[3]);
00851 
00853 
00854   static void UninitializeBounds(double bounds[6]){
00855     bounds[0] = 1.0;
00856     bounds[1] = -1.0;
00857     bounds[2] = 1.0;
00858     bounds[3] = -1.0;
00859     bounds[4] = 1.0;
00860     bounds[5] = -1.0;
00861   }
00863 
00865 
00866   static int AreBoundsInitialized(double bounds[6]){
00867     if ( bounds[1]-bounds[0]<0.0 )
00868       {
00869       return 0;
00870       }
00871     return 1;
00872   }
00874 
00876 
00878   static void ClampValue(double *value, const double range[2]);
00879   static void ClampValue(double value, const double range[2], double *clamped_value);
00880   static void ClampValues(
00881     double *values, int nb_values, const double range[2]);
00882   static void ClampValues(
00883     const double *values, int nb_values, const double range[2], double *clamped_values);
00885 
00887 
00890   static double ClampAndNormalizeValue(double value,
00891                                        const double range[2]);
00893 
00895 
00901   static int GetScalarTypeFittingRange(
00902     double range_min, double range_max,
00903     double scale = 1.0, double shift = 0.0);
00905 
00907 
00913   static int GetAdjustedScalarRange(
00914     vtkDataArray *array, int comp, double range[2]);
00916 
00919   static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]);
00920 
00924   static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]);
00925 
00929   static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]);
00930 
00938   static double Solve3PointCircle(const double p1[3], const double p2[3], const double p3[3], double center[3]);
00939 
00941   static double Inf();
00942 
00944   static double NegInf();
00945 
00947   static double Nan();
00948 
00951   static int IsInf(double x);
00952 
00955   static int IsNan(double x);
00956 
00959   static bool IsFinite(double x);
00960 
00961 protected:
00962   vtkMath() {}
00963   ~vtkMath() {}
00964 
00965   static vtkMathInternal Internal;
00966 private:
00967   vtkMath(const vtkMath&);  // Not implemented.
00968   void operator=(const vtkMath&);  // Not implemented.
00969 };
00970 
00971 //----------------------------------------------------------------------------
00972 inline float vtkMath::RadiansFromDegrees( float x )
00973 {
00974   return x * 0.017453292f;
00975 }
00976 
00977 //----------------------------------------------------------------------------
00978 inline double vtkMath::RadiansFromDegrees( double x )
00979 {
00980   return x * 0.017453292519943295;
00981 }
00982 
00983 //----------------------------------------------------------------------------
00984 inline float vtkMath::DegreesFromRadians( float x )
00985 {
00986   return x * 57.2957795131f;
00987 }
00988 
00989 //----------------------------------------------------------------------------
00990 inline double vtkMath::DegreesFromRadians( double x )
00991 {
00992   return x * 57.29577951308232;
00993 }
00994 
00995 //----------------------------------------------------------------------------
00996 inline vtkTypeInt64 vtkMath::Factorial( int N )
00997 {
00998   vtkTypeInt64 r = 1;
00999   while ( N > 1 )
01000     {
01001     r *= N--;
01002     }
01003   return r;
01004 }
01005 
01006 //----------------------------------------------------------------------------
01007 inline bool vtkMath::IsPowerOfTwo(vtkTypeUInt64 x)
01008 {
01009   return ((x != 0) & ((x & (x - 1)) == 0));
01010 }
01011 
01012 //----------------------------------------------------------------------------
01013 // Credit goes to Peter Hart and William Lewis on comp.lang.python 1997
01014 inline int vtkMath::NearestPowerOfTwo(int x)
01015 {
01016   unsigned int z = ((x > 0) ? x - 1 : 0);
01017   z |= z >> 1;
01018   z |= z >> 2;
01019   z |= z >> 4;
01020   z |= z >> 8;
01021   z |= z >> 16;
01022   return static_cast<int>(z + 1);
01023 }
01024 
01025 //----------------------------------------------------------------------------
01026 // Modify the trunc() operation provided by static_cast<int>() to get floor(),
01027 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
01028 inline int vtkMath::Floor(double x)
01029 {
01030   int i = static_cast<int>(x);
01031   return i - ( i > x );
01032 }
01033 
01034 //----------------------------------------------------------------------------
01035 // Modify the trunc() operation provided by static_cast<int>() to get ceil(),
01036 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
01037 inline int vtkMath::Ceil(double x)
01038 {
01039   int i = static_cast<int>(x);
01040   return i + ( i < x );
01041 }
01042 
01043 //----------------------------------------------------------------------------
01044 inline float vtkMath::Normalize(float x[3])
01045 {
01046   float den;
01047   if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01048     {
01049     for (int i=0; i < 3; i++)
01050       {
01051       x[i] /= den;
01052       }
01053     }
01054   return den;
01055 }
01056 
01057 //----------------------------------------------------------------------------
01058 inline double vtkMath::Normalize(double x[3])
01059 {
01060   double den;
01061   if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01062     {
01063     for (int i=0; i < 3; i++)
01064       {
01065       x[i] /= den;
01066       }
01067     }
01068   return den;
01069 }
01070 
01071 //----------------------------------------------------------------------------
01072 inline float vtkMath::Normalize2D(float x[3])
01073 {
01074   float den;
01075   if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01076     {
01077     for (int i=0; i < 2; i++)
01078       {
01079       x[i] /= den;
01080       }
01081     }
01082   return den;
01083 }
01084 
01085 //----------------------------------------------------------------------------
01086 inline double vtkMath::Normalize2D(double x[3])
01087 {
01088   double den;
01089   if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01090     {
01091     for (int i=0; i < 2; i++)
01092       {
01093       x[i] /= den;
01094       }
01095     }
01096   return den;
01097 }
01098 
01099 //----------------------------------------------------------------------------
01100 inline float vtkMath::Determinant3x3(const float c1[3],
01101                                      const float c2[3],
01102                                      const float c3[3])
01103 {
01104   return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01105          c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01106 }
01107 
01108 //----------------------------------------------------------------------------
01109 inline double vtkMath::Determinant3x3(const double c1[3],
01110                                       const double c2[3],
01111                                       const double c3[3])
01112 {
01113   return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01114          c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01115 }
01116 
01117 //----------------------------------------------------------------------------
01118 inline double vtkMath::Determinant3x3(double a1, double a2, double a3,
01119                                       double b1, double b2, double b3,
01120                                       double c1, double c2, double c3)
01121 {
01122     return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
01123            - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
01124            + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
01125 }
01126 
01127 //----------------------------------------------------------------------------
01128 inline float vtkMath::Distance2BetweenPoints(const float x[3],
01129                                              const float y[3])
01130 {
01131   return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01132            + ( x[1] - y[1] ) * ( x[1] - y[1] )
01133            + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01134 }
01135 
01136 //----------------------------------------------------------------------------
01137 inline double vtkMath::Distance2BetweenPoints(const double x[3],
01138                                               const double y[3])
01139 {
01140   return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01141            + ( x[1] - y[1] ) * ( x[1] - y[1] )
01142            + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01143 }
01144 
01145 //----------------------------------------------------------------------------
01146 // Cross product of two 3-vectors. Result (a x b) is stored in z[3].
01147 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
01148 {
01149   float Zx = x[1] * y[2] - x[2] * y[1];
01150   float Zy = x[2] * y[0] - x[0] * y[2];
01151   float Zz = x[0] * y[1] - x[1] * y[0];
01152   z[0] = Zx; z[1] = Zy; z[2] = Zz;
01153 }
01154 
01155 //----------------------------------------------------------------------------
01156 // Cross product of two 3-vectors. Result (a x b) is stored in z[3].
01157 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3])
01158 {
01159   double Zx = x[1] * y[2] - x[2] * y[1];
01160   double Zy = x[2] * y[0] - x[0] * y[2];
01161   double Zz = x[0] * y[1] - x[1] * y[0];
01162   z[0] = Zx; z[1] = Zy; z[2] = Zz;
01163 }
01164 
01165 //BTX
01166 //----------------------------------------------------------------------------
01167 template<class T>
01168 inline double vtkDeterminant3x3(T A[3][3])
01169 {
01170   return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] +
01171          A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] -
01172          A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2];
01173 }
01174 //ETX
01175 
01176 //----------------------------------------------------------------------------
01177 inline double vtkMath::Determinant3x3(float A[3][3])
01178 {
01179   return vtkDeterminant3x3( A );
01180 }
01181 
01182 //----------------------------------------------------------------------------
01183 inline double vtkMath::Determinant3x3(double A[3][3])
01184 {
01185   return vtkDeterminant3x3( A );
01186 }
01187 
01188 //----------------------------------------------------------------------------
01189 inline void vtkMath::ClampValue(double *value, const double range[2])
01190 {
01191   if (value && range)
01192     {
01193     if (*value < range[0])
01194       {
01195       *value = range[0];
01196       }
01197     else if (*value > range[1])
01198       {
01199       *value = range[1];
01200       }
01201     }
01202 }
01203 
01204 //----------------------------------------------------------------------------
01205 inline void vtkMath::ClampValue(
01206   double value, const double range[2], double *clamped_value)
01207 {
01208   if (range && clamped_value)
01209     {
01210     if (value < range[0])
01211       {
01212       *clamped_value = range[0];
01213       }
01214     else if (value > range[1])
01215       {
01216       *clamped_value = range[1];
01217       }
01218     else
01219       {
01220       *clamped_value = value;
01221       }
01222     }
01223 }
01224 
01225 // ---------------------------------------------------------------------------
01226 inline double vtkMath::ClampAndNormalizeValue(double value,
01227                                               const double range[2])
01228 {
01229   assert("pre: valid_range" && range[0]<=range[1]);
01230 
01231   double result;
01232   if(range[0]==range[1])
01233     {
01234       result=0.0;
01235     }
01236   else
01237     {
01238       // clamp
01239       if(value<range[0])
01240         {
01241           result=range[0];
01242         }
01243       else
01244         {
01245           if(value>range[1])
01246             {
01247               result=range[1];
01248             }
01249           else
01250             {
01251               result=value;
01252             }
01253         }
01254 
01255       // normalize
01256       result=( result - range[0] ) / ( range[1] - range[0] );
01257     }
01258 
01259   assert("post: valid_result" && result>=0.0 && result<=1.0);
01260 
01261   return result;
01262 }
01263 
01264 //-----------------------------------------------------------------------------
01265 #if defined(VTK_HAS_ISINF) || defined(VTK_HAS_STD_ISINF)
01266 #define VTK_MATH_ISINF_IS_INLINE
01267 inline int vtkMath::IsInf(double x)
01268 {
01269 #if defined(VTK_HAS_STD_ISINF)
01270   return std::isinf(x);
01271 #else
01272   return (isinf(x) != 0); // Force conversion to bool
01273 #endif
01274 }
01275 #endif
01276 
01277 //-----------------------------------------------------------------------------
01278 #if defined(VTK_HAS_ISNAN) || defined(VTK_HAS_STD_ISNAN)
01279 #define VTK_MATH_ISNAN_IS_INLINE
01280 inline int vtkMath::IsNan(double x)
01281 {
01282 #if defined(VTK_HAS_STD_ISNAN)
01283   return std::isnan(x);
01284 #else
01285   return (isnan(x) != 0); // Force conversion to bool
01286 #endif
01287 }
01288 #endif
01289 
01290 //-----------------------------------------------------------------------------
01291 #if defined(VTK_HAS_ISFINITE) || defined(VTK_HAS_STD_ISFINITE) || defined(VTK_HAS_FINITE)
01292 #define VTK_MATH_ISFINITE_IS_INLINE
01293 inline bool vtkMath::IsFinite(double x)
01294 {
01295 #if defined(VTK_HAS_STD_ISFINITE)
01296   return std::isfinite(x);
01297 #elif defined(VTK_HAS_ISFINITE)
01298   return (isfinite(x) != 0); // Force conversion to bool
01299 #else
01300   return (finite(x) != 0); // Force conversion to bool
01301 #endif
01302 }
01303 #endif
01304 
01305 #endif