VTK
dox/Common/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 2008 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 =========================================================================*/
00043 #ifndef __vtkMath_h
00044 #define __vtkMath_h
00045 
00046 #include "vtkObject.h"
00047 #ifndef VTK_LEGACY_REMOVE
00048 # include "vtkPolynomialSolversUnivariate.h" // For backwards compatibility of old solvers
00049 #endif
00050 
00051 #include <assert.h> // assert() in inline implementations.
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   // Description:
00294   // Outer product of two 3-vectors (double-precision version).
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   // Description:
00417   // Outer product of two 2-vectors (float version).
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   // Test if a number is equal to the special floating point value Not-A-Number (Nan).
00966   static int IsNan(double x);
00967 
00968 protected:
00969   vtkMath() {};
00970   ~vtkMath() {};
00971 
00972   static vtkMathInternal Internal;
00973 private:
00974   vtkMath(const vtkMath&);  // Not implemented.
00975   void operator=(const vtkMath&);  // Not implemented.
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 // Cross product of two 3-vectors. Result (a x b) is stored in z[3].
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 // Cross product of two 3-vectors. Result (a x b) is stored in z[3].
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 //BTX
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 //ETX
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       // clamp
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       // normalize
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