00001 #include "umatrix.h"
00002
00007 #include <iostream>
00008 using namespace std;
00009
00010 #include <glt/gl.h>
00011
00012 #include <math/matrix4.h>
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 UnMatrix::UnMatrix()
00035 {
00036 memset(_tran,0,sizeof(_tran));
00037 }
00038
00039 UnMatrix::UnMatrix(const UnMatrix &umatrix)
00040 {
00041 memcpy(_tran,umatrix._tran,sizeof(_tran));
00042 }
00043
00044 UnMatrix::UnMatrix(const Matrix &matrix)
00045 {
00046 UnMatrix umatrix = matrix.unmatrix();
00047 memcpy(_tran,umatrix._tran,sizeof(_tran));
00048 }
00049
00050 UnMatrix::~UnMatrix()
00051 {
00052 }
00053
00054 static char *UnMatrixFieldDescription[] =
00055 {
00056 "U_SCALEX",
00057 "U_SCALEY",
00058 "U_SCALEZ",
00059 "U_SHEARXY",
00060 "U_SHEARXZ",
00061 "U_SHEARYZ",
00062 "U_ROTATEX",
00063 "U_ROTATEY",
00064 "U_ROTATEZ",
00065 "U_TRANSX",
00066 "U_TRANSY",
00067 "U_TRANSZ",
00068 "U_PERSPX",
00069 "U_PERSPY",
00070 "U_PERSPZ",
00071 "U_PERSPW"
00072 };
00073
00079 UnMatrix
00080 operator-(const UnMatrix &b,const UnMatrix &a)
00081 {
00082 UnMatrix um;
00083
00084 um[U_SCALEX] = b._tran[U_SCALEX] - a._tran[U_SCALEX];
00085 um[U_SCALEY] = b._tran[U_SCALEY] - a._tran[U_SCALEY];
00086 um[U_SCALEZ] = b._tran[U_SCALEZ] - a._tran[U_SCALEZ];
00087
00088 um[U_ROTATEX] = b._tran[U_ROTATEX] - a._tran[U_ROTATEX];
00089 um[U_ROTATEY] = b._tran[U_ROTATEY] - a._tran[U_ROTATEY];
00090 um[U_ROTATEZ] = b._tran[U_ROTATEZ] - a._tran[U_ROTATEZ];
00091
00092 um[U_TRANSX] = b._tran[U_TRANSX] - a._tran[U_TRANSX];
00093 um[U_TRANSY] = b._tran[U_TRANSY] - a._tran[U_TRANSY];
00094 um[U_TRANSZ] = b._tran[U_TRANSZ] - a._tran[U_TRANSZ];
00095
00096 return um;
00097 }
00098
00104 UnMatrix
00105 operator*(const UnMatrix &a,const double scaleFactor)
00106 {
00107 UnMatrix um = a;
00108
00109 um[U_SCALEX] *= scaleFactor;
00110 um[U_SCALEY] *= scaleFactor;
00111 um[U_SCALEZ] *= scaleFactor;
00112
00113 um[U_ROTATEX] *= scaleFactor;
00114 um[U_ROTATEY] *= scaleFactor;
00115 um[U_ROTATEZ] *= scaleFactor;
00116
00117 um[U_TRANSX] *= scaleFactor;
00118 um[U_TRANSY] *= scaleFactor;
00119 um[U_TRANSZ] *= scaleFactor;
00120
00121 return um;
00122 }
00123
00129 UnMatrix
00130 operator+(const UnMatrix &a,const UnMatrix &b)
00131 {
00132 UnMatrix um;
00133
00134 um[U_SCALEX] = b._tran[U_SCALEX] + a._tran[U_SCALEX];
00135 um[U_SCALEY] = b._tran[U_SCALEY] + a._tran[U_SCALEY];
00136 um[U_SCALEZ] = b._tran[U_SCALEZ] + a._tran[U_SCALEZ];
00137
00138 um[U_ROTATEX] = b._tran[U_ROTATEX] + a._tran[U_ROTATEX];
00139 um[U_ROTATEY] = b._tran[U_ROTATEY] + a._tran[U_ROTATEY];
00140 um[U_ROTATEZ] = b._tran[U_ROTATEZ] + a._tran[U_ROTATEZ];
00141
00142 um[U_TRANSX] = b._tran[U_TRANSX] + a._tran[U_TRANSX];
00143 um[U_TRANSY] = b._tran[U_TRANSY] + a._tran[U_TRANSY];
00144 um[U_TRANSZ] = b._tran[U_TRANSZ] + a._tran[U_TRANSZ];
00145
00146 return um;
00147 }
00148
00149
00155 std::ostream &
00156 operator<<(std::ostream &os,const UnMatrixField &field)
00157 {
00158 if (field>=U_SCALEX && field<=U_PERSPW)
00159 os << UnMatrixFieldDescription[field];
00160 else
00161 os << "Unknown";
00162
00163 return os;
00164 }
00165
00171 istream &
00172 operator>>(istream &is,UnMatrixField &field)
00173 {
00174 char buffer[128];
00175
00176 is >> buffer;
00177
00178 for (int f=0;f<16;f++)
00179 if (!strcmp(buffer,UnMatrixFieldDescription[f]))
00180 {
00181 field = (UnMatrixField) f;
00182 break;
00183 }
00184
00185 return is;
00186 }
00187
00193 std::ostream &
00194 operator<<(std::ostream &os,const UnMatrix &unMatrix)
00195 {
00196 for (int f=0;f<16;f++)
00197 os << (UnMatrixField) f << ' ' << unMatrix._tran[f] << endl;
00198
00199 return os;
00200 }
00201
00207 istream &
00208 operator>>(istream &is,UnMatrix &unMatrix)
00209 {
00210 for (int f=0;f<16;f++)
00211 {
00212 UnMatrixField field;
00213 double value;
00214
00215 is >> field;
00216 is >> value;
00217
00218 if (!is.eof()) unMatrix[field] = value;
00219 }
00220
00221 return is;
00222 }
00223
00224 typedef struct {
00225 double x,y,z,w;
00226 } Vector4;
00227
00228 UnMatrix
00229 Matrix::unmatrix() const
00230 {
00231 UnMatrix tran;
00232
00233 Matrix locmat = (*this);
00234
00235 if (locmat.element(3,3)==0.0)
00236 return tran;
00237
00238 register int i, j;
00239
00240 for ( i=0; i<4;i++ )
00241 for ( j=0; j<4; j++ )
00242 locmat.element(i,j) /= locmat.element(3,3);
00243
00244
00245
00246
00247
00248 Matrix pmat = locmat;
00249
00250 for ( i=0; i<3; i++ )
00251 pmat.set(i,3,0.0);
00252
00253 pmat.set(3,3,1.0);
00254
00255 if ( pmat.det() == 0.0 )
00256 return tran;
00257
00258
00259
00260 if
00261 (
00262 locmat.element(0,3) != 0.0 ||
00263 locmat.element(1,3) != 0.0 ||
00264 locmat.element(2,3) != 0.0
00265 )
00266 {
00267 Vector4 prhs, psol;
00268
00269
00270
00271 prhs.x = locmat.element(0,3);
00272 prhs.y = locmat.element(1,3);
00273 prhs.z = locmat.element(2,3);
00274 prhs.w = locmat.element(3,3);
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 psol.x = 0.0;
00288 psol.y = 0.0;
00289 psol.z = 0.0;
00290 psol.w = 0.0;
00291
00292
00293 tran[U_PERSPX] = psol.x;
00294 tran[U_PERSPY] = psol.y;
00295 tran[U_PERSPZ] = psol.z;
00296 tran[U_PERSPW] = psol.w;
00297
00298
00299 locmat.element(0,3) = locmat.element(1,3) = locmat.element(2,3) = 0.0;
00300 locmat.element(3,3) = 1.0;
00301
00302 } else
00303 tran[U_PERSPX] = tran[U_PERSPY] = tran[U_PERSPZ] = tran[U_PERSPW] = 0;
00304
00305
00306 for ( i=0; i<3; i++ )
00307 {
00308 tran[(UnMatrixField) (U_TRANSX + i)] = locmat.element(3,i);
00309 locmat.set(3,i,0.0);
00310 }
00311
00312 Vector row[3];
00313
00314
00315 for ( i=0; i<3; i++ )
00316 {
00317 row[i][0] = locmat.get(i,0);
00318 row[i][1] = locmat.get(i,1);
00319 row[i][2] = locmat.get(i,2);
00320 }
00321
00322
00323
00324 tran[U_SCALEX] = sqrt(row[0].norm());
00325 row[0].normalize();
00326
00327
00328 tran[U_SHEARXY] = row[0] * row[1];
00329 row[1] = row[1] - row[0] * tran[U_SHEARXY];
00330
00331
00332 tran[U_SCALEY] = sqrt(row[1].norm());
00333 row[1].normalize();
00334 tran[U_SHEARXY] /= tran[U_SCALEY];
00335
00336
00337 tran[U_SHEARXZ] = row[0] * row[2];
00338 row[2] = row[2] - row[0] * tran[U_SHEARXZ];
00339
00340 tran[U_SHEARYZ] = row[1] * row[2];
00341 row[2] = row[2] - row[1] * tran[U_SHEARYZ];
00342
00343
00344 tran[U_SCALEZ] = sqrt(row[2].norm());
00345 row[2].normalize();
00346
00347 tran[U_SHEARXZ] /= tran[U_SCALEZ];
00348 tran[U_SHEARYZ] /= tran[U_SCALEZ];
00349
00350
00351
00352
00353
00354 if ( row[0] * xProduct(row[1],row[2]) < 0.0 )
00355 for ( i = 0; i < 3; i++ )
00356 {
00357 tran[(UnMatrixField) (U_SCALEX+i)] *= -1;
00358 row[i] = row[i] * -1.0;
00359 }
00360
00361
00362 tran[U_ROTATEY] = asin(-row[0][2]);
00363
00364 if ( cos(tran[U_ROTATEY]) != 0 )
00365 {
00366 tran[U_ROTATEX] = atan2(row[1][2], row[2][2]);
00367 tran[U_ROTATEZ] = atan2(row[0][1], row[0][0]);
00368 }
00369 else
00370 {
00371 tran[U_ROTATEX] = atan2(row[1][0], row[1][1]);
00372 tran[U_ROTATEZ] = 0;
00373 }
00374
00375 return tran;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 double
00387 Matrix::det() const
00388 {
00389 double ans;
00390 double a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
00391
00392
00393
00394
00395 a1 = get(0,0); b1 = get(0,1);
00396 c1 = get(0,2); d1 = get(0,3);
00397
00398 a2 = get(1,0); b2 = get(1,1);
00399 c2 = get(1,2); d2 = get(1,3);
00400
00401 a3 = get(2,0); b3 = get(2,1);
00402 c3 = get(2,2); d3 = get(2,3);
00403
00404 a4 = get(3,0); b4 = get(3,1);
00405 c4 = get(3,2); d4 = get(3,3);
00406
00407 ans = a1 * det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4)
00408 - b1 * det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4)
00409 + c1 * det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4)
00410 - d1 * det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4);
00411 return ans;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 double
00424 Matrix::det3x3
00425 (
00426 const double a1,
00427 const double a2,
00428 const double a3,
00429 const double b1,
00430 const double b2,
00431 const double b3,
00432 const double c1,
00433 const double c2,
00434 const double c3
00435 ) const
00436 {
00437 return
00438 a1 * det2x2( b2, b3, c2, c3 )
00439 - b1 * det2x2( a2, a3, c2, c3 )
00440 + c1 * det2x2( a2, a3, b2, b3 );
00441 }
00442
00443
00444
00445 double
00446 Matrix::det2x2
00447 (
00448 const double a,
00449 const double b,
00450 const double c,
00451 const double d
00452 ) const
00453 {
00454 return a * d - b * c;
00455 }
00456
00457
00458 bool
00459 UnMatrix::uniformScale(const double tol) const
00460 {
00461 if (fabs(_tran[U_SCALEX]-_tran[U_SCALEY])>tol) return false;
00462 if (fabs(_tran[U_SCALEX]-_tran[U_SCALEZ])>tol) return false;
00463 if (fabs(_tran[U_SCALEY]-_tran[U_SCALEZ])>tol) return false;
00464 return true;
00465 }
00466
00467 bool
00468 UnMatrix::noRotation(const double tol) const
00469 {
00470 if (fabs(_tran[U_ROTATEX])>tol) return false;
00471 if (fabs(_tran[U_ROTATEY])>tol) return false;
00472 if (fabs(_tran[U_ROTATEZ])>tol) return false;
00473 return true;
00474 }
00475
00476 bool
00477 UnMatrix::noShear(const double tol) const
00478 {
00479 if (fabs(_tran[U_SHEARXY])>tol) return false;
00480 if (fabs(_tran[U_SHEARXZ])>tol) return false;
00481 if (fabs(_tran[U_SHEARYZ])>tol) return false;
00482 return true;
00483 }
00484
00485 bool
00486 UnMatrix::noPerspective(const double tol) const
00487 {
00488 if (fabs(_tran[U_PERSPX])>tol) return false;
00489 if (fabs(_tran[U_PERSPY])>tol) return false;
00490 if (fabs(_tran[U_PERSPZ])>tol) return false;
00491 if (fabs(_tran[U_PERSPW])>tol) return false;
00492 return true;
00493 }
00494