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 <assert.h> // 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 
00670   static int LUFactorLinearSystem(double **A, int *index, int size);
00671 
00673 
00675   static int LUFactorLinearSystem(double **A, int *index, int size,
00676                                   double *tmpSize);
00678 
00680 
00686   static void LUSolveLinearSystem(double **A, int *index,
00687                                   double *x, int size);
00689 
00697   static double EstimateMatrixCondition(double **A, int size);
00698 
00700 
00704   static int Jacobi(float **a, float *w, float **v);
00705   static int Jacobi(double **a, double *w, double **v);
00707 
00709 
00714   static int JacobiN(float **a, int n, float *w, float **v);
00715   static int JacobiN(double **a, int n, double *w, double **v);
00717 
00719 
00729   static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder,
00730                                 double **mt);
00732 
00733 
00735 
00746   static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
00747                                double **yt, int yOrder, double **mt, int checkHomogeneous=1);
00749 
00751 
00755   static void RGBToHSV(const float rgb[3], float hsv[3])
00756     { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00757   static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v);
00758   static double* RGBToHSV(const double rgb[3]);
00759   static double* RGBToHSV(double r, double g, double b);
00760   static void RGBToHSV(const double rgb[3], double hsv[3])
00761     { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00762   static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v);
00764 
00766 
00770   static void HSVToRGB(const float hsv[3], float rgb[3])
00771     { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00772   static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b);
00773   static double* HSVToRGB(const double hsv[3]);
00774   static double* HSVToRGB(double h, double s, double v);
00775   static void HSVToRGB(const double hsv[3], double rgb[3])
00776     { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00777   static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b);
00779 
00781 
00782   static void LabToXYZ(const double lab[3], double xyz[3]) {
00783     LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2);
00784   }
00785   static void LabToXYZ(double L, double a, double b,
00786                        double *x, double *y, double *z);
00787   static double *LabToXYZ(const double lab[3]);
00789 
00791 
00792   static void XYZToLab(const double xyz[3], double lab[3]) {
00793     XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2);
00794   }
00795   static void XYZToLab(double x, double y, double z,
00796                        double *L, double *a, double *b);
00797   static double *XYZToLab(const double xyz[3]);
00799 
00801 
00802   static void XYZToRGB(const double xyz[3], double rgb[3]) {
00803     XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2);
00804   }
00805   static void XYZToRGB(double x, double y, double z,
00806                        double *r, double *g, double *b);
00807   static double *XYZToRGB(const double xyz[3]);
00809 
00811 
00812   static void RGBToXYZ(const double rgb[3], double xyz[3]) {
00813     RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2);
00814   }
00815   static void RGBToXYZ(double r, double g, double b,
00816                        double *x, double *y, double *z);
00817   static double *RGBToXYZ(const double rgb[3]);
00819 
00821 
00824   static void RGBToLab(const double rgb[3], double lab[3]) {
00825     RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2);
00826   }
00827   static void RGBToLab(double red, double green, double blue,
00828                        double *L, double *a, double *b);
00829   static double *RGBToLab(const double rgb[3]);
00831 
00833 
00834   static void LabToRGB(const double lab[3], double rgb[3]) {
00835     LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2);
00836   }
00837   static void LabToRGB(double L, double a, double b,
00838                        double *red, double *green, double *blue);
00839   static double *LabToRGB(const double lab[3]);
00841 
00843 
00844   static void UninitializeBounds(double bounds[6]){
00845     bounds[0] = 1.0;
00846     bounds[1] = -1.0;
00847     bounds[2] = 1.0;
00848     bounds[3] = -1.0;
00849     bounds[4] = 1.0;
00850     bounds[5] = -1.0;
00851   }
00853 
00855 
00856   static int AreBoundsInitialized(double bounds[6]){
00857     if ( bounds[1]-bounds[0]<0.0 )
00858       {
00859       return 0;
00860       }
00861     return 1;
00862   }
00864 
00866 
00868   static void ClampValue(double *value, const double range[2]);
00869   static void ClampValue(double value, const double range[2], double *clamped_value);
00870   static void ClampValues(
00871     double *values, int nb_values, const double range[2]);
00872   static void ClampValues(
00873     const double *values, int nb_values, const double range[2], double *clamped_values);
00875 
00877 
00880   static double ClampAndNormalizeValue(double value,
00881                                        const double range[2]);
00883 
00885 
00891   static int GetScalarTypeFittingRange(
00892     double range_min, double range_max,
00893     double scale = 1.0, double shift = 0.0);
00895 
00897 
00903   static int GetAdjustedScalarRange(
00904     vtkDataArray *array, int comp, double range[2]);
00906 
00909   static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]);
00910 
00914   static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]);
00915 
00919   static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]);
00920 
00928   static double Solve3PointCircle(const double p1[3], const double p2[3], const double p3[3], double center[3]);
00929 
00931   static double Inf();
00932 
00934   static double NegInf();
00935 
00937   static double Nan();
00938 
00941   static int IsInf(double x);
00942 
00945   static int IsNan(double x);
00946 
00949   static bool IsFinite(double x);
00950 
00951 protected:
00952   vtkMath() {};
00953   ~vtkMath() {};
00954 
00955   static vtkMathInternal Internal;
00956 private:
00957   vtkMath(const vtkMath&);  // Not implemented.
00958   void operator=(const vtkMath&);  // Not implemented.
00959 };
00960 
00961 //----------------------------------------------------------------------------
00962 inline float vtkMath::RadiansFromDegrees( float x )
00963 {
00964   return x * 0.017453292f;
00965 }
00966 
00967 //----------------------------------------------------------------------------
00968 inline double vtkMath::RadiansFromDegrees( double x )
00969 {
00970   return x * 0.017453292519943295;
00971 }
00972 
00973 //----------------------------------------------------------------------------
00974 inline float vtkMath::DegreesFromRadians( float x )
00975 {
00976   return x * 57.2957795131f;
00977 }
00978 
00979 //----------------------------------------------------------------------------
00980 inline double vtkMath::DegreesFromRadians( double x )
00981 {
00982   return x * 57.29577951308232;
00983 }
00984 
00985 //----------------------------------------------------------------------------
00986 inline vtkTypeInt64 vtkMath::Factorial( int N )
00987 {
00988   vtkTypeInt64 r = 1;
00989   while ( N > 1 )
00990     {
00991     r *= N--;
00992     }
00993   return r;
00994 }
00995 
00996 //----------------------------------------------------------------------------
00997 inline bool vtkMath::IsPowerOfTwo(vtkTypeUInt64 x)
00998 {
00999   return ((x != 0) & ((x & (x - 1)) == 0));
01000 }
01001 
01002 //----------------------------------------------------------------------------
01003 // Credit goes to Peter Hart and William Lewis on comp.lang.python 1997
01004 inline int vtkMath::NearestPowerOfTwo(int x)
01005 {
01006   unsigned int z = ((x > 0) ? x - 1 : 0);
01007   z |= z >> 1;
01008   z |= z >> 2;
01009   z |= z >> 4;
01010   z |= z >> 8;
01011   z |= z >> 16;
01012   return static_cast<int>(z + 1);
01013 }
01014 
01015 //----------------------------------------------------------------------------
01016 // Modify the trunc() operation provided by static_cast<int>() to get floor(),
01017 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
01018 inline int vtkMath::Floor(double x)
01019 {
01020   int i = static_cast<int>(x);
01021   return i - ( i > x );
01022 }
01023 
01024 //----------------------------------------------------------------------------
01025 // Modify the trunc() operation provided by static_cast<int>() to get ceil(),
01026 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
01027 inline int vtkMath::Ceil(double x)
01028 {
01029   int i = static_cast<int>(x);
01030   return i + ( i < x );
01031 }
01032 
01033 //----------------------------------------------------------------------------
01034 inline float vtkMath::Normalize(float x[3])
01035 {
01036   float den;
01037   if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01038     {
01039     for (int i=0; i < 3; i++)
01040       {
01041       x[i] /= den;
01042       }
01043     }
01044   return den;
01045 }
01046 
01047 //----------------------------------------------------------------------------
01048 inline double vtkMath::Normalize(double x[3])
01049 {
01050   double den;
01051   if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01052     {
01053     for (int i=0; i < 3; i++)
01054       {
01055       x[i] /= den;
01056       }
01057     }
01058   return den;
01059 }
01060 
01061 //----------------------------------------------------------------------------
01062 inline float vtkMath::Normalize2D(float x[3])
01063 {
01064   float den;
01065   if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01066     {
01067     for (int i=0; i < 2; i++)
01068       {
01069       x[i] /= den;
01070       }
01071     }
01072   return den;
01073 }
01074 
01075 //----------------------------------------------------------------------------
01076 inline double vtkMath::Normalize2D(double x[3])
01077 {
01078   double den;
01079   if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01080     {
01081     for (int i=0; i < 2; i++)
01082       {
01083       x[i] /= den;
01084       }
01085     }
01086   return den;
01087 }
01088 
01089 //----------------------------------------------------------------------------
01090 inline float vtkMath::Determinant3x3(const float c1[3],
01091                                      const float c2[3],
01092                                      const float c3[3])
01093 {
01094   return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01095          c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01096 }
01097 
01098 //----------------------------------------------------------------------------
01099 inline double vtkMath::Determinant3x3(const double c1[3],
01100                                       const double c2[3],
01101                                       const double c3[3])
01102 {
01103   return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01104          c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01105 }
01106 
01107 //----------------------------------------------------------------------------
01108 inline double vtkMath::Determinant3x3(double a1, double a2, double a3,
01109                                       double b1, double b2, double b3,
01110                                       double c1, double c2, double c3)
01111 {
01112     return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
01113            - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
01114            + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
01115 }
01116 
01117 //----------------------------------------------------------------------------
01118 inline float vtkMath::Distance2BetweenPoints(const float x[3],
01119                                              const float y[3])
01120 {
01121   return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01122            + ( x[1] - y[1] ) * ( x[1] - y[1] )
01123            + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01124 }
01125 
01126 //----------------------------------------------------------------------------
01127 inline double vtkMath::Distance2BetweenPoints(const double x[3],
01128                                               const double y[3])
01129 {
01130   return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01131            + ( x[1] - y[1] ) * ( x[1] - y[1] )
01132            + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01133 }
01134 
01135 //----------------------------------------------------------------------------
01136 // Cross product of two 3-vectors. Result (a x b) is stored in z[3].
01137 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
01138 {
01139   float Zx = x[1] * y[2] - x[2] * y[1];
01140   float Zy = x[2] * y[0] - x[0] * y[2];
01141   float Zz = x[0] * y[1] - x[1] * y[0];
01142   z[0] = Zx; z[1] = Zy; z[2] = Zz;
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 double x[3], const double y[3], double z[3])
01148 {
01149   double Zx = x[1] * y[2] - x[2] * y[1];
01150   double Zy = x[2] * y[0] - x[0] * y[2];
01151   double Zz = x[0] * y[1] - x[1] * y[0];
01152   z[0] = Zx; z[1] = Zy; z[2] = Zz;
01153 }
01154 
01155 //BTX
01156 //----------------------------------------------------------------------------
01157 template<class T>
01158 inline double vtkDeterminant3x3(T A[3][3])
01159 {
01160   return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] +
01161          A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] -
01162          A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2];
01163 }
01164 //ETX
01165 
01166 //----------------------------------------------------------------------------
01167 inline double vtkMath::Determinant3x3(float A[3][3])
01168 {
01169   return vtkDeterminant3x3( A );
01170 }
01171 
01172 //----------------------------------------------------------------------------
01173 inline double vtkMath::Determinant3x3(double A[3][3])
01174 {
01175   return vtkDeterminant3x3( A );
01176 }
01177 
01178 //----------------------------------------------------------------------------
01179 inline void vtkMath::ClampValue(double *value, const double range[2])
01180 {
01181   if (value && range)
01182     {
01183     if (*value < range[0])
01184       {
01185       *value = range[0];
01186       }
01187     else if (*value > range[1])
01188       {
01189       *value = range[1];
01190       }
01191     }
01192 }
01193 
01194 //----------------------------------------------------------------------------
01195 inline void vtkMath::ClampValue(
01196   double value, const double range[2], double *clamped_value)
01197 {
01198   if (range && clamped_value)
01199     {
01200     if (value < range[0])
01201       {
01202       *clamped_value = range[0];
01203       }
01204     else if (value > range[1])
01205       {
01206       *clamped_value = range[1];
01207       }
01208     else
01209       {
01210       *clamped_value = value;
01211       }
01212     }
01213 }
01214 
01215 // ---------------------------------------------------------------------------
01216 inline double vtkMath::ClampAndNormalizeValue(double value,
01217                                               const double range[2])
01218 {
01219   assert("pre: valid_range" && range[0]<=range[1]);
01220 
01221   double result;
01222   if(range[0]==range[1])
01223     {
01224       result=0.0;
01225     }
01226   else
01227     {
01228       // clamp
01229       if(value<range[0])
01230         {
01231           result=range[0];
01232         }
01233       else
01234         {
01235           if(value>range[1])
01236             {
01237               result=range[1];
01238             }
01239           else
01240             {
01241               result=value;
01242             }
01243         }
01244 
01245       // normalize
01246       result=( result - range[0] ) / ( range[1] - range[0] );
01247     }
01248 
01249   assert("post: valid_result" && result>=0.0 && result<=1.0);
01250 
01251   return result;
01252 }
01253 
01254 //-----------------------------------------------------------------------------
01255 #if defined(VTK_HAS_ISINF) || defined(VTK_HAS_STD_ISINF)
01256 #define VTK_MATH_ISINF_IS_INLINE
01257 inline int vtkMath::IsInf(double x)
01258 {
01259   using namespace std; // Could be isinf() or std::isinf()
01260   return (isinf(x) != 0); // Force conversion to bool
01261 }
01262 #endif
01263 
01264 //-----------------------------------------------------------------------------
01265 #if defined(VTK_HAS_ISNAN) || defined(VTK_HAS_STD_ISNAN)
01266 #define VTK_MATH_ISNAN_IS_INLINE
01267 inline int vtkMath::IsNan(double x)
01268 {
01269   using namespace std; // Could be isnan() or std::isnan()
01270   return (isnan(x) != 0); // Force conversion to bool
01271 }
01272 #endif
01273 
01274 //-----------------------------------------------------------------------------
01275 #if defined(VTK_HAS_ISFINITE) || defined(VTK_HAS_STD_ISFINITE) || defined(VTK_HAS_FINITE)
01276 #define VTK_MATH_ISFINITE_IS_INLINE
01277 inline bool vtkMath::IsFinite(double x)
01278 {
01279 #if defined(VTK_HAS_ISFINITE) || defined(VTK_HAS_STD_ISFINITE)
01280   using namespace std; // Could be isfinite() or std::isfinite()
01281   return (isfinite(x) != 0); // Force conversion to bool
01282 #else
01283   return (finite(x) != 0); // Force conversion to bool
01284 #endif
01285 }
01286 #endif
01287 
01288 #endif