00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __OPENKN_MATH__MATRIX4X4_HPP__
00027 #define __OPENKN_MATH__MATRIX4X4_HPP__
00028
00029
00030
00031
00032 #include "Matrix.hpp"
00033 #include "Vector4.hpp"
00034
00035 namespace kn {
00036
00037 template<class T>
00038 class Matrix4x4 : public Matrix<T> {
00039
00040 protected:
00041
00042 public:
00043
00048 Matrix4x4(void)
00049 : Matrix<T>(4) {
00050 setIdentity();
00051 }
00052
00058 Matrix4x4(const Matrix4x4<T>& m)
00059 : Matrix<T>(4) {
00060 std::copy(m.begin_, m.end_, this->begin_);
00061 }
00062
00069 Matrix4x4(const Matrix<T>& m);
00070
00077 Matrix4x4(const Matrix4x4<T>* m);
00078
00084 Matrix4x4(const T& d)
00085 : Matrix<T>(4) {
00086 std::fill(this->begin_, this->end_, d);
00087 }
00088
00095 Matrix4x4(const T* d);
00096
00105 Matrix4x4(const Vector<T>& v,
00106 const bool& setasrows = true);
00107
00116 Matrix4x4(const Vector4<T>* v,
00117 const bool& setasrows = true);
00118
00122 ~Matrix4x4(void) {
00123 }
00124
00125 public:
00126
00127
00128 using Matrix<T>::operator*;
00129
00136 Vector4<T> operator*(const Vector4<T>& v) const;
00137
00142 inline size_t rows(void) const {
00143 return 4;
00144 }
00145
00150 inline size_t columns(void) const {
00151 return 4;
00152 }
00153
00158 Matrix4x4<T>& transpose(void);
00159
00163 void setIdentity(void);
00164
00169 inline bool isSquare(void) const {
00170 return true;
00171 }
00172
00179 Matrix4x4<T>& operator=(const Matrix4x4<T>& m);
00180
00187 Matrix4x4<T> operator+(const Matrix4x4<T>& m) const;
00188
00195 Matrix4x4<T> operator-(const Matrix4x4<T>& m) const;
00196
00203 Matrix4x4<T> operator/(const T& d) const;
00204
00211 Matrix4x4<T> operator*(const Matrix4x4<T>& m) const;
00212
00218 Matrix4x4<T> operator*(const T& d) const;
00219
00224 Matrix4x4<T> operator-(void) const;
00225
00232 Matrix4x4<T>& operator+=(const Matrix4x4<T>& m);
00233
00240 Matrix4x4<T>& operator-=(const Matrix4x4<T>& m);
00241
00249 Matrix4x4<T>& operator/=(const T& d);
00250
00257 Matrix4x4<T>& operator*=(const Matrix4x4<T>& m);
00258
00264 Matrix4x4<T>& operator*=(const T& d);
00265
00272 Vector4<T> getRow(const unsigned int& row) const;
00273
00280 Vector4<T> getColumn(const unsigned int& column) const;
00281
00286 Vector4<T> getDiagonal(void) const;
00287
00293 inline Matrix4x4<T> getTranspose(void) const
00294 {
00295 return Matrix4x4<T>(*this).transpose();
00296 }
00297
00303 Matrix4x4<T>& power(const unsigned int& p);
00304
00312 T trace(void) const;
00313
00314 };
00315
00316
00317 template<class T>
00318 Matrix4x4<T>::Matrix4x4(const Matrix4x4<T>* m)
00319 : Matrix<T>(4)
00320 {
00321 if(m==0)
00322 throw MathException("Pointer is null");
00323 std::copy(m->begin_, m->end_, this->begin_);
00324 }
00325
00326
00327
00328 template<class T>
00329 Matrix4x4<T>::Matrix4x4(const T* a)
00330 : Matrix<T>(4)
00331 {
00332 if(a==0)
00333 throw MathException("Pointer is null");
00334 std::copy(a, a + 16, this->begin_);
00335 }
00336
00337
00338 template<class T>
00339 Matrix4x4<T>::Matrix4x4(const Vector<T>& v,
00340 const bool& setasrows)
00341 : Matrix<T>(4)
00342 {
00343 if(v.size()!=16)
00344 throw MathException("Vector size is different from Matrix size");
00345
00346 if(setasrows)
00347 for(unsigned int i = 0; i < 16; ++i)
00348 (this->data)[i] = v[i];
00349 else
00350 for(unsigned int j = 0; j < 4; ++j)
00351 for(unsigned int i = 0; i < 4; ++i)
00352 (this->accessor)[i][j] = v[j*4+i];
00353 }
00354
00355
00356 template<class T>
00357 Matrix4x4<T>::Matrix4x4(const Vector4<T>* v,
00358 const bool& setasrows)
00359 : Matrix<T>(4)
00360 {
00361
00362 if(v==0)
00363 throw MathException("Pointer is null");
00364
00365 if(setasrows)
00366 for(unsigned int i = 0; i < 4; ++i)
00367 for(unsigned int j = 0; j < 4; ++j)
00368 (this->accessor)[i][j] = v[i][j];
00369 else
00370 for(unsigned int j = 0; j < 4; ++j)
00371 for(unsigned int i = 0; i < 4; ++i)
00372 (this->accessor)[i][j] = v[j][i];
00373
00374 }
00375
00376
00377 template<class T>
00378 Matrix4x4<T>::Matrix4x4(const Matrix<T>& m)
00379 : Matrix<T>(4) {
00380 if ((m.rows() != 4) || (m.columns() != 4))
00381 throw MathException("Matrix4x4 Constructor","Matrix sizes are different");
00382 std::copy(m.getMatrixArray(), m.getMatrixArray()+m.rows()*m.columns(), this->begin_);
00383 }
00384
00385
00386 template<class T>
00387 Vector4<T> Matrix4x4<T>::operator*(const Vector4<T>& v) const {
00388
00389 Vector<T> vtmp(4);
00390 vtmp[0] = v[0]*(this->accessor)[0][0] + v[1]*(this->accessor)[0][1] + v[2]*(this->accessor)[0][2] + v[3]*(this->accessor)[0][3];
00391 vtmp[1] = v[0]*(this->accessor)[1][0] + v[1]*(this->accessor)[1][1] + v[2]*(this->accessor)[1][2] + v[3]*(this->accessor)[1][3];
00392 vtmp[2] = v[0]*(this->accessor)[2][0] + v[1]*(this->accessor)[2][1] + v[2]*(this->accessor)[2][2] + v[3]*(this->accessor)[2][3];
00393 vtmp[3] = v[0]*(this->accessor)[3][0] + v[1]*(this->accessor)[3][1] + v[2]*(this->accessor)[3][2] + v[3]*(this->accessor)[3][3];
00394 return vtmp;
00395 }
00396
00397
00398
00399 template<class T>
00400 Matrix4x4<T>& Matrix4x4<T>::transpose(void) {
00401
00402 for(unsigned int i = 0; i < 4; ++i)
00403 for(unsigned int j = 0; j < i; ++j)
00404 std::swap((this->accessor)[i][j],(this->accessor)[j][i]);
00405
00406 return *this;
00407 }
00408
00409 template<class T>
00410 void Matrix4x4<T>::setIdentity(void){
00411 this->setZero();
00412 (this->accessor)[0][0] = (this->accessor)[1][1] = (this->accessor)[2][2] = (this->accessor)[3][3] = T(1.0);
00413 }
00414
00415
00416
00417
00425 template<class U>
00426 Vector4<U> operator* (const Vector4<U>& v,
00427 const Matrix4x4<U>& m){
00428
00429 Vector4<U> result;
00430 result[0] = m[0][0]*v[0] + m[1][0]*v[1] + m[2][0]*v[2] + m[3][0]*v[3];
00431 result[1] = m[0][1]*v[0] + m[1][1]*v[1] + m[2][1]*v[2] + m[3][1]*v[3];
00432 result[2] = m[0][2]*v[0] + m[1][2]*v[1] + m[2][2]*v[2] + m[3][2]*v[3];
00433 result[3] = m[0][3]*v[0] + m[1][3]*v[1] + m[2][3]*v[2] + m[3][3]*v[3];
00434 return result;
00435 }
00436
00437
00438 template<typename T>
00439 Matrix4x4<T>& Matrix4x4<T>::operator=(const Matrix4x4<T>& m){
00440 if(&m == this) return *this;
00441
00442 std::copy(m.begin_,m.end_,this->begin_);
00443
00444 return *this;
00445 }
00446
00447
00448 template<typename T>
00449 Matrix4x4<T> Matrix4x4<T>::operator+(const Matrix4x4<T>& m) const{
00450 Matrix4x4<T> result = *this;
00451 result += m;
00452 return result;
00453 }
00454
00455
00456 template<typename T>
00457 Matrix4x4<T> Matrix4x4<T>::operator-(const Matrix4x4<T>& m) const{
00458 Matrix4x4<T> result = *this;
00459 result -= m;
00460 return result;
00461 }
00462
00463
00464 template<typename T>
00465 Matrix4x4<T> Matrix4x4<T>::operator/(const T& d) const{
00466 Matrix4x4<T> result = *this;
00467 result /= d;
00468 return result;
00469 }
00470
00471
00472 template<typename T>
00473 Matrix4x4<T> Matrix4x4<T>::operator*(const Matrix4x4<T>& m) const{
00474
00475 Matrix4x4<T> result;
00476 T sum;
00477 for(unsigned int i = 0; i < 4; ++i)
00478 for(unsigned int j = 0; j < 4; ++j){
00479 sum = T(0.0);
00480
00481 for(unsigned int k = 0; k < 4; ++k){
00482 sum += (*this)[i][k]*m[k][j];
00483 }
00484 result[i][j] = sum;
00485 }
00486
00487 return result;
00488 }
00489
00490 template<typename T>
00491 Matrix4x4<T> Matrix4x4<T>::operator*(const T& d) const{
00492 Matrix4x4<T> result = *this;
00493 result *= d;
00494 return result;
00495 }
00496
00497
00498 template<typename T>
00499 Matrix4x4<T> Matrix4x4<T>::operator-(void) const{
00500 Matrix4x4<T> result = *this;
00501 std::transform(this->begin_, this->end_, result.begin_, std::negate<T>());
00502 return result;
00503 }
00504
00505
00506 template<typename T>
00507 Matrix4x4<T>& Matrix4x4<T>::operator+=(const Matrix4x4<T>& m){
00508 std::transform(this->begin_, this->end_, m.begin_, this->begin_, std::plus<T>());
00509 return *this;
00510 }
00511
00512
00513 template<typename T>
00514 Matrix4x4<T>& Matrix4x4<T>::operator-=(const Matrix4x4<T>& m){
00515 std::transform(this->begin_, this->end_, m.begin_, this->begin_, std::minus<T>());
00516 return *this;
00517 }
00518
00519 template<typename T>
00520 Matrix4x4<T>& Matrix4x4<T>::operator/=(const T& d){
00521 if(d==0)
00522 throw MathException("Value is null");
00523 std::transform(this->begin_, this->end_, this->begin_, std::bind2nd(std::divides<T>(),d));
00524 return *this;
00525 }
00526
00527
00528 template<typename T>
00529 Matrix4x4<T>& Matrix4x4<T>::operator*=(const Matrix4x4<T>& m){
00530 Matrix4x4<T> tmp = *this;
00531 T sum;
00532 for(unsigned int i = 0; i < 4; ++i)
00533 for(unsigned int j = 0; j < 4; ++j){
00534 sum = T(0.0);
00535
00536 for(unsigned int k = 0; k < 4; ++k){
00537 sum += tmp[i][k]*m[k][j];
00538 }
00539 this->accessor[i][j] = sum;
00540 }
00541 return *this;
00542 }
00543
00544 template<typename T>
00545 Matrix4x4<T>& Matrix4x4<T>::operator*=(const T& d){
00546 std::transform(this->begin_, this->end_, this->begin_, std::bind2nd(std::multiplies<T>(),d));
00547 return *this;
00548 }
00549
00550
00551 template<typename T>
00552 Matrix4x4<T>& Matrix4x4<T>::power(const unsigned int& p){
00553 if(p == 0){
00554 setIdentity();
00555 return *this;
00556 }
00557 Matrix4x4<T> tmp(*this);
00558
00559 for(unsigned int i=1; i < p; ++i)
00560 *this *= tmp;
00561
00562 return *this;
00563 }
00564
00565 template<typename T>
00566 Vector4<T> Matrix4x4<T>::getDiagonal(void) const{
00567 Vector4<T> v;
00568 for(unsigned int i = 0; i < 4; ++i)
00569 v[i] = this->accessor[i][i];
00570 return v;
00571 }
00572
00573 template<typename T>
00574 Vector4<T> Matrix4x4<T>::getRow(const unsigned int& row) const{
00575 if(row >= this->rowsMatrix)
00576 throw MathException("Out of bounds");
00577 Vector4<T> v;
00578 for(unsigned int i = 0; i < this->columnsMatrix; ++i)
00579 v[i] = this->accessor[row][i];
00580 return v;
00581 }
00582
00583 template<typename T>
00584 Vector4<T> Matrix4x4<T>::getColumn(const unsigned int& column) const{
00585 if(column >= this->columnsMatrix)
00586 throw MathException("Out of bounds");
00587 Vector4<T> v;
00588 for(unsigned int i = 0; i < this->columnsMatrix; ++i)
00589 v[i] = this->accessor[i][column];
00590 return v;
00591 }
00592
00600 template<typename T>
00601 T Matrix4x4<T>::trace(void) const{
00602 return (this->accessor[0][0] + this->accessor[1][1] + this->accessor[2][2] + this->accessor[3][3]);
00603 }
00604
00605
00612 template<class U> Matrix4x4<U> operator* (const U& d,
00613 const Matrix4x4<U>& m){
00614 return m*d;
00615 }
00616
00617
00618
00619
00620
00621
00622 typedef Matrix4x4<float> Matrix4x4f;
00623 typedef Matrix4x4<double> Matrix4x4d;
00624 typedef Matrix4x4<int> Matrix4x4i;
00625
00626 }
00627
00628
00629 #endif