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 00398 static double AngleBetweenVectors(const double v1[3], const double v2[3]); 00399 00403 static double GaussianAmplitude(const double variance, const double distanceFromMean); 00404 00408 static double GaussianAmplitude(const double mean, const double variance, const double position); 00409 00414 static double GaussianWeight(const double variance, const double distanceFromMean); 00415 00420 static double GaussianWeight(const double mean, const double variance, const double position); 00421 00423 00424 static float Dot2D(const float x[2], const float y[2]) { 00425 return ( x[0] * y[0] + x[1] * y[1] );}; 00427 00429 00430 static double Dot2D(const double x[2], const double y[2]) { 00431 return ( x[0] * y[0] + x[1] * y[1] );}; 00433 00435 00436 static void Outer2D(const float x[2], const float y[2], float A[2][2]) 00437 { 00438 for (int i=0; i < 2; i++) 00439 { 00440 for (int j=0; j < 2; j++) 00441 { 00442 A[i][j] = x[i] * y[j]; 00443 } 00444 } 00445 } 00447 00448 00449 static void Outer2D(const double x[2], const double y[2], double A[2][2]) 00450 { 00451 for (int i=0; i < 2; i++) 00452 { 00453 for (int j=0; j < 2; j++) 00454 { 00455 A[i][j] = x[i] * y[j]; 00456 } 00457 } 00458 } 00460 00462 00463 static float Norm2D(const float x[2]) { 00464 return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] ) );}; 00466 00468 00469 static double Norm2D(const double x[2]) { 00470 return sqrt( x[0] * x[0] + x[1] * x[1] );}; 00472 00474 static float Normalize2D(float x[2]); 00475 00478 static double Normalize2D(double x[2]); 00479 00481 00482 static float Determinant2x2(const float c1[2], const float c2[2]) { 00483 return (c1[0] * c2[1] - c2[0] * c1[1] );}; 00485 00487 00488 static double Determinant2x2(double a, double b, double c, double d) { 00489 return (a * d - b * c);}; 00490 static double Determinant2x2(const double c1[2], const double c2[2]) { 00491 return (c1[0] * c2[1] - c2[0] * c1[1] );}; 00493 00495 00496 static void LUFactor3x3(float A[3][3], int index[3]); 00497 static void LUFactor3x3(double A[3][3], int index[3]); 00499 00501 00502 static void LUSolve3x3(const float A[3][3], const int index[3], 00503 float x[3]); 00504 static void LUSolve3x3(const double A[3][3], const int index[3], 00505 double x[3]); 00507 00509 00511 static void LinearSolve3x3(const float A[3][3], const float x[3], 00512 float y[3]); 00513 static void LinearSolve3x3(const double A[3][3], const double x[3], 00514 double y[3]); 00516 00518 00519 static void Multiply3x3(const float A[3][3], const float in[3], 00520 float out[3]); 00521 static void Multiply3x3(const double A[3][3], const double in[3], 00522 double out[3]); 00524 00526 00527 static void Multiply3x3(const float A[3][3], const float B[3][3], 00528 float C[3][3]); 00529 static void Multiply3x3(const double A[3][3], const double B[3][3], 00530 double C[3][3]); 00532 00534 00536 static void MultiplyMatrix(double **A, double **B, 00537 unsigned int rowA, unsigned int colA, 00538 unsigned int rowB, unsigned int colB, 00539 double **C); 00541 00543 00545 static void Transpose3x3(const float A[3][3], float AT[3][3]); 00546 static void Transpose3x3(const double A[3][3], double AT[3][3]); 00548 00550 00552 static void Invert3x3(const float A[3][3], float AI[3][3]); 00553 static void Invert3x3(const double A[3][3], double AI[3][3]); 00555 00557 00558 static void Identity3x3(float A[3][3]); 00559 static void Identity3x3(double A[3][3]); 00561 00563 00564 static double Determinant3x3(float A[3][3]); 00565 static double Determinant3x3(double A[3][3]); 00567 00569 00570 static float Determinant3x3(const float c1[3], 00571 const float c2[3], 00572 const float c3[3]); 00574 00576 00577 static double Determinant3x3(const double c1[3], 00578 const double c2[3], 00579 const double c3[3]); 00581 00583 00585 static double Determinant3x3(double a1, double a2, double a3, 00586 double b1, double b2, double b3, 00587 double c1, double c2, double c3); 00589 00591 00595 static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]); 00596 static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]); 00598 00600 00605 static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]); 00606 static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]); 00608 00610 00613 static void MultiplyQuaternion( const float q1[4], const float q2[4], float q[4] ); 00614 static void MultiplyQuaternion( const double q1[4], const double q2[4], double q[4] ); 00616 00618 00621 static void Orthogonalize3x3(const float A[3][3], float B[3][3]); 00622 static void Orthogonalize3x3(const double A[3][3], double B[3][3]); 00624 00626 00630 static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]); 00631 static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]); 00633 00635 00642 static void SingularValueDecomposition3x3(const float A[3][3], 00643 float U[3][3], float w[3], 00644 float VT[3][3]); 00645 static void SingularValueDecomposition3x3(const double A[3][3], 00646 double U[3][3], double w[3], 00647 double VT[3][3]); 00649 00654 static int SolveLinearSystem(double **A, double *x, int size); 00655 00659 static int InvertMatrix(double **A, double **AI, int size); 00660 00662 00664 static int InvertMatrix(double **A, double **AI, int size, 00665 int *tmp1Size, double *tmp2Size); 00667 00683 static int LUFactorLinearSystem(double **A, int *index, int size); 00684 00686 00688 static int LUFactorLinearSystem(double **A, int *index, int size, 00689 double *tmpSize); 00691 00693 00699 static void LUSolveLinearSystem(double **A, int *index, 00700 double *x, int size); 00702 00710 static double EstimateMatrixCondition(double **A, int size); 00711 00713 00718 static int Jacobi(float **a, float *w, float **v); 00719 static int Jacobi(double **a, double *w, double **v); 00721 00723 00729 static int JacobiN(float **a, int n, float *w, float **v); 00730 static int JacobiN(double **a, int n, double *w, double **v); 00732 00734 00744 static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder, 00745 double **mt); 00747 00748 00750 00761 static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder, 00762 double **yt, int yOrder, double **mt, int checkHomogeneous=1); 00764 00766 00770 static void RGBToHSV(const float rgb[3], float hsv[3]) 00771 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); } 00772 static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v); 00773 static double* RGBToHSV(const double rgb[3]); 00774 static double* RGBToHSV(double r, double g, double b); 00775 static void RGBToHSV(const double rgb[3], double hsv[3]) 00776 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); } 00777 static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v); 00779 00781 00785 static void HSVToRGB(const float hsv[3], float rgb[3]) 00786 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); } 00787 static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b); 00788 static double* HSVToRGB(const double hsv[3]); 00789 static double* HSVToRGB(double h, double s, double v); 00790 static void HSVToRGB(const double hsv[3], double rgb[3]) 00791 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); } 00792 static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b); 00794 00796 00797 static void LabToXYZ(const double lab[3], double xyz[3]) { 00798 LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2); 00799 } 00800 static void LabToXYZ(double L, double a, double b, 00801 double *x, double *y, double *z); 00802 static double *LabToXYZ(const double lab[3]); 00804 00806 00807 static void XYZToLab(const double xyz[3], double lab[3]) { 00808 XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2); 00809 } 00810 static void XYZToLab(double x, double y, double z, 00811 double *L, double *a, double *b); 00812 static double *XYZToLab(const double xyz[3]); 00814 00816 00817 static void XYZToRGB(const double xyz[3], double rgb[3]) { 00818 XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2); 00819 } 00820 static void XYZToRGB(double x, double y, double z, 00821 double *r, double *g, double *b); 00822 static double *XYZToRGB(const double xyz[3]); 00824 00826 00827 static void RGBToXYZ(const double rgb[3], double xyz[3]) { 00828 RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2); 00829 } 00830 static void RGBToXYZ(double r, double g, double b, 00831 double *x, double *y, double *z); 00832 static double *RGBToXYZ(const double rgb[3]); 00834 00836 00839 static void RGBToLab(const double rgb[3], double lab[3]) { 00840 RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2); 00841 } 00842 static void RGBToLab(double red, double green, double blue, 00843 double *L, double *a, double *b); 00844 static double *RGBToLab(const double rgb[3]); 00846 00848 00849 static void LabToRGB(const double lab[3], double rgb[3]) { 00850 LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2); 00851 } 00852 static void LabToRGB(double L, double a, double b, 00853 double *red, double *green, double *blue); 00854 static double *LabToRGB(const double lab[3]); 00856 00858 00859 static void UninitializeBounds(double bounds[6]){ 00860 bounds[0] = 1.0; 00861 bounds[1] = -1.0; 00862 bounds[2] = 1.0; 00863 bounds[3] = -1.0; 00864 bounds[4] = 1.0; 00865 bounds[5] = -1.0; 00866 } 00868 00870 00871 static int AreBoundsInitialized(double bounds[6]){ 00872 if ( bounds[1]-bounds[0]<0.0 ) 00873 { 00874 return 0; 00875 } 00876 return 1; 00877 } 00879 00881 00883 static void ClampValue(double *value, const double range[2]); 00884 static void ClampValue(double value, const double range[2], double *clamped_value); 00885 static void ClampValues( 00886 double *values, int nb_values, const double range[2]); 00887 static void ClampValues( 00888 const double *values, int nb_values, const double range[2], double *clamped_values); 00890 00892 00895 static double ClampAndNormalizeValue(double value, 00896 const double range[2]); 00898 00900 00906 static int GetScalarTypeFittingRange( 00907 double range_min, double range_max, 00908 double scale = 1.0, double shift = 0.0); 00910 00912 00918 static int GetAdjustedScalarRange( 00919 vtkDataArray *array, int comp, double range[2]); 00921 00924 static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]); 00925 00929 static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]); 00930 00934 static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]); 00935 00944 static double Solve3PointCircle(const double p1[3], const double p2[3], const double p3[3], double center[3]); 00945 00947 static double Inf(); 00948 00950 static double NegInf(); 00951 00953 static double Nan(); 00954 00957 static int IsInf(double x); 00958 00961 static int IsNan(double x); 00962 00965 static bool IsFinite(double x); 00966 00967 protected: 00968 vtkMath() {} 00969 ~vtkMath() {} 00970 00971 static vtkMathInternal Internal; 00972 private: 00973 vtkMath(const vtkMath&); // Not implemented. 00974 void operator=(const vtkMath&); // Not implemented. 00975 }; 00976 00977 //---------------------------------------------------------------------------- 00978 inline float vtkMath::RadiansFromDegrees( float x ) 00979 { 00980 return x * 0.017453292f; 00981 } 00982 00983 //---------------------------------------------------------------------------- 00984 inline double vtkMath::RadiansFromDegrees( double x ) 00985 { 00986 return x * 0.017453292519943295; 00987 } 00988 00989 //---------------------------------------------------------------------------- 00990 inline float vtkMath::DegreesFromRadians( float x ) 00991 { 00992 return x * 57.2957795131f; 00993 } 00994 00995 //---------------------------------------------------------------------------- 00996 inline double vtkMath::DegreesFromRadians( double x ) 00997 { 00998 return x * 57.29577951308232; 00999 } 01000 01001 //---------------------------------------------------------------------------- 01002 inline vtkTypeInt64 vtkMath::Factorial( int N ) 01003 { 01004 vtkTypeInt64 r = 1; 01005 while ( N > 1 ) 01006 { 01007 r *= N--; 01008 } 01009 return r; 01010 } 01011 01012 //---------------------------------------------------------------------------- 01013 inline bool vtkMath::IsPowerOfTwo(vtkTypeUInt64 x) 01014 { 01015 return ((x != 0) & ((x & (x - 1)) == 0)); 01016 } 01017 01018 //---------------------------------------------------------------------------- 01019 // Credit goes to Peter Hart and William Lewis on comp.lang.python 1997 01020 inline int vtkMath::NearestPowerOfTwo(int x) 01021 { 01022 unsigned int z = ((x > 0) ? x - 1 : 0); 01023 z |= z >> 1; 01024 z |= z >> 2; 01025 z |= z >> 4; 01026 z |= z >> 8; 01027 z |= z >> 16; 01028 return static_cast<int>(z + 1); 01029 } 01030 01031 //---------------------------------------------------------------------------- 01032 // Modify the trunc() operation provided by static_cast<int>() to get floor(), 01033 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false). 01034 inline int vtkMath::Floor(double x) 01035 { 01036 int i = static_cast<int>(x); 01037 return i - ( i > x ); 01038 } 01039 01040 //---------------------------------------------------------------------------- 01041 // Modify the trunc() operation provided by static_cast<int>() to get ceil(), 01042 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false). 01043 inline int vtkMath::Ceil(double x) 01044 { 01045 int i = static_cast<int>(x); 01046 return i + ( i < x ); 01047 } 01048 01049 //---------------------------------------------------------------------------- 01050 inline float vtkMath::Normalize(float x[3]) 01051 { 01052 float den = vtkMath::Norm( x ); 01053 if ( den != 0.0 ) 01054 { 01055 for (int i=0; i < 3; i++) 01056 { 01057 x[i] /= den; 01058 } 01059 } 01060 return den; 01061 } 01062 01063 //---------------------------------------------------------------------------- 01064 inline double vtkMath::Normalize(double x[3]) 01065 { 01066 double den = vtkMath::Norm( x ); 01067 if ( den != 0.0 ) 01068 { 01069 for (int i=0; i < 3; i++) 01070 { 01071 x[i] /= den; 01072 } 01073 } 01074 return den; 01075 } 01076 01077 //---------------------------------------------------------------------------- 01078 inline float vtkMath::Normalize2D(float x[3]) 01079 { 01080 float den = vtkMath::Norm2D( x ); 01081 if ( den != 0.0 ) 01082 { 01083 for (int i=0; i < 2; i++) 01084 { 01085 x[i] /= den; 01086 } 01087 } 01088 return den; 01089 } 01090 01091 //---------------------------------------------------------------------------- 01092 inline double vtkMath::Normalize2D(double x[3]) 01093 { 01094 double den = vtkMath::Norm2D( x ); 01095 if ( den != 0.0 ) 01096 { 01097 for (int i=0; i < 2; i++) 01098 { 01099 x[i] /= den; 01100 } 01101 } 01102 return den; 01103 } 01104 01105 //---------------------------------------------------------------------------- 01106 inline float vtkMath::Determinant3x3(const float c1[3], 01107 const float c2[3], 01108 const float c3[3]) 01109 { 01110 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] - 01111 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2]; 01112 } 01113 01114 //---------------------------------------------------------------------------- 01115 inline double vtkMath::Determinant3x3(const double c1[3], 01116 const double c2[3], 01117 const double c3[3]) 01118 { 01119 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] - 01120 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2]; 01121 } 01122 01123 //---------------------------------------------------------------------------- 01124 inline double vtkMath::Determinant3x3(double a1, double a2, double a3, 01125 double b1, double b2, double b3, 01126 double c1, double c2, double c3) 01127 { 01128 return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 ) 01129 - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 ) 01130 + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) ); 01131 } 01132 01133 //---------------------------------------------------------------------------- 01134 inline float vtkMath::Distance2BetweenPoints(const float x[3], 01135 const float y[3]) 01136 { 01137 return ( ( x[0] - y[0] ) * ( x[0] - y[0] ) 01138 + ( x[1] - y[1] ) * ( x[1] - y[1] ) 01139 + ( x[2] - y[2] ) * ( x[2] - y[2] ) ); 01140 } 01141 01142 //---------------------------------------------------------------------------- 01143 inline double vtkMath::Distance2BetweenPoints(const double x[3], 01144 const double y[3]) 01145 { 01146 return ( ( x[0] - y[0] ) * ( x[0] - y[0] ) 01147 + ( x[1] - y[1] ) * ( x[1] - y[1] ) 01148 + ( x[2] - y[2] ) * ( x[2] - y[2] ) ); 01149 } 01150 01151 //---------------------------------------------------------------------------- 01152 // Cross product of two 3-vectors. Result (a x b) is stored in z[3]. 01153 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3]) 01154 { 01155 float Zx = x[1] * y[2] - x[2] * y[1]; 01156 float Zy = x[2] * y[0] - x[0] * y[2]; 01157 float Zz = x[0] * y[1] - x[1] * y[0]; 01158 z[0] = Zx; z[1] = Zy; z[2] = Zz; 01159 } 01160 01161 //---------------------------------------------------------------------------- 01162 // Cross product of two 3-vectors. Result (a x b) is stored in z[3]. 01163 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3]) 01164 { 01165 double Zx = x[1] * y[2] - x[2] * y[1]; 01166 double Zy = x[2] * y[0] - x[0] * y[2]; 01167 double Zz = x[0] * y[1] - x[1] * y[0]; 01168 z[0] = Zx; z[1] = Zy; z[2] = Zz; 01169 } 01170 01171 //BTX 01172 //---------------------------------------------------------------------------- 01173 template<class T> 01174 inline double vtkDeterminant3x3(T A[3][3]) 01175 { 01176 return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] + 01177 A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] - 01178 A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2]; 01179 } 01180 //ETX 01181 01182 //---------------------------------------------------------------------------- 01183 inline double vtkMath::Determinant3x3(float A[3][3]) 01184 { 01185 return vtkDeterminant3x3( A ); 01186 } 01187 01188 //---------------------------------------------------------------------------- 01189 inline double vtkMath::Determinant3x3(double A[3][3]) 01190 { 01191 return vtkDeterminant3x3( A ); 01192 } 01193 01194 //---------------------------------------------------------------------------- 01195 inline void vtkMath::ClampValue(double *value, const double range[2]) 01196 { 01197 if (value && range) 01198 { 01199 if (*value < range[0]) 01200 { 01201 *value = range[0]; 01202 } 01203 else if (*value > range[1]) 01204 { 01205 *value = range[1]; 01206 } 01207 } 01208 } 01209 01210 //---------------------------------------------------------------------------- 01211 inline void vtkMath::ClampValue( 01212 double value, const double range[2], double *clamped_value) 01213 { 01214 if (range && clamped_value) 01215 { 01216 if (value < range[0]) 01217 { 01218 *clamped_value = range[0]; 01219 } 01220 else if (value > range[1]) 01221 { 01222 *clamped_value = range[1]; 01223 } 01224 else 01225 { 01226 *clamped_value = value; 01227 } 01228 } 01229 } 01230 01231 // --------------------------------------------------------------------------- 01232 inline double vtkMath::ClampAndNormalizeValue(double value, 01233 const double range[2]) 01234 { 01235 assert("pre: valid_range" && range[0]<=range[1]); 01236 01237 double result; 01238 if(range[0]==range[1]) 01239 { 01240 result=0.0; 01241 } 01242 else 01243 { 01244 // clamp 01245 if(value<range[0]) 01246 { 01247 result=range[0]; 01248 } 01249 else 01250 { 01251 if(value>range[1]) 01252 { 01253 result=range[1]; 01254 } 01255 else 01256 { 01257 result=value; 01258 } 01259 } 01260 01261 // normalize 01262 result=( result - range[0] ) / ( range[1] - range[0] ); 01263 } 01264 01265 assert("post: valid_result" && result>=0.0 && result<=1.0); 01266 01267 return result; 01268 } 01269 01270 //----------------------------------------------------------------------------- 01271 #if defined(VTK_HAS_ISINF) || defined(VTK_HAS_STD_ISINF) 01272 #define VTK_MATH_ISINF_IS_INLINE 01273 inline int vtkMath::IsInf(double x) 01274 { 01275 #if defined(VTK_HAS_STD_ISINF) 01276 return std::isinf(x); 01277 #else 01278 return (isinf(x) != 0); // Force conversion to bool 01279 #endif 01280 } 01281 #endif 01282 01283 //----------------------------------------------------------------------------- 01284 #if defined(VTK_HAS_ISNAN) || defined(VTK_HAS_STD_ISNAN) 01285 #define VTK_MATH_ISNAN_IS_INLINE 01286 inline int vtkMath::IsNan(double x) 01287 { 01288 #if defined(VTK_HAS_STD_ISNAN) 01289 return std::isnan(x); 01290 #else 01291 return (isnan(x) != 0); // Force conversion to bool 01292 #endif 01293 } 01294 #endif 01295 01296 //----------------------------------------------------------------------------- 01297 #if defined(VTK_HAS_ISFINITE) || defined(VTK_HAS_STD_ISFINITE) || defined(VTK_HAS_FINITE) 01298 #define VTK_MATH_ISFINITE_IS_INLINE 01299 inline bool vtkMath::IsFinite(double x) 01300 { 01301 #if defined(VTK_HAS_STD_ISFINITE) 01302 return std::isfinite(x); 01303 #elif defined(VTK_HAS_ISFINITE) 01304 return (isfinite(x) != 0); // Force conversion to bool 01305 #else 01306 return (finite(x) != 0); // Force conversion to bool 01307 #endif 01308 } 01309 #endif 01310 01311 #endif