00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00031 #ifndef __vtkMath_h
00032 #define __vtkMath_h
00033
00034 #include "vtkObject.h"
00035
00036 class vtkDataArray;
00037
00038 class VTK_COMMON_EXPORT vtkMath : public vtkObject
00039 {
00040 public:
00041 static vtkMath *New();
00042 vtkTypeRevisionMacro(vtkMath,vtkObject);
00043 void PrintSelf(ostream& os, vtkIndent indent);
00044
00046
00047 static float Pi() {return 3.14159265358979f;};
00048 static float DegreesToRadians() {return 0.017453292f;};
00049 static float RadiansToDegrees() {return 57.2957795131f;};
00051
00053
00054 static double DoubleDegreesToRadians() {return 0.017453292519943295;};
00055 static double DoublePi() {return 3.1415926535897932384626;};
00056 static double DoubleRadiansToDegrees() {return 57.29577951308232;};
00058
00060
00061 static int Round(float f) {
00062 return static_cast<int>(f + (f >= 0 ? 0.5 : -0.5)); }
00063 static int Round(double f) {
00064 return static_cast<int>(f + (f >= 0 ? 0.5 : -0.5)); }
00066
00067 static int Floor(double x);
00068
00070
00071 static float Dot(const float x[3], const float y[3]) {
00072 return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);};
00074
00076
00077 static double Dot(const double x[3], const double y[3]) {
00078 return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);};
00080
00082 static void Cross(const float x[3], const float y[3], float z[3]);
00083
00086 static void Cross(const double x[3], const double y[3], double z[3]);
00087
00089
00090 static float Norm(const float* x, int n);
00091 static double Norm(const double* x, int n);
00093
00095
00096 static float Norm(const float x[3]) {
00097 return static_cast<float> (sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]));};
00099
00101
00102 static double Norm(const double x[3]) {
00103 return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);};
00105
00107 static float Normalize(float x[3]);
00108
00111 static double Normalize(double x[3]);
00112
00114
00119 static void Perpendiculars(const double x[3], double y[3], double z[3],
00120 double theta);
00121 static void Perpendiculars(const float x[3], float y[3], float z[3],
00122 double theta);
00124
00126 static float Distance2BetweenPoints(const float x[3], const float y[3]);
00127
00130 static double Distance2BetweenPoints(const double x[3], const double y[3]);
00131
00133
00134 static float Dot2D(const float x[3], const float y[3]) {
00135 return (x[0]*y[0] + x[1]*y[1]);};
00137
00139
00141 static double Dot2D(const double x[3], const double y[3]) {
00142 return (x[0]*y[0] + x[1]*y[1]);};
00144
00146
00147 static float Norm2D(const float x[3]) {
00148 return static_cast<float> (sqrt(x[0]*x[0] + x[1]*x[1]));};
00150
00152
00154 static double Norm2D(const double x[3]) {
00155 return sqrt(x[0]*x[0] + x[1]*x[1]);};
00157
00160 static float Normalize2D(float x[3]);
00161
00164 static double Normalize2D(double x[3]);
00165
00167
00168 static float Determinant2x2(const float c1[2], const float c2[2]) {
00169 return (c1[0]*c2[1] - c2[0]*c1[1]);};
00171
00173
00174 static double Determinant2x2(double a, double b, double c, double d) {
00175 return (a * d - b * c);};
00176 static double Determinant2x2(const double c1[2], const double c2[2]) {
00177 return (c1[0]*c2[1] - c2[0]*c1[1]);};
00179
00181
00183 static void LUFactor3x3(float A[3][3], int index[3]);
00184 static void LUFactor3x3(double A[3][3], int index[3]);
00186
00188
00190 static void LUSolve3x3(const float A[3][3], const int index[3],
00191 float x[3]);
00192 static void LUSolve3x3(const double A[3][3], const int index[3],
00193 double x[3]);
00195
00197
00199 static void LinearSolve3x3(const float A[3][3], const float x[3],
00200 float y[3]);
00201 static void LinearSolve3x3(const double A[3][3], const double x[3],
00202 double y[3]);
00204
00206
00207 static void Multiply3x3(const float A[3][3], const float in[3],
00208 float out[3]);
00209 static void Multiply3x3(const double A[3][3], const double in[3],
00210 double out[3]);
00212
00214
00215 static void Multiply3x3(const float A[3][3], const float B[3][3],
00216 float C[3][3]);
00217 static void Multiply3x3(const double A[3][3], const double B[3][3],
00218 double C[3][3]);
00220
00222
00223 static void Transpose3x3(const float A[3][3], float AT[3][3]);
00224 static void Transpose3x3(const double A[3][3], double AT[3][3]);
00226
00228
00229 static void Invert3x3(const float A[3][3], float AI[3][3]);
00230 static void Invert3x3(const double A[3][3], double AI[3][3]);
00232
00234
00235 static void Identity3x3(float A[3][3]);
00236 static void Identity3x3(double A[3][3]);
00238
00240
00241 static double Determinant3x3(float A[3][3]);
00242 static double Determinant3x3(double A[3][3]);
00244
00246
00247 static float Determinant3x3(const float c1[3],
00248 const float c2[3],
00249 const float c3[3]);
00251
00253
00254 static double Determinant3x3(const double c1[3],
00255 const double c2[3],
00256 const double c3[3]);
00258
00260
00262 static double Determinant3x3(double a1, double a2, double a3,
00263 double b1, double b2, double b3,
00264 double c1, double c2, double c3);
00266
00268
00270 static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]);
00271 static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]);
00273
00275
00278 static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
00279 static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
00281
00283
00286 static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
00287 static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
00289
00291
00295 static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
00296 static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]);
00298
00300
00307 static void SingularValueDecomposition3x3(const float A[3][3],
00308 float U[3][3], float w[3],
00309 float VT[3][3]);
00310 static void SingularValueDecomposition3x3(const double A[3][3],
00311 double U[3][3], double w[3],
00312 double VT[3][3]);
00314
00319 static int SolveLinearSystem(double **A, double *x, int size);
00320
00324 static int InvertMatrix(double **A, double **AI, int size);
00325
00327
00329 static int InvertMatrix(double **A, double **AI, int size,
00330 int *tmp1Size, double *tmp2Size);
00332
00338 static int LUFactorLinearSystem(double **A, int *index, int size);
00339
00341
00343 static int LUFactorLinearSystem(double **A, int *index, int size,
00344 double *tmpSize);
00346
00348
00354 static void LUSolveLinearSystem(double **A, int *index,
00355 double *x, int size);
00357
00365 static double EstimateMatrixCondition(double **A, int size);
00366
00372 static void RandomSeed(long s);
00373
00376 static double Random();
00377
00379 static double Random(double min, double max);
00380
00382
00386 static int Jacobi(float **a, float *w, float **v);
00387 static int Jacobi(double **a, double *w, double **v);
00389
00391
00396 static int JacobiN(float **a, int n, float *w, float **v);
00397 static int JacobiN(double **a, int n, double *w, double **v);
00399
00406 static double* SolveCubic(double c0, double c1, double c2, double c3);
00407
00414 static double* SolveQuadratic(double c0, double c1, double c2);
00415
00419 static double* SolveLinear(double c0, double c1);
00420
00422
00433 static int SolveCubic(double c0, double c1, double c2, double c3,
00434 double *r1, double *r2, double *r3, int *num_roots);
00436
00438
00442 static int SolveQuadratic(double c0, double c1, double c2,
00443 double *r1, double *r2, int *num_roots);
00445
00450 static int SolveLinear(double c0, double c1, double *r1, int *num_roots);
00451
00453
00463 static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder,
00464 double **mt);
00466
00467
00469
00480 static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
00481 double **yt, int yOrder, double **mt, int checkHomogeneous=1);
00483
00485
00487 static void RGBToHSV(float rgb[3], float hsv[3])
00488 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00489 static void RGBToHSV(float r, float g, float b, float *h, float *s, float *v);
00490 static double* RGBToHSV(double rgb[3]);
00491 static double* RGBToHSV(double r, double g, double b);
00492 static void RGBToHSV(double rgb[3], double hsv[3])
00493 { RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); }
00494 static void RGBToHSV(double r, double g, double b, double *h, double *s, double *v);
00496
00498
00500 static void HSVToRGB(float hsv[3], float rgb[3])
00501 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00502 static void HSVToRGB(float h, float s, float v, float *r, float *g, float *b);
00503 static double* HSVToRGB(double hsv[3]);
00504 static double* HSVToRGB(double h, double s, double v);
00505 static void HSVToRGB(double hsv[3], double rgb[3])
00506 { HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); }
00507 static void HSVToRGB(double h, double s, double v, double *r, double *g, double *b);
00509
00511
00512 static void LabToXYZ(double lab[3], double xyz[3]);
00513 static void XYZToRGB(double xyz[3], double rgb[3]);
00515
00517
00518 static void UninitializeBounds(double bounds[6]){
00519 bounds[0] = 1.0;
00520 bounds[1] = -1.0;
00521 bounds[2] = 1.0;
00522 bounds[3] = -1.0;
00523 bounds[4] = 1.0;
00524 bounds[5] = -1.0;
00525 }
00527
00529
00530 static int AreBoundsInitialized(double bounds[6]){
00531 if (bounds[1]-bounds[0]<0.0)
00532 {
00533 return 0;
00534 }
00535 return 1;
00536 }
00538
00540
00542 static void ClampValue(double *value, const double range[2]);
00543 static void ClampValue(double value, const double range[2], double *clamped_value);
00544 static void ClampValues(
00545 double *values, int nb_values, const double range[2]);
00546 static void ClampValues(
00547 const double *values, int nb_values, const double range[2], double *clamped_values);
00549
00551
00557 static int GetScalarTypeFittingRange(
00558 double range_min, double range_max,
00559 double scale = 1.0, double shift = 0.0);
00561
00563
00569 static int GetAdjustedScalarRange(
00570 vtkDataArray *array, int comp, double range[2]);
00572
00575 static int ExtentIsWithinOtherExtent(int extent1[6], int extent2[6]);
00576
00580 static int BoundsIsWithinOtherBounds(double bounds1[6], double bounds2[6], double delta[3]);
00581
00585 static int PointIsWithinBounds(double point[3], double bounds[6], double delta[3]);
00586
00587
00588 protected:
00589 vtkMath() {};
00590 ~vtkMath() {};
00591
00592 static long Seed;
00593 private:
00594 vtkMath(const vtkMath&);
00595 void operator=(const vtkMath&);
00596 };
00597
00598
00599 inline int vtkMath::Floor(double x)
00600 {
00601 #if defined i386 || defined _M_IX86
00602 union { int i[2]; double d; } u;
00603
00604
00605
00606 u.d = (x - 0.25) + 3377699720527872.0;
00607
00608
00609
00610 return u.i[0] >> 1;
00611 #else
00612 return (int)floor(x);
00613 #endif
00614 }
00615
00616
00617 inline float vtkMath::Normalize(float x[3])
00618 {
00619 float den;
00620 if ( (den = vtkMath::Norm(x)) != 0.0 )
00621 {
00622 for (int i=0; i < 3; i++)
00623 {
00624 x[i] /= den;
00625 }
00626 }
00627 return den;
00628 }
00629
00630
00631 inline double vtkMath::Normalize(double x[3])
00632 {
00633 double den;
00634 if ( (den = vtkMath::Norm(x)) != 0.0 )
00635 {
00636 for (int i=0; i < 3; i++)
00637 {
00638 x[i] /= den;
00639 }
00640 }
00641 return den;
00642 }
00643
00644
00645 inline float vtkMath::Normalize2D(float x[3])
00646 {
00647 float den;
00648 if ( (den = vtkMath::Norm2D(x)) != 0.0 )
00649 {
00650 for (int i=0; i < 2; i++)
00651 {
00652 x[i] /= den;
00653 }
00654 }
00655 return den;
00656 }
00657
00658
00659 inline double vtkMath::Normalize2D(double x[3])
00660 {
00661 double den;
00662 if ( (den = vtkMath::Norm2D(x)) != 0.0 )
00663 {
00664 for (int i=0; i < 2; i++)
00665 {
00666 x[i] /= den;
00667 }
00668 }
00669 return den;
00670 }
00671
00672
00673 inline float vtkMath::Determinant3x3(const float c1[3],
00674 const float c2[3],
00675 const float c3[3])
00676 {
00677 return c1[0]*c2[1]*c3[2] + c2[0]*c3[1]*c1[2] + c3[0]*c1[1]*c2[2] -
00678 c1[0]*c3[1]*c2[2] - c2[0]*c1[1]*c3[2] - c3[0]*c2[1]*c1[2];
00679 }
00680
00681
00682 inline double vtkMath::Determinant3x3(const double c1[3],
00683 const double c2[3],
00684 const double c3[3])
00685 {
00686 return c1[0]*c2[1]*c3[2] + c2[0]*c3[1]*c1[2] + c3[0]*c1[1]*c2[2] -
00687 c1[0]*c3[1]*c2[2] - c2[0]*c1[1]*c3[2] - c3[0]*c2[1]*c1[2];
00688 }
00689
00690
00691 inline double vtkMath::Determinant3x3(double a1, double a2, double a3,
00692 double b1, double b2, double b3,
00693 double c1, double c2, double c3)
00694 {
00695 return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
00696 - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
00697 + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
00698 }
00699
00700
00701 inline float vtkMath::Distance2BetweenPoints(const float x[3],
00702 const float y[3])
00703 {
00704 return ((x[0]-y[0])*(x[0]-y[0]) + (x[1]-y[1])*(x[1]-y[1]) +
00705 (x[2]-y[2])*(x[2]-y[2]));
00706 }
00707
00708
00709 inline double vtkMath::Distance2BetweenPoints(const double x[3],
00710 const double y[3])
00711 {
00712 return ((x[0]-y[0])*(x[0]-y[0]) + (x[1]-y[1])*(x[1]-y[1]) +
00713 (x[2]-y[2])*(x[2]-y[2]));
00714 }
00715
00716
00717 inline double vtkMath::Random(double min, double max)
00718 {
00719 return (min + vtkMath::Random()*(max-min));
00720 }
00721
00722
00723
00724 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
00725 {
00726 float Zx = x[1]*y[2] - x[2]*y[1];
00727 float Zy = x[2]*y[0] - x[0]*y[2];
00728 float Zz = x[0]*y[1] - x[1]*y[0];
00729 z[0] = Zx; z[1] = Zy; z[2] = Zz;
00730 }
00731
00732
00733
00734 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3])
00735 {
00736 double Zx = x[1]*y[2] - x[2]*y[1];
00737 double Zy = x[2]*y[0] - x[0]*y[2];
00738 double Zz = x[0]*y[1] - x[1]*y[0];
00739 z[0] = Zx; z[1] = Zy; z[2] = Zz;
00740 }
00741
00742
00743
00744 template<class T>
00745 inline double vtkDeterminant3x3(T A[3][3])
00746 {
00747 return A[0][0]*A[1][1]*A[2][2] + A[1][0]*A[2][1]*A[0][2] +
00748 A[2][0]*A[0][1]*A[1][2] - A[0][0]*A[2][1]*A[1][2] -
00749 A[1][0]*A[0][1]*A[2][2] - A[2][0]*A[1][1]*A[0][2];
00750 }
00751
00752
00753
00754 inline double vtkMath::Determinant3x3(float A[3][3])
00755 {
00756 return vtkDeterminant3x3(A);
00757 }
00758
00759
00760 inline double vtkMath::Determinant3x3(double A[3][3])
00761 {
00762 return vtkDeterminant3x3(A);
00763 }
00764
00765
00766 inline void vtkMath::ClampValue(double *value, const double range[2])
00767 {
00768 if (value && range)
00769 {
00770 if (*value < range[0])
00771 {
00772 *value = range[0];
00773 }
00774 else if (*value > range[1])
00775 {
00776 *value = range[1];
00777 }
00778 }
00779 }
00780
00781
00782 inline void vtkMath::ClampValue(
00783 double value, const double range[2], double *clamped_value)
00784 {
00785 if (range && clamped_value)
00786 {
00787 if (value < range[0])
00788 {
00789 *clamped_value = range[0];
00790 }
00791 else if (value > range[1])
00792 {
00793 *clamped_value = range[1];
00794 }
00795 else
00796 {
00797 *clamped_value = value;
00798 }
00799 }
00800 }
00801
00802 #endif