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 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 =========================================================================*/
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_MIN
00054 #  define VTK_DBL_MIN    2.2250738585072014e-308
00055 #else  // DBL_MIN
00056 #  define VTK_DBL_MIN    DBL_MIN
00057 #endif  // DBL_MIN
00058 
00059 #ifndef DBL_EPSILON
00060 #  define VTK_DBL_EPSILON    2.2204460492503131e-16
00061 #else  // DBL_EPSILON
00062 #  define VTK_DBL_EPSILON    DBL_EPSILON
00063 #endif  // DBL_EPSILON
00064 #include "vtkMathConfigure.h" // For VTK_HAS_ISINF and VTK_HAS_ISNAN
00065 
00066 #include <assert.h> // assert() in inline implementations.
00067 
00068 #ifndef VTK_DBL_EPSILON
00069 #  ifndef DBL_EPSILON
00070 #    define VTK_DBL_EPSILON    2.2204460492503131e-16
00071 #  else  // DBL_EPSILON
00072 #    define VTK_DBL_EPSILON    DBL_EPSILON
00073 #  endif  // DBL_EPSILON
00074 #endif  // VTK_DBL_EPSILON
00075 
00076 class vtkDataArray;
00077 class vtkPoints;
00078 class vtkMathInternal;
00079 class vtkMinimalStandardRandomSequence;
00080 class vtkBoxMuellerRandomSequence;
00081 
00082 class VTK_COMMON_EXPORT vtkMath : public vtkObject
00083 {
00084 public:
00085   static vtkMath *New();
00086   vtkTypeMacro(vtkMath,vtkObject);
00087   void PrintSelf(ostream& os, vtkIndent indent);
00088 
00090   static float Pi() { return 3.14159265358979f; };
00091 
00094   static double DoubleTwoPi() { return  6.283185307179586; };
00095 
00098   static double DoublePi() { return 3.1415926535897932384626; };
00099 
00101 
00102   static float RadiansFromDegrees( float degrees);
00103   static double RadiansFromDegrees( double degrees);
00105 
00107 
00108   static float DegreesFromRadians( float radians);
00109   static double DegreesFromRadians( double radians);
00111 
00113 
00114   static int Round(float f) {
00115     return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
00116   static int Round(double f) {
00117     return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
00119 
00122   static int Floor(double x);
00123 
00126   static int Ceil(double x);
00127 
00130   static vtkTypeInt64 Factorial( int N );
00131 
00135   static vtkTypeInt64 Binomial( int m, int n );
00136 
00143   static int* BeginCombination( int m, int n );
00144 
00151   static int NextCombination( int m, int n, int* combination );
00152 
00154   static void FreeCombination( int* combination);
00155 
00167   static void RandomSeed(int s);
00168 
00177   static int GetSeed();
00178 
00188   static double Random();
00189 
00198   static double Random( double min, double max );
00199 
00208   static double Gaussian();
00209 
00219   static double Gaussian( double mean, double std );
00220 
00222 
00223   static void Add(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 
00231   static void Add(const double a[3], const double b[3], double c[3]) {
00232     for (int i = 0; i < 3; ++i)
00233       c[i] = a[i] + b[i];
00234   }
00236 
00238 
00240   static void Subtract(const float a[3], const float b[3], float 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 double a[3], const double b[3], double c[3]) {
00250     for (int i = 0; i < 3; ++i)
00251       c[i] = a[i] - b[i];
00252   }
00254 
00256 
00258   static void MultiplyScalar(float a[3], float s) {
00259     for (int i = 0; i < 3; ++i)
00260       a[i] *= s;
00261   }
00263 
00265 
00267   static void MultiplyScalar2D(float a[2], float s) {
00268     for (int i = 0; i < 2; ++i)
00269       a[i] *= s;
00270   }
00272 
00274 
00276   static void MultiplyScalar(double a[3], double s) {
00277     for (int i = 0; i < 3; ++i)
00278       a[i] *= s;
00279   }
00281 
00283 
00285   static void MultiplyScalar2D(double a[2], double s) {
00286     for (int i = 0; i < 2; ++i)
00287       a[i] *= s;
00288   }
00290 
00292 
00293   static float Dot(const float x[3], const float y[3]) {
00294     return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
00296 
00298 
00299   static double Dot(const double x[3], const double y[3]) {
00300     return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
00302 
00304 
00305   static void Outer(const float x[3], const float y[3], float A[3][3]) {
00306     for (int i=0; i < 3; i++)
00307       for (int j=0; j < 3; j++)
00308         A[i][j] = x[i] * y[j];
00309   }
00311 
00312 
00313   static void Outer(const double x[3], const double y[3], double A[3][3]) {
00314     for (int i=0; i < 3; i++)
00315       for (int j=0; j < 3; j++)
00316         A[i][j] = x[i] * y[j];
00317   }
00319 
00321   static void Cross(const float x[3], const float y[3], float z[3]);
00322 
00325   static void Cross(const double x[3], const double y[3], double z[3]);
00326 
00328 
00329   static float Norm(const float* x, int n);
00330   static double Norm(const double* x, int n);
00332 
00334 
00335   static float Norm(const float x[3]) {
00336     return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ) );};
00338 
00340 
00341   static double Norm(const double x[3]) {
00342     return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );};
00344 
00346   static float Normalize(float x[3]);
00347 
00350   static double Normalize(double x[3]);
00351 
00353 
00358   static void Perpendiculars(const double x[3], double y[3], double z[3],
00359                              double theta);
00360   static void Perpendiculars(const float x[3], float y[3], float z[3],
00361                              double theta);
00363 
00365 
00368   static bool ProjectVector(const float a[3], const float b[3], float projection[3]);
00369   static bool ProjectVector(const double a[3], const double b[3], double projection[3]);
00371 
00373 
00377   static bool ProjectVector2D(const float a[2], const float b[2], float projection[2]);
00378   static bool ProjectVector2D(const double a[2], const double b[2], double projection[2]);
00380 
00382   static float Distance2BetweenPoints(const float x[3], const float y[3]);
00383 
00386   static double Distance2BetweenPoints(const double x[3], const double y[3]);
00387 
00391   static double GaussianAmplitude(const double variance, const double distanceFromMean);
00392 
00396   static double GaussianAmplitude(const double mean, const double variance, const double position);
00397 
00402   static double GaussianWeight(const double variance, const double distanceFromMean);
00403 
00408   static double GaussianWeight(const double mean, const double variance, const double position);
00409 
00411 
00412   static float Dot2D(const float x[2], const float y[2]) {
00413     return ( x[0] * y[0] + x[1] * y[1] );};
00415 
00417 
00418   static double Dot2D(const double x[2], const double y[2]) {
00419     return ( x[0] * y[0] + x[1] * y[1] );};
00421 
00423 
00424   static void Outer2D(const float x[2], const float y[2], float A[2][2])
00425     {
00426     for (int i=0; i < 2; i++)
00427       {
00428       for (int j=0; j < 2; j++)
00429         {
00430         A[i][j] = x[i] * y[j];
00431         }
00432       }
00433     }
00435 
00436 
00437   static void Outer2D(const double x[2], const double y[2], double A[2][2])
00438     {
00439     for (int i=0; i < 2; i++)
00440       {
00441       for (int j=0; j < 2; j++)
00442         {
00443         A[i][j] = x[i] * y[j];
00444         }
00445       }
00446     }
00448 
00450 
00451   static float Norm2D(const float x[2]) {
00452     return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] ) );};
00454 
00456 
00457   static double Norm2D(const double x[2]) {
00458     return sqrt( x[0] * x[0] + x[1] * x[1] );};
00460 
00462   static float Normalize2D(float x[2]);
00463 
00466   static double Normalize2D(double x[2]);
00467 
00469 
00470   static float Determinant2x2(const float c1[2], const float c2[2]) {
00471     return (c1[0] * c2[1] - c2[0] * c1[1] );};
00473 
00475 
00476   static double Determinant2x2(double a, double b, double c, double d) {
00477     return (a * d - b * c);};
00478   static double Determinant2x2(const double c1[2], const double c2[2]) {
00479     return (c1[0] * c2[1] - c2[0] * c1[1] );};
00481 
00483 
00484   static void LUFactor3x3(float A[3][3], int index[3]);
00485   static void LUFactor3x3(double A[3][3], int index[3]);
00487 
00489 
00490   static void LUSolve3x3(const float A[3][3], const int index[3],
00491                          float x[3]);
00492   static void LUSolve3x3(const double A[3][3], const int index[3],
00493                          double x[3]);
00495 
00497 
00499   static void LinearSolve3x3(const float A[3][3], const float x[3],
00500                              float y[3]);
00501   static void LinearSolve3x3(const double A[3][3], const double x[3],
00502                              double y[3]);
00504 
00506 
00507   static void Multiply3x3(const float A[3][3], const float in[3],
00508                           float out[3]);
00509   static void Multiply3x3(const double A[3][3], const double in[3],
00510                           double out[3]);
00512 
00514 
00515   static void Multiply3x3(const float A[3][3], const float B[3][3],
00516                           float C[3][3]);
00517   static void Multiply3x3(const double A[3][3], const double B[3][3],
00518                           double C[3][3]);
00520 
00522 
00524   static void MultiplyMatrix(const double **A, const double **B,
00525                              unsigned int rowA, unsigned int colA,
00526                              unsigned int rowB, unsigned int colB,
00527                              double **C);
00529 
00531 
00533   static void Transpose3x3(const float A[3][3], float AT[3][3]);
00534   static void Transpose3x3(const double A[3][3], double AT[3][3]);
00536 
00538 
00540   static void Invert3x3(const float A[3][3], float AI[3][3]);
00541   static void Invert3x3(const double A[3][3], double AI[3][3]);
00543 
00545 
00546   static void Identity3x3(float A[3][3]);
00547   static void Identity3x3(double A[3][3]);
00549 
00551 
00552   static double Determinant3x3(float A[3][3]);
00553   static double Determinant3x3(double A[3][3]);
00555 
00557 
00558   static float Determinant3x3(const float c1[3],
00559                               const float c2[3],
00560                               const float c3[3]);
00562 
00564 
00565   static double Determinant3x3(const double c1[3],
00566                                const double c2[3],
00567                                const double c3[3]);
00569 
00571 
00573   static double Determinant3x3(double a1, double a2, double a3,
00574                                double b1, double b2, double b3,
00575                                double c1, double c2, double c3);
00577 
00579 
00581   static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]);
00582   static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]);
00584 
00586 
00589   static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
00590   static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
00592 
00594 
00595   static void MultiplyQuaternion( const float q1[4], const float q2[4],  float q[4] );
00596   static void MultiplyQuaternion( const double q1[4], const double q2[4],  double q[4] );
00598 
00600 
00603   static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
00604   static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
00606 
00608 
00612   static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
00613   static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]);
00615 
00617 
00624   static void SingularValueDecomposition3x3(const float A[3][3],
00625                                             float U[3][3], float w[3],
00626                                             float VT[3][3]);
00627   static void SingularValueDecomposition3x3(const double A[3][3],
00628                                             double U[3][3], double w[3],
00629                                             double VT[3][3]);
00631 
00636   static int SolveLinearSystem(double **A, double *x, int size);
00637 
00641   static int InvertMatrix(double **A, double **AI, int size);
00642 
00644 
00646   static int InvertMatrix(double **A, double **AI, int size,
00647                           int *tmp1Size, double *tmp2Size);
00649 
00655   static int LUFactorLinearSystem(double **A, int *index, int size);
00656 
00658 
00660   static int LUFactorLinearSystem(double **A, int *index, int size,
00661                                   double *tmpSize);
00663 
00665 
00671   static void LUSolveLinearSystem(double **A, int *index,
00672                                   double *x, int size);
00674 
00682   static double EstimateMatrixCondition(double **A, int size);
00683 
00685 
00689   static int Jacobi(float **a, float *w, float **v);
00690   static int Jacobi(double **a, double *w, double **v);
00692 
00694 
00699   static int JacobiN(float **a, int n, float *w, float **v);
00700   static int JacobiN(double **a, int n, double *w, double **v);
00702 
00710   VTK_LEGACY(static double* SolveCubic(double c0, double c1, double c2, double c3));
00711 
00719   VTK_LEGACY(static double* SolveQuadratic(double c0, double c1, double c2));
00720 
00726   VTK_LEGACY(static double* SolveLinear(double c0, double c1));
00727 
00729 
00742   VTK_LEGACY(static int SolveCubic(double c0, double c1, double c2, double c3,
00743                         double *r1, double *r2, double *r3, int *num_roots));
00745 
00747 
00752   VTK_LEGACY(static int SolveQuadratic(double c0, double c1, double c2,
00753                             double *r1, double *r2, int *num_roots));
00755 
00762   VTK_LEGACY(static int SolveQuadratic( double* c, double* r, int* m ));
00763 
00769   VTK_LEGACY(static int SolveLinear(double c0, double c1, double *r1, int *num_roots));
00770 
00772 
00782   static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder,
00783                                 double **mt);
00785 
00786 
00788 
00799   static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
00800                                double **yt, int yOrder, double **mt, int checkHomogeneous=1);
00802 
00804 
00808   static void RGBToHSV(const float rgb[3], float hsv[3])
00809     { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00810   static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v);
00811   static double* RGBToHSV(const double rgb[3]);
00812   static double* RGBToHSV(double r, double g, double b);
00813   static void RGBToHSV(const double rgb[3], double hsv[3])
00814     { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00815   static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v);
00817 
00819 
00821   static void HSVToRGB(const float hsv[3], float rgb[3])
00822     { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00823   static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b);
00824   static double* HSVToRGB(const double hsv[3]);
00825   static double* HSVToRGB(double h, double s, double v);
00826   static void HSVToRGB(const double hsv[3], double rgb[3])
00827     { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00828   static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b);
00830 
00832 
00833   static void LabToXYZ(const double lab[3], double xyz[3]) {
00834     LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2);
00835   }
00836   static void LabToXYZ(double L, double a, double b,
00837                        double *x, double *y, double *z);
00838   static double *LabToXYZ(const double lab[3]);
00840 
00842 
00843   static void XYZToLab(const double xyz[3], double lab[3]) {
00844     XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2);
00845   }
00846   static void XYZToLab(double x, double y, double z,
00847                        double *L, double *a, double *b);
00848   static double *XYZToLab(const double xyz[3]);
00850 
00852 
00853   static void XYZToRGB(const double xyz[3], double rgb[3]) {
00854     XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2);
00855   }
00856   static void XYZToRGB(double x, double y, double z,
00857                        double *r, double *g, double *b);
00858   static double *XYZToRGB(const double xyz[3]);
00860 
00862 
00863   static void RGBToXYZ(const double rgb[3], double xyz[3]) {
00864     RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2);
00865   }
00866   static void RGBToXYZ(double r, double g, double b,
00867                        double *x, double *y, double *z);
00868   static double *RGBToXYZ(const double rgb[3]);
00870 
00872 
00875   static void RGBToLab(const double rgb[3], double lab[3]) {
00876     RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2);
00877   }
00878   static void RGBToLab(double red, double green, double blue,
00879                        double *L, double *a, double *b);
00880   static double *RGBToLab(const double rgb[3]);
00882 
00884 
00885   static void LabToRGB(const double lab[3], double rgb[3]) {
00886     LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2);
00887   }
00888   static void LabToRGB(double L, double a, double b,
00889                        double *red, double *green, double *blue);
00890   static double *LabToRGB(const double lab[3]);
00892 
00894 
00895   static void UninitializeBounds(double bounds[6]){
00896     bounds[0] = 1.0;
00897     bounds[1] = -1.0;
00898     bounds[2] = 1.0;
00899     bounds[3] = -1.0;
00900     bounds[4] = 1.0;
00901     bounds[5] = -1.0;
00902   }
00904 
00906 
00907   static int AreBoundsInitialized(double bounds[6]){
00908     if ( bounds[1]-bounds[0]<0.0 )
00909       {
00910       return 0;
00911       }
00912     return 1;
00913   }
00915 
00917 
00919   static void ClampValue(double *value, const double range[2]);
00920   static void ClampValue(double value, const double range[2], double *clamped_value);
00921   static void ClampValues(
00922     double *values, int nb_values, const double range[2]);
00923   static void ClampValues(
00924     const double *values, int nb_values, const double range[2], double *clamped_values);
00926 
00928 
00931   static double ClampAndNormalizeValue(double value,
00932                                        const double range[2]);
00934 
00936 
00942   static int GetScalarTypeFittingRange(
00943     double range_min, double range_max,
00944     double scale = 1.0, double shift = 0.0);
00946 
00948 
00954   static int GetAdjustedScalarRange(
00955     vtkDataArray *array, int comp, double range[2]);
00957 
00960   static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]);
00961 
00965   static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]);
00966 
00970   static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]);
00971 
00979   static double Solve3PointCircle(const double p1[3], const double p2[3], const double p3[3], double center[3]);
00980 
00982   static double Inf();
00983 
00985   static double NegInf();
00986 
00988   static double Nan();
00989 
00992   static int IsInf(double x);
00993 
00996   static int IsNan(double x);
00997 
00998 protected:
00999   vtkMath() {};
01000   ~vtkMath() {};
01001 
01002   static vtkMathInternal Internal;
01003 private:
01004   vtkMath(const vtkMath&);  // Not implemented.
01005   void operator=(const vtkMath&);  // Not implemented.
01006 };
01007 
01008 //----------------------------------------------------------------------------
01009 inline float vtkMath::RadiansFromDegrees( float x )
01010 {
01011   return x * 0.017453292f;
01012 }
01013 
01014 //----------------------------------------------------------------------------
01015 inline double vtkMath::RadiansFromDegrees( double x )
01016 {
01017   return x * 0.017453292519943295;
01018 }
01019 
01020 //----------------------------------------------------------------------------
01021 inline float vtkMath::DegreesFromRadians( float x )
01022 {
01023   return x * 57.2957795131f;
01024 }
01025 
01026 //----------------------------------------------------------------------------
01027 inline double vtkMath::DegreesFromRadians( double x )
01028 {
01029   return x * 57.29577951308232;
01030 }
01031 
01032 //----------------------------------------------------------------------------
01033 inline vtkTypeInt64 vtkMath::Factorial( int N )
01034 {
01035   vtkTypeInt64 r = 1;
01036   while ( N > 1 )
01037     {
01038     r *= N--;
01039     }
01040   return r;
01041 }
01042 
01043 //----------------------------------------------------------------------------
01044 // Modify the trunc() operation provided by static_cast<int>() to get floor(),
01045 // if x<0 (condition g) and x!=trunc(x) (condition n) then floor(x)=trunc(x)-1
01046 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
01047 inline int vtkMath::Floor(double x)
01048 {
01049   const int r = static_cast<int>(x);
01050   const int n = ( x != static_cast<double>(r) );
01051   const int g = ( x < 0 );
01052   return r - ( n & g );
01053 }
01054 
01055 //----------------------------------------------------------------------------
01056 // Modify the trunc() operation provided by static_cast<int>() to get ceil(),
01057 // if x>=0 (condition g) and x!=trunc(x) (condition n) then ceil(x)=trunc(x)+1
01058 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false).
01059 inline int vtkMath::Ceil(double x)
01060 {
01061   const int r = static_cast<int>(x);
01062   const int n = ( x != static_cast<double>(r) );
01063   const int g = ( x >= 0 );
01064   return r + ( n & g );
01065 }
01066 
01067 //----------------------------------------------------------------------------
01068 inline float vtkMath::Normalize(float x[3])
01069 {
01070   float den;
01071   if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01072     {
01073     for (int i=0; i < 3; i++)
01074       {
01075       x[i] /= den;
01076       }
01077     }
01078   return den;
01079 }
01080 
01081 //----------------------------------------------------------------------------
01082 inline double vtkMath::Normalize(double x[3])
01083 {
01084   double den;
01085   if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01086     {
01087     for (int i=0; i < 3; i++)
01088       {
01089       x[i] /= den;
01090       }
01091     }
01092   return den;
01093 }
01094 
01095 //----------------------------------------------------------------------------
01096 inline float vtkMath::Normalize2D(float x[3])
01097 {
01098   float den;
01099   if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01100     {
01101     for (int i=0; i < 2; i++)
01102       {
01103       x[i] /= den;
01104       }
01105     }
01106   return den;
01107 }
01108 
01109 //----------------------------------------------------------------------------
01110 inline double vtkMath::Normalize2D(double x[3])
01111 {
01112   double den;
01113   if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01114     {
01115     for (int i=0; i < 2; i++)
01116       {
01117       x[i] /= den;
01118       }
01119     }
01120   return den;
01121 }
01122 
01123 //----------------------------------------------------------------------------
01124 inline float vtkMath::Determinant3x3(const float c1[3],
01125                                      const float c2[3],
01126                                      const float c3[3])
01127 {
01128   return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01129          c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01130 }
01131 
01132 //----------------------------------------------------------------------------
01133 inline double vtkMath::Determinant3x3(const double c1[3],
01134                                       const double c2[3],
01135                                       const double c3[3])
01136 {
01137   return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01138          c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01139 }
01140 
01141 //----------------------------------------------------------------------------
01142 inline double vtkMath::Determinant3x3(double a1, double a2, double a3,
01143                                       double b1, double b2, double b3,
01144                                       double c1, double c2, double c3)
01145 {
01146     return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
01147            - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
01148            + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
01149 }
01150 
01151 //----------------------------------------------------------------------------
01152 inline float vtkMath::Distance2BetweenPoints(const float x[3],
01153                                              const float y[3])
01154 {
01155   return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01156            + ( x[1] - y[1] ) * ( x[1] - y[1] )
01157            + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01158 }
01159 
01160 //----------------------------------------------------------------------------
01161 inline double vtkMath::Distance2BetweenPoints(const double x[3],
01162                                               const double y[3])
01163 {
01164   return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01165            + ( x[1] - y[1] ) * ( x[1] - y[1] )
01166            + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01167 }
01168 
01169 //----------------------------------------------------------------------------
01170 // Cross product of two 3-vectors. Result (a x b) is stored in z[3].
01171 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
01172 {
01173   float Zx = x[1] * y[2] - x[2] * y[1];
01174   float Zy = x[2] * y[0] - x[0] * y[2];
01175   float Zz = x[0] * y[1] - x[1] * y[0];
01176   z[0] = Zx; z[1] = Zy; z[2] = Zz;
01177 }
01178 
01179 //----------------------------------------------------------------------------
01180 // Cross product of two 3-vectors. Result (a x b) is stored in z[3].
01181 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3])
01182 {
01183   double Zx = x[1] * y[2] - x[2] * y[1];
01184   double Zy = x[2] * y[0] - x[0] * y[2];
01185   double Zz = x[0] * y[1] - x[1] * y[0];
01186   z[0] = Zx; z[1] = Zy; z[2] = Zz;
01187 }
01188 
01189 //BTX
01190 //----------------------------------------------------------------------------
01191 template<class T>
01192 inline double vtkDeterminant3x3(T A[3][3])
01193 {
01194   return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] +
01195          A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] -
01196          A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2];
01197 }
01198 //ETX
01199 
01200 //----------------------------------------------------------------------------
01201 inline double vtkMath::Determinant3x3(float A[3][3])
01202 {
01203   return vtkDeterminant3x3( A );
01204 }
01205 
01206 //----------------------------------------------------------------------------
01207 inline double vtkMath::Determinant3x3(double A[3][3])
01208 {
01209   return vtkDeterminant3x3( A );
01210 }
01211 
01212 #ifndef VTK_LEGACY_REMOVE
01213 //----------------------------------------------------------------------------
01214 inline double* vtkMath::SolveCubic(double c0, double c1, double c2, double c3)
01215 {
01216   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveCubic, "VTK 5.8",
01217                            vtkPolynomialSolversUnivariate::SolveCubic);
01218   return vtkPolynomialSolversUnivariate::SolveCubic( c0, c1, c2, c3 );
01219 }
01220 
01221 //----------------------------------------------------------------------------
01222 inline double* vtkMath::SolveQuadratic(double c0, double c1, double c2)
01223 {
01224   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveQuadratic, "VTK 5.8",
01225                            vtkPolynomialSolversUnivariate::SolveQuadratic);
01226   return vtkPolynomialSolversUnivariate::SolveQuadratic( c0, c1, c2 );
01227 }
01228 
01229 //----------------------------------------------------------------------------
01230 inline double* vtkMath::SolveLinear(double c0, double c1)
01231 {
01232   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveLinear, "VTK 5.8",
01233                            vtkPolynomialSolversUnivariate::SolveLinear);
01234   return vtkPolynomialSolversUnivariate::SolveLinear( c0, c1 );
01235 }
01236 
01237 //----------------------------------------------------------------------------
01238 inline int vtkMath::SolveCubic(double c0, double c1, double c2, double c3,
01239                                double *r1, double *r2, double *r3, int *num_roots)
01240 {
01241   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveCubic, "VTK 5.8",
01242                            vtkPolynomialSolversUnivariate::SolveCubic);
01243   return vtkPolynomialSolversUnivariate::SolveCubic( c0, c1, c2, c3, r1, r2, r3, num_roots );
01244 }
01245 
01246 //----------------------------------------------------------------------------
01247 inline int vtkMath::SolveQuadratic(double c0, double c1, double c2,
01248                                    double *r1, double *r2, int *num_roots)
01249 {
01250   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveQuadratic, "VTK 5.8",
01251                            vtkPolynomialSolversUnivariate::SolveQuadratic);
01252   return vtkPolynomialSolversUnivariate::SolveQuadratic( c0, c1, c2, r1, r2, num_roots );
01253 }
01254 
01255 //----------------------------------------------------------------------------
01256 inline int vtkMath::SolveQuadratic( double* c, double* r, int* m )
01257 {
01258   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveQuadratic, "VTK 5.8",
01259                            vtkPolynomialSolversUnivariate::SolveQuadratic);
01260   return vtkPolynomialSolversUnivariate::SolveQuadratic( c, r, m );
01261 }
01262 
01263 //----------------------------------------------------------------------------
01264 inline int vtkMath::SolveLinear(double c0, double c1, double *r1, int *num_roots)
01265 {
01266   VTK_LEGACY_REPLACED_BODY(vtkMath::SolveLinear, "VTK 5.8",
01267                            vtkPolynomialSolversUnivariate::SolveLinear);
01268   return vtkPolynomialSolversUnivariate::SolveLinear( c0, c1, r1, num_roots );
01269 }
01270 #endif
01271 
01272 //----------------------------------------------------------------------------
01273 inline void vtkMath::ClampValue(double *value, const double range[2])
01274 {
01275   if (value && range)
01276     {
01277     if (*value < range[0])
01278       {
01279       *value = range[0];
01280       }
01281     else if (*value > range[1])
01282       {
01283       *value = range[1];
01284       }
01285     }
01286 }
01287 
01288 //----------------------------------------------------------------------------
01289 inline void vtkMath::ClampValue(
01290   double value, const double range[2], double *clamped_value)
01291 {
01292   if (range && clamped_value)
01293     {
01294     if (value < range[0])
01295       {
01296       *clamped_value = range[0];
01297       }
01298     else if (value > range[1])
01299       {
01300       *clamped_value = range[1];
01301       }
01302     else
01303       {
01304       *clamped_value = value;
01305       }
01306     }
01307 }
01308 
01309 // ---------------------------------------------------------------------------
01310 inline double vtkMath::ClampAndNormalizeValue(double value,
01311                                               const double range[2])
01312 {
01313   assert("pre: valid_range" && range[0]<=range[1]);
01314 
01315   double result;
01316   if(range[0]==range[1])
01317     {
01318       result=0.0;
01319     }
01320   else
01321     {
01322       // clamp
01323       if(value<range[0])
01324         {
01325           result=range[0];
01326         }
01327       else
01328         {
01329           if(value>range[1])
01330             {
01331               result=range[1];
01332             }
01333           else
01334             {
01335               result=value;
01336             }
01337         }
01338 
01339       // normalize
01340       result=( result - range[0] ) / ( range[1] - range[0] );
01341     }
01342 
01343   assert("post: valid_result" && result>=0.0 && result<=1.0);
01344 
01345   return result;
01346 }
01347 
01348 #if defined(VTK_HAS_ISINF)
01349 //-----------------------------------------------------------------------------
01350 inline int vtkMath::IsInf(double x)
01351 {
01352   return (isinf(x) ? 1 : 0);
01353 }
01354 #endif
01355 
01356 #if defined(VTK_HAS_ISNAN)
01357 //-----------------------------------------------------------------------------
01358 inline int vtkMath::IsNan(double x)
01359 {
01360   return (isnan(x) ? 1 : 0);
01361 }
01362 #endif
01363 
01364 #endif