VTK
|
00001 /*========================================================================= 00002 00003 Program: Visualization Toolkit 00004 Module: $RCSfile: vtkMath.h,v $ 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 2008 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 =========================================================================*/ 00038 #ifndef __vtkMath_h 00039 #define __vtkMath_h 00040 00041 #include "vtkObject.h" 00042 #include <assert.h> // assert() in inline implementations. 00043 00044 #ifndef DBL_EPSILON 00045 # define VTK_DBL_EPSILON 2.2204460492503131e-16 00046 #else // DBL_EPSILON 00047 # define VTK_DBL_EPSILON DBL_EPSILON 00048 #endif // DBL_EPSILON 00049 00050 class vtkDataArray; 00051 class vtkPoints; 00052 00053 class VTK_COMMON_EXPORT vtkMath : public vtkObject 00054 { 00055 public: 00056 static vtkMath *New(); 00057 vtkTypeRevisionMacro(vtkMath,vtkObject); 00058 void PrintSelf(ostream& os, vtkIndent indent); 00059 00061 static float Pi() { return 3.14159265358979f; }; 00062 00064 00065 static double DoubleTwoPi() { return 6.283185307179586; }; 00066 static double DoublePi() { return 3.1415926535897932384626; }; 00068 00070 00071 static float RadiansFromDegrees( float ); 00072 static double RadiansFromDegrees( double ); 00074 00076 00077 static float DegreesFromRadians( float ); 00078 static double DegreesFromRadians( double ); 00080 00082 00083 VTK_LEGACY(static float DegreesToRadians()); 00084 VTK_LEGACY(static double DoubleDegreesToRadians()); 00086 00088 00089 VTK_LEGACY(static float RadiansToDegrees()); 00090 VTK_LEGACY(static double DoubleRadiansToDegrees()); 00092 00094 00095 static int Round(float f) { 00096 return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); } 00097 static int Round(double f) { 00098 return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); } 00100 00101 static int Floor(double x); 00102 00105 static vtkTypeInt64 Factorial( int N ); 00106 00110 static vtkTypeInt64 Binomial( int m, int n ); 00111 00118 static int* BeginCombination( int m, int n ); 00119 00126 static int NextCombination( int m, int n, int* combination ); 00127 00129 static void FreeCombination( int* combination); 00130 00136 static void RandomSeed(long s); 00137 00139 static long GetSeed(); 00140 00144 static double Random(); 00145 00148 static double Random( double min, double max ); 00149 00152 static double Gaussian(); 00153 00156 static double Gaussian( double mean, double std ); 00157 00159 00160 static float Dot(const float x[3], const float y[3]) { 00161 return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );}; 00163 00165 00166 static double Dot(const double x[3], const double y[3]) { 00167 return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );}; 00169 00171 00172 static void Outer(const float x[3], const float y[3], float A[3][3]) { 00173 for (int i=0; i < 3; i++) 00174 for (int j=0; j < 3; j++) 00175 A[i][j] = x[i] * y[j]; 00176 } 00177 // Description: 00178 // Outer product of two 3-vectors (double-precision version). 00179 static void Outer(const double x[3], const double y[3], double A[3][3]) { 00180 for (int i=0; i < 3; i++) 00181 for (int j=0; j < 3; j++) 00182 A[i][j] = x[i] * y[j]; 00183 } 00185 00187 static void Cross(const float x[3], const float y[3], float z[3]); 00188 00191 static void Cross(const double x[3], const double y[3], double z[3]); 00192 00194 00195 static float Norm(const float* x, int n); 00196 static double Norm(const double* x, int n); 00198 00200 00201 static float Norm(const float x[3]) { 00202 return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ) );}; 00204 00206 00207 static double Norm(const double x[3]) { 00208 return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );}; 00210 00212 static float Normalize(float x[3]); 00213 00216 static double Normalize(double x[3]); 00217 00219 00224 static void Perpendiculars(const double x[3], double y[3], double z[3], 00225 double theta); 00226 static void Perpendiculars(const float x[3], float y[3], float z[3], 00227 double theta); 00229 00231 static float Distance2BetweenPoints(const float x[3], const float y[3]); 00232 00235 static double Distance2BetweenPoints(const double x[3], const double y[3]); 00236 00238 00239 static float Dot2D(const float x[3], const float y[3]) { 00240 return ( x[0] * y[0] + x[1] * y[1] );}; 00242 00244 00246 static double Dot2D(const double x[3], const double y[3]) { 00247 return ( x[0] * y[0] + x[1] * y[1] );}; 00249 00251 00252 static void Outer2D(const float x[3], const float y[3], float A[3][3]) 00253 { 00254 for (int i=0; i < 2; i++) 00255 { 00256 for (int j=0; j < 2; j++) 00257 { 00258 A[i][j] = x[i] * y[j]; 00259 } 00260 } 00261 } 00262 // Description: 00263 // Outer product of two 2-vectors (float version). z-comp is ignored 00264 static void Outer2D(const double x[3], const double y[3], double A[3][3]) 00265 { 00266 for (int i=0; i < 2; i++) 00267 { 00268 for (int j=0; j < 2; j++) 00269 { 00270 A[i][j] = x[i] * y[j]; 00271 } 00272 } 00273 } 00275 00277 00278 static float Norm2D(const float x[3]) { 00279 return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] ) );}; 00281 00283 00285 static double Norm2D(const double x[3]) { 00286 return sqrt( x[0] * x[0] + x[1] * x[1] );}; 00288 00291 static float Normalize2D(float x[3]); 00292 00295 static double Normalize2D(double x[3]); 00296 00298 00299 static float Determinant2x2(const float c1[2], const float c2[2]) { 00300 return (c1[0] * c2[1] - c2[0] * c1[1] );}; 00302 00304 00305 static double Determinant2x2(double a, double b, double c, double d) { 00306 return (a * d - b * c);}; 00307 static double Determinant2x2(const double c1[2], const double c2[2]) { 00308 return (c1[0] * c2[1] - c2[0] * c1[1] );}; 00310 00312 00314 static void LUFactor3x3(float A[3][3], int index[3]); 00315 static void LUFactor3x3(double A[3][3], int index[3]); 00317 00319 00321 static void LUSolve3x3(const float A[3][3], const int index[3], 00322 float x[3]); 00323 static void LUSolve3x3(const double A[3][3], const int index[3], 00324 double x[3]); 00326 00328 00330 static void LinearSolve3x3(const float A[3][3], const float x[3], 00331 float y[3]); 00332 static void LinearSolve3x3(const double A[3][3], const double x[3], 00333 double y[3]); 00335 00337 00338 static void Multiply3x3(const float A[3][3], const float in[3], 00339 float out[3]); 00340 static void Multiply3x3(const double A[3][3], const double in[3], 00341 double out[3]); 00343 00345 00346 static void Multiply3x3(const float A[3][3], const float B[3][3], 00347 float C[3][3]); 00348 static void Multiply3x3(const double A[3][3], const double B[3][3], 00349 double C[3][3]); 00351 00353 00355 static void MultiplyMatrix(const double **A, const double **B, 00356 unsigned int rowA, unsigned int colA, 00357 unsigned int rowB, unsigned int colB, 00358 double **C); 00360 00362 00363 static void Transpose3x3(const float A[3][3], float AT[3][3]); 00364 static void Transpose3x3(const double A[3][3], double AT[3][3]); 00366 00368 00369 static void Invert3x3(const float A[3][3], float AI[3][3]); 00370 static void Invert3x3(const double A[3][3], double AI[3][3]); 00372 00374 00375 static void Identity3x3(float A[3][3]); 00376 static void Identity3x3(double A[3][3]); 00378 00380 00381 static double Determinant3x3(float A[3][3]); 00382 static double Determinant3x3(double A[3][3]); 00384 00386 00387 static float Determinant3x3(const float c1[3], 00388 const float c2[3], 00389 const float c3[3]); 00391 00393 00394 static double Determinant3x3(const double c1[3], 00395 const double c2[3], 00396 const double c3[3]); 00398 00400 00402 static double Determinant3x3(double a1, double a2, double a3, 00403 double b1, double b2, double b3, 00404 double c1, double c2, double c3); 00406 00408 00410 static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]); 00411 static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]); 00413 00415 00418 static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]); 00419 static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]); 00421 00423 00426 static void Orthogonalize3x3(const float A[3][3], float B[3][3]); 00427 static void Orthogonalize3x3(const double A[3][3], double B[3][3]); 00429 00431 00435 static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]); 00436 static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]); 00438 00440 00447 static void SingularValueDecomposition3x3(const float A[3][3], 00448 float U[3][3], float w[3], 00449 float VT[3][3]); 00450 static void SingularValueDecomposition3x3(const double A[3][3], 00451 double U[3][3], double w[3], 00452 double VT[3][3]); 00454 00459 static int SolveLinearSystem(double **A, double *x, int size); 00460 00464 static int InvertMatrix(double **A, double **AI, int size); 00465 00467 00469 static int InvertMatrix(double **A, double **AI, int size, 00470 int *tmp1Size, double *tmp2Size); 00472 00478 static int LUFactorLinearSystem(double **A, int *index, int size); 00479 00481 00483 static int LUFactorLinearSystem(double **A, int *index, int size, 00484 double *tmpSize); 00486 00488 00494 static void LUSolveLinearSystem(double **A, int *index, 00495 double *x, int size); 00497 00505 static double EstimateMatrixCondition(double **A, int size); 00506 00508 00512 static int Jacobi(float **a, float *w, float **v); 00513 static int Jacobi(double **a, double *w, double **v); 00515 00517 00522 static int JacobiN(float **a, int n, float *w, float **v); 00523 static int JacobiN(double **a, int n, double *w, double **v); 00525 00532 static double* SolveCubic(double c0, double c1, double c2, double c3); 00533 00540 static double* SolveQuadratic(double c0, double c1, double c2); 00541 00545 static double* SolveLinear(double c0, double c1); 00546 00548 00559 static int SolveCubic(double c0, double c1, double c2, double c3, 00560 double *r1, double *r2, double *r3, int *num_roots); 00562 00564 00568 static int SolveQuadratic(double c0, double c1, double c2, 00569 double *r1, double *r2, int *num_roots); 00571 00577 static int SolveQuadratic( double* c, double* r, int* m ); 00578 00583 static int SolveLinear(double c0, double c1, double *r1, int *num_roots); 00584 00586 00596 static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder, 00597 double **mt); 00599 00600 00602 00613 static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder, 00614 double **yt, int yOrder, double **mt, int checkHomogeneous=1); 00616 00618 00620 static void RGBToHSV(const float rgb[3], float hsv[3]) 00621 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); } 00622 static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v); 00623 static double* RGBToHSV(const double rgb[3]); 00624 static double* RGBToHSV(double r, double g, double b); 00625 static void RGBToHSV(const double rgb[3], double hsv[3]) 00626 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); } 00627 static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v); 00629 00631 00633 static void HSVToRGB(const float hsv[3], float rgb[3]) 00634 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); } 00635 static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b); 00636 static double* HSVToRGB(const double hsv[3]); 00637 static double* HSVToRGB(double h, double s, double v); 00638 static void HSVToRGB(const double hsv[3], double rgb[3]) 00639 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); } 00640 static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b); 00642 00644 00645 static void LabToXYZ(const double lab[3], double xyz[3]) { 00646 LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2); 00647 } 00648 static void LabToXYZ(double L, double a, double b, 00649 double *x, double *y, double *z); 00650 static double *LabToXYZ(const double lab[3]); 00652 00654 00655 static void XYZToLab(const double xyz[3], double lab[3]) { 00656 XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2); 00657 } 00658 static void XYZToLab(double x, double y, double z, 00659 double *L, double *a, double *b); 00660 static double *XYZToLab(const double xyz[3]); 00662 00664 00665 static void XYZToRGB(const double xyz[3], double rgb[3]) { 00666 XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2); 00667 } 00668 static void XYZToRGB(double x, double y, double z, 00669 double *r, double *g, double *b); 00670 static double *XYZToRGB(const double xyz[3]); 00672 00674 00675 static void RGBToXYZ(const double rgb[3], double xyz[3]) { 00676 RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2); 00677 } 00678 static void RGBToXYZ(double r, double g, double b, 00679 double *x, double *y, double *z); 00680 static double *RGBToXYZ(const double rgb[3]); 00682 00684 00685 static void RGBToLab(const double rgb[3], double lab[3]) { 00686 RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2); 00687 } 00688 static void RGBToLab(double red, double green, double blue, 00689 double *L, double *a, double *b); 00690 static double *RGBToLab(const double rgb[3]); 00692 00694 00695 static void LabToRGB(const double lab[3], double rgb[3]) { 00696 LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2); 00697 } 00698 static void LabToRGB(double L, double a, double b, 00699 double *red, double *green, double *blue); 00700 static double *LabToRGB(const double lab[3]); 00702 00704 00705 static void UninitializeBounds(double bounds[6]){ 00706 bounds[0] = 1.0; 00707 bounds[1] = -1.0; 00708 bounds[2] = 1.0; 00709 bounds[3] = -1.0; 00710 bounds[4] = 1.0; 00711 bounds[5] = -1.0; 00712 } 00714 00716 00717 static int AreBoundsInitialized(double bounds[6]){ 00718 if ( bounds[1]-bounds[0]<0.0 ) 00719 { 00720 return 0; 00721 } 00722 return 1; 00723 } 00725 00727 00729 static void ClampValue(double *value, const double range[2]); 00730 static void ClampValue(double value, const double range[2], double *clamped_value); 00731 static void ClampValues( 00732 double *values, int nb_values, const double range[2]); 00733 static void ClampValues( 00734 const double *values, int nb_values, const double range[2], double *clamped_values); 00736 00738 00741 static double ClampAndNormalizeValue(double value, 00742 const double range[2]); 00744 00746 00752 static int GetScalarTypeFittingRange( 00753 double range_min, double range_max, 00754 double scale = 1.0, double shift = 0.0); 00756 00758 00764 static int GetAdjustedScalarRange( 00765 vtkDataArray *array, int comp, double range[2]); 00767 00770 static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]); 00771 00775 static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]); 00776 00780 static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]); 00781 00785 static void SpiralPoints(vtkIdType num, vtkPoints * offsets); 00786 00788 00790 static double Inf(); 00791 static double NegInf(); 00792 static double Nan(); 00794 00795 protected: 00796 vtkMath() {}; 00797 ~vtkMath() {}; 00798 00799 static long Seed; 00800 private: 00801 vtkMath(const vtkMath&); // Not implemented. 00802 void operator=(const vtkMath&); // Not implemented. 00803 }; 00804 00805 //---------------------------------------------------------------------------- 00806 inline float vtkMath::RadiansFromDegrees( float x ) 00807 { 00808 return x * 0.017453292f; 00809 } 00810 00811 //---------------------------------------------------------------------------- 00812 inline double vtkMath::RadiansFromDegrees( double x ) 00813 { 00814 return x * 0.017453292519943295; 00815 } 00816 00817 //---------------------------------------------------------------------------- 00818 inline float vtkMath::DegreesFromRadians( float x ) 00819 { 00820 return x * 57.2957795131f; 00821 } 00822 00823 //---------------------------------------------------------------------------- 00824 inline double vtkMath::DegreesFromRadians( double x ) 00825 { 00826 return x * 57.29577951308232; 00827 } 00828 00829 #ifndef VTK_LEGACY_REMOVE 00830 //---------------------------------------------------------------------------- 00831 inline float vtkMath::DegreesToRadians() 00832 { 00833 VTK_LEGACY_REPLACED_BODY(vtkMath::DegreesToRadians, "VTK 5.4", 00834 vtkMath::RadiansFromDegrees); 00835 00836 return vtkMath::RadiansFromDegrees( 1.f ); 00837 } 00838 00839 //---------------------------------------------------------------------------- 00840 inline double vtkMath::DoubleDegreesToRadians() 00841 { 00842 VTK_LEGACY_REPLACED_BODY(vtkMath::DoubleDegreesToRadians, "VTK 5.4", 00843 vtkMath::RadiansFromDegrees); 00844 00845 00846 return vtkMath::RadiansFromDegrees( 1. ); 00847 } 00848 00849 //---------------------------------------------------------------------------- 00850 inline float vtkMath::RadiansToDegrees() 00851 { 00852 VTK_LEGACY_REPLACED_BODY(vtkMath::RadiansToDegrees, "VTK 5.4", 00853 vtkMath::DegreesFromRadians); 00854 00855 return vtkMath::DegreesFromRadians( 1.f ); 00856 } 00857 00858 //---------------------------------------------------------------------------- 00859 inline double vtkMath::DoubleRadiansToDegrees() 00860 { 00861 VTK_LEGACY_REPLACED_BODY(vtkMath::DoubleRadiansToDegrees, "VTK 5.4", 00862 vtkMath::DegreesFromRadians); 00863 00864 return vtkMath::DegreesFromRadians( 1. ); 00865 } 00866 #endif // #ifndef VTK_LEGACY_REMOVE 00867 00868 //---------------------------------------------------------------------------- 00869 inline vtkTypeInt64 vtkMath::Factorial( int N ) 00870 { 00871 vtkTypeInt64 r = 1; 00872 while ( N > 1 ) 00873 { 00874 r *= N--; 00875 } 00876 return r; 00877 } 00878 00879 //---------------------------------------------------------------------------- 00880 inline double vtkMath::Random( double min, double max ) 00881 { 00882 return ( min + vtkMath::Random() * ( max - min ) ); 00883 } 00884 00885 //---------------------------------------------------------------------------- 00886 inline double vtkMath::Gaussian() 00887 { 00888 // Use the Box-Mueller transform 00889 double x = vtkMath::Random(); 00890 double y = vtkMath::Random(); 00891 return sqrt( -2. * log( x ) ) * cos( vtkMath::DoubleTwoPi() * y ); 00892 } 00893 00894 //---------------------------------------------------------------------------- 00895 inline double vtkMath::Gaussian( double mean, double std ) 00896 { 00897 return mean + std * vtkMath::Gaussian(); 00898 } 00899 00900 //---------------------------------------------------------------------------- 00901 inline int vtkMath::Floor(double x) 00902 { 00903 #if defined i386 || defined _M_IX86 00904 union { int i[2]; double d; } u; 00905 // use 52-bit precision of IEEE double to round (x - 0.25) to 00906 // the nearest multiple of 0.5, according to prevailing rounding 00907 // mode which is IEEE round-to-nearest,even 00908 u.d = (x - 0.25) + 3377699720527872.0; // (2**51)*1.5 00909 // extract mantissa, use shift to divide by 2 and hence get rid 00910 // of the bit that gets messed up because the FPU uses 00911 // round-to-nearest,even mode instead of round-to-nearest,+infinity 00912 return u.i[0] >> 1; 00913 #else 00914 return static_cast<int>(floor( x ) ); 00915 #endif 00916 } 00917 00918 //---------------------------------------------------------------------------- 00919 inline float vtkMath::Normalize(float x[3]) 00920 { 00921 float den; 00922 if ( ( den = vtkMath::Norm( x ) ) != 0.0 ) 00923 { 00924 for (int i=0; i < 3; i++) 00925 { 00926 x[i] /= den; 00927 } 00928 } 00929 return den; 00930 } 00931 00932 //---------------------------------------------------------------------------- 00933 inline double vtkMath::Normalize(double x[3]) 00934 { 00935 double den; 00936 if ( ( den = vtkMath::Norm( x ) ) != 0.0 ) 00937 { 00938 for (int i=0; i < 3; i++) 00939 { 00940 x[i] /= den; 00941 } 00942 } 00943 return den; 00944 } 00945 00946 //---------------------------------------------------------------------------- 00947 inline float vtkMath::Normalize2D(float x[3]) 00948 { 00949 float den; 00950 if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 ) 00951 { 00952 for (int i=0; i < 2; i++) 00953 { 00954 x[i] /= den; 00955 } 00956 } 00957 return den; 00958 } 00959 00960 //---------------------------------------------------------------------------- 00961 inline double vtkMath::Normalize2D(double x[3]) 00962 { 00963 double den; 00964 if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 ) 00965 { 00966 for (int i=0; i < 2; i++) 00967 { 00968 x[i] /= den; 00969 } 00970 } 00971 return den; 00972 } 00973 00974 //---------------------------------------------------------------------------- 00975 inline float vtkMath::Determinant3x3(const float c1[3], 00976 const float c2[3], 00977 const float c3[3]) 00978 { 00979 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] - 00980 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2]; 00981 } 00982 00983 //---------------------------------------------------------------------------- 00984 inline double vtkMath::Determinant3x3(const double c1[3], 00985 const double c2[3], 00986 const double c3[3]) 00987 { 00988 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] - 00989 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2]; 00990 } 00991 00992 //---------------------------------------------------------------------------- 00993 inline double vtkMath::Determinant3x3(double a1, double a2, double a3, 00994 double b1, double b2, double b3, 00995 double c1, double c2, double c3) 00996 { 00997 return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 ) 00998 - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 ) 00999 + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) ); 01000 } 01001 01002 //---------------------------------------------------------------------------- 01003 inline float vtkMath::Distance2BetweenPoints(const float x[3], 01004 const float y[3]) 01005 { 01006 return ( ( x[0] - y[0] ) * ( x[0] - y[0] ) 01007 + ( x[1] - y[1] ) * ( x[1] - y[1] ) 01008 + ( x[2] - y[2] ) * ( x[2] - y[2] ) ); 01009 } 01010 01011 //---------------------------------------------------------------------------- 01012 inline double vtkMath::Distance2BetweenPoints(const double x[3], 01013 const double y[3]) 01014 { 01015 return ( ( x[0] - y[0] ) * ( x[0] - y[0] ) 01016 + ( x[1] - y[1] ) * ( x[1] - y[1] ) 01017 + ( x[2] - y[2] ) * ( x[2] - y[2] ) ); 01018 } 01019 01020 //---------------------------------------------------------------------------- 01021 // Cross product of two 3-vectors. Result vector in z[3]. 01022 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3]) 01023 { 01024 float Zx = x[1] * y[2] - x[2] * y[1]; 01025 float Zy = x[2] * y[0] - x[0] * y[2]; 01026 float Zz = x[0] * y[1] - x[1] * y[0]; 01027 z[0] = Zx; z[1] = Zy; z[2] = Zz; 01028 } 01029 01030 //---------------------------------------------------------------------------- 01031 // Cross product of two 3-vectors. Result vector in z[3]. 01032 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3]) 01033 { 01034 double Zx = x[1] * y[2] - x[2] * y[1]; 01035 double Zy = x[2] * y[0] - x[0] * y[2]; 01036 double Zz = x[0] * y[1] - x[1] * y[0]; 01037 z[0] = Zx; z[1] = Zy; z[2] = Zz; 01038 } 01039 01040 //BTX 01041 //---------------------------------------------------------------------------- 01042 template<class T> 01043 inline double vtkDeterminant3x3(T A[3][3]) 01044 { 01045 return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] + 01046 A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] - 01047 A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2]; 01048 } 01049 //ETX 01050 01051 //---------------------------------------------------------------------------- 01052 inline double vtkMath::Determinant3x3(float A[3][3]) 01053 { 01054 return vtkDeterminant3x3( A ); 01055 } 01056 01057 //---------------------------------------------------------------------------- 01058 inline double vtkMath::Determinant3x3(double A[3][3]) 01059 { 01060 return vtkDeterminant3x3( A ); 01061 } 01062 01063 //---------------------------------------------------------------------------- 01064 inline void vtkMath::ClampValue(double *value, const double range[2]) 01065 { 01066 if (value && range) 01067 { 01068 if (*value < range[0]) 01069 { 01070 *value = range[0]; 01071 } 01072 else if (*value > range[1]) 01073 { 01074 *value = range[1]; 01075 } 01076 } 01077 } 01078 01079 //---------------------------------------------------------------------------- 01080 inline void vtkMath::ClampValue( 01081 double value, const double range[2], double *clamped_value) 01082 { 01083 if (range && clamped_value) 01084 { 01085 if (value < range[0]) 01086 { 01087 *clamped_value = range[0]; 01088 } 01089 else if (value > range[1]) 01090 { 01091 *clamped_value = range[1]; 01092 } 01093 else 01094 { 01095 *clamped_value = value; 01096 } 01097 } 01098 } 01099 01100 // --------------------------------------------------------------------------- 01101 inline double vtkMath::ClampAndNormalizeValue(double value, 01102 const double range[2]) 01103 { 01104 assert("pre: valid_range" && range[0]<=range[1]); 01105 01106 double result; 01107 if(range[0]==range[1]) 01108 { 01109 result=0.0; 01110 } 01111 else 01112 { 01113 // clamp 01114 if(value<range[0]) 01115 { 01116 result=range[0]; 01117 } 01118 else 01119 { 01120 if(value>range[1]) 01121 { 01122 result=range[1]; 01123 } 01124 else 01125 { 01126 result=value; 01127 } 01128 } 01129 01130 // normalize 01131 result=( result - range[0] ) / ( range[1] - range[0] ); 01132 } 01133 01134 assert("post: valid_result" && result>=0.0 && result<=1.0); 01135 01136 return result; 01137 } 01138 01139 #endif