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 =========================================================================*/ 00044 #ifndef __vtkMath_h 00045 #define __vtkMath_h 00046 00047 #include "vtkCommonCoreModule.h" // For export macro 00048 #include "vtkObject.h" 00049 00050 #include "vtkMathConfigure.h" // For <cmath> and VTK_HAS_ISNAN etc. 00051 00052 #include <cassert> // assert() in inline implementations. 00053 00054 #ifndef DBL_MIN 00055 # define VTK_DBL_MIN 2.2250738585072014e-308 00056 #else // DBL_MIN 00057 # define VTK_DBL_MIN DBL_MIN 00058 #endif // DBL_MIN 00059 00060 #ifndef DBL_EPSILON 00061 # define VTK_DBL_EPSILON 2.2204460492503131e-16 00062 #else // DBL_EPSILON 00063 # define VTK_DBL_EPSILON DBL_EPSILON 00064 #endif // DBL_EPSILON 00065 00066 #ifndef VTK_DBL_EPSILON 00067 # ifndef DBL_EPSILON 00068 # define VTK_DBL_EPSILON 2.2204460492503131e-16 00069 # else // DBL_EPSILON 00070 # define VTK_DBL_EPSILON DBL_EPSILON 00071 # endif // DBL_EPSILON 00072 #endif // VTK_DBL_EPSILON 00073 00074 class vtkDataArray; 00075 class vtkPoints; 00076 class vtkMathInternal; 00077 class vtkMinimalStandardRandomSequence; 00078 class vtkBoxMuellerRandomSequence; 00079 00080 class VTKCOMMONCORE_EXPORT vtkMath : public vtkObject 00081 { 00082 public: 00083 static vtkMath *New(); 00084 vtkTypeMacro(vtkMath,vtkObject); 00085 void PrintSelf(ostream& os, vtkIndent indent); 00086 00088 static double Pi() { return 3.141592653589793; }; 00089 00091 VTK_LEGACY(static double DoublePi()); 00092 00094 VTK_LEGACY(static double DoubleTwoPi()); 00095 00097 00098 static float RadiansFromDegrees( float degrees); 00099 static double RadiansFromDegrees( double degrees); 00101 00103 00104 static float DegreesFromRadians( float radians); 00105 static double DegreesFromRadians( double radians); 00107 00109 00110 static int Round(float f) { 00111 return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); } 00112 static int Round(double f) { 00113 return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); } 00115 00118 static int Floor(double x); 00119 00122 static int Ceil(double x); 00123 00127 static int CeilLog2(vtkTypeUInt64 x); 00128 00130 static bool IsPowerOfTwo(vtkTypeUInt64 x); 00131 00135 static int NearestPowerOfTwo(int x); 00136 00139 static vtkTypeInt64 Factorial( int N ); 00140 00144 static vtkTypeInt64 Binomial( int m, int n ); 00145 00152 static int* BeginCombination( int m, int n ); 00153 00160 static int NextCombination( int m, int n, int* combination ); 00161 00163 static void FreeCombination( int* combination); 00164 00176 static void RandomSeed(int s); 00177 00186 static int GetSeed(); 00187 00197 static double Random(); 00198 00207 static double Random( double min, double max ); 00208 00217 static double Gaussian(); 00218 00228 static double Gaussian( double mean, double std ); 00229 00231 00232 static void Add(const float a[3], const float b[3], float c[3]) { 00233 for (int i = 0; i < 3; ++i) 00234 c[i] = a[i] + b[i]; 00235 } 00237 00239 00240 static void Add(const double a[3], const double b[3], double c[3]) { 00241 for (int i = 0; i < 3; ++i) 00242 c[i] = a[i] + b[i]; 00243 } 00245 00247 00249 static void Subtract(const float a[3], const float b[3], float c[3]) { 00250 for (int i = 0; i < 3; ++i) 00251 c[i] = a[i] - b[i]; 00252 } 00254 00256 00258 static void Subtract(const double a[3], const double b[3], double c[3]) { 00259 for (int i = 0; i < 3; ++i) 00260 c[i] = a[i] - b[i]; 00261 } 00263 00265 00267 static void MultiplyScalar(float a[3], float s) { 00268 for (int i = 0; i < 3; ++i) 00269 a[i] *= s; 00270 } 00272 00274 00276 static void MultiplyScalar2D(float a[2], float s) { 00277 for (int i = 0; i < 2; ++i) 00278 a[i] *= s; 00279 } 00281 00283 00285 static void MultiplyScalar(double a[3], double s) { 00286 for (int i = 0; i < 3; ++i) 00287 a[i] *= s; 00288 } 00290 00292 00294 static void MultiplyScalar2D(double a[2], double s) { 00295 for (int i = 0; i < 2; ++i) 00296 a[i] *= s; 00297 } 00299 00301 00302 static float Dot(const float x[3], const float y[3]) { 00303 return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );}; 00305 00307 00308 static double Dot(const double x[3], const double y[3]) { 00309 return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );}; 00311 00313 00314 static void Outer(const float x[3], const float y[3], float A[3][3]) { 00315 for (int i=0; i < 3; i++) 00316 for (int j=0; j < 3; j++) 00317 A[i][j] = x[i] * y[j]; 00318 } 00320 00321 00322 static void Outer(const double x[3], const double y[3], double A[3][3]) { 00323 for (int i=0; i < 3; i++) 00324 for (int j=0; j < 3; j++) 00325 A[i][j] = x[i] * y[j]; 00326 } 00328 00330 static void Cross(const float x[3], const float y[3], float z[3]); 00331 00334 static void Cross(const double x[3], const double y[3], double z[3]); 00335 00337 00338 static float Norm(const float* x, int n); 00339 static double Norm(const double* x, int n); 00341 00343 00344 static float Norm(const float x[3]) { 00345 return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ) );}; 00347 00349 00350 static double Norm(const double x[3]) { 00351 return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );}; 00353 00355 static float Normalize(float x[3]); 00356 00359 static double Normalize(double x[3]); 00360 00362 00367 static void Perpendiculars(const double x[3], double y[3], double z[3], 00368 double theta); 00369 static void Perpendiculars(const float x[3], float y[3], float z[3], 00370 double theta); 00372 00374 00377 static bool ProjectVector(const float a[3], const float b[3], float projection[3]); 00378 static bool ProjectVector(const double a[3], const double b[3], double projection[3]); 00380 00382 00386 static bool ProjectVector2D(const float a[2], const float b[2], float projection[2]); 00387 static bool ProjectVector2D(const double a[2], const double b[2], double projection[2]); 00389 00391 static float Distance2BetweenPoints(const float x[3], const float y[3]); 00392 00395 static double Distance2BetweenPoints(const double x[3], const double y[3]); 00396 00400 static double GaussianAmplitude(const double variance, const double distanceFromMean); 00401 00405 static double GaussianAmplitude(const double mean, const double variance, const double position); 00406 00411 static double GaussianWeight(const double variance, const double distanceFromMean); 00412 00417 static double GaussianWeight(const double mean, const double variance, const double position); 00418 00420 00421 static float Dot2D(const float x[2], const float y[2]) { 00422 return ( x[0] * y[0] + x[1] * y[1] );}; 00424 00426 00427 static double Dot2D(const double x[2], const double y[2]) { 00428 return ( x[0] * y[0] + x[1] * y[1] );}; 00430 00432 00433 static void Outer2D(const float x[2], const float y[2], float A[2][2]) 00434 { 00435 for (int i=0; i < 2; i++) 00436 { 00437 for (int j=0; j < 2; j++) 00438 { 00439 A[i][j] = x[i] * y[j]; 00440 } 00441 } 00442 } 00444 00445 00446 static void Outer2D(const double x[2], const double y[2], double A[2][2]) 00447 { 00448 for (int i=0; i < 2; i++) 00449 { 00450 for (int j=0; j < 2; j++) 00451 { 00452 A[i][j] = x[i] * y[j]; 00453 } 00454 } 00455 } 00457 00459 00460 static float Norm2D(const float x[2]) { 00461 return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] ) );}; 00463 00465 00466 static double Norm2D(const double x[2]) { 00467 return sqrt( x[0] * x[0] + x[1] * x[1] );}; 00469 00471 static float Normalize2D(float x[2]); 00472 00475 static double Normalize2D(double x[2]); 00476 00478 00479 static float Determinant2x2(const float c1[2], const float c2[2]) { 00480 return (c1[0] * c2[1] - c2[0] * c1[1] );}; 00482 00484 00485 static double Determinant2x2(double a, double b, double c, double d) { 00486 return (a * d - b * c);}; 00487 static double Determinant2x2(const double c1[2], const double c2[2]) { 00488 return (c1[0] * c2[1] - c2[0] * c1[1] );}; 00490 00492 00493 static void LUFactor3x3(float A[3][3], int index[3]); 00494 static void LUFactor3x3(double A[3][3], int index[3]); 00496 00498 00499 static void LUSolve3x3(const float A[3][3], const int index[3], 00500 float x[3]); 00501 static void LUSolve3x3(const double A[3][3], const int index[3], 00502 double x[3]); 00504 00506 00508 static void LinearSolve3x3(const float A[3][3], const float x[3], 00509 float y[3]); 00510 static void LinearSolve3x3(const double A[3][3], const double x[3], 00511 double y[3]); 00513 00515 00516 static void Multiply3x3(const float A[3][3], const float in[3], 00517 float out[3]); 00518 static void Multiply3x3(const double A[3][3], const double in[3], 00519 double out[3]); 00521 00523 00524 static void Multiply3x3(const float A[3][3], const float B[3][3], 00525 float C[3][3]); 00526 static void Multiply3x3(const double A[3][3], const double B[3][3], 00527 double C[3][3]); 00529 00531 00533 static void MultiplyMatrix(const double **A, const double **B, 00534 unsigned int rowA, unsigned int colA, 00535 unsigned int rowB, unsigned int colB, 00536 double **C); 00538 00540 00542 static void Transpose3x3(const float A[3][3], float AT[3][3]); 00543 static void Transpose3x3(const double A[3][3], double AT[3][3]); 00545 00547 00549 static void Invert3x3(const float A[3][3], float AI[3][3]); 00550 static void Invert3x3(const double A[3][3], double AI[3][3]); 00552 00554 00555 static void Identity3x3(float A[3][3]); 00556 static void Identity3x3(double A[3][3]); 00558 00560 00561 static double Determinant3x3(float A[3][3]); 00562 static double Determinant3x3(double A[3][3]); 00564 00566 00567 static float Determinant3x3(const float c1[3], 00568 const float c2[3], 00569 const float c3[3]); 00571 00573 00574 static double Determinant3x3(const double c1[3], 00575 const double c2[3], 00576 const double c3[3]); 00578 00580 00582 static double Determinant3x3(double a1, double a2, double a3, 00583 double b1, double b2, double b3, 00584 double c1, double c2, double c3); 00586 00588 00592 static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]); 00593 static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]); 00595 00597 00602 static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]); 00603 static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]); 00605 00607 00610 static void MultiplyQuaternion( const float q1[4], const float q2[4], float q[4] ); 00611 static void MultiplyQuaternion( const double q1[4], const double q2[4], double q[4] ); 00613 00615 00618 static void Orthogonalize3x3(const float A[3][3], float B[3][3]); 00619 static void Orthogonalize3x3(const double A[3][3], double B[3][3]); 00621 00623 00627 static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]); 00628 static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]); 00630 00632 00639 static void SingularValueDecomposition3x3(const float A[3][3], 00640 float U[3][3], float w[3], 00641 float VT[3][3]); 00642 static void SingularValueDecomposition3x3(const double A[3][3], 00643 double U[3][3], double w[3], 00644 double VT[3][3]); 00646 00651 static int SolveLinearSystem(double **A, double *x, int size); 00652 00656 static int InvertMatrix(double **A, double **AI, int size); 00657 00659 00661 static int InvertMatrix(double **A, double **AI, int size, 00662 int *tmp1Size, double *tmp2Size); 00664 00680 static int LUFactorLinearSystem(double **A, int *index, int size); 00681 00683 00685 static int LUFactorLinearSystem(double **A, int *index, int size, 00686 double *tmpSize); 00688 00690 00696 static void LUSolveLinearSystem(double **A, int *index, 00697 double *x, int size); 00699 00707 static double EstimateMatrixCondition(double **A, int size); 00708 00710 00714 static int Jacobi(float **a, float *w, float **v); 00715 static int Jacobi(double **a, double *w, double **v); 00717 00719 00724 static int JacobiN(float **a, int n, float *w, float **v); 00725 static int JacobiN(double **a, int n, double *w, double **v); 00727 00729 00739 static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder, 00740 double **mt); 00742 00743 00745 00756 static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder, 00757 double **yt, int yOrder, double **mt, int checkHomogeneous=1); 00759 00761 00765 static void RGBToHSV(const float rgb[3], float hsv[3]) 00766 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); } 00767 static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v); 00768 static double* RGBToHSV(const double rgb[3]); 00769 static double* RGBToHSV(double r, double g, double b); 00770 static void RGBToHSV(const double rgb[3], double hsv[3]) 00771 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); } 00772 static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v); 00774 00776 00780 static void HSVToRGB(const float hsv[3], float rgb[3]) 00781 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); } 00782 static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b); 00783 static double* HSVToRGB(const double hsv[3]); 00784 static double* HSVToRGB(double h, double s, double v); 00785 static void HSVToRGB(const double hsv[3], double rgb[3]) 00786 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); } 00787 static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b); 00789 00791 00792 static void LabToXYZ(const double lab[3], double xyz[3]) { 00793 LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2); 00794 } 00795 static void LabToXYZ(double L, double a, double b, 00796 double *x, double *y, double *z); 00797 static double *LabToXYZ(const double lab[3]); 00799 00801 00802 static void XYZToLab(const double xyz[3], double lab[3]) { 00803 XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2); 00804 } 00805 static void XYZToLab(double x, double y, double z, 00806 double *L, double *a, double *b); 00807 static double *XYZToLab(const double xyz[3]); 00809 00811 00812 static void XYZToRGB(const double xyz[3], double rgb[3]) { 00813 XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2); 00814 } 00815 static void XYZToRGB(double x, double y, double z, 00816 double *r, double *g, double *b); 00817 static double *XYZToRGB(const double xyz[3]); 00819 00821 00822 static void RGBToXYZ(const double rgb[3], double xyz[3]) { 00823 RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2); 00824 } 00825 static void RGBToXYZ(double r, double g, double b, 00826 double *x, double *y, double *z); 00827 static double *RGBToXYZ(const double rgb[3]); 00829 00831 00834 static void RGBToLab(const double rgb[3], double lab[3]) { 00835 RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2); 00836 } 00837 static void RGBToLab(double red, double green, double blue, 00838 double *L, double *a, double *b); 00839 static double *RGBToLab(const double rgb[3]); 00841 00843 00844 static void LabToRGB(const double lab[3], double rgb[3]) { 00845 LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2); 00846 } 00847 static void LabToRGB(double L, double a, double b, 00848 double *red, double *green, double *blue); 00849 static double *LabToRGB(const double lab[3]); 00851 00853 00854 static void UninitializeBounds(double bounds[6]){ 00855 bounds[0] = 1.0; 00856 bounds[1] = -1.0; 00857 bounds[2] = 1.0; 00858 bounds[3] = -1.0; 00859 bounds[4] = 1.0; 00860 bounds[5] = -1.0; 00861 } 00863 00865 00866 static int AreBoundsInitialized(double bounds[6]){ 00867 if ( bounds[1]-bounds[0]<0.0 ) 00868 { 00869 return 0; 00870 } 00871 return 1; 00872 } 00874 00876 00878 static void ClampValue(double *value, const double range[2]); 00879 static void ClampValue(double value, const double range[2], double *clamped_value); 00880 static void ClampValues( 00881 double *values, int nb_values, const double range[2]); 00882 static void ClampValues( 00883 const double *values, int nb_values, const double range[2], double *clamped_values); 00885 00887 00890 static double ClampAndNormalizeValue(double value, 00891 const double range[2]); 00893 00895 00901 static int GetScalarTypeFittingRange( 00902 double range_min, double range_max, 00903 double scale = 1.0, double shift = 0.0); 00905 00907 00913 static int GetAdjustedScalarRange( 00914 vtkDataArray *array, int comp, double range[2]); 00916 00919 static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]); 00920 00924 static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]); 00925 00929 static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]); 00930 00938 static double Solve3PointCircle(const double p1[3], const double p2[3], const double p3[3], double center[3]); 00939 00941 static double Inf(); 00942 00944 static double NegInf(); 00945 00947 static double Nan(); 00948 00951 static int IsInf(double x); 00952 00955 static int IsNan(double x); 00956 00959 static bool IsFinite(double x); 00960 00961 protected: 00962 vtkMath() {} 00963 ~vtkMath() {} 00964 00965 static vtkMathInternal Internal; 00966 private: 00967 vtkMath(const vtkMath&); // Not implemented. 00968 void operator=(const vtkMath&); // Not implemented. 00969 }; 00970 00971 //---------------------------------------------------------------------------- 00972 inline float vtkMath::RadiansFromDegrees( float x ) 00973 { 00974 return x * 0.017453292f; 00975 } 00976 00977 //---------------------------------------------------------------------------- 00978 inline double vtkMath::RadiansFromDegrees( double x ) 00979 { 00980 return x * 0.017453292519943295; 00981 } 00982 00983 //---------------------------------------------------------------------------- 00984 inline float vtkMath::DegreesFromRadians( float x ) 00985 { 00986 return x * 57.2957795131f; 00987 } 00988 00989 //---------------------------------------------------------------------------- 00990 inline double vtkMath::DegreesFromRadians( double x ) 00991 { 00992 return x * 57.29577951308232; 00993 } 00994 00995 //---------------------------------------------------------------------------- 00996 inline vtkTypeInt64 vtkMath::Factorial( int N ) 00997 { 00998 vtkTypeInt64 r = 1; 00999 while ( N > 1 ) 01000 { 01001 r *= N--; 01002 } 01003 return r; 01004 } 01005 01006 //---------------------------------------------------------------------------- 01007 inline bool vtkMath::IsPowerOfTwo(vtkTypeUInt64 x) 01008 { 01009 return ((x != 0) & ((x & (x - 1)) == 0)); 01010 } 01011 01012 //---------------------------------------------------------------------------- 01013 // Credit goes to Peter Hart and William Lewis on comp.lang.python 1997 01014 inline int vtkMath::NearestPowerOfTwo(int x) 01015 { 01016 unsigned int z = ((x > 0) ? x - 1 : 0); 01017 z |= z >> 1; 01018 z |= z >> 2; 01019 z |= z >> 4; 01020 z |= z >> 8; 01021 z |= z >> 16; 01022 return static_cast<int>(z + 1); 01023 } 01024 01025 //---------------------------------------------------------------------------- 01026 // Modify the trunc() operation provided by static_cast<int>() to get floor(), 01027 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false). 01028 inline int vtkMath::Floor(double x) 01029 { 01030 int i = static_cast<int>(x); 01031 return i - ( i > x ); 01032 } 01033 01034 //---------------------------------------------------------------------------- 01035 // Modify the trunc() operation provided by static_cast<int>() to get ceil(), 01036 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false). 01037 inline int vtkMath::Ceil(double x) 01038 { 01039 int i = static_cast<int>(x); 01040 return i + ( i < x ); 01041 } 01042 01043 //---------------------------------------------------------------------------- 01044 inline float vtkMath::Normalize(float x[3]) 01045 { 01046 float den; 01047 if ( ( den = vtkMath::Norm( x ) ) != 0.0 ) 01048 { 01049 for (int i=0; i < 3; i++) 01050 { 01051 x[i] /= den; 01052 } 01053 } 01054 return den; 01055 } 01056 01057 //---------------------------------------------------------------------------- 01058 inline double vtkMath::Normalize(double x[3]) 01059 { 01060 double den; 01061 if ( ( den = vtkMath::Norm( x ) ) != 0.0 ) 01062 { 01063 for (int i=0; i < 3; i++) 01064 { 01065 x[i] /= den; 01066 } 01067 } 01068 return den; 01069 } 01070 01071 //---------------------------------------------------------------------------- 01072 inline float vtkMath::Normalize2D(float x[3]) 01073 { 01074 float den; 01075 if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 ) 01076 { 01077 for (int i=0; i < 2; i++) 01078 { 01079 x[i] /= den; 01080 } 01081 } 01082 return den; 01083 } 01084 01085 //---------------------------------------------------------------------------- 01086 inline double vtkMath::Normalize2D(double x[3]) 01087 { 01088 double den; 01089 if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 ) 01090 { 01091 for (int i=0; i < 2; i++) 01092 { 01093 x[i] /= den; 01094 } 01095 } 01096 return den; 01097 } 01098 01099 //---------------------------------------------------------------------------- 01100 inline float vtkMath::Determinant3x3(const float c1[3], 01101 const float c2[3], 01102 const float c3[3]) 01103 { 01104 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] - 01105 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2]; 01106 } 01107 01108 //---------------------------------------------------------------------------- 01109 inline double vtkMath::Determinant3x3(const double c1[3], 01110 const double c2[3], 01111 const double c3[3]) 01112 { 01113 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] - 01114 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2]; 01115 } 01116 01117 //---------------------------------------------------------------------------- 01118 inline double vtkMath::Determinant3x3(double a1, double a2, double a3, 01119 double b1, double b2, double b3, 01120 double c1, double c2, double c3) 01121 { 01122 return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 ) 01123 - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 ) 01124 + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) ); 01125 } 01126 01127 //---------------------------------------------------------------------------- 01128 inline float vtkMath::Distance2BetweenPoints(const float x[3], 01129 const float y[3]) 01130 { 01131 return ( ( x[0] - y[0] ) * ( x[0] - y[0] ) 01132 + ( x[1] - y[1] ) * ( x[1] - y[1] ) 01133 + ( x[2] - y[2] ) * ( x[2] - y[2] ) ); 01134 } 01135 01136 //---------------------------------------------------------------------------- 01137 inline double vtkMath::Distance2BetweenPoints(const double x[3], 01138 const double y[3]) 01139 { 01140 return ( ( x[0] - y[0] ) * ( x[0] - y[0] ) 01141 + ( x[1] - y[1] ) * ( x[1] - y[1] ) 01142 + ( x[2] - y[2] ) * ( x[2] - y[2] ) ); 01143 } 01144 01145 //---------------------------------------------------------------------------- 01146 // Cross product of two 3-vectors. Result (a x b) is stored in z[3]. 01147 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3]) 01148 { 01149 float Zx = x[1] * y[2] - x[2] * y[1]; 01150 float Zy = x[2] * y[0] - x[0] * y[2]; 01151 float Zz = x[0] * y[1] - x[1] * y[0]; 01152 z[0] = Zx; z[1] = Zy; z[2] = Zz; 01153 } 01154 01155 //---------------------------------------------------------------------------- 01156 // Cross product of two 3-vectors. Result (a x b) is stored in z[3]. 01157 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3]) 01158 { 01159 double Zx = x[1] * y[2] - x[2] * y[1]; 01160 double Zy = x[2] * y[0] - x[0] * y[2]; 01161 double Zz = x[0] * y[1] - x[1] * y[0]; 01162 z[0] = Zx; z[1] = Zy; z[2] = Zz; 01163 } 01164 01165 //BTX 01166 //---------------------------------------------------------------------------- 01167 template<class T> 01168 inline double vtkDeterminant3x3(T A[3][3]) 01169 { 01170 return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] + 01171 A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] - 01172 A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2]; 01173 } 01174 //ETX 01175 01176 //---------------------------------------------------------------------------- 01177 inline double vtkMath::Determinant3x3(float A[3][3]) 01178 { 01179 return vtkDeterminant3x3( A ); 01180 } 01181 01182 //---------------------------------------------------------------------------- 01183 inline double vtkMath::Determinant3x3(double A[3][3]) 01184 { 01185 return vtkDeterminant3x3( A ); 01186 } 01187 01188 //---------------------------------------------------------------------------- 01189 inline void vtkMath::ClampValue(double *value, const double range[2]) 01190 { 01191 if (value && range) 01192 { 01193 if (*value < range[0]) 01194 { 01195 *value = range[0]; 01196 } 01197 else if (*value > range[1]) 01198 { 01199 *value = range[1]; 01200 } 01201 } 01202 } 01203 01204 //---------------------------------------------------------------------------- 01205 inline void vtkMath::ClampValue( 01206 double value, const double range[2], double *clamped_value) 01207 { 01208 if (range && clamped_value) 01209 { 01210 if (value < range[0]) 01211 { 01212 *clamped_value = range[0]; 01213 } 01214 else if (value > range[1]) 01215 { 01216 *clamped_value = range[1]; 01217 } 01218 else 01219 { 01220 *clamped_value = value; 01221 } 01222 } 01223 } 01224 01225 // --------------------------------------------------------------------------- 01226 inline double vtkMath::ClampAndNormalizeValue(double value, 01227 const double range[2]) 01228 { 01229 assert("pre: valid_range" && range[0]<=range[1]); 01230 01231 double result; 01232 if(range[0]==range[1]) 01233 { 01234 result=0.0; 01235 } 01236 else 01237 { 01238 // clamp 01239 if(value<range[0]) 01240 { 01241 result=range[0]; 01242 } 01243 else 01244 { 01245 if(value>range[1]) 01246 { 01247 result=range[1]; 01248 } 01249 else 01250 { 01251 result=value; 01252 } 01253 } 01254 01255 // normalize 01256 result=( result - range[0] ) / ( range[1] - range[0] ); 01257 } 01258 01259 assert("post: valid_result" && result>=0.0 && result<=1.0); 01260 01261 return result; 01262 } 01263 01264 //----------------------------------------------------------------------------- 01265 #if defined(VTK_HAS_ISINF) || defined(VTK_HAS_STD_ISINF) 01266 #define VTK_MATH_ISINF_IS_INLINE 01267 inline int vtkMath::IsInf(double x) 01268 { 01269 #if defined(VTK_HAS_STD_ISINF) 01270 return std::isinf(x); 01271 #else 01272 return (isinf(x) != 0); // Force conversion to bool 01273 #endif 01274 } 01275 #endif 01276 01277 //----------------------------------------------------------------------------- 01278 #if defined(VTK_HAS_ISNAN) || defined(VTK_HAS_STD_ISNAN) 01279 #define VTK_MATH_ISNAN_IS_INLINE 01280 inline int vtkMath::IsNan(double x) 01281 { 01282 #if defined(VTK_HAS_STD_ISNAN) 01283 return std::isnan(x); 01284 #else 01285 return (isnan(x) != 0); // Force conversion to bool 01286 #endif 01287 } 01288 #endif 01289 01290 //----------------------------------------------------------------------------- 01291 #if defined(VTK_HAS_ISFINITE) || defined(VTK_HAS_STD_ISFINITE) || defined(VTK_HAS_FINITE) 01292 #define VTK_MATH_ISFINITE_IS_INLINE 01293 inline bool vtkMath::IsFinite(double x) 01294 { 01295 #if defined(VTK_HAS_STD_ISFINITE) 01296 return std::isfinite(x); 01297 #elif defined(VTK_HAS_ISFINITE) 01298 return (isfinite(x) != 0); // Force conversion to bool 01299 #else 01300 return (finite(x) != 0); // Force conversion to bool 01301 #endif 01302 } 01303 #endif 01304 01305 #endif