Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

Common/vtkMath.h

Go to the documentation of this file.
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 =========================================================================*/
00031 #ifndef __vtkMath_h
00032 #define __vtkMath_h
00033 
00034 #include "vtkObject.h"
00035 
00036 class VTK_COMMON_EXPORT vtkMath : public vtkObject
00037 {
00038 public:
00039   static vtkMath *New();
00040   vtkTypeRevisionMacro(vtkMath,vtkObject);
00041   
00043 
00044   static float Pi() {return 3.14159265358979f;};
00045   static float DegreesToRadians() {return 0.017453292f;};
00046   static float RadiansToDegrees() {return 57.2957795131f;};
00048 
00050 
00051   static double DoubleDegreesToRadians() {return 0.017453292519943295;};
00052   static double DoublePi() {return 3.1415926535897932384626;};
00053   static double DoubleRadiansToDegrees() {return 57.29577951308232;};
00055 
00057 
00058   static int Round(float f) {
00059     return static_cast<int>(f + (f >= 0 ? 0.5 : -0.5)); }
00060   static int Round(double f) {
00061     return static_cast<int>(f + (f >= 0 ? 0.5 : -0.5)); }
00063 
00064   static int Floor(double x);
00065   
00067 
00068   static float Dot(const float x[3], const float y[3]) {
00069     return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);};
00071 
00073 
00074   static double Dot(const double x[3], const double y[3]) {
00075     return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);};
00077   
00079   static void Cross(const float x[3], const float y[3], float z[3]);
00080 
00083   static void Cross(const double x[3], const double y[3], double z[3]);
00084 
00086 
00087   static float Norm(const float* x, int n); 
00088   static double Norm(const double* x, int n); 
00090 
00092 
00093   static float Norm(const float x[3]) {
00094     return static_cast<float> (sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]));};
00096   
00098 
00099   static double Norm(const double x[3]) {
00100     return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);};
00102   
00104   static float Normalize(float x[3]);
00105 
00108   static double Normalize(double x[3]);
00109 
00111 
00116   static void Perpendiculars(const double x[3], double y[3], double z[3], 
00117                              double theta);
00118   static void Perpendiculars(const float x[3], float y[3], float z[3],
00119                              double theta);
00121 
00123   static float Distance2BetweenPoints(const float x[3], const float y[3]);
00124 
00127   static double Distance2BetweenPoints(const double x[3], const double y[3]);
00128 
00130 
00131   static float Dot2D(const float x[3], const float y[3]) {
00132     return (x[0]*y[0] + x[1]*y[1]);};
00134   
00136 
00138   static double Dot2D(const double x[3], const double y[3]) {
00139     return (x[0]*y[0] + x[1]*y[1]);};
00141 
00143 
00144   static float Norm2D(const float x[3]) {
00145     return static_cast<float> (sqrt(x[0]*x[0] + x[1]*x[1]));};
00147 
00149 
00151   static double Norm2D(const double x[3]) {
00152     return sqrt(x[0]*x[0] + x[1]*x[1]);};
00154 
00157   static float Normalize2D(float x[3]);
00158 
00161   static double Normalize2D(double x[3]);
00162 
00164 
00165   static float Determinant2x2(const float c1[2], const float c2[2]) {
00166     return (c1[0]*c2[1] - c2[0]*c1[1]);};
00168 
00170 
00171   static double Determinant2x2(double a, double b, double c, double d) {
00172     return (a * d - b * c);};
00173   static double Determinant2x2(const double c1[2], const double c2[2]) {
00174     return (c1[0]*c2[1] - c2[0]*c1[1]);};
00176 
00178 
00180   static void LUFactor3x3(float A[3][3], int index[3]);
00181   static void LUFactor3x3(double A[3][3], int index[3]);
00183 
00185 
00187   static void LUSolve3x3(const float A[3][3], const int index[3], 
00188                          float x[3]);
00189   static void LUSolve3x3(const double A[3][3], const int index[3], 
00190                          double x[3]);
00192 
00194 
00196   static void LinearSolve3x3(const float A[3][3], const float x[3], 
00197                              float y[3]);
00198   static void LinearSolve3x3(const double A[3][3], const double x[3], 
00199                              double y[3]);
00201 
00203 
00204   static void Multiply3x3(const float A[3][3], const float in[3], 
00205                           float out[3]);
00206   static void Multiply3x3(const double A[3][3], const double in[3], 
00207                           double out[3]);
00209   
00211 
00212   static void Multiply3x3(const float A[3][3], const float B[3][3], 
00213                           float C[3][3]);
00214   static void Multiply3x3(const double A[3][3], const double B[3][3], 
00215                           double C[3][3]);
00217 
00219 
00220   static void Transpose3x3(const float A[3][3], float AT[3][3]);
00221   static void Transpose3x3(const double A[3][3], double AT[3][3]);
00223 
00225 
00226   static void Invert3x3(const float A[3][3], float AI[3][3]);
00227   static void Invert3x3(const double A[3][3], double AI[3][3]);
00229 
00231 
00232   static void Identity3x3(float A[3][3]);
00233   static void Identity3x3(double A[3][3]);
00235 
00237 
00238   static double Determinant3x3(float A[3][3]);
00239   static double Determinant3x3(double A[3][3]);
00241 
00243 
00244   static float Determinant3x3(const float c1[3], 
00245                               const float c2[3], 
00246                               const float c3[3]);
00248 
00250 
00251   static double Determinant3x3(const double c1[3], 
00252                                const double c2[3], 
00253                                const double c3[3]);
00255 
00257 
00259   static double Determinant3x3(double a1, double a2, double a3, 
00260                                double b1, double b2, double b3, 
00261                                double c1, double c2, double c3);
00263 
00265 
00267   static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]); 
00268   static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]); 
00270 
00272 
00275   static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
00276   static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
00278   
00280 
00283   static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
00284   static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
00286 
00288 
00292   static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
00293   static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]);
00295 
00297 
00304   static void SingularValueDecomposition3x3(const float A[3][3],
00305                                             float U[3][3], float w[3],
00306                                             float VT[3][3]);
00307   static void SingularValueDecomposition3x3(const double A[3][3],
00308                                             double U[3][3], double w[3],
00309                                             double VT[3][3]);
00311 
00316   static int SolveLinearSystem(double **A, double *x, int size);
00317 
00321   static int InvertMatrix(double **A, double **AI, int size);
00322 
00324 
00326   static int InvertMatrix(double **A, double **AI, int size,
00327                           int *tmp1Size, double *tmp2Size);
00329 
00335   static int LUFactorLinearSystem(double **A, int *index, int size);
00336 
00338 
00340   static int LUFactorLinearSystem(double **A, int *index, int size,
00341                                   double *tmpSize);
00343 
00345 
00351   static void LUSolveLinearSystem(double **A, int *index, 
00352                                   double *x, int size);
00354 
00362   static double EstimateMatrixCondition(double **A, int size);
00363 
00369   static void RandomSeed(long s);  
00370 
00373   static float Random();  
00374 
00376   static float Random(float min, float max);
00377 
00379 
00383   static int Jacobi(float **a, float *w, float **v);
00384   static int Jacobi(double **a, double *w, double **v);
00386 
00388 
00393   static int JacobiN(float **a, int n, float *w, float **v);
00394   static int JacobiN(double **a, int n, double *w, double **v);
00396 
00403   static double* SolveCubic(double c0, double c1, double c2, double c3);
00404 
00411   static double* SolveQuadratic(double c0, double c1, double c2);
00412 
00416   static double* SolveLinear(double c0, double c1);
00417 
00419 
00430   static int SolveCubic(double c0, double c1, double c2, double c3, 
00431                         double *r1, double *r2, double *r3, int *num_roots);
00433 
00435 
00439   static int SolveQuadratic(double c0, double c1, double c2, 
00440                             double *r1, double *r2, int *num_roots);
00442   
00447   static int SolveLinear(double c0, double c1, double *r1, int *num_roots);
00448 
00449 
00451 
00458   static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
00459                                double **yt, int yOrder, double **mt);
00461 
00463 
00465   static void RGBToHSV(float rgb[3], float hsv[3])
00466     { 
00467     RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
00468     }
00469   static void RGBToHSV(float r, float g, float b, 
00470                        float *h, float *s, float *v);
00471   static void RGBToHSV(double rgb[3], double hsv[3])
00472     { 
00473     RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
00474     }
00475   static void RGBToHSV(double r, double g, double b, 
00476                        double *h, double *s, double *v);
00478 
00480 
00482   static void HSVToRGB(float hsv[3], float rgb[3])
00483     { 
00484     HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
00485     }
00486   static void HSVToRGB(float h, float s, float v, 
00487                        float *r, float *g, float *b);
00488   static void HSVToRGB(double hsv[3], double rgb[3])
00489     { 
00490     HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
00491     }
00492   static void HSVToRGB(double h, double s, double v, 
00493                        double *r, double *g, double *b);
00495 
00497 
00498   static void UninitializeBounds(double bounds[6]){
00499     bounds[0] = 1.0;
00500     bounds[1] = -1.0;
00501     bounds[2] = 1.0;
00502     bounds[3] = -1.0;
00503     bounds[4] = 1.0;
00504     bounds[5] = -1.0;
00505   }
00507   
00509 
00510   static int AreBoundsInitialized(double bounds[6]){
00511     if (bounds[1]-bounds[0]<0.0)
00512       {
00513       return 0;
00514       }
00515     return 1;
00516   }
00518 
00519 
00520 protected:
00521   vtkMath() {};
00522   ~vtkMath() {};
00523   
00524   static long Seed;
00525 private:
00526   vtkMath(const vtkMath&);  // Not implemented.
00527   void operator=(const vtkMath&);  // Not implemented.
00528 };
00529 
00530 inline int vtkMath::Floor(double x)
00531 {
00532 #if defined i386 || defined _M_IX86
00533   double tempval;
00534   // use 52-bit precision of IEEE double to round (x - 0.25) to 
00535   // the nearest multiple of 0.5, according to prevailing rounding
00536   // mode which is IEEE round-to-nearest,even
00537   tempval = (x - 0.25) + 3377699720527872.0; // (2**51)*1.5
00538   // extract mantissa, use shift to divide by 2 and hence get rid
00539   // of the bit that gets messed up because the FPU uses
00540   // round-to-nearest,even mode instead of round-to-nearest,+infinity
00541   return ((int*)&tempval)[0] >> 1;
00542 #else
00543   return (int)floor(x);
00544 #endif
00545 }
00546 
00547 inline float vtkMath::Normalize(float x[3])
00548 {
00549   float den; 
00550   if ( (den = vtkMath::Norm(x)) != 0.0 )
00551     {
00552     for (int i=0; i < 3; i++)
00553       {
00554       x[i] /= den;
00555       }
00556     }
00557   return den;
00558 }
00559 inline double vtkMath::Normalize(double x[3])
00560 {
00561   double den; 
00562   if ( (den = vtkMath::Norm(x)) != 0.0 )
00563     {
00564     for (int i=0; i < 3; i++)
00565       {
00566       x[i] /= den;
00567       }
00568     }
00569   return den;
00570 }
00571 
00572 inline float vtkMath::Normalize2D(float x[3])
00573 {
00574   float den; 
00575   if ( (den = vtkMath::Norm2D(x)) != 0.0 )
00576     {
00577     for (int i=0; i < 2; i++)
00578       {
00579       x[i] /= den;
00580       }
00581     }
00582   return den;
00583 }
00584 
00585 inline double vtkMath::Normalize2D(double x[3])
00586 {
00587   double den; 
00588   if ( (den = vtkMath::Norm2D(x)) != 0.0 )
00589     {
00590     for (int i=0; i < 2; i++)
00591       {
00592       x[i] /= den;
00593       }
00594     }
00595   return den;
00596 }
00597 
00598 inline float vtkMath::Determinant3x3(const float c1[3], 
00599                                      const float c2[3], 
00600                                      const float c3[3])
00601 {
00602   return c1[0]*c2[1]*c3[2] + c2[0]*c3[1]*c1[2] + c3[0]*c1[1]*c2[2] -
00603          c1[0]*c3[1]*c2[2] - c2[0]*c1[1]*c3[2] - c3[0]*c2[1]*c1[2];
00604 }
00605 
00606 inline double vtkMath::Determinant3x3(const double c1[3], 
00607                                       const double c2[3], 
00608                                       const double c3[3])
00609 {
00610   return c1[0]*c2[1]*c3[2] + c2[0]*c3[1]*c1[2] + c3[0]*c1[1]*c2[2] -
00611          c1[0]*c3[1]*c2[2] - c2[0]*c1[1]*c3[2] - c3[0]*c2[1]*c1[2];
00612 }
00613 
00614 inline double vtkMath::Determinant3x3(double a1, double a2, double a3, 
00615                                       double b1, double b2, double b3, 
00616                                       double c1, double c2, double c3)
00617 {
00618     return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
00619            - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
00620            + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
00621 }
00622 
00623 inline float vtkMath::Distance2BetweenPoints(const float x[3], 
00624                                              const float y[3])
00625 {
00626   return ((x[0]-y[0])*(x[0]-y[0]) + (x[1]-y[1])*(x[1]-y[1]) +
00627           (x[2]-y[2])*(x[2]-y[2]));
00628 }
00629 inline double vtkMath::Distance2BetweenPoints(const double x[3], 
00630                                               const double y[3])
00631 {
00632   return ((x[0]-y[0])*(x[0]-y[0]) + (x[1]-y[1])*(x[1]-y[1]) +
00633           (x[2]-y[2])*(x[2]-y[2]));
00634 }
00635 
00636 inline float vtkMath::Random(float min, float max)
00637 {
00638   return (min + vtkMath::Random()*(max-min));
00639 }
00640 
00641 // Cross product of two 3-vectors. Result vector in z[3].
00642 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
00643 {
00644   float Zx = x[1]*y[2] - x[2]*y[1]; 
00645   float Zy = x[2]*y[0] - x[0]*y[2];
00646   float Zz = x[0]*y[1] - x[1]*y[0];
00647   z[0] = Zx; z[1] = Zy; z[2] = Zz; 
00648 }
00649 
00650 // Cross product of two 3-vectors. Result vector in z[3].
00651 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3])
00652 {
00653   double Zx = x[1]*y[2] - x[2]*y[1]; 
00654   double Zy = x[2]*y[0] - x[0]*y[2];
00655   double Zz = x[0]*y[1] - x[1]*y[0];
00656   z[0] = Zx; z[1] = Zy; z[2] = Zz; 
00657 }
00658 
00659 //BTX
00660 //----------------------------------------------------------------------------
00661 template<class T>
00662 inline double vtkDeterminant3x3(T A[3][3])
00663 {
00664   return A[0][0]*A[1][1]*A[2][2] + A[1][0]*A[2][1]*A[0][2] + 
00665          A[2][0]*A[0][1]*A[1][2] - A[0][0]*A[2][1]*A[1][2] - 
00666          A[1][0]*A[0][1]*A[2][2] - A[2][0]*A[1][1]*A[0][2];
00667 }
00668 //ETX
00669 
00670 inline double vtkMath::Determinant3x3(float A[3][3])
00671 {
00672   return vtkDeterminant3x3(A);
00673 }
00674 
00675 inline double vtkMath::Determinant3x3(double A[3][3])
00676 {
00677   return vtkDeterminant3x3(A);
00678 }
00679 
00680 
00681 #endif