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 <assert.h> // 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 00670 static int LUFactorLinearSystem(double **A, int *index, int size); 00671 00673 00675 static int LUFactorLinearSystem(double **A, int *index, int size, 00676 double *tmpSize); 00678 00680 00686 static void LUSolveLinearSystem(double **A, int *index, 00687 double *x, int size); 00689 00697 static double EstimateMatrixCondition(double **A, int size); 00698 00700 00704 static int Jacobi(float **a, float *w, float **v); 00705 static int Jacobi(double **a, double *w, double **v); 00707 00709 00714 static int JacobiN(float **a, int n, float *w, float **v); 00715 static int JacobiN(double **a, int n, double *w, double **v); 00717 00719 00729 static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder, 00730 double **mt); 00732 00733 00735 00746 static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder, 00747 double **yt, int yOrder, double **mt, int checkHomogeneous=1); 00749 00751 00755 static void RGBToHSV(const float rgb[3], float hsv[3]) 00756 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); } 00757 static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v); 00758 static double* RGBToHSV(const double rgb[3]); 00759 static double* RGBToHSV(double r, double g, double b); 00760 static void RGBToHSV(const double rgb[3], double hsv[3]) 00761 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); } 00762 static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v); 00764 00766 00770 static void HSVToRGB(const float hsv[3], float rgb[3]) 00771 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); } 00772 static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b); 00773 static double* HSVToRGB(const double hsv[3]); 00774 static double* HSVToRGB(double h, double s, double v); 00775 static void HSVToRGB(const double hsv[3], double rgb[3]) 00776 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); } 00777 static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b); 00779 00781 00782 static void LabToXYZ(const double lab[3], double xyz[3]) { 00783 LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2); 00784 } 00785 static void LabToXYZ(double L, double a, double b, 00786 double *x, double *y, double *z); 00787 static double *LabToXYZ(const double lab[3]); 00789 00791 00792 static void XYZToLab(const double xyz[3], double lab[3]) { 00793 XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2); 00794 } 00795 static void XYZToLab(double x, double y, double z, 00796 double *L, double *a, double *b); 00797 static double *XYZToLab(const double xyz[3]); 00799 00801 00802 static void XYZToRGB(const double xyz[3], double rgb[3]) { 00803 XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2); 00804 } 00805 static void XYZToRGB(double x, double y, double z, 00806 double *r, double *g, double *b); 00807 static double *XYZToRGB(const double xyz[3]); 00809 00811 00812 static void RGBToXYZ(const double rgb[3], double xyz[3]) { 00813 RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2); 00814 } 00815 static void RGBToXYZ(double r, double g, double b, 00816 double *x, double *y, double *z); 00817 static double *RGBToXYZ(const double rgb[3]); 00819 00821 00824 static void RGBToLab(const double rgb[3], double lab[3]) { 00825 RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2); 00826 } 00827 static void RGBToLab(double red, double green, double blue, 00828 double *L, double *a, double *b); 00829 static double *RGBToLab(const double rgb[3]); 00831 00833 00834 static void LabToRGB(const double lab[3], double rgb[3]) { 00835 LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2); 00836 } 00837 static void LabToRGB(double L, double a, double b, 00838 double *red, double *green, double *blue); 00839 static double *LabToRGB(const double lab[3]); 00841 00843 00844 static void UninitializeBounds(double bounds[6]){ 00845 bounds[0] = 1.0; 00846 bounds[1] = -1.0; 00847 bounds[2] = 1.0; 00848 bounds[3] = -1.0; 00849 bounds[4] = 1.0; 00850 bounds[5] = -1.0; 00851 } 00853 00855 00856 static int AreBoundsInitialized(double bounds[6]){ 00857 if ( bounds[1]-bounds[0]<0.0 ) 00858 { 00859 return 0; 00860 } 00861 return 1; 00862 } 00864 00866 00868 static void ClampValue(double *value, const double range[2]); 00869 static void ClampValue(double value, const double range[2], double *clamped_value); 00870 static void ClampValues( 00871 double *values, int nb_values, const double range[2]); 00872 static void ClampValues( 00873 const double *values, int nb_values, const double range[2], double *clamped_values); 00875 00877 00880 static double ClampAndNormalizeValue(double value, 00881 const double range[2]); 00883 00885 00891 static int GetScalarTypeFittingRange( 00892 double range_min, double range_max, 00893 double scale = 1.0, double shift = 0.0); 00895 00897 00903 static int GetAdjustedScalarRange( 00904 vtkDataArray *array, int comp, double range[2]); 00906 00909 static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]); 00910 00914 static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]); 00915 00919 static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]); 00920 00928 static double Solve3PointCircle(const double p1[3], const double p2[3], const double p3[3], double center[3]); 00929 00931 static double Inf(); 00932 00934 static double NegInf(); 00935 00937 static double Nan(); 00938 00941 static int IsInf(double x); 00942 00945 static int IsNan(double x); 00946 00949 static bool IsFinite(double x); 00950 00951 protected: 00952 vtkMath() {}; 00953 ~vtkMath() {}; 00954 00955 static vtkMathInternal Internal; 00956 private: 00957 vtkMath(const vtkMath&); // Not implemented. 00958 void operator=(const vtkMath&); // Not implemented. 00959 }; 00960 00961 //---------------------------------------------------------------------------- 00962 inline float vtkMath::RadiansFromDegrees( float x ) 00963 { 00964 return x * 0.017453292f; 00965 } 00966 00967 //---------------------------------------------------------------------------- 00968 inline double vtkMath::RadiansFromDegrees( double x ) 00969 { 00970 return x * 0.017453292519943295; 00971 } 00972 00973 //---------------------------------------------------------------------------- 00974 inline float vtkMath::DegreesFromRadians( float x ) 00975 { 00976 return x * 57.2957795131f; 00977 } 00978 00979 //---------------------------------------------------------------------------- 00980 inline double vtkMath::DegreesFromRadians( double x ) 00981 { 00982 return x * 57.29577951308232; 00983 } 00984 00985 //---------------------------------------------------------------------------- 00986 inline vtkTypeInt64 vtkMath::Factorial( int N ) 00987 { 00988 vtkTypeInt64 r = 1; 00989 while ( N > 1 ) 00990 { 00991 r *= N--; 00992 } 00993 return r; 00994 } 00995 00996 //---------------------------------------------------------------------------- 00997 inline bool vtkMath::IsPowerOfTwo(vtkTypeUInt64 x) 00998 { 00999 return ((x != 0) & ((x & (x - 1)) == 0)); 01000 } 01001 01002 //---------------------------------------------------------------------------- 01003 // Credit goes to Peter Hart and William Lewis on comp.lang.python 1997 01004 inline int vtkMath::NearestPowerOfTwo(int x) 01005 { 01006 unsigned int z = ((x > 0) ? x - 1 : 0); 01007 z |= z >> 1; 01008 z |= z >> 2; 01009 z |= z >> 4; 01010 z |= z >> 8; 01011 z |= z >> 16; 01012 return static_cast<int>(z + 1); 01013 } 01014 01015 //---------------------------------------------------------------------------- 01016 // Modify the trunc() operation provided by static_cast<int>() to get floor(), 01017 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false). 01018 inline int vtkMath::Floor(double x) 01019 { 01020 int i = static_cast<int>(x); 01021 return i - ( i > x ); 01022 } 01023 01024 //---------------------------------------------------------------------------- 01025 // Modify the trunc() operation provided by static_cast<int>() to get ceil(), 01026 // Note that in C++ conditions evaluate to values of 1 or 0 (true or false). 01027 inline int vtkMath::Ceil(double x) 01028 { 01029 int i = static_cast<int>(x); 01030 return i + ( i < x ); 01031 } 01032 01033 //---------------------------------------------------------------------------- 01034 inline float vtkMath::Normalize(float x[3]) 01035 { 01036 float den; 01037 if ( ( den = vtkMath::Norm( x ) ) != 0.0 ) 01038 { 01039 for (int i=0; i < 3; i++) 01040 { 01041 x[i] /= den; 01042 } 01043 } 01044 return den; 01045 } 01046 01047 //---------------------------------------------------------------------------- 01048 inline double vtkMath::Normalize(double x[3]) 01049 { 01050 double den; 01051 if ( ( den = vtkMath::Norm( x ) ) != 0.0 ) 01052 { 01053 for (int i=0; i < 3; i++) 01054 { 01055 x[i] /= den; 01056 } 01057 } 01058 return den; 01059 } 01060 01061 //---------------------------------------------------------------------------- 01062 inline float vtkMath::Normalize2D(float x[3]) 01063 { 01064 float den; 01065 if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 ) 01066 { 01067 for (int i=0; i < 2; i++) 01068 { 01069 x[i] /= den; 01070 } 01071 } 01072 return den; 01073 } 01074 01075 //---------------------------------------------------------------------------- 01076 inline double vtkMath::Normalize2D(double x[3]) 01077 { 01078 double den; 01079 if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 ) 01080 { 01081 for (int i=0; i < 2; i++) 01082 { 01083 x[i] /= den; 01084 } 01085 } 01086 return den; 01087 } 01088 01089 //---------------------------------------------------------------------------- 01090 inline float vtkMath::Determinant3x3(const float c1[3], 01091 const float c2[3], 01092 const float c3[3]) 01093 { 01094 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] - 01095 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2]; 01096 } 01097 01098 //---------------------------------------------------------------------------- 01099 inline double vtkMath::Determinant3x3(const double c1[3], 01100 const double c2[3], 01101 const double c3[3]) 01102 { 01103 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] - 01104 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2]; 01105 } 01106 01107 //---------------------------------------------------------------------------- 01108 inline double vtkMath::Determinant3x3(double a1, double a2, double a3, 01109 double b1, double b2, double b3, 01110 double c1, double c2, double c3) 01111 { 01112 return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 ) 01113 - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 ) 01114 + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) ); 01115 } 01116 01117 //---------------------------------------------------------------------------- 01118 inline float vtkMath::Distance2BetweenPoints(const float x[3], 01119 const float y[3]) 01120 { 01121 return ( ( x[0] - y[0] ) * ( x[0] - y[0] ) 01122 + ( x[1] - y[1] ) * ( x[1] - y[1] ) 01123 + ( x[2] - y[2] ) * ( x[2] - y[2] ) ); 01124 } 01125 01126 //---------------------------------------------------------------------------- 01127 inline double vtkMath::Distance2BetweenPoints(const double x[3], 01128 const double y[3]) 01129 { 01130 return ( ( x[0] - y[0] ) * ( x[0] - y[0] ) 01131 + ( x[1] - y[1] ) * ( x[1] - y[1] ) 01132 + ( x[2] - y[2] ) * ( x[2] - y[2] ) ); 01133 } 01134 01135 //---------------------------------------------------------------------------- 01136 // Cross product of two 3-vectors. Result (a x b) is stored in z[3]. 01137 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3]) 01138 { 01139 float Zx = x[1] * y[2] - x[2] * y[1]; 01140 float Zy = x[2] * y[0] - x[0] * y[2]; 01141 float Zz = x[0] * y[1] - x[1] * y[0]; 01142 z[0] = Zx; z[1] = Zy; z[2] = Zz; 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 double x[3], const double y[3], double z[3]) 01148 { 01149 double Zx = x[1] * y[2] - x[2] * y[1]; 01150 double Zy = x[2] * y[0] - x[0] * y[2]; 01151 double Zz = x[0] * y[1] - x[1] * y[0]; 01152 z[0] = Zx; z[1] = Zy; z[2] = Zz; 01153 } 01154 01155 //BTX 01156 //---------------------------------------------------------------------------- 01157 template<class T> 01158 inline double vtkDeterminant3x3(T A[3][3]) 01159 { 01160 return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] + 01161 A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] - 01162 A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2]; 01163 } 01164 //ETX 01165 01166 //---------------------------------------------------------------------------- 01167 inline double vtkMath::Determinant3x3(float A[3][3]) 01168 { 01169 return vtkDeterminant3x3( A ); 01170 } 01171 01172 //---------------------------------------------------------------------------- 01173 inline double vtkMath::Determinant3x3(double A[3][3]) 01174 { 01175 return vtkDeterminant3x3( A ); 01176 } 01177 01178 //---------------------------------------------------------------------------- 01179 inline void vtkMath::ClampValue(double *value, const double range[2]) 01180 { 01181 if (value && range) 01182 { 01183 if (*value < range[0]) 01184 { 01185 *value = range[0]; 01186 } 01187 else if (*value > range[1]) 01188 { 01189 *value = range[1]; 01190 } 01191 } 01192 } 01193 01194 //---------------------------------------------------------------------------- 01195 inline void vtkMath::ClampValue( 01196 double value, const double range[2], double *clamped_value) 01197 { 01198 if (range && clamped_value) 01199 { 01200 if (value < range[0]) 01201 { 01202 *clamped_value = range[0]; 01203 } 01204 else if (value > range[1]) 01205 { 01206 *clamped_value = range[1]; 01207 } 01208 else 01209 { 01210 *clamped_value = value; 01211 } 01212 } 01213 } 01214 01215 // --------------------------------------------------------------------------- 01216 inline double vtkMath::ClampAndNormalizeValue(double value, 01217 const double range[2]) 01218 { 01219 assert("pre: valid_range" && range[0]<=range[1]); 01220 01221 double result; 01222 if(range[0]==range[1]) 01223 { 01224 result=0.0; 01225 } 01226 else 01227 { 01228 // clamp 01229 if(value<range[0]) 01230 { 01231 result=range[0]; 01232 } 01233 else 01234 { 01235 if(value>range[1]) 01236 { 01237 result=range[1]; 01238 } 01239 else 01240 { 01241 result=value; 01242 } 01243 } 01244 01245 // normalize 01246 result=( result - range[0] ) / ( range[1] - range[0] ); 01247 } 01248 01249 assert("post: valid_result" && result>=0.0 && result<=1.0); 01250 01251 return result; 01252 } 01253 01254 //----------------------------------------------------------------------------- 01255 #if defined(VTK_HAS_ISINF) || defined(VTK_HAS_STD_ISINF) 01256 #define VTK_MATH_ISINF_IS_INLINE 01257 inline int vtkMath::IsInf(double x) 01258 { 01259 using namespace std; // Could be isinf() or std::isinf() 01260 return (isinf(x) != 0); // Force conversion to bool 01261 } 01262 #endif 01263 01264 //----------------------------------------------------------------------------- 01265 #if defined(VTK_HAS_ISNAN) || defined(VTK_HAS_STD_ISNAN) 01266 #define VTK_MATH_ISNAN_IS_INLINE 01267 inline int vtkMath::IsNan(double x) 01268 { 01269 using namespace std; // Could be isnan() or std::isnan() 01270 return (isnan(x) != 0); // Force conversion to bool 01271 } 01272 #endif 01273 01274 //----------------------------------------------------------------------------- 01275 #if defined(VTK_HAS_ISFINITE) || defined(VTK_HAS_STD_ISFINITE) || defined(VTK_HAS_FINITE) 01276 #define VTK_MATH_ISFINITE_IS_INLINE 01277 inline bool vtkMath::IsFinite(double x) 01278 { 01279 #if defined(VTK_HAS_ISFINITE) || defined(VTK_HAS_STD_ISFINITE) 01280 using namespace std; // Could be isfinite() or std::isfinite() 01281 return (isfinite(x) != 0); // Force conversion to bool 01282 #else 01283 return (finite(x) != 0); // Force conversion to bool 01284 #endif 01285 } 01286 #endif 01287 01288 #endif