Matrix4 Class Reference

4x4 matrix class with numerous operators, conversions, etc. More...

#include <Matrix4.h>

List of all members.

Public Member Functions

 Matrix4 (void)
 identity constructor
 Matrix4 (double f)
 const elements constructor
 Matrix4 (const double *m)
 construct from double array
 Matrix4 (const Matrix4 &m)
 copy constructor
 ~Matrix4 (void)
 destructor
void multpoint3d (const double[3], double[3]) const
 multiplies a 3D point (first arg) by the Matrix, returns in second arg
void multnorm3d (const double[3], double[3]) const
 multiplies a 3D norm (first arg) by the Matrix, returns in second arg
void multpoint4d (const double[4], double[4]) const
 multiplies a 4D point (first arg) by the Matrix, returns in second arg
void identity (void)
 clears the matrix (resets it to identity)
void constant (double)
 sets the matrix so all items are the given constant value
int inverse (void)
void transpose (void)
 transposes the matrix
void loadmatrix (const Matrix4 &m)
 replaces this matrix with the given one
Matrix4operator= (const Matrix4 &m)
void multmatrix (const Matrix4 &)
 premultiply the matrix by the given matrix, this->other * this
void rot (double, char)
 performs a left-handed rotation around an axis (char == 'x', 'y', or 'z')
void rotate_axis (const double axis[3], double angle)
 apply a rotation around the given vector; angle in radians.
void transvec (double x, double y, double z)
 apply a rotation such that 'x' is brought along the given vector.
void transvecinv (double x, double y, double z)
 apply a rotation such that the given vector is brought along 'x'.
void translate (double, double, double)
 performs a translation
void translate (double d[3])
void scale (double, double, double)
 performs scaling
void scale (double f)
void window (double, double, double, double, double, double)
 sets this matrix to represent a window perspective
void ortho (double, double, double, double, double, double)
 sets this matrix to a 3D orthographic matrix
void ortho2 (double, double, double, double)
 sets this matrix to a 2D orthographic matrix
void lookat (double, double, double, double, double, double, short)

Public Attributes

double mat [16]
 the matrix itself


Detailed Description

4x4 matrix class with numerous operators, conversions, etc.

Definition at line 26 of file Matrix4.h.


Constructor & Destructor Documentation

Matrix4::Matrix4 ( void   )  [inline]

identity constructor

Definition at line 28 of file Matrix4.h.

References identity().

Matrix4::Matrix4 ( double  f  )  [inline]

const elements constructor

Definition at line 29 of file Matrix4.h.

References constant().

Matrix4::Matrix4 ( const double *  m  ) 

construct from double array

Definition at line 36 of file Matrix4.C.

References mat.

00036                                 {
00037   memcpy((void *)mat, (const void *)m, 16*sizeof(double));
00038 }

Matrix4::Matrix4 ( const Matrix4 m  )  [inline]

copy constructor

Definition at line 31 of file Matrix4.h.

References loadmatrix().

Matrix4::~Matrix4 ( void   )  [inline]

destructor

Definition at line 32 of file Matrix4.h.


Member Function Documentation

void Matrix4::constant ( double   ) 

sets the matrix so all items are the given constant value

Definition at line 102 of file Matrix4.C.

References mat.

Referenced by lookat(), Matrix4(), ortho(), ortho2(), and window().

00102                                {
00103   for (int i=0; i<16; mat[i++] = f); 
00104 }

void Matrix4::identity ( void   ) 

clears the matrix (resets it to identity)

Definition at line 92 of file Matrix4.C.

References mat.

Referenced by Matrix4().

00092                            {
00093   memset((void *)mat, 0, 16*sizeof(double));
00094   mat[0]=1.0;
00095   mat[5]=1.0;
00096   mat[10]=1.0;
00097   mat[15]=1.0;
00098 }

int Matrix4::inverse ( void   ) 

inverts the matrix, that is, the inverse of the rotation, the inverse of the scaling, and the opposite of the translation vector. returns 0 if there were no problems, -1 if the matrix is singular

Definition at line 110 of file Matrix4.C.

References j, mat, and MATSWAP.

00110                          {
00111 
00112   double matr[4][4], ident[4][4];
00113   int i, j, k, l, ll;
00114   int icol=0, irow=0;
00115   int indxc[4], indxr[4], ipiv[4];
00116   double big, dum, pivinv, temp;
00117  
00118   for (i=0; i<4; i++) {
00119     for (j=0; j<4; j++) {
00120       matr[i][j] = mat[4*i+j];
00121       ident[i][j] = 0.0;
00122     }
00123     ident[i][i]=1.0;
00124   } 
00125   // Gauss-jordan elimination with full pivoting.  Yes, folks, a 
00126   // GL Matrix4 is inverted like any other, since the identity is 
00127   // still the identity.
00128   
00129   // from numerical recipies in C second edition, pg 39
00130 
00131   for(j=0;j<=3;j++) ipiv[j] = 0;
00132   for(i=0;i<=3;i++) {
00133     big=0.0;
00134     for (j=0;j<=3;j++) {
00135       if(ipiv[j] != 1) {
00136         for (k=0;k<=3;k++) {
00137           if(ipiv[k] == 0) {
00138             if(fabs(matr[j][k]) >= big) {
00139               big = (double) fabs(matr[j][k]);
00140               irow=j;
00141               icol=k;
00142             }
00143           } else if (ipiv[k] > 1) return 1;
00144         } 
00145       }
00146     }
00147     ++(ipiv[icol]);
00148     if (irow != icol) {
00149       for (l=0;l<=3;l++) MATSWAP(matr[irow][l],matr[icol][l]);
00150       for (l=0;l<=3;l++) MATSWAP(ident[irow][l],ident[icol][l]);
00151     }
00152     indxr[i]=irow;
00153     indxc[i]=icol;
00154     if(matr[icol][icol] == 0.0) return 1; 
00155     pivinv = 1.0 / matr[icol][icol];
00156     matr[icol][icol]=1.0;
00157     for (l=0;l<=3;l++) matr[icol][l] *= pivinv;
00158     for (l=0;l<=3;l++) ident[icol][l] *= pivinv;
00159     for (ll=0;ll<=3;ll++) {
00160       if (ll != icol) {
00161         dum=matr[ll][icol];
00162         matr[ll][icol]=0.0;
00163         for (l=0;l<=3;l++) matr[ll][l] -= matr[icol][l]*dum;
00164         for (l=0;l<=3;l++) ident[ll][l] -= ident[icol][l]*dum;
00165       }
00166     }
00167   }
00168   for (l=3;l>=0;l--) {
00169     if (indxr[l] != indxc[l]) {
00170       for (k=0;k<=3;k++) {
00171         MATSWAP(matr[k][indxr[l]],matr[k][indxc[l]]);
00172       }
00173     }
00174   }
00175   for (i=0; i<4; i++) 
00176     for (j=0; j<4; j++)
00177       mat[4*i+j] = matr[i][j];
00178   return 0;
00179 }

void Matrix4::loadmatrix ( const Matrix4 m  ) 

replaces this matrix with the given one

Definition at line 194 of file Matrix4.C.

References mat.

Referenced by Matrix4(), and operator=().

00194                                          {
00195   memcpy((void *)mat, (const void *)m.mat, 16*sizeof(double));
00196 }

void Matrix4::lookat ( double  ,
double  ,
double  ,
double  ,
double  ,
double  ,
short   
)

This subroutine defines a viewing transformation with the eye at point (vx,vy,vz) looking at the point (px,py,pz). Twist is the right-hand rotation about this line. The resultant matrix is multiplied with the top of the transformation stack and then replaces it. Precisely, lookat does: lookat=trans(-vx,-vy,-vz)*rotate(theta,y)*rotate(phi,x)*rotate(-twist,z)

Definition at line 336 of file Matrix4.C.

References constant(), mat, multmatrix(), rot(), and translate().

00337                                                  {
00338   Matrix4 m(0.0);
00339   double tmp;
00340 
00341   /* pre multiply stack by rotate(-twist,z) */
00342   rot(-twist / 10.0,'z');
00343 
00344   tmp = sqrtf((px-vx)*(px-vx) + (py-vy)*(py-vy) + (pz-vz)*(pz-vz));
00345   m.mat[0] = 1.0;
00346   m.mat[5] = sqrtf((px-vx)*(px-vx) + (pz-vz)*(pz-vz)) / tmp;
00347   m.mat[6] = (vy-py) / tmp;
00348   m.mat[9] = -m.mat[6];
00349   m.mat[10] = m.mat[5];
00350   m.mat[15] = 1.0;
00351   multmatrix(m);
00352 
00353   /* premultiply by rotate(theta,y) */
00354   m.constant(0.0);
00355   tmp = sqrtf((px-vx)*(px-vx) + (pz-vz)*(pz-vz));
00356   m.mat[0] = (vz-pz) / tmp;
00357   m.mat[5] = 1.0;
00358   m.mat[10] = m.mat[0];
00359   m.mat[15] = 1.0;
00360   m.mat[2] = -(px-vx) / tmp;
00361   m.mat[8] = -m.mat[2];
00362   multmatrix(m);
00363 
00364   /* premultiply by trans(-vx,-vy,-vz) */
00365   translate(-vx,-vy,-vz);
00366 }

void Matrix4::multmatrix ( const Matrix4  ) 

premultiply the matrix by the given matrix, this->other * this

Definition at line 199 of file Matrix4.C.

References j, and mat.

Referenced by lookat(), rot(), scale(), and translate().

00199                                          {
00200   double tmp[4];
00201   for (int j=0; j<4; j++) {
00202     tmp[0] = mat[j];
00203     tmp[1] = mat[4+j];
00204     tmp[2] = mat[8+j]; 
00205     tmp[3] = mat[12+j];
00206     for (int i=0; i<4; i++) {
00207       mat[4*i+j] = m.mat[4*i]*tmp[0] + m.mat[4*i+1]*tmp[1] +
00208         m.mat[4*i+2]*tmp[2] + m.mat[4*i+3]*tmp[3]; 
00209     }
00210   } 
00211 }

void Matrix4::multnorm3d ( const   double[3],
double  [3] 
) const

multiplies a 3D norm (first arg) by the Matrix, returns in second arg

Definition at line 68 of file Matrix4.C.

References mat.

00068                                                                      {
00069   double tmp[4];
00070 
00071   tmp[0]=onorm[0]*mat[0] + onorm[1]*mat[4] + onorm[2]*mat[8];
00072   tmp[1]=onorm[0]*mat[1] + onorm[1]*mat[5] + onorm[2]*mat[9];
00073   tmp[2]=onorm[0]*mat[2] + onorm[1]*mat[6] + onorm[2]*mat[10];
00074   tmp[3]=onorm[0]*mat[3] + onorm[1]*mat[7] + onorm[2]*mat[11];
00075   double itmp = 1.0 / sqrtf(tmp[0]*tmp[0] + tmp[1]*tmp[1] + tmp[2]*tmp[2]);
00076   nnorm[0]=tmp[0]*itmp;
00077   nnorm[1]=tmp[1]*itmp;
00078   nnorm[2]=tmp[2]*itmp;
00079 }

void Matrix4::multpoint3d ( const   double[3],
double  [3] 
) const

multiplies a 3D point (first arg) by the Matrix, returns in second arg

Definition at line 41 of file Matrix4.C.

References mat.

00041                                                                         {
00042 #if 0
00043     // should try re-testing this formulation to see if it outperforms
00044     // the old one, without introducing doubleing point imprecision
00045     double tmp[3];
00046     double itmp3 = 1.0 / (opoint[0]*mat[3] + opoint[1]*mat[7] + 
00047                           opoint[2]*mat[11] + mat[15]);
00048     npoint[0]=itmp3 * (opoint[0]*mat[0] + opoint[1]*mat[4] + opoint[2]*mat[ 8] + mat[12]);
00049     npoint[1]=itmp3 * (opoint[0]*mat[1] + opoint[1]*mat[5] + opoint[2]*mat[ 9] + mat[13]);
00050     npoint[2]=itmp3 * (opoint[0]*mat[2] + opoint[1]*mat[6] + opoint[2]*mat[10] + mat[14]);
00051 #else
00052     double tmp[3];
00053     double itmp3 = 1.0 / (opoint[0]*mat[3] + opoint[1]*mat[7] +
00054                           opoint[2]*mat[11] + mat[15]);
00055     tmp[0] = itmp3*opoint[0];
00056     tmp[1] = itmp3*opoint[1];
00057     tmp[2] = itmp3*opoint[2];
00058     npoint[0]=tmp[0]*mat[0] + tmp[1]*mat[4] + tmp[2]*mat[ 8] + itmp3*mat[12];
00059     npoint[1]=tmp[0]*mat[1] + tmp[1]*mat[5] + tmp[2]*mat[ 9] + itmp3*mat[13];
00060     npoint[2]=tmp[0]*mat[2] + tmp[1]*mat[6] + tmp[2]*mat[10] + itmp3*mat[14];
00061 #endif
00062 }

void Matrix4::multpoint4d ( const   double[4],
double  [4] 
) const

multiplies a 4D point (first arg) by the Matrix, returns in second arg

Definition at line 83 of file Matrix4.C.

References mat.

00083                                                                         {
00084   npoint[0]=opoint[0]*mat[0]+opoint[1]*mat[4]+opoint[2]*mat[8]+opoint[3]*mat[12];
00085   npoint[1]=opoint[0]*mat[1]+opoint[1]*mat[5]+opoint[2]*mat[9]+opoint[3]*mat[13];
00086   npoint[2]=opoint[0]*mat[2]+opoint[1]*mat[6]+opoint[2]*mat[10]+opoint[3]*mat[14];
00087   npoint[3]=opoint[0]*mat[3]+opoint[1]*mat[7]+opoint[2]*mat[11]+opoint[3]*mat[15];
00088 }

Matrix4& Matrix4::operator= ( const Matrix4 m  )  [inline]

Definition at line 61 of file Matrix4.h.

References loadmatrix().

00061 {loadmatrix(m); return *this;}

void Matrix4::ortho ( double  ,
double  ,
double  ,
double  ,
double  ,
double   
)

sets this matrix to a 3D orthographic matrix

Definition at line 303 of file Matrix4.C.

References constant(), and mat.

00304                                                                    {
00305 
00306   constant(0.0);                // initialize this matrix to 0
00307   mat[0] =  2.0 / (right-left);
00308   mat[5] =  2.0 / (top-bottom);
00309   mat[10] = -2.0 / (farval-nearval);
00310   mat[12] = -(right+left) / (right-left);
00311   mat[13] = -(top+bottom) / (top-bottom);
00312   mat[14] = -(farval+nearval) / (farval-nearval);
00313   mat[15] = 1.0;
00314 }

void Matrix4::ortho2 ( double  ,
double  ,
double  ,
double   
)

sets this matrix to a 2D orthographic matrix

Definition at line 318 of file Matrix4.C.

References constant(), and mat.

00318                                                                          {
00319 
00320   constant(0.0);                // initialize this matrix to 0
00321   mat[0] =  2.0 / (right-left);
00322   mat[5] =  2.0 / (top-bottom);
00323   mat[10] = -1.0;
00324   mat[12] = -(right+left) / (right-left);
00325   mat[13] = -(top+bottom) / (top-bottom);
00326   mat[15] =  1.0;
00327 }

void Matrix4::rot ( double  ,
char   
)

performs a left-handed rotation around an axis (char == 'x', 'y', or 'z')

Definition at line 215 of file Matrix4.C.

References DEGTORAD, mat, and multmatrix().

Referenced by lookat(), rotate_axis(), transvec(), and transvecinv().

00215                                      {
00216   Matrix4 m;                    // create identity matrix
00217   double angle;
00218 
00219   angle = (double)DEGTORAD(a);
00220 
00221   if (axis == 'x') {
00222     m.mat[0]=1.0;
00223     m.mat[5]=(double)cos(angle);
00224     m.mat[10]=m.mat[5];
00225     m.mat[6] = (double)sin(angle);
00226     m.mat[9] = -m.mat[6];
00227   } else if (axis == 'y') {
00228     m.mat[0] = (double)cos(angle);
00229     m.mat[5] = 1.0;
00230     m.mat[10] = m.mat[0];
00231     m.mat[2] = (double) -sin(angle);
00232     m.mat[8] = -m.mat[2];
00233   } else if (axis == 'z') {
00234     m.mat[0] = (double)cos(angle);
00235     m.mat[5] = m.mat[0];
00236     m.mat[10] = 1.0;
00237     m.mat[1] = (double)sin(angle);
00238     m.mat[4] = -m.mat[1];
00239   }
00240   // If there was an error, m is identity so we can multiply anyway.
00241   multmatrix(m);
00242 }

void Matrix4::rotate_axis ( const double  axis[3],
double  angle 
)

apply a rotation around the given vector; angle in radians.

Definition at line 245 of file Matrix4.C.

References RADTODEG, rot(), transvec(), and transvecinv().

Referenced by obj_transabout().

00245                                                             {
00246   transvec(axis[0], axis[1], axis[2]);
00247   rot((double) (RADTODEG(angle)), 'x');
00248   transvecinv(axis[0], axis[1], axis[2]);
00249 }

void Matrix4::scale ( double  f  )  [inline]

Definition at line 84 of file Matrix4.h.

References scale().

00084 { scale(f, f, f); }

void Matrix4::scale ( double  ,
double  ,
double   
)

performs scaling

Definition at line 279 of file Matrix4.C.

References mat, and multmatrix().

Referenced by scale().

00279                                                 {
00280   Matrix4 m;            // create identity matrix
00281   m.mat[0] = x;
00282   m.mat[5] = y;
00283   m.mat[10] = z;
00284   multmatrix(m);
00285 }

void Matrix4::translate ( double  d[3]  )  [inline]

Definition at line 80 of file Matrix4.h.

References translate().

00080 { translate(d[0], d[1], d[2]); }

void Matrix4::translate ( double  ,
double  ,
double   
)

performs a translation

Definition at line 270 of file Matrix4.C.

References mat, and multmatrix().

Referenced by lookat(), and translate().

00270                                                     {
00271   Matrix4 m;            // create identity matrix
00272   m.mat[12] = x;
00273   m.mat[13] = y;
00274   m.mat[14] = z;
00275   multmatrix(m);
00276 }

void Matrix4::transpose ( void   ) 

transposes the matrix

Definition at line 181 of file Matrix4.C.

References j, and mat.

00181                         {
00182   double tmp[16];
00183   int i,j;
00184   for(i=0;i<4;i++) {
00185     for(j=0;j<4;j++) {
00186       tmp[4*i+j] = mat[i+4*j];
00187     }
00188   }
00189   for(i=0;i<16;i++)
00190     mat[i] = tmp[i];
00191 }

void Matrix4::transvec ( double  x,
double  y,
double  z 
)

apply a rotation such that 'x' is brought along the given vector.

Definition at line 252 of file Matrix4.C.

References RADTODEG, and rot().

Referenced by obj_transvec(), and rotate_axis().

00252                                                    {
00253   double theta = atan2(y,x);
00254   double length = sqrt(y*y + x*x);
00255   double phi = atan2((double) z, length);
00256   rot((double) RADTODEG(theta), 'z');
00257   rot((double) RADTODEG(-phi), 'y');
00258 }

void Matrix4::transvecinv ( double  x,
double  y,
double  z 
)

apply a rotation such that the given vector is brought along 'x'.

Definition at line 261 of file Matrix4.C.

References RADTODEG, and rot().

Referenced by obj_transvecinv(), and rotate_axis().

00261                                                       {
00262   double theta = atan2(y,x);
00263   double length = sqrt(y*y + x*x);
00264   double phi = atan2((double) z, length);
00265   rot((double) RADTODEG(phi), 'y');
00266   rot((double) RADTODEG(-theta), 'z');
00267 }

void Matrix4::window ( double  ,
double  ,
double  ,
double  ,
double  ,
double   
)

sets this matrix to represent a window perspective

Definition at line 288 of file Matrix4.C.

References constant(), and mat.

00289                                                                     {
00290 
00291   constant(0.0);                // initialize this matrix to 0
00292   mat[0] = (2.0*nearval) / (right-left);
00293   mat[5] = (2.0*nearval) / (top-bottom);
00294   mat[8] = (right+left) / (right-left);
00295   mat[9] = (top+bottom) / (top-bottom);
00296   mat[10] = -(farval+nearval) / (farval-nearval);
00297   mat[11] = -1.0;
00298   mat[14] = -(2.0*farval*nearval) / (farval-nearval);
00299 }


Member Data Documentation

double Matrix4::mat[16]

the matrix itself

Definition at line 33 of file Matrix4.h.

Referenced by constant(), identity(), inverse(), loadmatrix(), lookat(), Matrix4(), multmatrix(), multnorm3d(), multpoint3d(), multpoint4d(), obj_transabout(), obj_transvec(), obj_transvecinv(), ortho(), ortho2(), print_Matrix4(), rot(), scale(), trans_from_rotate(), translate(), transpose(), and window().


The documentation for this class was generated from the following files:
Generated on Sat Sep 23 01:17:20 2017 for NAMD by  doxygen 1.4.7