00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00041 #ifndef __vtkMath_h
00042 #define __vtkMath_h
00043
00044 #include "vtkObject.h"
00045
00046 #ifndef DBL_EPSILON
00047 # define VTK_DBL_EPSILON 2.2204460492503131e-16
00048 #else // DBL_EPSILON
00049 # define VTK_DBL_EPSILON DBL_EPSILON
00050 #endif // DBL_EPSILON
00051
00052 class vtkDataArray;
00053
00054 class VTK_COMMON_EXPORT vtkMath : public vtkObject
00055 {
00056 public:
00057 static vtkMath *New();
00058 vtkTypeRevisionMacro(vtkMath,vtkObject);
00059 void PrintSelf(ostream& os, vtkIndent indent);
00060
00062
00063 static float Pi() {return 3.14159265358979f;};
00064 static float DegreesToRadians() {return 0.017453292f;};
00065 static float RadiansToDegrees() {return 57.2957795131f;};
00067
00069
00070 static double DoubleDegreesToRadians() {return 0.017453292519943295;};
00071 static double DoublePi() {return 3.1415926535897932384626;};
00072 static double DoubleRadiansToDegrees() {return 57.29577951308232;};
00074
00076
00077 static int Round(float f) {
00078 return static_cast<int>(f + (f >= 0 ? 0.5 : -0.5)); }
00079 static int Round(double f) {
00080 return static_cast<int>(f + (f >= 0 ? 0.5 : -0.5)); }
00082
00083 static int Floor(double x);
00084
00087 static vtkTypeInt64 Factorial( int N );
00088
00092 static vtkTypeInt64 Binomial( int m, int n );
00093
00100 static int* BeginCombination( int m, int n );
00101
00108 static int NextCombination( int m, int n, int* combination );
00109
00111 static void FreeCombination( int* combination);
00112
00114
00115 static float Dot(const float x[3], const float y[3]) {
00116 return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);};
00118
00120
00121 static double Dot(const double x[3], const double y[3]) {
00122 return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);};
00124
00126
00127 static void Outer(const float x[3], const float y[3], float A[3][3]) {
00128 for (int i=0; i < 3; i++)
00129 for (int j=0; j < 3; j++)
00130 A[i][j] = x[i]*y[j];
00131 }
00132
00133
00134 static void Outer(const double x[3], const double y[3], double A[3][3]) {
00135 for (int i=0; i < 3; i++)
00136 for (int j=0; j < 3; j++)
00137 A[i][j] = x[i]*y[j];
00138 }
00140
00142 static void Cross(const float x[3], const float y[3], float z[3]);
00143
00146 static void Cross(const double x[3], const double y[3], double z[3]);
00147
00149
00150 static float Norm(const float* x, int n);
00151 static double Norm(const double* x, int n);
00153
00155
00156 static float Norm(const float x[3]) {
00157 return static_cast<float> (sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]));};
00159
00161
00162 static double Norm(const double x[3]) {
00163 return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);};
00165
00167 static float Normalize(float x[3]);
00168
00171 static double Normalize(double x[3]);
00172
00174
00179 static void Perpendiculars(const double x[3], double y[3], double z[3],
00180 double theta);
00181 static void Perpendiculars(const float x[3], float y[3], float z[3],
00182 double theta);
00184
00186 static float Distance2BetweenPoints(const float x[3], const float y[3]);
00187
00190 static double Distance2BetweenPoints(const double x[3], const double y[3]);
00191
00193
00194 static float Dot2D(const float x[3], const float y[3]) {
00195 return (x[0]*y[0] + x[1]*y[1]);};
00197
00199
00201 static double Dot2D(const double x[3], const double y[3]) {
00202 return (x[0]*y[0] + x[1]*y[1]);};
00204
00206
00207 static void Outer2D(const float x[3], const float y[3], float A[3][3]) {
00208 for (int i=0; i < 2; i++)
00209 for (int j=0; j < 2; j++)
00210 A[i][j] = x[i]*y[j];
00211 }
00212
00213
00214 static void Outer2D(const double x[3], const double y[3], double A[3][3]) {
00215 for (int i=0; i < 2; i++)
00216 for (int j=0; j < 2; j++)
00217 A[i][j] = x[i]*y[j];
00218 }
00220
00222
00223 static float Norm2D(const float x[3]) {
00224 return static_cast<float> (sqrt(x[0]*x[0] + x[1]*x[1]));};
00226
00228
00230 static double Norm2D(const double x[3]) {
00231 return sqrt(x[0]*x[0] + x[1]*x[1]);};
00233
00236 static float Normalize2D(float x[3]);
00237
00240 static double Normalize2D(double x[3]);
00241
00243
00244 static float Determinant2x2(const float c1[2], const float c2[2]) {
00245 return (c1[0]*c2[1] - c2[0]*c1[1]);};
00247
00249
00250 static double Determinant2x2(double a, double b, double c, double d) {
00251 return (a * d - b * c);};
00252 static double Determinant2x2(const double c1[2], const double c2[2]) {
00253 return (c1[0]*c2[1] - c2[0]*c1[1]);};
00255
00257
00259 static void LUFactor3x3(float A[3][3], int index[3]);
00260 static void LUFactor3x3(double A[3][3], int index[3]);
00262
00264
00266 static void LUSolve3x3(const float A[3][3], const int index[3],
00267 float x[3]);
00268 static void LUSolve3x3(const double A[3][3], const int index[3],
00269 double x[3]);
00271
00273
00275 static void LinearSolve3x3(const float A[3][3], const float x[3],
00276 float y[3]);
00277 static void LinearSolve3x3(const double A[3][3], const double x[3],
00278 double y[3]);
00280
00282
00283 static void Multiply3x3(const float A[3][3], const float in[3],
00284 float out[3]);
00285 static void Multiply3x3(const double A[3][3], const double in[3],
00286 double out[3]);
00288
00290
00291 static void Multiply3x3(const float A[3][3], const float B[3][3],
00292 float C[3][3]);
00293 static void Multiply3x3(const double A[3][3], const double B[3][3],
00294 double C[3][3]);
00296
00298
00300 static void MultiplyMatrix(const double **A, const double **B,
00301 unsigned int rowA, unsigned int colA,
00302 unsigned int rowB, unsigned int colB,
00303 double **C);
00305
00307
00308 static void Transpose3x3(const float A[3][3], float AT[3][3]);
00309 static void Transpose3x3(const double A[3][3], double AT[3][3]);
00311
00313
00314 static void Invert3x3(const float A[3][3], float AI[3][3]);
00315 static void Invert3x3(const double A[3][3], double AI[3][3]);
00317
00319
00320 static void Identity3x3(float A[3][3]);
00321 static void Identity3x3(double A[3][3]);
00323
00325
00326 static double Determinant3x3(float A[3][3]);
00327 static double Determinant3x3(double A[3][3]);
00329
00331
00332 static float Determinant3x3(const float c1[3],
00333 const float c2[3],
00334 const float c3[3]);
00336
00338
00339 static double Determinant3x3(const double c1[3],
00340 const double c2[3],
00341 const double c3[3]);
00343
00345
00347 static double Determinant3x3(double a1, double a2, double a3,
00348 double b1, double b2, double b3,
00349 double c1, double c2, double c3);
00351
00353
00355 static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]);
00356 static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]);
00358
00360
00363 static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
00364 static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
00366
00368
00371 static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
00372 static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
00374
00376
00380 static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
00381 static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]);
00383
00385
00392 static void SingularValueDecomposition3x3(const float A[3][3],
00393 float U[3][3], float w[3],
00394 float VT[3][3]);
00395 static void SingularValueDecomposition3x3(const double A[3][3],
00396 double U[3][3], double w[3],
00397 double VT[3][3]);
00399
00404 static int SolveLinearSystem(double **A, double *x, int size);
00405
00409 static int InvertMatrix(double **A, double **AI, int size);
00410
00412
00414 static int InvertMatrix(double **A, double **AI, int size,
00415 int *tmp1Size, double *tmp2Size);
00417
00423 static int LUFactorLinearSystem(double **A, int *index, int size);
00424
00426
00428 static int LUFactorLinearSystem(double **A, int *index, int size,
00429 double *tmpSize);
00431
00433
00439 static void LUSolveLinearSystem(double **A, int *index,
00440 double *x, int size);
00442
00450 static double EstimateMatrixCondition(double **A, int size);
00451
00457 static void RandomSeed(long s);
00458
00460 static long GetSeed();
00461
00464 static double Random();
00465
00467 static double Random(double min, double max);
00468
00470
00474 static int Jacobi(float **a, float *w, float **v);
00475 static int Jacobi(double **a, double *w, double **v);
00477
00479
00484 static int JacobiN(float **a, int n, float *w, float **v);
00485 static int JacobiN(double **a, int n, double *w, double **v);
00487
00494 static double* SolveCubic(double c0, double c1, double c2, double c3);
00495
00502 static double* SolveQuadratic(double c0, double c1, double c2);
00503
00507 static double* SolveLinear(double c0, double c1);
00508
00510
00521 static int SolveCubic(double c0, double c1, double c2, double c3,
00522 double *r1, double *r2, double *r3, int *num_roots);
00524
00526
00530 static int SolveQuadratic(double c0, double c1, double c2,
00531 double *r1, double *r2, int *num_roots);
00533
00539 static int SolveQuadratic( double* c, double* r, int* m );
00540
00545 static int SolveLinear(double c0, double c1, double *r1, int *num_roots);
00546
00548
00558 static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder,
00559 double **mt);
00561
00562
00564
00575 static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
00576 double **yt, int yOrder, double **mt, int checkHomogeneous=1);
00578
00580
00582 static void RGBToHSV(const float rgb[3], float hsv[3])
00583 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00584 static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v);
00585 static double* RGBToHSV(const double rgb[3]);
00586 static double* RGBToHSV(double r, double g, double b);
00587 static void RGBToHSV(const double rgb[3], double hsv[3])
00588 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00589 static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v);
00591
00593
00595 static void HSVToRGB(const float hsv[3], float rgb[3])
00596 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00597 static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b);
00598 static double* HSVToRGB(const double hsv[3]);
00599 static double* HSVToRGB(double h, double s, double v);
00600 static void HSVToRGB(const double hsv[3], double rgb[3])
00601 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00602 static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b);
00604
00606
00607 static void LabToXYZ(const double lab[3], double xyz[3]) {
00608 LabToXYZ(lab[0], lab[1], lab[2], xyz+0, xyz+1, xyz+2);
00609 }
00610 static void LabToXYZ(double L, double a, double b,
00611 double *x, double *y, double *z);
00612 static double *LabToXYZ(const double lab[3]);
00614
00616
00617 static void XYZToLab(const double xyz[3], double lab[3]) {
00618 XYZToLab(xyz[0], xyz[1], xyz[2], lab+0, lab+1, lab+2);
00619 }
00620 static void XYZToLab(double x, double y, double z,
00621 double *L, double *a, double *b);
00622 static double *XYZToLab(const double xyz[3]);
00624
00626
00627 static void XYZToRGB(const double xyz[3], double rgb[3]) {
00628 XYZToRGB(xyz[0], xyz[1], xyz[2], rgb+0, rgb+1, rgb+2);
00629 }
00630 static void XYZToRGB(double x, double y, double z,
00631 double *r, double *g, double *b);
00632 static double *XYZToRGB(const double xyz[3]);
00634
00636
00637 static void RGBToXYZ(const double rgb[3], double xyz[3]) {
00638 RGBToXYZ(rgb[0], rgb[1], rgb[2], xyz+0, xyz+1, xyz+2);
00639 }
00640 static void RGBToXYZ(double r, double g, double b,
00641 double *x, double *y, double *z);
00642 static double *RGBToXYZ(const double rgb[3]);
00644
00646
00647 static void RGBToLab(const double rgb[3], double lab[3]) {
00648 RGBToLab(rgb[0], rgb[1], rgb[2], lab+0, lab+1, lab+2);
00649 }
00650 static void RGBToLab(double red, double green, double blue,
00651 double *L, double *a, double *b);
00652 static double *RGBToLab(const double rgb[3]);
00654
00656
00657 static void LabToRGB(const double lab[3], double rgb[3]) {
00658 LabToRGB(lab[0], lab[1], lab[2], rgb+0, rgb+1, rgb+2);
00659 }
00660 static void LabToRGB(double L, double a, double b,
00661 double *red, double *green, double *blue);
00662 static double *LabToRGB(const double lab[3]);
00664
00666
00667 static void UninitializeBounds(double bounds[6]){
00668 bounds[0] = 1.0;
00669 bounds[1] = -1.0;
00670 bounds[2] = 1.0;
00671 bounds[3] = -1.0;
00672 bounds[4] = 1.0;
00673 bounds[5] = -1.0;
00674 }
00676
00678
00679 static int AreBoundsInitialized(double bounds[6]){
00680 if (bounds[1]-bounds[0]<0.0)
00681 {
00682 return 0;
00683 }
00684 return 1;
00685 }
00687
00689
00691 static void ClampValue(double *value, const double range[2]);
00692 static void ClampValue(double value, const double range[2], double *clamped_value);
00693 static void ClampValues(
00694 double *values, int nb_values, const double range[2]);
00695 static void ClampValues(
00696 const double *values, int nb_values, const double range[2], double *clamped_values);
00698
00700
00706 static int GetScalarTypeFittingRange(
00707 double range_min, double range_max,
00708 double scale = 1.0, double shift = 0.0);
00710
00712
00718 static int GetAdjustedScalarRange(
00719 vtkDataArray *array, int comp, double range[2]);
00721
00724 static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]);
00725
00729 static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]);
00730
00734 static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]);
00735
00737
00739 static double Inf();
00740 static double NegInf();
00741 static double Nan();
00743
00744 protected:
00745 vtkMath() {};
00746 ~vtkMath() {};
00747
00748 static long Seed;
00749 private:
00750 vtkMath(const vtkMath&);
00751 void operator=(const vtkMath&);
00752 };
00753
00754
00755 inline vtkTypeInt64 vtkMath::Factorial( int N )
00756 {
00757 vtkTypeInt64 r = 1;
00758 while ( N > 1 )
00759 {
00760 r *= N--;
00761 }
00762 return r;
00763 }
00764
00765
00766 inline int vtkMath::Floor(double x)
00767 {
00768 #if defined i386 || defined _M_IX86
00769 union { int i[2]; double d; } u;
00770
00771
00772
00773 u.d = (x - 0.25) + 3377699720527872.0;
00774
00775
00776
00777 return u.i[0] >> 1;
00778 #else
00779 return static_cast<int>(floor(x));
00780 #endif
00781 }
00782
00783
00784 inline float vtkMath::Normalize(float x[3])
00785 {
00786 float den;
00787 if ( (den = vtkMath::Norm(x)) != 0.0 )
00788 {
00789 for (int i=0; i < 3; i++)
00790 {
00791 x[i] /= den;
00792 }
00793 }
00794 return den;
00795 }
00796
00797
00798 inline double vtkMath::Normalize(double x[3])
00799 {
00800 double den;
00801 if ( (den = vtkMath::Norm(x)) != 0.0 )
00802 {
00803 for (int i=0; i < 3; i++)
00804 {
00805 x[i] /= den;
00806 }
00807 }
00808 return den;
00809 }
00810
00811
00812 inline float vtkMath::Normalize2D(float x[3])
00813 {
00814 float den;
00815 if ( (den = vtkMath::Norm2D(x)) != 0.0 )
00816 {
00817 for (int i=0; i < 2; i++)
00818 {
00819 x[i] /= den;
00820 }
00821 }
00822 return den;
00823 }
00824
00825
00826 inline double vtkMath::Normalize2D(double x[3])
00827 {
00828 double den;
00829 if ( (den = vtkMath::Norm2D(x)) != 0.0 )
00830 {
00831 for (int i=0; i < 2; i++)
00832 {
00833 x[i] /= den;
00834 }
00835 }
00836 return den;
00837 }
00838
00839
00840 inline float vtkMath::Determinant3x3(const float c1[3],
00841 const float c2[3],
00842 const float c3[3])
00843 {
00844 return c1[0]*c2[1]*c3[2] + c2[0]*c3[1]*c1[2] + c3[0]*c1[1]*c2[2] -
00845 c1[0]*c3[1]*c2[2] - c2[0]*c1[1]*c3[2] - c3[0]*c2[1]*c1[2];
00846 }
00847
00848
00849 inline double vtkMath::Determinant3x3(const double c1[3],
00850 const double c2[3],
00851 const double c3[3])
00852 {
00853 return c1[0]*c2[1]*c3[2] + c2[0]*c3[1]*c1[2] + c3[0]*c1[1]*c2[2] -
00854 c1[0]*c3[1]*c2[2] - c2[0]*c1[1]*c3[2] - c3[0]*c2[1]*c1[2];
00855 }
00856
00857
00858 inline double vtkMath::Determinant3x3(double a1, double a2, double a3,
00859 double b1, double b2, double b3,
00860 double c1, double c2, double c3)
00861 {
00862 return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
00863 - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
00864 + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
00865 }
00866
00867
00868 inline float vtkMath::Distance2BetweenPoints(const float x[3],
00869 const float y[3])
00870 {
00871 return ((x[0]-y[0])*(x[0]-y[0]) + (x[1]-y[1])*(x[1]-y[1]) +
00872 (x[2]-y[2])*(x[2]-y[2]));
00873 }
00874
00875
00876 inline double vtkMath::Distance2BetweenPoints(const double x[3],
00877 const double y[3])
00878 {
00879 return ((x[0]-y[0])*(x[0]-y[0]) + (x[1]-y[1])*(x[1]-y[1]) +
00880 (x[2]-y[2])*(x[2]-y[2]));
00881 }
00882
00883
00884 inline double vtkMath::Random(double min, double max)
00885 {
00886 return (min + vtkMath::Random()*(max-min));
00887 }
00888
00889
00890
00891 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
00892 {
00893 float Zx = x[1]*y[2] - x[2]*y[1];
00894 float Zy = x[2]*y[0] - x[0]*y[2];
00895 float Zz = x[0]*y[1] - x[1]*y[0];
00896 z[0] = Zx; z[1] = Zy; z[2] = Zz;
00897 }
00898
00899
00900
00901 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3])
00902 {
00903 double Zx = x[1]*y[2] - x[2]*y[1];
00904 double Zy = x[2]*y[0] - x[0]*y[2];
00905 double Zz = x[0]*y[1] - x[1]*y[0];
00906 z[0] = Zx; z[1] = Zy; z[2] = Zz;
00907 }
00908
00909
00910
00911 template<class T>
00912 inline double vtkDeterminant3x3(T A[3][3])
00913 {
00914 return A[0][0]*A[1][1]*A[2][2] + A[1][0]*A[2][1]*A[0][2] +
00915 A[2][0]*A[0][1]*A[1][2] - A[0][0]*A[2][1]*A[1][2] -
00916 A[1][0]*A[0][1]*A[2][2] - A[2][0]*A[1][1]*A[0][2];
00917 }
00918
00919
00920
00921 inline double vtkMath::Determinant3x3(float A[3][3])
00922 {
00923 return vtkDeterminant3x3(A);
00924 }
00925
00926
00927 inline double vtkMath::Determinant3x3(double A[3][3])
00928 {
00929 return vtkDeterminant3x3(A);
00930 }
00931
00932
00933 inline void vtkMath::ClampValue(double *value, const double range[2])
00934 {
00935 if (value && range)
00936 {
00937 if (*value < range[0])
00938 {
00939 *value = range[0];
00940 }
00941 else if (*value > range[1])
00942 {
00943 *value = range[1];
00944 }
00945 }
00946 }
00947
00948
00949 inline void vtkMath::ClampValue(
00950 double value, const double range[2], double *clamped_value)
00951 {
00952 if (range && clamped_value)
00953 {
00954 if (value < range[0])
00955 {
00956 *clamped_value = range[0];
00957 }
00958 else if (value > range[1])
00959 {
00960 *clamped_value = range[1];
00961 }
00962 else
00963 {
00964 *clamped_value = value;
00965 }
00966 }
00967 }
00968
00969 #endif