00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00043 #ifndef __vtkMath_h
00044 #define __vtkMath_h
00045 
00046 #include "vtkObject.h"
00047 #ifndef VTK_LEGACY_REMOVE
00048 # include "vtkPolynomialSolversUnivariate.h" 
00049 #endif
00050 
00051 #include <assert.h> 
00052 
00053 #ifndef DBL_EPSILON
00054 #  define VTK_DBL_EPSILON    2.2204460492503131e-16
00055 #else  // DBL_EPSILON
00056 #  define VTK_DBL_EPSILON    DBL_EPSILON
00057 #endif  // DBL_EPSILON
00058 
00059 class vtkDataArray;
00060 class vtkPoints;
00061 class vtkMathInternal;
00062 class vtkMinimalStandardRandomSequence;
00063 class vtkBoxMuellerRandomSequence;
00064 
00065 class VTK_COMMON_EXPORT vtkMath : public vtkObject
00066 {
00067 public:
00068   static vtkMath *New();
00069   vtkTypeMacro(vtkMath,vtkObject);
00070   void PrintSelf(ostream& os, vtkIndent indent);
00071 
00073   static float Pi() { return 3.14159265358979f; };
00074 
00077   static double DoubleTwoPi() { return  6.283185307179586; };
00078 
00081   static double DoublePi() { return 3.1415926535897932384626; };
00082 
00084 
00085   static float RadiansFromDegrees( float degrees);
00086   static double RadiansFromDegrees( double degrees);
00088 
00090 
00091   static float DegreesFromRadians( float radians);
00092   static double DegreesFromRadians( double radians);
00094 
00096 
00097   static int Round(float f) {
00098     return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
00099   static int Round(double f) {
00100     return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
00102 
00105   static int Floor(double x);
00106 
00109   static int Ceil(double x);
00110 
00113   static vtkTypeInt64 Factorial( int N );
00114 
00118   static vtkTypeInt64 Binomial( int m, int n );
00119 
00126   static int* BeginCombination( int m, int n );
00127 
00134   static int NextCombination( int m, int n, int* combination );
00135 
00137   static void FreeCombination( int* combination);
00138 
00150   static void RandomSeed(int s);
00151 
00160   static int GetSeed();
00161 
00171   static double Random();
00172 
00181   static double Random( double min, double max );
00182 
00191   static double Gaussian();
00192 
00202   static double Gaussian( double mean, double std );
00203 
00205 
00206   static void Add(const float a[3], const float b[3], float c[3]) {
00207     for (int i = 0; i < 3; ++i)
00208       c[i] = a[i] + b[i];
00209   }
00211 
00213 
00214   static void Add(const double a[3], const double b[3], double c[3]) {
00215     for (int i = 0; i < 3; ++i)
00216       c[i] = a[i] + b[i];
00217   }
00219 
00221 
00223   static void Subtract(const float a[3], const float b[3], float c[3]) {
00224     for (int i = 0; i < 3; ++i)
00225       c[i] = a[i] - b[i];
00226   }
00228 
00230 
00232   static void Subtract(const double a[3], const double b[3], double c[3]) {
00233     for (int i = 0; i < 3; ++i)
00234       c[i] = a[i] - b[i];
00235   }
00237 
00239 
00241   static void MultiplyScalar(float a[3], float s) {
00242     for (int i = 0; i < 3; ++i)
00243       a[i] *= s;
00244   }
00246 
00248 
00250   static void MultiplyScalar2D(float a[2], float s) {
00251     for (int i = 0; i < 2; ++i)
00252       a[i] *= s;
00253   }
00255 
00257 
00259   static void MultiplyScalar(double a[3], double s) {
00260     for (int i = 0; i < 3; ++i)
00261       a[i] *= s;
00262   }
00264 
00266 
00268   static void MultiplyScalar2D(double a[2], double s) {
00269     for (int i = 0; i < 2; ++i)
00270       a[i] *= s;
00271   }
00273 
00275 
00276   static float Dot(const float x[3], const float y[3]) {
00277     return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
00279 
00281 
00282   static double Dot(const double x[3], const double y[3]) {
00283     return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
00285 
00287 
00288   static void Outer(const float x[3], const float y[3], float A[3][3]) {
00289     for (int i=0; i < 3; i++)
00290       for (int j=0; j < 3; j++)
00291         A[i][j] = x[i] * y[j];
00292   }
00293   
00294   
00295   static void Outer(const double x[3], const double y[3], double A[3][3]) {
00296     for (int i=0; i < 3; i++)
00297       for (int j=0; j < 3; j++)
00298         A[i][j] = x[i] * y[j];
00299   }
00301 
00303   static void Cross(const float x[3], const float y[3], float z[3]);
00304 
00307   static void Cross(const double x[3], const double y[3], double z[3]);
00308 
00310 
00311   static float Norm(const float* x, int n);
00312   static double Norm(const double* x, int n);
00314 
00316 
00317   static float Norm(const float x[3]) {
00318     return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ) );};
00320 
00322 
00323   static double Norm(const double x[3]) {
00324     return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );};
00326 
00328   static float Normalize(float x[3]);
00329 
00332   static double Normalize(double x[3]);
00333 
00335 
00340   static void Perpendiculars(const double x[3], double y[3], double z[3],
00341                              double theta);
00342   static void Perpendiculars(const float x[3], float y[3], float z[3],
00343                              double theta);
00345 
00347 
00350   static bool ProjectVector(const float a[3], const float b[3], float projection[3]);
00351   static bool ProjectVector(const double a[3], const double b[3], double projection[3]);
00353 
00355 
00359   static bool ProjectVector2D(const float a[2], const float b[2], float projection[2]);
00360   static bool ProjectVector2D(const double a[2], const double b[2], double projection[2]);
00362 
00364   static float Distance2BetweenPoints(const float x[3], const float y[3]);
00365 
00368   static double Distance2BetweenPoints(const double x[3], const double y[3]);
00369 
00373   static double GaussianAmplitude(const double variance, const double distanceFromMean);
00374 
00378   static double GaussianAmplitude(const double mean, const double variance, const double position);
00379 
00384   static double GaussianWeight(const double variance, const double distanceFromMean);
00385 
00390   static double GaussianWeight(const double mean, const double variance, const double position);
00391 
00393 
00394   static float Dot2D(const float x[2], const float y[2]) {
00395     return ( x[0] * y[0] + x[1] * y[1] );};
00397 
00399 
00400   static double Dot2D(const double x[2], const double y[2]) {
00401     return ( x[0] * y[0] + x[1] * y[1] );};
00403 
00405 
00406   static void Outer2D(const float x[2], const float y[2], float A[2][2])
00407     {
00408     for (int i=0; i < 2; i++)
00409       {
00410       for (int j=0; j < 2; j++)
00411         {
00412         A[i][j] = x[i] * y[j];
00413         }
00414       }
00415     }
00416   
00417   
00418   static void Outer2D(const double x[2], const double y[2], double A[2][2])
00419     {
00420     for (int i=0; i < 2; i++)
00421       {
00422       for (int j=0; j < 2; j++)
00423         {
00424         A[i][j] = x[i] * y[j];
00425         }
00426       }
00427     }
00429 
00431 
00432   static float Norm2D(const float x[2]) {
00433     return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] ) );};
00435 
00437 
00438   static double Norm2D(const double x[2]) {
00439     return sqrt( x[0] * x[0] + x[1] * x[1] );};
00441 
00443   static float Normalize2D(float x[2]);
00444 
00447   static double Normalize2D(double x[2]);
00448 
00450 
00451   static float Determinant2x2(const float c1[2], const float c2[2]) {
00452     return (c1[0] * c2[1] - c2[0] * c1[1] );};
00454 
00456 
00457   static double Determinant2x2(double a, double b, double c, double d) {
00458     return (a * d - b * c);};
00459   static double Determinant2x2(const double c1[2], const double c2[2]) {
00460     return (c1[0] * c2[1] - c2[0] * c1[1] );};
00462 
00464 
00465   static void LUFactor3x3(float A[3][3], int index[3]);
00466   static void LUFactor3x3(double A[3][3], int index[3]);
00468 
00470 
00471   static void LUSolve3x3(const float A[3][3], const int index[3],
00472                          float x[3]);
00473   static void LUSolve3x3(const double A[3][3], const int index[3],
00474                          double x[3]);
00476 
00478 
00480   static void LinearSolve3x3(const float A[3][3], const float x[3],
00481                              float y[3]);
00482   static void LinearSolve3x3(const double A[3][3], const double x[3],
00483                              double y[3]);
00485 
00487 
00488   static void Multiply3x3(const float A[3][3], const float in[3],
00489                           float out[3]);
00490   static void Multiply3x3(const double A[3][3], const double in[3],
00491                           double out[3]);
00493 
00495 
00496   static void Multiply3x3(const float A[3][3], const float B[3][3],
00497                           float C[3][3]);
00498   static void Multiply3x3(const double A[3][3], const double B[3][3],
00499                           double C[3][3]);
00501 
00503 
00505   static void MultiplyMatrix(const double **A, const double **B,
00506                              unsigned int rowA, unsigned int colA,
00507                              unsigned int rowB, unsigned int colB,
00508                              double **C);
00510 
00512 
00514   static void Transpose3x3(const float A[3][3], float AT[3][3]);
00515   static void Transpose3x3(const double A[3][3], double AT[3][3]);
00517 
00519 
00521   static void Invert3x3(const float A[3][3], float AI[3][3]);
00522   static void Invert3x3(const double A[3][3], double AI[3][3]);
00524 
00526 
00527   static void Identity3x3(float A[3][3]);
00528   static void Identity3x3(double A[3][3]);
00530 
00532 
00533   static double Determinant3x3(float A[3][3]);
00534   static double Determinant3x3(double A[3][3]);
00536 
00538 
00539   static float Determinant3x3(const float c1[3],
00540                               const float c2[3],
00541                               const float c3[3]);
00543 
00545 
00546   static double Determinant3x3(const double c1[3],
00547                                const double c2[3],
00548                                const double c3[3]);
00550 
00552 
00554   static double Determinant3x3(double a1, double a2, double a3,
00555                                double b1, double b2, double b3,
00556                                double c1, double c2, double c3);
00558 
00560 
00562   static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]);
00563   static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]);
00565 
00567 
00570   static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
00571   static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
00573 
00575 
00578   static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
00579   static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
00581 
00583 
00587   static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
00588   static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]);
00590 
00592 
00599   static void SingularValueDecomposition3x3(const float A[3][3],
00600                                             float U[3][3], float w[3],
00601                                             float VT[3][3]);
00602   static void SingularValueDecomposition3x3(const double A[3][3],
00603                                             double U[3][3], double w[3],
00604                                             double VT[3][3]);
00606 
00611   static int SolveLinearSystem(double **A, double *x, int size);
00612 
00616   static int InvertMatrix(double **A, double **AI, int size);
00617 
00619 
00621   static int InvertMatrix(double **A, double **AI, int size,
00622                           int *tmp1Size, double *tmp2Size);
00624 
00630   static int LUFactorLinearSystem(double **A, int *index, int size);
00631 
00633 
00635   static int LUFactorLinearSystem(double **A, int *index, int size,
00636                                   double *tmpSize);
00638 
00640 
00646   static void LUSolveLinearSystem(double **A, int *index,
00647                                   double *x, int size);
00649 
00657   static double EstimateMatrixCondition(double **A, int size);
00658 
00660 
00664   static int Jacobi(float **a, float *w, float **v);
00665   static int Jacobi(double **a, double *w, double **v);
00667 
00669 
00674   static int JacobiN(float **a, int n, float *w, float **v);
00675   static int JacobiN(double **a, int n, double *w, double **v);
00677 
00685   VTK_LEGACY(static double* SolveCubic(double c0, double c1, double c2, double c3));
00686 
00694   VTK_LEGACY(static double* SolveQuadratic(double c0, double c1, double c2));
00695 
00701   VTK_LEGACY(static double* SolveLinear(double c0, double c1));
00702 
00704 
00717   VTK_LEGACY(static int SolveCubic(double c0, double c1, double c2, double c3,
00718                         double *r1, double *r2, double *r3, int *num_roots));
00720 
00722 
00727   VTK_LEGACY(static int SolveQuadratic(double c0, double c1, double c2,
00728                             double *r1, double *r2, int *num_roots));
00730 
00737   VTK_LEGACY(static int SolveQuadratic( double* c, double* r, int* m ));
00738 
00744   VTK_LEGACY(static int SolveLinear(double c0, double c1, double *r1, int *num_roots));
00745 
00747 
00757   static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder,
00758                                 double **mt);
00760 
00761 
00763 
00774   static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
00775                                double **yt, int yOrder, double **mt, int checkHomogeneous=1);
00777 
00779 
00781   static void RGBToHSV(const float rgb[3], float hsv[3])
00782     { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00783   static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v);
00784   static double* RGBToHSV(const double rgb[3]);
00785   static double* RGBToHSV(double r, double g, double b);
00786   static void RGBToHSV(const double rgb[3], double hsv[3])
00787     { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00788   static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v);
00790 
00792 
00794   static void HSVToRGB(const float hsv[3], float rgb[3])
00795     { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00796   static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b);
00797   static double* HSVToRGB(const double hsv[3]);
00798   static double* HSVToRGB(double h, double s, double v);
00799   static void HSVToRGB(const double hsv[3], double rgb[3])
00800     { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00801   static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b);
00803 
00805 
00806   static void LabToXYZ(const double lab[3], double xyz[3]) {
00807     LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2);
00808   }
00809   static void LabToXYZ(double L, double a, double b,
00810                        double *x, double *y, double *z);
00811   static double *LabToXYZ(const double lab[3]);
00813 
00815 
00816   static void XYZToLab(const double xyz[3], double lab[3]) {
00817     XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2);
00818   }
00819   static void XYZToLab(double x, double y, double z,
00820                        double *L, double *a, double *b);
00821   static double *XYZToLab(const double xyz[3]);
00823 
00825 
00826   static void XYZToRGB(const double xyz[3], double rgb[3]) {
00827     XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2);
00828   }
00829   static void XYZToRGB(double x, double y, double z,
00830                        double *r, double *g, double *b);
00831   static double *XYZToRGB(const double xyz[3]);
00833 
00835 
00836   static void RGBToXYZ(const double rgb[3], double xyz[3]) {
00837     RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2);
00838   }
00839   static void RGBToXYZ(double r, double g, double b,
00840                        double *x, double *y, double *z);
00841   static double *RGBToXYZ(const double rgb[3]);
00843 
00845 
00846   static void RGBToLab(const double rgb[3], double lab[3]) {
00847     RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2);
00848   }
00849   static void RGBToLab(double red, double green, double blue,
00850                        double *L, double *a, double *b);
00851   static double *RGBToLab(const double rgb[3]);
00853 
00855 
00856   static void LabToRGB(const double lab[3], double rgb[3]) {
00857     LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2);
00858   }
00859   static void LabToRGB(double L, double a, double b,
00860                        double *red, double *green, double *blue);
00861   static double *LabToRGB(const double lab[3]);
00863 
00865 
00866   static void UninitializeBounds(double bounds[6]){
00867     bounds[0] = 1.0;
00868     bounds[1] = -1.0;
00869     bounds[2] = 1.0;
00870     bounds[3] = -1.0;
00871     bounds[4] = 1.0;
00872     bounds[5] = -1.0;
00873   }
00875 
00877 
00878   static int AreBoundsInitialized(double bounds[6]){
00879     if ( bounds[1]-bounds[0]<0.0 )
00880       {
00881       return 0;
00882       }
00883     return 1;
00884   }
00886 
00888 
00890   static void ClampValue(double *value, const double range[2]);
00891   static void ClampValue(double value, const double range[2], double *clamped_value);
00892   static void ClampValues(
00893     double *values, int nb_values, const double range[2]);
00894   static void ClampValues(
00895     const double *values, int nb_values, const double range[2], double *clamped_values);
00897 
00899 
00902   static double ClampAndNormalizeValue(double value,
00903                                        const double range[2]);
00905 
00907 
00913   static int GetScalarTypeFittingRange(
00914     double range_min, double range_max,
00915     double scale = 1.0, double shift = 0.0);
00917 
00919 
00925   static int GetAdjustedScalarRange(
00926     vtkDataArray *array, int comp, double range[2]);
00928 
00931   static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]);
00932 
00936   static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]);
00937 
00941   static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]);
00942 
00950   static double Solve3PointCircle(const double p1[3], const double p2[3], const double p3[3], double center[3]);
00951 
00953   static double Inf();
00954 
00956   static double NegInf();
00957 
00959   static double Nan();
00960 
00963   static int IsInf(double x);
00964 
00965   
00966   static int IsNan(double x);
00967 
00968 protected:
00969   vtkMath() {};
00970   ~vtkMath() {};
00971 
00972   static vtkMathInternal Internal;
00973 private:
00974   vtkMath(const vtkMath&);  
00975   void operator=(const vtkMath&);  
00976 };
00977 
00978 
00979 inline float vtkMath::RadiansFromDegrees( float x )
00980 {
00981   return x * 0.017453292f;
00982 }
00983 
00984 
00985 inline double vtkMath::RadiansFromDegrees( double x )
00986 {
00987   return x * 0.017453292519943295;
00988 }
00989 
00990 
00991 inline float vtkMath::DegreesFromRadians( float x )
00992 {
00993   return x * 57.2957795131f;
00994 }
00995 
00996 
00997 inline double vtkMath::DegreesFromRadians( double x )
00998 {
00999   return x * 57.29577951308232;
01000 }
01001 
01002 
01003 inline vtkTypeInt64 vtkMath::Factorial( int N )
01004 {
01005   vtkTypeInt64 r = 1;
01006   while ( N > 1 )
01007     {
01008     r *= N--;
01009     }
01010   return r;
01011 }
01012 
01013 
01014 inline int vtkMath::Floor(double x)
01015 {
01016   const int r = static_cast<int>(x);
01017   const int n = ( x != static_cast<double>(r) );
01018   const int g = ( x < 0 );
01019   return r - ( n & g );
01020 }
01021 
01022 
01023 inline int vtkMath::Ceil(double x)
01024 {
01025   const int r = static_cast<int>(x);
01026   const int n = ( x != static_cast<double>(r) );
01027   const int g = ( x >= 0 );
01028   return r + ( n & g );
01029 }
01030 
01031 
01032 inline float vtkMath::Normalize(float x[3])
01033 {
01034   float den;
01035   if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01036     {
01037     for (int i=0; i < 3; i++)
01038       {
01039       x[i] /= den;
01040       }
01041     }
01042   return den;
01043 }
01044 
01045 
01046 inline double vtkMath::Normalize(double x[3])
01047 {
01048   double den;
01049   if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01050     {
01051     for (int i=0; i < 3; i++)
01052       {
01053       x[i] /= den;
01054       }
01055     }
01056   return den;
01057 }
01058 
01059 
01060 inline float vtkMath::Normalize2D(float x[3])
01061 {
01062   float den;
01063   if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01064     {
01065     for (int i=0; i < 2; i++)
01066       {
01067       x[i] /= den;
01068       }
01069     }
01070   return den;
01071 }
01072 
01073 
01074 inline double vtkMath::Normalize2D(double x[3])
01075 {
01076   double den;
01077   if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01078     {
01079     for (int i=0; i < 2; i++)
01080       {
01081       x[i] /= den;
01082       }
01083     }
01084   return den;
01085 }
01086 
01087 
01088 inline float vtkMath::Determinant3x3(const float c1[3],
01089                                      const float c2[3],
01090                                      const float c3[3])
01091 {
01092   return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01093          c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01094 }
01095 
01096 
01097 inline double vtkMath::Determinant3x3(const double c1[3],
01098                                       const double c2[3],
01099                                       const double c3[3])
01100 {
01101   return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01102          c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01103 }
01104 
01105 
01106 inline double vtkMath::Determinant3x3(double a1, double a2, double a3,
01107                                       double b1, double b2, double b3,
01108                                       double c1, double c2, double c3)
01109 {
01110     return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
01111            - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
01112            + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
01113 }
01114 
01115 
01116 inline float vtkMath::Distance2BetweenPoints(const float x[3],
01117                                              const float y[3])
01118 {
01119   return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01120            + ( x[1] - y[1] ) * ( x[1] - y[1] )
01121            + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01122 }
01123 
01124 
01125 inline double vtkMath::Distance2BetweenPoints(const double x[3],
01126                                               const double y[3])
01127 {
01128   return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01129            + ( x[1] - y[1] ) * ( x[1] - y[1] )
01130            + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01131 }
01132 
01133 
01134 
01135 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
01136 {
01137   float Zx = x[1] * y[2] - x[2] * y[1];
01138   float Zy = x[2] * y[0] - x[0] * y[2];
01139   float Zz = x[0] * y[1] - x[1] * y[0];
01140   z[0] = Zx; z[1] = Zy; z[2] = Zz;
01141 }
01142 
01143 
01144 
01145 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3])
01146 {
01147   double Zx = x[1] * y[2] - x[2] * y[1];
01148   double Zy = x[2] * y[0] - x[0] * y[2];
01149   double Zz = x[0] * y[1] - x[1] * y[0];
01150   z[0] = Zx; z[1] = Zy; z[2] = Zz;
01151 }
01152 
01153 
01154 
01155 template<class T>
01156 inline double vtkDeterminant3x3(T A[3][3])
01157 {
01158   return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] +
01159          A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] -
01160          A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2];
01161 }
01162 
01163 
01164 
01165 inline double vtkMath::Determinant3x3(float A[3][3])
01166 {
01167   return vtkDeterminant3x3( A );
01168 }
01169 
01170 
01171 inline double vtkMath::Determinant3x3(double A[3][3])
01172 {
01173   return vtkDeterminant3x3( A );
01174 }
01175 
01176 #ifndef VTK_LEGACY_REMOVE
01177 
01178 inline double* vtkMath::SolveCubic(double c0, double c1, double c2, double c3)
01179 {
01180   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveCubic, "VTK 5.8",
01181                            vtkPolynomialSolversUnivariate::SolveCubic);
01182   return vtkPolynomialSolversUnivariate::SolveCubic( c0, c1, c2, c3 );
01183 }
01184 
01185 
01186 inline double* vtkMath::SolveQuadratic(double c0, double c1, double c2)
01187 {
01188   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveQuadratic, "VTK 5.8",
01189                            vtkPolynomialSolversUnivariate::SolveQuadratic);
01190   return vtkPolynomialSolversUnivariate::SolveQuadratic( c0, c1, c2 );
01191 }
01192 
01193 
01194 inline double* vtkMath::SolveLinear(double c0, double c1)
01195 {
01196   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveLinear, "VTK 5.8",
01197                            vtkPolynomialSolversUnivariate::SolveLinear);
01198   return vtkPolynomialSolversUnivariate::SolveLinear( c0, c1 );
01199 }
01200 
01201 
01202 inline int vtkMath::SolveCubic(double c0, double c1, double c2, double c3,
01203                                double *r1, double *r2, double *r3, int *num_roots)
01204 {
01205   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveCubic, "VTK 5.8",
01206                            vtkPolynomialSolversUnivariate::SolveCubic);
01207   return vtkPolynomialSolversUnivariate::SolveCubic( c0, c1, c2, c3, r1, r2, r3, num_roots );
01208 }
01209 
01210 
01211 inline int vtkMath::SolveQuadratic(double c0, double c1, double c2,
01212                                    double *r1, double *r2, int *num_roots)
01213 {
01214   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveQuadratic, "VTK 5.8",
01215                            vtkPolynomialSolversUnivariate::SolveQuadratic);
01216   return vtkPolynomialSolversUnivariate::SolveQuadratic( c0, c1, c2, r1, r2, num_roots );
01217 }
01218 
01219 
01220 inline int vtkMath::SolveQuadratic( double* c, double* r, int* m )
01221 {
01222   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveQuadratic, "VTK 5.8",
01223                            vtkPolynomialSolversUnivariate::SolveQuadratic);
01224   return vtkPolynomialSolversUnivariate::SolveQuadratic( c, r, m );
01225 }
01226 
01227 
01228 inline int vtkMath::SolveLinear(double c0, double c1, double *r1, int *num_roots)
01229 {
01230   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveLinear, "VTK 5.8",
01231                            vtkPolynomialSolversUnivariate::SolveLinear);
01232   return vtkPolynomialSolversUnivariate::SolveLinear( c0, c1, r1, num_roots );
01233 }
01234 #endif
01235 
01236 
01237 inline void vtkMath::ClampValue(double *value, const double range[2])
01238 {
01239   if (value && range)
01240     {
01241     if (*value < range[0])
01242       {
01243       *value = range[0];
01244       }
01245     else if (*value > range[1])
01246       {
01247       *value = range[1];
01248       }
01249     }
01250 }
01251 
01252 
01253 inline void vtkMath::ClampValue(
01254   double value, const double range[2], double *clamped_value)
01255 {
01256   if (range && clamped_value)
01257     {
01258     if (value < range[0])
01259       {
01260       *clamped_value = range[0];
01261       }
01262     else if (value > range[1])
01263       {
01264       *clamped_value = range[1];
01265       }
01266     else
01267       {
01268       *clamped_value = value;
01269       }
01270     }
01271 }
01272 
01273 
01274 inline double vtkMath::ClampAndNormalizeValue(double value,
01275                                               const double range[2])
01276 {
01277   assert("pre: valid_range" && range[0]<=range[1]);
01278 
01279   double result;
01280   if(range[0]==range[1])
01281     {
01282       result=0.0;
01283     }
01284   else
01285     {
01286       
01287       if(value<range[0])
01288         {
01289           result=range[0];
01290         }
01291       else
01292         {
01293           if(value>range[1])
01294             {
01295               result=range[1];
01296             }
01297           else
01298             {
01299               result=value;
01300             }
01301         }
01302 
01303       
01304       result=( result - range[0] ) / ( range[1] - range[0] );
01305     }
01306 
01307   assert("post: valid_result" && result>=0.0 && result<=1.0);
01308 
01309   return result;
01310 }
01311 
01312 #endif