VTK
|
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