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

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 =========================================================================*/
00044 #ifndef __vtkMath_h
00045 #define __vtkMath_h
00046 
00047 #include "vtkObject.h"
00048 
00049 class VTK_COMMON_EXPORT vtkMath : public vtkObject
00050 {
00051 public:
00052   static vtkMath *New();
00053   vtkTypeRevisionMacro(vtkMath,vtkObject);
00054   void PrintSelf(ostream& os, vtkIndent indent);
00055 
00057 
00058   static float Pi() {return 3.14159265358979f;};
00059   static float DegreesToRadians() {return 0.017453292f;};
00060   static float RadiansToDegrees() {return 57.2957795131f;};
00062 
00064 
00065   static double DoubleDegreesToRadians() {return 0.017453292519943295;};
00066   static double DoublePi() {return 3.1415926535897932384626;};
00067   static double DoubleRadiansToDegrees() {return 57.29577951308232;};
00069 
00071 
00072   static int Round(float f) {
00073     return static_cast<int>(f + (f >= 0 ? 0.5 : -0.5)); }
00074   static int Round(double f) {
00075     return static_cast<int>(f + (f >= 0 ? 0.5 : -0.5)); }
00077 
00078   static int Floor(double x);
00079   
00081 
00082   static float Dot(const float x[3], const float y[3]) {
00083     return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);};
00085 
00087 
00088   static double Dot(const double x[3], const double y[3]) {
00089     return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);};
00091   
00093   static void Cross(const float x[3], const float y[3], float z[3]);
00094 
00097   static void Cross(const double x[3], const double y[3], double z[3]);
00098 
00100 
00101   static float Norm(const float* x, int n); 
00102   static double Norm(const double* x, int n); 
00104 
00106 
00107   static float Norm(const float x[3]) {
00108     return static_cast<float> (sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]));};
00110   
00112 
00113   static double Norm(const double x[3]) {
00114     return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);};
00116   
00118   static float Normalize(float x[3]);
00119 
00122   static double Normalize(double x[3]);
00123 
00125 
00130   static void Perpendiculars(const double x[3], double y[3], double z[3], 
00131                              double theta);
00132   static void Perpendiculars(const float x[3], float y[3], float z[3],
00133                              double theta);
00135 
00137   static float Distance2BetweenPoints(const float x[3], const float y[3]);
00138 
00141   static double Distance2BetweenPoints(const double x[3], const double y[3]);
00142 
00144 
00145   static float Dot2D(const float x[3], const float y[3]) {
00146     return (x[0]*y[0] + x[1]*y[1]);};
00148   
00150 
00152   static double Dot2D(const double x[3], const double y[3]) {
00153     return (x[0]*y[0] + x[1]*y[1]);};
00155 
00157 
00158   static float Norm2D(const float x[3]) {
00159     return static_cast<float> (sqrt(x[0]*x[0] + x[1]*x[1]));};
00161 
00163 
00165   static double Norm2D(const double x[3]) {
00166     return sqrt(x[0]*x[0] + x[1]*x[1]);};
00168 
00171   static float Normalize2D(float x[3]);
00172 
00175   static double Normalize2D(double x[3]);
00176 
00178 
00179   static float Determinant2x2(const float c1[2], const float c2[2]) {
00180     return (c1[0]*c2[1] - c2[0]*c1[1]);};
00182 
00184 
00185   static double Determinant2x2(double a, double b, double c, double d) {
00186     return (a * d - b * c);};
00187   static double Determinant2x2(const double c1[2], const double c2[2]) {
00188     return (c1[0]*c2[1] - c2[0]*c1[1]);};
00190 
00192 
00194   static void LUFactor3x3(float A[3][3], int index[3]);
00195   static void LUFactor3x3(double A[3][3], int index[3]);
00197 
00199 
00201   static void LUSolve3x3(const float A[3][3], const int index[3], 
00202                          float x[3]);
00203   static void LUSolve3x3(const double A[3][3], const int index[3], 
00204                          double x[3]);
00206 
00208 
00210   static void LinearSolve3x3(const float A[3][3], const float x[3], 
00211                              float y[3]);
00212   static void LinearSolve3x3(const double A[3][3], const double x[3], 
00213                              double y[3]);
00215 
00217 
00218   static void Multiply3x3(const float A[3][3], const float in[3], 
00219                           float out[3]);
00220   static void Multiply3x3(const double A[3][3], const double in[3], 
00221                           double out[3]);
00223   
00225 
00226   static void Multiply3x3(const float A[3][3], const float B[3][3], 
00227                           float C[3][3]);
00228   static void Multiply3x3(const double A[3][3], const double B[3][3], 
00229                           double C[3][3]);
00231 
00233 
00234   static void Transpose3x3(const float A[3][3], float AT[3][3]);
00235   static void Transpose3x3(const double A[3][3], double AT[3][3]);
00237 
00239 
00240   static void Invert3x3(const float A[3][3], float AI[3][3]);
00241   static void Invert3x3(const double A[3][3], double AI[3][3]);
00243 
00245 
00246   static void Identity3x3(float A[3][3]);
00247   static void Identity3x3(double A[3][3]);
00249 
00251 
00252   static double Determinant3x3(float A[3][3]);
00253   static double Determinant3x3(double A[3][3]);
00255 
00257 
00258   static float Determinant3x3(const float c1[3], 
00259                               const float c2[3], 
00260                               const float c3[3]);
00262 
00264 
00265   static double Determinant3x3(const double c1[3], 
00266                                const double c2[3], 
00267                                const double c3[3]);
00269 
00271 
00273   static double Determinant3x3(double a1, double a2, double a3, 
00274                                double b1, double b2, double b3, 
00275                                double c1, double c2, double c3);
00277 
00279 
00281   static void QuaternionToMatrix3x3(const float quat[4], float A[3][3]); 
00282   static void QuaternionToMatrix3x3(const double quat[4], double A[3][3]); 
00284 
00286 
00289   static void Matrix3x3ToQuaternion(const float A[3][3], float quat[4]);
00290   static void Matrix3x3ToQuaternion(const double A[3][3], double quat[4]);
00292   
00294 
00297   static void Orthogonalize3x3(const float A[3][3], float B[3][3]);
00298   static void Orthogonalize3x3(const double A[3][3], double B[3][3]);
00300 
00302 
00306   static void Diagonalize3x3(const float A[3][3], float w[3], float V[3][3]);
00307   static void Diagonalize3x3(const double A[3][3],double w[3],double V[3][3]);
00309 
00311 
00318   static void SingularValueDecomposition3x3(const float A[3][3],
00319                                             float U[3][3], float w[3],
00320                                             float VT[3][3]);
00321   static void SingularValueDecomposition3x3(const double A[3][3],
00322                                             double U[3][3], double w[3],
00323                                             double VT[3][3]);
00325 
00330   static int SolveLinearSystem(double **A, double *x, int size);
00331 
00335   static int InvertMatrix(double **A, double **AI, int size);
00336 
00338 
00340   static int InvertMatrix(double **A, double **AI, int size,
00341                           int *tmp1Size, double *tmp2Size);
00343 
00349   static int LUFactorLinearSystem(double **A, int *index, int size);
00350 
00352 
00354   static int LUFactorLinearSystem(double **A, int *index, int size,
00355                                   double *tmpSize);
00357 
00359 
00365   static void LUSolveLinearSystem(double **A, int *index, 
00366                                   double *x, int size);
00368 
00376   static double EstimateMatrixCondition(double **A, int size);
00377 
00383   static void RandomSeed(long s);  
00384 
00387   static double Random();  
00388 
00390   static double Random(double min, double max);
00391 
00393 
00397   static int Jacobi(float **a, float *w, float **v);
00398   static int Jacobi(double **a, double *w, double **v);
00400 
00402 
00407   static int JacobiN(float **a, int n, float *w, float **v);
00408   static int JacobiN(double **a, int n, double *w, double **v);
00410 
00417   static double* SolveCubic(double c0, double c1, double c2, double c3);
00418 
00425   static double* SolveQuadratic(double c0, double c1, double c2);
00426 
00430   static double* SolveLinear(double c0, double c1);
00431 
00433 
00444   static int SolveCubic(double c0, double c1, double c2, double c3, 
00445                         double *r1, double *r2, double *r3, int *num_roots);
00447 
00449 
00453   static int SolveQuadratic(double c0, double c1, double c2, 
00454                             double *r1, double *r2, int *num_roots);
00456   
00461   static int SolveLinear(double c0, double c1, double *r1, int *num_roots);
00462 
00464 
00474   static int SolveHomogeneousLeastSquares(int numberOfSamples, double **xt, int xOrder,
00475                                 double **mt);
00477 
00478 
00480 
00491   static int SolveLeastSquares(int numberOfSamples, double **xt, int xOrder,
00492                                double **yt, int yOrder, double **mt, int checkHomogeneous=1);
00494 
00496 
00498   static void RGBToHSV(float rgb[3], float hsv[3])
00499     { 
00500     RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
00501     }
00502   static void RGBToHSV(float r, float g, float b, 
00503                        float *h, float *s, float *v);
00504   static void RGBToHSV(double rgb[3], double hsv[3])
00505     { 
00506     RGBToHSV(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
00507     }
00508   static void RGBToHSV(double r, double g, double b, 
00509                        double *h, double *s, double *v);
00511 
00513 
00515   static void HSVToRGB(float hsv[3], float rgb[3])
00516     { 
00517     HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
00518     }
00519   static void HSVToRGB(float h, float s, float v, 
00520                        float *r, float *g, float *b);
00521   static void HSVToRGB(double hsv[3], double rgb[3])
00522     { 
00523     HSVToRGB(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
00524     }
00525   static void HSVToRGB(double h, double s, double v, 
00526                        double *r, double *g, double *b);
00528 
00530 
00531   static void UninitializeBounds(double bounds[6]){
00532     bounds[0] = 1.0;
00533     bounds[1] = -1.0;
00534     bounds[2] = 1.0;
00535     bounds[3] = -1.0;
00536     bounds[4] = 1.0;
00537     bounds[5] = -1.0;
00538   }
00540   
00542 
00543   static int AreBoundsInitialized(double bounds[6]){
00544     if (bounds[1]-bounds[0]<0.0)
00545       {
00546       return 0;
00547       }
00548     return 1;
00549   }
00551 
00553 
00555   static void ClampValue(double *value, const double range[2]);
00556   static void ClampValue(double value, const double range[2], double *clamped_value);
00557   static void ClampValues(
00558     double *values, int nb_values, const double range[2]);
00559   static void ClampValues(
00560     const double *values, int nb_values, const double range[2], double *clamped_values);
00562 
00563 protected:
00564   vtkMath() {};
00565   ~vtkMath() {};
00566   
00567   static long Seed;
00568 private:
00569   vtkMath(const vtkMath&);  // Not implemented.
00570   void operator=(const vtkMath&);  // Not implemented.
00571 };
00572 
00573 //----------------------------------------------------------------------------
00574 inline int vtkMath::Floor(double x)
00575 {
00576 #if defined i386 || defined _M_IX86
00577   double tempval;
00578   // use 52-bit precision of IEEE double to round (x - 0.25) to 
00579   // the nearest multiple of 0.5, according to prevailing rounding
00580   // mode which is IEEE round-to-nearest,even
00581   tempval = (x - 0.25) + 3377699720527872.0; // (2**51)*1.5
00582   // extract mantissa, use shift to divide by 2 and hence get rid
00583   // of the bit that gets messed up because the FPU uses
00584   // round-to-nearest,even mode instead of round-to-nearest,+infinity
00585   return ((int*)&tempval)[0] >> 1;
00586 #else
00587   return (int)floor(x);
00588 #endif
00589 }
00590 
00591 //----------------------------------------------------------------------------
00592 inline float vtkMath::Normalize(float x[3])
00593 {
00594   float den; 
00595   if ( (den = vtkMath::Norm(x)) != 0.0 )
00596     {
00597     for (int i=0; i < 3; i++)
00598       {
00599       x[i] /= den;
00600       }
00601     }
00602   return den;
00603 }
00604 
00605 //----------------------------------------------------------------------------
00606 inline double vtkMath::Normalize(double x[3])
00607 {
00608   double den; 
00609   if ( (den = vtkMath::Norm(x)) != 0.0 )
00610     {
00611     for (int i=0; i < 3; i++)
00612       {
00613       x[i] /= den;
00614       }
00615     }
00616   return den;
00617 }
00618 
00619 //----------------------------------------------------------------------------
00620 inline float vtkMath::Normalize2D(float x[3])
00621 {
00622   float den; 
00623   if ( (den = vtkMath::Norm2D(x)) != 0.0 )
00624     {
00625     for (int i=0; i < 2; i++)
00626       {
00627       x[i] /= den;
00628       }
00629     }
00630   return den;
00631 }
00632 
00633 //----------------------------------------------------------------------------
00634 inline double vtkMath::Normalize2D(double x[3])
00635 {
00636   double den; 
00637   if ( (den = vtkMath::Norm2D(x)) != 0.0 )
00638     {
00639     for (int i=0; i < 2; i++)
00640       {
00641       x[i] /= den;
00642       }
00643     }
00644   return den;
00645 }
00646 
00647 //----------------------------------------------------------------------------
00648 inline float vtkMath::Determinant3x3(const float c1[3], 
00649                                      const float c2[3], 
00650                                      const float c3[3])
00651 {
00652   return c1[0]*c2[1]*c3[2] + c2[0]*c3[1]*c1[2] + c3[0]*c1[1]*c2[2] -
00653          c1[0]*c3[1]*c2[2] - c2[0]*c1[1]*c3[2] - c3[0]*c2[1]*c1[2];
00654 }
00655 
00656 //----------------------------------------------------------------------------
00657 inline double vtkMath::Determinant3x3(const double c1[3], 
00658                                       const double c2[3], 
00659                                       const double c3[3])
00660 {
00661   return c1[0]*c2[1]*c3[2] + c2[0]*c3[1]*c1[2] + c3[0]*c1[1]*c2[2] -
00662          c1[0]*c3[1]*c2[2] - c2[0]*c1[1]*c3[2] - c3[0]*c2[1]*c1[2];
00663 }
00664 
00665 //----------------------------------------------------------------------------
00666 inline double vtkMath::Determinant3x3(double a1, double a2, double a3, 
00667                                       double b1, double b2, double b3, 
00668                                       double c1, double c2, double c3)
00669 {
00670     return ( a1 * vtkMath::Determinant2x2( b2, b3, c2, c3 )
00671            - b1 * vtkMath::Determinant2x2( a2, a3, c2, c3 )
00672            + c1 * vtkMath::Determinant2x2( a2, a3, b2, b3 ) );
00673 }
00674 
00675 //----------------------------------------------------------------------------
00676 inline float vtkMath::Distance2BetweenPoints(const float x[3], 
00677                                              const float y[3])
00678 {
00679   return ((x[0]-y[0])*(x[0]-y[0]) + (x[1]-y[1])*(x[1]-y[1]) +
00680           (x[2]-y[2])*(x[2]-y[2]));
00681 }
00682 
00683 //----------------------------------------------------------------------------
00684 inline double vtkMath::Distance2BetweenPoints(const double x[3], 
00685                                               const double y[3])
00686 {
00687   return ((x[0]-y[0])*(x[0]-y[0]) + (x[1]-y[1])*(x[1]-y[1]) +
00688           (x[2]-y[2])*(x[2]-y[2]));
00689 }
00690 
00691 //----------------------------------------------------------------------------
00692 inline double vtkMath::Random(double min, double max)
00693 {
00694   return (min + vtkMath::Random()*(max-min));
00695 }
00696 
00697 //----------------------------------------------------------------------------
00698 // Cross product of two 3-vectors. Result vector in z[3].
00699 inline void vtkMath::Cross(const float x[3], const float y[3], float z[3])
00700 {
00701   float Zx = x[1]*y[2] - x[2]*y[1]; 
00702   float Zy = x[2]*y[0] - x[0]*y[2];
00703   float Zz = x[0]*y[1] - x[1]*y[0];
00704   z[0] = Zx; z[1] = Zy; z[2] = Zz; 
00705 }
00706 
00707 //----------------------------------------------------------------------------
00708 // Cross product of two 3-vectors. Result vector in z[3].
00709 inline void vtkMath::Cross(const double x[3], const double y[3], double z[3])
00710 {
00711   double Zx = x[1]*y[2] - x[2]*y[1]; 
00712   double Zy = x[2]*y[0] - x[0]*y[2];
00713   double Zz = x[0]*y[1] - x[1]*y[0];
00714   z[0] = Zx; z[1] = Zy; z[2] = Zz; 
00715 }
00716 
00717 //BTX
00718 //----------------------------------------------------------------------------
00719 template<class T>
00720 inline double vtkDeterminant3x3(T A[3][3])
00721 {
00722   return A[0][0]*A[1][1]*A[2][2] + A[1][0]*A[2][1]*A[0][2] + 
00723          A[2][0]*A[0][1]*A[1][2] - A[0][0]*A[2][1]*A[1][2] - 
00724          A[1][0]*A[0][1]*A[2][2] - A[2][0]*A[1][1]*A[0][2];
00725 }
00726 //ETX
00727 
00728 //----------------------------------------------------------------------------
00729 inline double vtkMath::Determinant3x3(float A[3][3])
00730 {
00731   return vtkDeterminant3x3(A);
00732 }
00733 
00734 //----------------------------------------------------------------------------
00735 inline double vtkMath::Determinant3x3(double A[3][3])
00736 {
00737   return vtkDeterminant3x3(A);
00738 }
00739 
00740 //----------------------------------------------------------------------------
00741 inline void vtkMath::ClampValue(double *value, const double range[2])
00742 {
00743   if (value && range)
00744     {
00745     if (*value < range[0])
00746       {
00747       *value = range[0];
00748       }
00749     else if (*value > range[1])
00750       {
00751       *value = range[1];
00752       }
00753     }
00754 }
00755 
00756 //----------------------------------------------------------------------------
00757 inline void vtkMath::ClampValue(
00758   double value, const double range[2], double *clamped_value)
00759 {
00760   if (range && clamped_value)
00761     {
00762     if (value < range[0])
00763       {
00764       *clamped_value = range[0];
00765       }
00766     else if (value > range[1])
00767       {
00768       *clamped_value = range[1];
00769       }
00770     else
00771       {
00772       *clamped_value = value;
00773       }
00774     }
00775 }
00776 
00777 #endif