00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00040 #ifndef __vtkMath_h
00041 #define __vtkMath_h
00042
00043 #include "vtkObject.h"
00044 #include "vtkPolynomialSolversUnivariate.h"
00045
00046 #include <assert.h>
00047
00048 #ifndef DBL_EPSILON
00049 # define VTK_DBL_EPSILON 2.2204460492503131e-16
00050 #else // DBL_EPSILON
00051 # define VTK_DBL_EPSILON DBL_EPSILON
00052 #endif // DBL_EPSILON
00053
00054 class vtkDataArray;
00055 class vtkPoints;
00056 class vtkMathInternal;
00057 class vtkMinimalStandardRandomSequence;
00058 class vtkBoxMuellerRandomSequence;
00059
00060 class VTK_COMMON_EXPORT vtkMath : public vtkObject
00061 {
00062 public:
00063 static vtkMath *New();
00064 vtkTypeRevisionMacro(vtkMath,vtkObject);
00065 void PrintSelf(ostream& os, vtkIndent indent);
00066
00068 static float Pi() { return 3.14159265358979f; };
00069
00072 static double DoubleTwoPi() { return 6.283185307179586; };
00073
00076 static double DoublePi() { return 3.1415926535897932384626; };
00077
00079
00080 static float RadiansFromDegrees( float degrees);
00081 static double RadiansFromDegrees( double degrees);
00083
00085
00086 static float DegreesFromRadians( float radians);
00087 static double DegreesFromRadians( double radians);
00089
00091
00092 VTK_LEGACY(static float DegreesToRadians());
00093 VTK_LEGACY(static double DoubleDegreesToRadians());
00095
00097
00098 VTK_LEGACY(static float RadiansToDegrees());
00099 VTK_LEGACY(static double DoubleRadiansToDegrees());
00101
00103
00104 static int Round(float f) {
00105 return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
00106 static int Round(double f) {
00107 return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
00109
00111 static int Floor(double x);
00112
00115 static vtkTypeInt64 Factorial( int N );
00116
00120 static vtkTypeInt64 Binomial( int m, int n );
00121
00128 static int* BeginCombination( int m, int n );
00129
00136 static int NextCombination( int m, int n, int* combination );
00137
00139 static void FreeCombination( int* combination);
00140
00152 static void RandomSeed(int s);
00153
00162 static int GetSeed();
00163
00173 static double Random();
00174
00183 static double Random( double min, double max );
00184
00193 static double Gaussian();
00194
00204 static double Gaussian( double mean, double std );
00205
00207
00208 static void Add(const float a[3], const float b[3], float c[3]) {
00209 for (int i = 0; i < 3; ++i)
00210 c[i] = a[i] + b[i];
00211 }
00213
00215
00216 static void Add(const double a[3], const double b[3], double c[3]) {
00217 for (int i = 0; i < 3; ++i)
00218 c[i] = a[i] + b[i];
00219 }
00221
00223
00225 static void Subtract(const float a[3], const float b[3], float c[3]) {
00226 for (int i = 0; i < 3; ++i)
00227 c[i] = a[i] - b[i];
00228 }
00230
00232
00234 static void Subtract(const double a[3], const double b[3], double c[3]) {
00235 for (int i = 0; i < 3; ++i)
00236 c[i] = a[i] - b[i];
00237 }
00239
00241
00243 static void MultiplyScalar(float a[3], float s) {
00244 for (int i = 0; i < 3; ++i)
00245 a[i] *= s;
00246 }
00248
00250
00252 static void MultiplyScalar(double a[3], double s) {
00253 for (int i = 0; i < 3; ++i)
00254 a[i] *= s;
00255 }
00257
00259
00260 static float Dot(const float x[3], const float y[3]) {
00261 return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
00263
00265
00266 static double Dot(const double x[3], const double y[3]) {
00267 return ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] );};
00269
00271
00272 static void Outer(const float x[3], const float y[3], float A[3][3]) {
00273 for (int i=0; i < 3; i++)
00274 for (int j=0; j < 3; j++)
00275 A[i][j] = x[i] * y[j];
00276 }
00277
00278
00279 static void Outer(const double x[3], const double y[3], double A[3][3]) {
00280 for (int i=0; i < 3; i++)
00281 for (int j=0; j < 3; j++)
00282 A[i][j] = x[i] * y[j];
00283 }
00285
00287 static void Cross(const float x[3], const float y[3], float z[3]);
00288
00291 static void Cross(const double x[3], const double y[3], double z[3]);
00292
00294
00295 static float Norm(const float* x, int n);
00296 static double Norm(const double* x, int n);
00298
00300
00301 static float Norm(const float x[3]) {
00302 return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ) );};
00304
00306
00307 static double Norm(const double x[3]) {
00308 return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );};
00310
00312 static float Normalize(float x[3]);
00313
00316 static double Normalize(double x[3]);
00317
00319
00324 static void Perpendiculars(const double x[3], double y[3], double z[3],
00325 double theta);
00326 static void Perpendiculars(const float x[3], float y[3], float z[3],
00327 double theta);
00329
00331 static float Distance2BetweenPoints(const float x[3], const float y[3]);
00332
00335 static double Distance2BetweenPoints(const double x[3], const double y[3]);
00336
00338
00339 static float Dot2D(const float x[2], const float y[2]) {
00340 return ( x[0] * y[0] + x[1] * y[1] );};
00342
00344
00345 static double Dot2D(const double x[2], const double y[2]) {
00346 return ( x[0] * y[0] + x[1] * y[1] );};
00348
00350
00351 static void Outer2D(const float x[2], const float y[2], float A[2][2])
00352 {
00353 for (int i=0; i < 2; i++)
00354 {
00355 for (int j=0; j < 2; j++)
00356 {
00357 A[i][j] = x[i] * y[j];
00358 }
00359 }
00360 }
00361
00362
00363 static void Outer2D(const double x[2], const double y[2], double A[2][2])
00364 {
00365 for (int i=0; i < 2; i++)
00366 {
00367 for (int j=0; j < 2; j++)
00368 {
00369 A[i][j] = x[i] * y[j];
00370 }
00371 }
00372 }
00374
00376
00377 static float Norm2D(const float x[2]) {
00378 return static_cast<float> (sqrt( x[0] * x[0] + x[1] * x[1] ) );};
00380
00382
00383 static double Norm2D(const double x[2]) {
00384 return sqrt( x[0] * x[0] + x[1] * x[1] );};
00386
00388 static float Normalize2D(float x[2]);
00389
00392 static double Normalize2D(double x[2]);
00393
00395
00396 static float Determinant2x2(const float c1[2], const float c2[2]) {
00397 return (c1[0] * c2[1] - c2[0] * c1[1] );};
00399
00401
00402 static double Determinant2x2(double a, double b, double c, double d) {
00403 return (a * d - b * c);};
00404 static double Determinant2x2(const double c1[2], const double c2[2]) {
00405 return (c1[0] * c2[1] - c2[0] * c1[1] );};
00407
00409
00410 static void LUFactor3x3(float A[3][3], int index[3]);
00411 static void LUFactor3x3(double A[3][3], int index[3]);
00413
00415
00416 static void LUSolve3x3(const float A[3][3], const int index[3],
00417 float x[3]);
00418 static void LUSolve3x3(const double A[3][3], const int index[3],
00419 double x[3]);
00421
00423
00425 static void LinearSolve3x3(const float A[3][3], const float x[3],
00426 float y[3]);
00427 static void LinearSolve3x3(const double A[3][3], const double x[3],
00428 double y[3]);
00430
00432
00433 static void Multiply3x3(const float A[3][3], const float in[3],
00434 float out[3]);
00435 static void Multiply3x3(const double A[3][3], const double in[3],
00436 double out[3]);
00438
00440
00441 static void Multiply3x3(const float A[3][3], const float B[3][3],
00442 float C[3][3]);
00443 static void Multiply3x3(const double A[3][3], const double B[3][3],
00444 double C[3][3]);
00446
00448
00450 static void MultiplyMatrix(const double **A, const double **B,
00451 unsigned int rowA, unsigned int colA,
00452 unsigned int rowB, unsigned int colB,
00453 double **C);
00455
00457
00459 static void Transpose3x3(const float A[3][3], float AT[3][3]);
00460 static void Transpose3x3(const double A[3][3], double AT[3][3]);
00462
00464
00466 static void Invert3x3(const float A[3][3], float AI[3][3]);
00467 static void Invert3x3(const double A[3][3], double AI[3][3]);
00469
00471
00472 static void Identity3x3(float A[3][3]);
00473 static void Identity3x3(double A[3][3]);
00475
00477
00478 static double Determinant3x3(float A[3][3]);
00479 static double Determinant3x3(double A[3][3]);
00481
00483
00484 static float Determinant3x3(const float c1[3],
00485 const float c2[3],
00486 const float c3[3]);
00488
00490
00491 static double Determinant3x3(const double c1[3],
00492 const double c2[3],
00493 const double c3[3]);
00495
00497
00499 static double Determinant3x3(double a1, double a2, double a3,
00500 double b1, double b2, double b3,
00501 double c1, double c2, double c3);
00503
00505
00507 static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]);
00508 static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]);
00510
00512
00515 static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
00516 static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
00518
00520
00523 static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
00524 static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
00526
00528
00532 static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
00533 static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]);
00535
00537
00544 static void SingularValueDecomposition3x3(const float A[3][3],
00545 float U[3][3], float w[3],
00546 float VT[3][3]);
00547 static void SingularValueDecomposition3x3(const double A[3][3],
00548 double U[3][3], double w[3],
00549 double VT[3][3]);
00551
00556 static int SolveLinearSystem(double **A, double *x, int size);
00557
00561 static int InvertMatrix(double **A, double **AI, int size);
00562
00564
00566 static int InvertMatrix(double **A, double **AI, int size,
00567 int *tmp1Size, double *tmp2Size);
00569
00575 static int LUFactorLinearSystem(double **A, int *index, int size);
00576
00578
00580 static int LUFactorLinearSystem(double **A, int *index, int size,
00581 double *tmpSize);
00583
00585
00591 static void LUSolveLinearSystem(double **A, int *index,
00592 double *x, int size);
00594
00602 static double EstimateMatrixCondition(double **A, int size);
00603
00605
00609 static int Jacobi(float **a, float *w, float **v);
00610 static int Jacobi(double **a, double *w, double **v);
00612
00614
00619 static int JacobiN(float **a, int n, float *w, float **v);
00620 static int JacobiN(double **a, int n, double *w, double **v);
00622
00629 static double* SolveCubic(double c0, double c1, double c2, double c3);
00630
00637 static double* SolveQuadratic(double c0, double c1, double c2);
00638
00642 static double* SolveLinear(double c0, double c1);
00643
00645
00656 static int SolveCubic(double c0, double c1, double c2, double c3,
00657 double *r1, double *r2, double *r3, int *num_roots);
00659
00661
00665 static int SolveQuadratic(double c0, double c1, double c2,
00666 double *r1, double *r2, int *num_roots);
00668
00674 static int SolveQuadratic( double* c, double* r, int* m );
00675
00680 static int SolveLinear(double c0, double c1, double *r1, int *num_roots);
00681
00683
00693 static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder,
00694 double **mt);
00696
00697
00699
00710 static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
00711 double **yt, int yOrder, double **mt, int checkHomogeneous=1);
00713
00715
00717 static void RGBToHSV(const float rgb[3], float hsv[3])
00718 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00719 static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v);
00720 static double* RGBToHSV(const double rgb[3]);
00721 static double* RGBToHSV(double r, double g, double b);
00722 static void RGBToHSV(const double rgb[3], double hsv[3])
00723 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00724 static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v);
00726
00728
00730 static void HSVToRGB(const float hsv[3], float rgb[3])
00731 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00732 static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b);
00733 static double* HSVToRGB(const double hsv[3]);
00734 static double* HSVToRGB(double h, double s, double v);
00735 static void HSVToRGB(const double hsv[3], double rgb[3])
00736 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00737 static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b);
00739
00741
00742 static void LabToXYZ(const double lab[3], double xyz[3]) {
00743 LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2);
00744 }
00745 static void LabToXYZ(double L, double a, double b,
00746 double *x, double *y, double *z);
00747 static double *LabToXYZ(const double lab[3]);
00749
00751
00752 static void XYZToLab(const double xyz[3], double lab[3]) {
00753 XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2);
00754 }
00755 static void XYZToLab(double x, double y, double z,
00756 double *L, double *a, double *b);
00757 static double *XYZToLab(const double xyz[3]);
00759
00761
00762 static void XYZToRGB(const double xyz[3], double rgb[3]) {
00763 XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2);
00764 }
00765 static void XYZToRGB(double x, double y, double z,
00766 double *r, double *g, double *b);
00767 static double *XYZToRGB(const double xyz[3]);
00769
00771
00772 static void RGBToXYZ(const double rgb[3], double xyz[3]) {
00773 RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2);
00774 }
00775 static void RGBToXYZ(double r, double g, double b,
00776 double *x, double *y, double *z);
00777 static double *RGBToXYZ(const double rgb[3]);
00779
00781
00782 static void RGBToLab(const double rgb[3], double lab[3]) {
00783 RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2);
00784 }
00785 static void RGBToLab(double red, double green, double blue,
00786 double *L, double *a, double *b);
00787 static double *RGBToLab(const double rgb[3]);
00789
00791
00792 static void LabToRGB(const double lab[3], double rgb[3]) {
00793 LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2);
00794 }
00795 static void LabToRGB(double L, double a, double b,
00796 double *red, double *green, double *blue);
00797 static double *LabToRGB(const double lab[3]);
00799
00801
00802 static void UninitializeBounds(double bounds[6]){
00803 bounds[0] = 1.0;
00804 bounds[1] = -1.0;
00805 bounds[2] = 1.0;
00806 bounds[3] = -1.0;
00807 bounds[4] = 1.0;
00808 bounds[5] = -1.0;
00809 }
00811
00813
00814 static int AreBoundsInitialized(double bounds[6]){
00815 if ( bounds[1]-bounds[0]<0.0 )
00816 {
00817 return 0;
00818 }
00819 return 1;
00820 }
00822
00824
00826 static void ClampValue(double *value, const double range[2]);
00827 static void ClampValue(double value, const double range[2], double *clamped_value);
00828 static void ClampValues(
00829 double *values, int nb_values, const double range[2]);
00830 static void ClampValues(
00831 const double *values, int nb_values, const double range[2], double *clamped_values);
00833
00835
00838 static double ClampAndNormalizeValue(double value,
00839 const double range[2]);
00841
00843
00849 static int GetScalarTypeFittingRange(
00850 double range_min, double range_max,
00851 double scale = 1.0, double shift = 0.0);
00853
00855
00861 static int GetAdjustedScalarRange(
00862 vtkDataArray *array, int comp, double range[2]);
00864
00867 static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]);
00868
00872 static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]);
00873
00877 static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]);
00878
00882 static void SpiralPoints(vtkIdType num, vtkPoints * offsets);
00883
00891 static double Solve3PointCircle(const double p1[3], const double p2[3], const double p3[3], double center[3]);
00892
00894 static double Inf();
00895
00897 static double NegInf();
00898
00900 static double Nan();
00901
00904 static int IsInf(double x);
00905
00906
00907 static int IsNan(double x);
00908
00909 protected:
00910 vtkMath() {};
00911 ~vtkMath() {};
00912
00913 static vtkMathInternal Internal;
00914 private:
00915 vtkMath(const vtkMath&);
00916 void operator=(const vtkMath&);
00917 };
00918
00919
00920 class vtkMathInternal
00921 {
00922 public:
00923 vtkMathInternal();
00924 ~vtkMathInternal();
00925 vtkMinimalStandardRandomSequence *Uniform;
00926 vtkBoxMuellerRandomSequence *Gaussian;
00927 };
00928
00929
00930
00931 inline float vtkMath::RadiansFromDegrees( float x )
00932 {
00933 return x * 0.017453292f;
00934 }
00935
00936
00937 inline double vtkMath::RadiansFromDegrees( double x )
00938 {
00939 return x * 0.017453292519943295;
00940 }
00941
00942
00943 inline float vtkMath::DegreesFromRadians( float x )
00944 {
00945 return x * 57.2957795131f;
00946 }
00947
00948
00949 inline double vtkMath::DegreesFromRadians( double x )
00950 {
00951 return x * 57.29577951308232;
00952 }
00953
00954 #ifndef VTK_LEGACY_REMOVE
00955
00956 inline float vtkMath::DegreesToRadians()
00957 {
00958 VTK_LEGACY_REPLACED_BODY(vtkMath::DegreesToRadians, "VTK 5.4",
00959 vtkMath::RadiansFromDegrees);
00960
00961 return vtkMath::RadiansFromDegrees( 1.f );
00962 }
00963
00964
00965 inline double vtkMath::DoubleDegreesToRadians()
00966 {
00967 VTK_LEGACY_REPLACED_BODY(vtkMath::DoubleDegreesToRadians, "VTK 5.4",
00968 vtkMath::RadiansFromDegrees);
00969
00970
00971 return vtkMath::RadiansFromDegrees( 1. );
00972 }
00973
00974
00975 inline float vtkMath::RadiansToDegrees()
00976 {
00977 VTK_LEGACY_REPLACED_BODY(vtkMath::RadiansToDegrees, "VTK 5.4",
00978 vtkMath::DegreesFromRadians);
00979
00980 return vtkMath::DegreesFromRadians( 1.f );
00981 }
00982
00983
00984 inline double vtkMath::DoubleRadiansToDegrees()
00985 {
00986 VTK_LEGACY_REPLACED_BODY(vtkMath::DoubleRadiansToDegrees, "VTK 5.4",
00987 vtkMath::DegreesFromRadians);
00988
00989 return vtkMath::DegreesFromRadians( 1. );
00990 }
00991 #endif // #ifndef VTK_LEGACY_REMOVE
00992
00993
00994 inline vtkTypeInt64 vtkMath::Factorial( int N )
00995 {
00996 vtkTypeInt64 r = 1;
00997 while ( N > 1 )
00998 {
00999 r *= N--;
01000 }
01001 return r;
01002 }
01003
01004
01005 inline int vtkMath::Floor(double x)
01006 {
01007 #if defined i386 || defined _M_IX86
01008 union { int i[2]; double d; } u;
01009
01010
01011
01012 u.d = (x - 0.25) + 3377699720527872.0;
01013
01014
01015
01016 return u.i[0] >> 1;
01017 #else
01018 return static_cast<int>(floor( x ) );
01019 #endif
01020 }
01021
01022
01023 inline float vtkMath::Normalize(float x[3])
01024 {
01025 float den;
01026 if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01027 {
01028 for (int i=0; i < 3; i++)
01029 {
01030 x[i] /= den;
01031 }
01032 }
01033 return den;
01034 }
01035
01036
01037 inline double vtkMath::Normalize(double x[3])
01038 {
01039 double den;
01040 if ( ( den = vtkMath::Norm( x ) ) != 0.0 )
01041 {
01042 for (int i=0; i < 3; i++)
01043 {
01044 x[i] /= den;
01045 }
01046 }
01047 return den;
01048 }
01049
01050
01051 inline float vtkMath::Normalize2D(float x[3])
01052 {
01053 float den;
01054 if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01055 {
01056 for (int i=0; i < 2; i++)
01057 {
01058 x[i] /= den;
01059 }
01060 }
01061 return den;
01062 }
01063
01064
01065 inline double vtkMath::Normalize2D(double x[3])
01066 {
01067 double den;
01068 if ( ( den = vtkMath::Norm2D( x ) ) != 0.0 )
01069 {
01070 for (int i=0; i < 2; i++)
01071 {
01072 x[i] /= den;
01073 }
01074 }
01075 return den;
01076 }
01077
01078
01079 inline float vtkMath::Determinant3x3(const float c1[3],
01080 const float c2[3],
01081 const float c3[3])
01082 {
01083 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01084 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01085 }
01086
01087
01088 inline double vtkMath::Determinant3x3(const double c1[3],
01089 const double c2[3],
01090 const double c3[3])
01091 {
01092 return c1[0] * c2[1] * c3[2] + c2[0] * c3[1] * c1[2] + c3[0] * c1[1] * c2[2] -
01093 c1[0] * c3[1] * c2[2] - c2[0] * c1[1] * c3[2] - c3[0] * c2[1] * c1[2];
01094 }
01095
01096
01097 inline double vtkMath::Determinant3x3(double a1, double a2, double a3,
01098 double b1, double b2, double b3,
01099 double c1, double c2, double c3)
01100 {
01101 return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
01102 - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
01103 + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
01104 }
01105
01106
01107 inline float vtkMath::Distance2BetweenPoints(const float x[3],
01108 const float y[3])
01109 {
01110 return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01111 + ( x[1] - y[1] ) * ( x[1] - y[1] )
01112 + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01113 }
01114
01115
01116 inline double vtkMath::Distance2BetweenPoints(const double x[3],
01117 const double y[3])
01118 {
01119 return ( ( x[0] - y[0] ) * ( x[0] - y[0] )
01120 + ( x[1] - y[1] ) * ( x[1] - y[1] )
01121 + ( x[2] - y[2] ) * ( x[2] - y[2] ) );
01122 }
01123
01124
01125
01126 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
01127 {
01128 float Zx = x[1] * y[2] - x[2] * y[1];
01129 float Zy = x[2] * y[0] - x[0] * y[2];
01130 float Zz = x[0] * y[1] - x[1] * y[0];
01131 z[0] = Zx; z[1] = Zy; z[2] = Zz;
01132 }
01133
01134
01135
01136 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3])
01137 {
01138 double Zx = x[1] * y[2] - x[2] * y[1];
01139 double Zy = x[2] * y[0] - x[0] * y[2];
01140 double Zz = x[0] * y[1] - x[1] * y[0];
01141 z[0] = Zx; z[1] = Zy; z[2] = Zz;
01142 }
01143
01144
01145
01146 template<class T>
01147 inline double vtkDeterminant3x3(T A[3][3])
01148 {
01149 return A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] +
01150 A[2][0] * A[0][1] * A[1][2] - A[0][0] * A[2][1] * A[1][2] -
01151 A[1][0] * A[0][1] * A[2][2] - A[2][0] * A[1][1] * A[0][2];
01152 }
01153
01154
01155
01156 inline double vtkMath::Determinant3x3(float A[3][3])
01157 {
01158 return vtkDeterminant3x3( A );
01159 }
01160
01161
01162 inline double vtkMath::Determinant3x3(double A[3][3])
01163 {
01164 return vtkDeterminant3x3( A );
01165 }
01166
01167
01168 inline double* vtkMath::SolveCubic(double c0, double c1, double c2, double c3)
01169 {
01170 return vtkPolynomialSolversUnivariate::SolveCubic( c0, c1, c2, c3 );
01171 }
01172
01173
01174 inline double* vtkMath::SolveQuadratic(double c0, double c1, double c2)
01175 {
01176 return vtkPolynomialSolversUnivariate::SolveQuadratic( c0, c1, c2 );
01177 }
01178
01179
01180 inline double* vtkMath::SolveLinear(double c0, double c1)
01181 {
01182 return vtkPolynomialSolversUnivariate::SolveLinear( c0, c1 );
01183 }
01184
01185
01186 inline int vtkMath::SolveCubic(double c0, double c1, double c2, double c3,
01187 double *r1, double *r2, double *r3, int *num_roots)
01188 {
01189 return vtkPolynomialSolversUnivariate::SolveCubic( c0, c1, c2, c3, r1, r2, r3, num_roots );
01190 }
01191
01192
01193 inline int vtkMath::SolveQuadratic(double c0, double c1, double c2,
01194 double *r1, double *r2, int *num_roots)
01195 {
01196 return vtkPolynomialSolversUnivariate::SolveQuadratic( c0, c1, c2, r1, r2, num_roots );
01197 }
01198
01199
01200 inline int vtkMath::SolveQuadratic( double* c, double* r, int* m )
01201 {
01202 return vtkPolynomialSolversUnivariate::SolveQuadratic( c, r, m );
01203 }
01204
01205
01206 inline int vtkMath::SolveLinear(double c0, double c1, double *r1, int *num_roots)
01207 {
01208 return vtkPolynomialSolversUnivariate::SolveLinear( c0, c1, r1, num_roots );
01209 }
01210
01211
01212 inline void vtkMath::ClampValue(double *value, const double range[2])
01213 {
01214 if (value && range)
01215 {
01216 if (*value < range[0])
01217 {
01218 *value = range[0];
01219 }
01220 else if (*value > range[1])
01221 {
01222 *value = range[1];
01223 }
01224 }
01225 }
01226
01227
01228 inline void vtkMath::ClampValue(
01229 double value, const double range[2], double *clamped_value)
01230 {
01231 if (range && clamped_value)
01232 {
01233 if (value < range[0])
01234 {
01235 *clamped_value = range[0];
01236 }
01237 else if (value > range[1])
01238 {
01239 *clamped_value = range[1];
01240 }
01241 else
01242 {
01243 *clamped_value = value;
01244 }
01245 }
01246 }
01247
01248
01249 inline double vtkMath::ClampAndNormalizeValue(double value,
01250 const double range[2])
01251 {
01252 assert("pre: valid_range" && range[0]<=range[1]);
01253
01254 double result;
01255 if(range[0]==range[1])
01256 {
01257 result=0.0;
01258 }
01259 else
01260 {
01261
01262 if(value<range[0])
01263 {
01264 result=range[0];
01265 }
01266 else
01267 {
01268 if(value>range[1])
01269 {
01270 result=range[1];
01271 }
01272 else
01273 {
01274 result=value;
01275 }
01276 }
01277
01278
01279 result=( result - range[0] ) / ( range[1] - range[0] );
01280 }
01281
01282 assert("post: valid_result" && result>=0.0 && result<=1.0);
01283
01284 return result;
01285 }
01286
01287 #endif