00001
00002
00003
00004
00005
00006
00007 #ifndef BALL_MATHS_MATRIX44_H
00008 #define BALL_MATHS_MATRIX44_H
00009
00010 #ifndef BALL_COMMON_EXCEPTION_H
00011 # include <BALL/COMMON/exception.h>
00012 #endif
00013
00014 #include <math.h>
00015 #include <iostream>
00016 #include <stdlib.h>
00017
00018 #ifndef BALL_MATHS_ANGLE_H
00019 # include <BALL/MATHS/angle.h>
00020 #endif
00021
00022 #ifndef BALL_MATHS_VECTOR3_H
00023 # include <BALL/MATHS/vector3.h>
00024 #endif
00025
00026 #ifndef BALL_MATHS_VECTOR4_H
00027 # include <BALL/MATHS/vector4.h>
00028 #endif
00029
00030 namespace BALL
00031 {
00038
00039 template <typename T>
00040 class TMatrix4x4;
00041
00050 template <typename T>
00051 std::istream& operator >> (std::istream& s, TMatrix4x4<T>& m)
00052 ;
00053
00059 template <typename T>
00060 std::ostream& operator << (std::ostream& s, const TMatrix4x4<T>& m)
00061 ;
00063
00066 template <typename T>
00067 class TMatrix4x4
00068 {
00069 public:
00070
00071 BALL_CREATE(TMatrix4x4)
00072
00073
00076
00081 TMatrix4x4()
00082 ;
00083
00090 TMatrix4x4(const T* ptr)
00091 throw(Exception::NullPointer);
00092
00099 TMatrix4x4(const T ptr[4][4])
00100 throw(Exception::NullPointer);
00101
00107 TMatrix4x4(const TMatrix4x4& m)
00108 ;
00109
00118 TMatrix4x4
00119 (const TVector4<T>& col1, const TVector4<T>& col2,
00120 const TVector4<T>& col3, const TVector4<T>& col4)
00121 ;
00122
00127 TMatrix4x4
00128 (const T& m11, const T& m12, const T& m13, const T& m14,
00129 const T& m21, const T& m22, const T& m23, const T& m24,
00130 const T& m31, const T& m32, const T& m33, const T& m34,
00131 const T& m41, const T& m42, const T& m43, const T& m44)
00132 ;
00133
00138 virtual ~TMatrix4x4()
00139
00140 {
00141 }
00142
00146 virtual void clear()
00147 ;
00148
00150
00153
00159 void set(const T* ptr)
00160 throw(Exception::NullPointer);
00161
00167 void set(const T ptr[4][4])
00168 throw(Exception::NullPointer);
00169
00173 void set(const TMatrix4x4& m)
00174 ;
00175
00182 void set
00183 (const TVector4<T>& col1, const TVector4<T>& col2,
00184 const TVector4<T>& col3, const TVector4<T>& col4)
00185 ;
00186
00190 void set
00191 (const T& m11, const T& m12, const T& m13, const T& m14,
00192 const T& m21, const T& m22, const T& m23, const T& m24,
00193 const T& m31, const T& m32, const T& m33, const T& m34,
00194 const T& m41, const T& m42, const T& m43, const T& m44)
00195 ;
00196
00201 TMatrix4x4& operator = (const T* ptr)
00202 throw(Exception::NullPointer);
00203
00208 TMatrix4x4& operator = (const T ptr[4][4])
00209 throw(Exception::NullPointer);
00210
00215 TMatrix4x4& operator = (const TMatrix4x4& m)
00216 ;
00217
00223 void get(T* ptr) const
00224 throw(Exception::NullPointer);
00225
00231 void get(T ptr[4][4]) const
00232 throw(Exception::NullPointer);
00233
00238 void get(TMatrix4x4& m) const
00239 ;
00240
00247 void get
00248 (TVector4<T>& col1, TVector4<T>& col2,
00249 TVector4<T>& col3, TVector4<T>& col4) const
00250 ;
00251
00255 void get
00256 (T& m11, T& m12, T& m13, T& m14,
00257 T& m21, T& m22, T& m23, T& m24,
00258 T& m31, T& m32, T& m33, T& m34,
00259 T& m41, T& m42, T& m43, T& m44) const
00260 ;
00261
00265 void swap(TMatrix4x4& m)
00266 ;
00267
00269
00272
00277 T getTrace() const ;
00278
00282 static const TMatrix4x4& getZero() ;
00283
00288 static const TMatrix4x4& getIdentity() ;
00289
00294 void setIdentity() ;
00295
00300 void set(const T& t = (T)1) ;
00301
00306 void transpose() ;
00307
00313 TVector4<T> getRow(Position row) const
00314 throw(Exception::IndexOverflow);
00315
00321 TVector4<T> getColumn(Position col) const
00322 throw(Exception::IndexOverflow);
00323
00329 void setRow(Position row, const TVector4<T>& row_value)
00330 throw(Exception::IndexOverflow);
00331
00337 void setColumn(Position col, const TVector4<T>& col_value)
00338 throw(Exception::IndexOverflow);
00339
00346 bool isEqual(const TMatrix4x4& m) const ;
00347
00351 TVector4<T> getDiagonal() const ;
00352
00359 T& operator () (Position row, Position col)
00360 throw(Exception::IndexOverflow);
00361
00368 const T& operator () (Position row, Position col) const
00369 throw(Exception::IndexOverflow);
00370
00377 const T& operator [] (Position position) const
00378 throw(Exception::IndexOverflow);
00379
00383 T& operator [] (Position position)
00384 throw(Exception::IndexOverflow);
00385
00388 TMatrix4x4 operator + () const ;
00389
00392 TMatrix4x4 operator - () const ;
00393
00399 TMatrix4x4 operator + (const TMatrix4x4& m) const ;
00400
00406 TMatrix4x4& operator += (const TMatrix4x4& m) ;
00407
00413 TMatrix4x4 operator - (const TMatrix4x4& m) const ;
00414
00420 TMatrix4x4& operator -= (const TMatrix4x4& m) ;
00421
00426 TMatrix4x4 operator * (const T& scalar) const ;
00427
00432 TMatrix4x4& operator *= (const T& scalar) ;
00433
00439 TMatrix4x4 operator / (const T& scalar) const
00440 throw(Exception::DivisionByZero);
00441
00447 TMatrix4x4& operator /= (const T& scalar)
00448 throw(Exception::DivisionByZero);
00449
00453 TMatrix4x4 operator * (const TMatrix4x4& m) const ;
00454
00458 TMatrix4x4& operator *= (const TMatrix4x4& m) ;
00459
00463 TVector4<T> operator * (const TVector4<T>& vector) const ;
00464
00471 bool invert(TMatrix4x4& inverse) const ;
00472
00478 bool invert() ;
00479
00483 T getDeterminant() const ;
00484
00490 void translate(const T &x, const T &y, const T &z) ;
00491
00495 void translate(const TVector3<T>& v) ;
00496
00502 void setTranslation(const T& x, const T& y, const T& z) ;
00503
00507 void setTranslation(const TVector3<T>& v) ;
00508
00514 void scale(const T& x_scale, const T& y_scale, const T& z_scale) ;
00515
00519 void scale(const T& scale) ;
00520
00524 void scale(const TVector3<T>& v) ;
00525
00531 void setScale(const T& x_scale, const T& y_scale, const T& z_scale) ;
00532
00536 void setScale(const T& scale) ;
00537
00541 void setScale(const TVector3<T>& v) ;
00542
00546 void rotateX(const TAngle<T>& phi) ;
00547
00551 void setRotationX(const TAngle<T>& phi) ;
00552
00556 void rotateY(const TAngle<T>& phi) ;
00557
00561 void setRotationY(const TAngle<T>& phi) ;
00562
00566 void rotateZ(const TAngle<T>& phi) ;
00567
00571 void setRotationZ(const TAngle<T>& phi) ;
00572
00579 void rotate(const TAngle<T>& phi, const T& axis_x, const T& axis_y, const T& axis_z) ;
00580
00585 void rotate(const TAngle<T>& phi, const TVector3<T>& axis) ;
00586
00591 void rotate(const TAngle<T>& phi, const TVector4<T>& axis) ;
00592
00599 void setRotation(const TAngle<T>& phi, const T& axis_x, const T& axis_y, const T& axis_z) ;
00600
00605 void setRotation(const TAngle<T>& phi, const TVector3<T>& axis) ;
00606
00611 void setRotation(const TAngle<T>& phi, const TVector4<T>& axis) ;
00613
00617
00623 bool operator == (const TMatrix4x4& m) const ;
00624
00630 bool operator != (const TMatrix4x4& m) const ;
00631
00636 bool isIdentity() const ;
00637
00641 bool isRegular() const ;
00642
00646 bool isSingular() const ;
00647
00652 bool isSymmetric() const ;
00653
00657 bool isLowerTriangular() const ;
00658
00662 bool isUpperTriangular() const ;
00663
00667 bool isDiagonal() const ;
00669
00673
00678 bool isValid() const ;
00679
00686 void dump(std::ostream& s = std::cout, Size depth = 0) const ;
00688
00692
00694 T m11;
00695
00697 T m12;
00698
00700 T m13;
00701
00703 T m14;
00704
00706 T m21;
00707
00709 T m22;
00710
00712 T m23;
00713
00715 T m24;
00716
00718 T m31;
00719
00721 T m32;
00722
00724 T m33;
00725
00727 T m34;
00728
00730 T m41;
00731
00733 T m42;
00734
00736 T m43;
00737
00739 T m44;
00741
00742 private:
00743
00744 void initializeComponentPointers_()
00745
00746 {
00747 T **ptr = (T **)comp_ptr_;
00748
00749 *ptr++ = &m11; *ptr++ = &m12; *ptr++ = &m13; *ptr++ = &m14;
00750 *ptr++ = &m21; *ptr++ = &m22; *ptr++ = &m23; *ptr++ = &m24;
00751 *ptr++ = &m31; *ptr++ = &m32; *ptr++ = &m33; *ptr++ = &m34;
00752 *ptr++ = &m41; *ptr++ = &m42; *ptr++ = &m43; *ptr = &m44;
00753 }
00754
00755
00756 T* comp_ptr_[16];
00757 };
00759
00760 template <typename T>
00761 TMatrix4x4<T>::TMatrix4x4()
00762
00763 : m11(0), m12(0), m13(0), m14(0),
00764 m21(0), m22(0), m23(0), m24(0),
00765 m31(0), m32(0), m33(0), m34(0),
00766 m41(0), m42(0), m43(0), m44(0)
00767 {
00768 initializeComponentPointers_();
00769 }
00770
00771 template <typename T>
00772 TMatrix4x4<T>::TMatrix4x4( const T* ptr)
00773 throw(Exception::NullPointer)
00774 {
00775 if (ptr == 0)
00776 {
00777 throw Exception::NullPointer(__FILE__, __LINE__);
00778 }
00779
00780 m11 = *ptr++; m12 = *ptr++; m13 = *ptr++; m14 = *ptr++;
00781 m21 = *ptr++; m22 = *ptr++; m23 = *ptr++; m24 = *ptr++;
00782 m31 = *ptr++; m32 = *ptr++; m33 = *ptr++; m34 = *ptr++;
00783 m41 = *ptr++; m42 = *ptr++; m43 = *ptr++; m44 = *ptr;
00784
00785 initializeComponentPointers_();
00786 }
00787
00788 template <typename T>
00789 TMatrix4x4<T>::TMatrix4x4(const T array_ptr[4][4])
00790 throw(Exception::NullPointer)
00791 {
00792 if (array_ptr == 0)
00793 {
00794 throw Exception::NullPointer(__FILE__, __LINE__);
00795 }
00796
00797 const T *ptr = *array_ptr;
00798
00799 m11 = *ptr++; m12 = *ptr++; m13 = *ptr++; m14 = *ptr++;
00800 m21 = *ptr++; m22 = *ptr++; m23 = *ptr++; m24 = *ptr++;
00801 m31 = *ptr++; m32 = *ptr++; m33 = *ptr++; m34 = *ptr++;
00802 m41 = *ptr++; m42 = *ptr++; m43 = *ptr++; m44 = *ptr;
00803
00804 initializeComponentPointers_();
00805 }
00806
00807 template <typename T>
00808 TMatrix4x4<T>::TMatrix4x4(const TMatrix4x4<T>& m)
00809
00810 : m11(m.m11), m12(m.m12), m13(m.m13), m14(m.m14),
00811 m21(m.m21), m22(m.m22), m23(m.m23), m24(m.m24),
00812 m31(m.m31), m32(m.m32), m33(m.m33), m34(m.m34),
00813 m41(m.m41), m42(m.m42), m43(m.m43), m44(m.m44)
00814 {
00815 initializeComponentPointers_();
00816 }
00817
00818
00819 template <typename T>
00820 TMatrix4x4<T>::TMatrix4x4
00821 (const TVector4<T>& col1, const TVector4<T>& col2,
00822 const TVector4<T>& col3,const TVector4<T>& col4)
00823
00824 : m11(col1.x), m12(col1.y), m13(col1.z), m14(col1.h),
00825 m21(col2.x), m22(col2.y), m23(col2.z), m24(col2.h),
00826 m31(col3.x), m32(col3.y), m33(col3.z), m34(col3.h),
00827 m41(col4.x), m42(col4.y), m43(col4.z), m44(col4.h)
00828 {
00829 initializeComponentPointers_();
00830 }
00831
00832 template <typename T>
00833 TMatrix4x4<T>::TMatrix4x4
00834 (const T& m11, const T& m12, const T& m13, const T& m14,
00835 const T& m21, const T& m22, const T& m23, const T& m24,
00836 const T& m31, const T& m32, const T& m33, const T& m34,
00837 const T& m41, const T& m42, const T& m43, const T& m44)
00838
00839 : m11(m11), m12(m12), m13(m13), m14(m14),
00840 m21(m21), m22(m22), m23(m23), m24(m24),
00841 m31(m31), m32(m32), m33(m33), m34(m34),
00842 m41(m41), m42(m42), m43(m43), m44(m44)
00843 {
00844 initializeComponentPointers_();
00845 }
00846
00847 template <typename T>
00848 void TMatrix4x4<T>::clear()
00849
00850 {
00851 set((T)0);
00852 }
00853
00854 template <typename T>
00855 void TMatrix4x4<T>::set(const T* ptr)
00856 throw(Exception::NullPointer)
00857 {
00858 if (ptr == 0)
00859 {
00860 throw Exception::NullPointer(__FILE__, __LINE__);
00861 }
00862
00863 m11 = *ptr++; m12 = *ptr++; m13 = *ptr++; m14 = *ptr++;
00864 m21 = *ptr++; m22 = *ptr++; m23 = *ptr++; m24 = *ptr++;
00865 m31 = *ptr++; m32 = *ptr++; m33 = *ptr++; m34 = *ptr++;
00866 m41 = *ptr++; m42 = *ptr++; m43 = *ptr++; m44 = *ptr;
00867 }
00868
00869 template <typename T>
00870 void TMatrix4x4<T>::set(const T array_ptr[4][4])
00871 throw(Exception::NullPointer)
00872 {
00873 if (array_ptr == 0)
00874 {
00875 throw Exception::NullPointer(__FILE__, __LINE__);
00876 }
00877
00878 const T *ptr = *array_ptr;
00879
00880 m11 = *ptr++; m12 = *ptr++; m13 = *ptr++; m14 = *ptr++;
00881 m21 = *ptr++; m22 = *ptr++; m23 = *ptr++; m24 = *ptr++;
00882 m31 = *ptr++; m32 = *ptr++; m33 = *ptr++; m34 = *ptr++;
00883 m41 = *ptr++; m42 = *ptr++; m43 = *ptr++; m44 = *ptr;
00884 }
00885
00886 template <typename T>
00887 void TMatrix4x4<T>::set(const TMatrix4x4<T>& m)
00888
00889 {
00890 m11 = m.m11; m12 = m.m12; m13 = m.m13; m14 = m.m14;
00891 m21 = m.m21; m22 = m.m22; m23 = m.m23; m24 = m.m24;
00892 m31 = m.m31; m32 = m.m32; m33 = m.m33; m34 = m.m34;
00893 m41 = m.m41; m42 = m.m42; m43 = m.m43; m44 = m.m44;
00894 }
00895
00896 template <typename T>
00897 void TMatrix4x4<T>::set
00898 (const TVector4<T>& col1, const TVector4<T>& col2,
00899 const TVector4<T>& col3, const TVector4<T>& col4)
00900
00901 {
00902 m11 = col1.x; m12 = col1.y; m13 = col1.z; m14 = col1.h;
00903 m21 = col2.x; m22 = col2.y; m23 = col2.z; m24 = col2.h;
00904 m31 = col3.x; m32 = col3.y; m33 = col3.z; m34 = col3.h;
00905 m41 = col4.x; m42 = col4.y; m43 = col4.z; m44 = col4.h;
00906 }
00907
00908 template <typename T>
00909 void TMatrix4x4<T>::set
00910 (const T& c11, const T& c12, const T& c13, const T& c14,
00911 const T& c21, const T& c22, const T& c23, const T& c24,
00912 const T& c31, const T& c32, const T& c33, const T& c34,
00913 const T& c41, const T& c42, const T& c43, const T& c44)
00914
00915 {
00916 m11 = c11; m12 = c12; m13 = c13; m14 = c14;
00917 m21 = c21; m22 = c22; m23 = c23; m24 = c24;
00918 m31 = c31; m32 = c32; m33 = c33; m34 = c34;
00919 m41 = c41; m42 = c42; m43 = c43; m44 = c44;
00920 }
00921
00922 template <typename T>
00923 BALL_INLINE
00924 TMatrix4x4<T>& TMatrix4x4<T>::operator = (const T* ptr)
00925 throw(Exception::NullPointer)
00926 {
00927 set(ptr);
00928 return *this;
00929 }
00930
00931 template <typename T>
00932 BALL_INLINE
00933 TMatrix4x4<T>& TMatrix4x4<T>::operator = (const T array_ptr[4][4])
00934 throw(Exception::NullPointer)
00935 {
00936 set(array_ptr);
00937 return *this;
00938 }
00939
00940 template <typename T>
00941 BALL_INLINE
00942 TMatrix4x4<T>& TMatrix4x4<T>::operator = (const TMatrix4x4<T>& m)
00943
00944 {
00945 set(m);
00946 return *this;
00947 }
00948
00949 template <typename T>
00950 void TMatrix4x4<T>::get(T* ptr) const
00951 throw(Exception::NullPointer)
00952 {
00953 if (ptr == 0)
00954 {
00955 throw Exception::NullPointer(__FILE__, __LINE__);
00956 }
00957
00958 *ptr++ = m11; *ptr++ = m12; *ptr++ = m13; *ptr++ = m14;
00959 *ptr++ = m21; *ptr++ = m22; *ptr++ = m23; *ptr++ = m24;
00960 *ptr++ = m31; *ptr++ = m32; *ptr++ = m33; *ptr++ = m34;
00961 *ptr++ = m41; *ptr++ = m42; *ptr++ = m43; *ptr = m44;
00962 }
00963
00964 template <typename T>
00965 void TMatrix4x4<T>::get(T array_ptr[4][4]) const
00966 throw(Exception::NullPointer)
00967 {
00968 if (array_ptr == 0)
00969 {
00970 throw Exception::NullPointer(__FILE__, __LINE__);
00971 }
00972
00973 T *ptr = *array_ptr;
00974
00975 *ptr++ = m11; *ptr++ = m12; *ptr++ = m13; *ptr++ = m14;
00976 *ptr++ = m21; *ptr++ = m22; *ptr++ = m23; *ptr++ = m24;
00977 *ptr++ = m31; *ptr++ = m32; *ptr++ = m33; *ptr++ = m34;
00978 *ptr++ = m41; *ptr++ = m42; *ptr++ = m43; *ptr = m44;
00979 }
00980
00981 template <typename T>
00982 void TMatrix4x4<T>::get(TMatrix4x4<T>& m) const
00983
00984 {
00985 m.set(*this);
00986 }
00987
00988 template <typename T>
00989 void TMatrix4x4<T>::get
00990 (TVector4<T>& col1, TVector4<T>& col2,
00991 TVector4<T>& col3, TVector4<T>& col4) const
00992
00993 {
00994 col1.x = m11; col1.y = m12; col1.z = m13; col1.h = m14;
00995 col2.x = m21; col2.y = m22; col2.z = m23; col2.h = m24;
00996 col3.x = m31; col3.y = m32; col3.z = m33; col3.h = m34;
00997 col4.x = m41; col4.y = m42; col4.z = m43; col4.h = m44;
00998 }
00999
01000 template <typename T>
01001 void TMatrix4x4<T>::get
01002 (T& c11, T& c12, T& c13, T& c14,
01003 T& c21, T& c22, T& c23, T& c24,
01004 T& c31, T& c32, T& c33, T& c34,
01005 T& c41, T& c42, T& c43, T& c44) const
01006
01007 {
01008 c11 = m11; c12 = m12; c13 = m13; c14 = m14;
01009 c21 = m21; c22 = m22; c23 = m23; c24 = m24;
01010 c31 = m31; c32 = m32; c33 = m33; c34 = m34;
01011 c41 = m41; c42 = m42; c43 = m43; c44 = m44;
01012 }
01013
01014 template <typename T>
01015 BALL_INLINE
01016 T TMatrix4x4<T>::getTrace() const
01017
01018 {
01019 return (m11 + m22 + m33 + m44);
01020 }
01021
01022 template <typename T>
01023 BALL_INLINE
01024 const TMatrix4x4<T>& TMatrix4x4<T>::getZero()
01025
01026 {
01027 static TMatrix4x4<T> null_matrix
01028 (0, 0, 0, 0,
01029 0, 0, 0, 0,
01030 0, 0, 0, 0,
01031 0, 0, 0, 0);
01032
01033 return null_matrix;
01034 }
01035
01036
01037 template <typename T>
01038 BALL_INLINE
01039 void TMatrix4x4<T>::setIdentity()
01040
01041 {
01042 m12 = m13 = m14 = m21 = m23 = m24 = m31 = m32 = m34 = m41 = m42 = m43 = 0;
01043 m11 = m22 = m33 = m44 = (T)1;
01044 }
01045 template <typename T>
01046 BALL_INLINE
01047 const TMatrix4x4<T>& TMatrix4x4<T>::getIdentity()
01048
01049 {
01050 static TMatrix4x4<T> identity
01051 (1, 0, 0, 0,
01052 0, 1, 0, 0,
01053 0, 0, 1, 0,
01054 0, 0, 0, 1);
01055
01056 return identity;
01057 }
01058
01059 template <typename T>
01060 void TMatrix4x4<T>::set(const T& t)
01061
01062 {
01063 m11 = m12 = m13 = m14
01064 = m21 = m22 = m23 = m24
01065 = m31 = m32 = m33 = m34
01066 = m41 = m42 = m43 = m44
01067 = t;
01068 }
01069
01070 template <typename T>
01071 void TMatrix4x4<T>::swap(TMatrix4x4<T>& m)
01072
01073 {
01074 T tmp = m11; m11 = m.m11; m.m11 = tmp;
01075 tmp = m12; m12 = m.m12; m.m12 = tmp;
01076 tmp = m13; m13 = m.m13; m.m13 = tmp;
01077 tmp = m14; m14 = m.m14; m.m14 = tmp;
01078 tmp = m21; m21 = m.m21; m.m21 = tmp;
01079 tmp = m22; m22 = m.m22; m.m22 = tmp;
01080 tmp = m23; m23 = m.m23; m.m23 = tmp;
01081 tmp = m24; m24 = m.m24; m.m24 = tmp;
01082 tmp = m31; m31 = m.m31; m.m31 = tmp;
01083 tmp = m32; m32 = m.m32; m.m32 = tmp;
01084 tmp = m33; m33 = m.m33; m.m33 = tmp;
01085 tmp = m34; m34 = m.m34; m.m34 = tmp;
01086 tmp = m41; m41 = m.m41; m.m41 = tmp;
01087 tmp = m42; m42 = m.m42; m.m42 = tmp;
01088 tmp = m43; m43 = m.m43; m.m43 = tmp;
01089 tmp = m44; m44 = m.m44; m.m44 = tmp;
01090 }
01091
01092 template <typename T>
01093 void TMatrix4x4<T>::transpose()
01094
01095 {
01096 T tmp = m12;
01097 m12 = m21;
01098 m21 = tmp;
01099
01100 tmp = m13;
01101 m13 = m31;
01102 m31 = tmp;
01103
01104 tmp = m14;
01105 m14 = m41;
01106 m41 = tmp;
01107
01108 tmp = m23;
01109 m23 = m32;
01110 m32 = tmp;
01111
01112 tmp = m24;
01113 m24 = m42;
01114 m42 = tmp;
01115
01116 tmp = m34;
01117 m34 = m43;
01118 m43 = tmp;
01119 }
01120
01121 template <typename T>
01122 TVector4<T> TMatrix4x4<T>::getRow(Position row) const
01123 throw(Exception::IndexOverflow)
01124 {
01125 if (row > 3)
01126 {
01127 throw Exception::IndexOverflow(__FILE__, __LINE__, row, 3);
01128 }
01129
01130
01131 const T* ptr = comp_ptr_[4 * row];
01132 return TVector4<T> (ptr[0], ptr[1], ptr[2], ptr[3]);
01133 }
01134
01135 template <typename T>
01136 TVector4<T> TMatrix4x4<T>::getColumn(Position col) const
01137 throw(Exception::IndexOverflow)
01138 {
01139 if (col > 3)
01140 {
01141 throw Exception::IndexOverflow(__FILE__, __LINE__, col, 3);
01142 }
01143
01144 const T* ptr = comp_ptr_[col];
01145
01146 return TVector4<T> (ptr[0], ptr[4], ptr[8], ptr[12]);
01147 }
01148
01149
01150 template <typename T>
01151 void TMatrix4x4<T>::setRow(Position row, const TVector4<T>& row_value)
01152 throw(Exception::IndexOverflow)
01153 {
01154 if (row > 3)
01155 {
01156 throw Exception::IndexOverflow(__FILE__, __LINE__, row, 3);
01157 }
01158
01159
01160 T* ptr = comp_ptr_[4 * row];
01161
01162 ptr[0] = row_value.x;
01163 ptr[1] = row_value.y;
01164 ptr[2] = row_value.z;
01165 ptr[3] = row_value.h;
01166 }
01167
01168 template <typename T>
01169 void TMatrix4x4<T>::setColumn(Position col, const TVector4<T>& col_value)
01170 throw(Exception::IndexOverflow)
01171 {
01172 if (col > 3)
01173 {
01174 throw Exception::IndexOverflow(__FILE__, __LINE__, col, 3);
01175 }
01176
01177
01178 T* ptr = comp_ptr_[col];
01179
01180 ptr[0] = col_value.x;
01181 ptr[4] = col_value.y;
01182 ptr[8] = col_value.z;
01183 ptr[12] = col_value.h;
01184 }
01185
01186 template <typename T>
01187 bool TMatrix4x4<T>::isEqual(const TMatrix4x4<T>& m) const
01188
01189 {
01190
01191
01192 for (Position i = 0; i < 16; i++)
01193 {
01194 if (Maths::isEqual(*comp_ptr_[i], *m.comp_ptr_[i]) == false)
01195 {
01196 return false;
01197 }
01198 }
01199
01200 return true;
01201 }
01202
01203 template <typename T>
01204 TVector4<T>TMatrix4x4<T>::getDiagonal() const
01205
01206 {
01207 return TVector4<T>(m11, m22, m33, m44);
01208 }
01209
01210 template <typename T>
01211 BALL_INLINE
01212 T& TMatrix4x4<T>::operator () (Position row, Position col)
01213 throw(Exception::IndexOverflow)
01214 {
01215 if ((row > 3) || (col > 3))
01216 {
01217 throw Exception::IndexOverflow(__FILE__, __LINE__, row + col, 3);
01218 }
01219
01220 return *comp_ptr_[4 * row + col];
01221 }
01222
01223 template <typename T>
01224 BALL_INLINE
01225 const T& TMatrix4x4<T>::operator () (Position row, Position col) const
01226 throw(Exception::IndexOverflow)
01227 {
01228 if ((row > 3) || (col > 3))
01229 {
01230 throw Exception::IndexOverflow(__FILE__, __LINE__, row + col, 3);
01231 }
01232
01233 return *comp_ptr_[4 * row + col];
01234 }
01235
01236 template <typename T>
01237 BALL_INLINE
01238 const T& TMatrix4x4<T>::operator [] (Position position) const
01239 throw(Exception::IndexOverflow)
01240 {
01241 if (position > 15)
01242 {
01243 throw Exception::IndexOverflow(__FILE__, __LINE__, position, 15);
01244 }
01245 return *comp_ptr_[position];
01246 }
01247
01248 template <typename T>
01249 BALL_INLINE
01250 T& TMatrix4x4<T>::operator [] (Position position)
01251 throw(Exception::IndexOverflow)
01252 {
01253 if (position > 15)
01254 {
01255 throw Exception::IndexOverflow(__FILE__, __LINE__, position, 15);
01256 }
01257 return *comp_ptr_[position];
01258 }
01259
01260 template <typename T>
01261 BALL_INLINE
01262 TMatrix4x4<T> TMatrix4x4<T>::operator + () const
01263
01264 {
01265 return *this;
01266 }
01267
01268 template <typename T>
01269 BALL_INLINE TMatrix4x4<T>
01270 TMatrix4x4<T>::operator - () const
01271
01272 {
01273 return TMatrix4x4<T>
01274 (-m11, -m12, -m13, -m14,
01275 -m21, -m22, -m23, -m24,
01276 -m31, -m32, -m33, -m34,
01277 -m41, -m42, -m43, -m44);
01278 }
01279
01280 template <typename T>
01281 TMatrix4x4<T> TMatrix4x4<T>::operator + (const TMatrix4x4<T>& m) const
01282
01283 {
01284 return TMatrix4x4<T>
01285 (m11 + m.m11, m12 + m.m12, m13 + m.m13, m14 + m.m14,
01286 m21 + m.m21, m22 + m.m22, m23 + m.m23, m24 + m.m24,
01287 m31 + m.m31, m32 + m.m32, m33 + m.m33, m34 + m.m34,
01288 m41 + m.m41, m42 + m.m42, m43 + m.m43, m44 + m.m44);
01289 }
01290
01291 template <typename T>
01292 TMatrix4x4<T>& TMatrix4x4<T>::operator += (const TMatrix4x4<T>& m)
01293
01294 {
01295 m11 += m.m11;
01296 m12 += m.m12;
01297 m13 += m.m13;
01298 m14 += m.m14;
01299 m21 += m.m21;
01300 m22 += m.m22;
01301 m23 += m.m23;
01302 m24 += m.m24;
01303 m31 += m.m31;
01304 m32 += m.m32;
01305 m33 += m.m33;
01306 m34 += m.m34;
01307 m41 += m.m41;
01308 m42 += m.m42;
01309 m43 += m.m43;
01310 m44 += m.m44;
01311
01312 return *this;
01313 }
01314
01315 template <typename T>
01316 TMatrix4x4<T> TMatrix4x4<T>::operator - (const TMatrix4x4<T>& m) const
01317
01318 {
01319 return TMatrix4x4<T>
01320 (m11 - m.m11, m12 - m.m12, m13 - m.m13, m14 - m.m14,
01321 m21 - m.m21, m22 - m.m22, m23 - m.m23, m24 - m.m24,
01322 m31 - m.m31, m32 - m.m32, m33 - m.m33, m34 - m.m34,
01323 m41 - m.m41, m42 - m.m42, m43 - m.m43, m44 - m.m44);
01324 }
01325
01326 template <typename T>
01327 TMatrix4x4<T>& TMatrix4x4<T>::operator -= (const TMatrix4x4<T>& m)
01328
01329 {
01330 m11 -= m.m11;
01331 m12 -= m.m12;
01332 m13 -= m.m13;
01333 m14 -= m.m14;
01334 m21 -= m.m21;
01335 m22 -= m.m22;
01336 m23 -= m.m23;
01337 m24 -= m.m24;
01338 m31 -= m.m31;
01339 m32 -= m.m32;
01340 m33 -= m.m33;
01341 m34 -= m.m34;
01342 m41 -= m.m41;
01343 m42 -= m.m42;
01344 m43 -= m.m43;
01345 m44 -= m.m44;
01346
01347 return *this;
01348 }
01349
01350 template <typename T>
01351 TMatrix4x4<T> TMatrix4x4<T>::operator * (const T& scalar) const
01352
01353 {
01354 return TMatrix4x4<T>
01355 (m11 * scalar, m12 * scalar, m13 * scalar, m14 * scalar,
01356 m21 * scalar, m22 * scalar, m23 * scalar, m24 * scalar,
01357 m31 * scalar, m32 * scalar, m33 * scalar, m34 * scalar,
01358 m41 * scalar, m42 * scalar, m43 * scalar, m44 * scalar);
01359 }
01360
01361 template <typename T>
01362 TMatrix4x4<T> operator * (const T& scalar, const TMatrix4x4<T>& m)
01363
01364 {
01365 return TMatrix4x4<T>
01366 (scalar * m.m11, scalar * m.m12, scalar * m.m13, scalar * m.m14,
01367 scalar * m.m21, scalar * m.m22, scalar * m.m23, scalar * m.m24,
01368 scalar * m.m31, scalar * m.m32, scalar * m.m33, scalar * m.m34,
01369 scalar * m.m41, scalar * m.m42, scalar * m.m43, scalar * m.m44);
01370 }
01371
01372 template <typename T>
01373 TMatrix4x4<T>& TMatrix4x4<T>::operator *= (const T& scalar)
01374
01375 {
01376 m11 *= scalar;
01377 m12 *= scalar;
01378 m13 *= scalar;
01379 m14 *= scalar;
01380 m21 *= scalar;
01381 m22 *= scalar;
01382 m23 *= scalar;
01383 m24 *= scalar;
01384 m31 *= scalar;
01385 m32 *= scalar;
01386 m33 *= scalar;
01387 m34 *= scalar;
01388 m41 *= scalar;
01389 m42 *= scalar;
01390 m43 *= scalar;
01391 m44 *= scalar;
01392
01393 return *this;
01394 }
01395
01396 template <typename T>
01397 TVector3<T> operator *(const TMatrix4x4<T>& matrix, const TVector3<T>& vector)
01398
01399 {
01400 return TVector3<T>
01401 (matrix.m11 * vector.x + matrix.m12 * vector.y + matrix.m13 * vector.z + matrix.m14,
01402 matrix.m21 * vector.x + matrix.m22 * vector.y + matrix.m23 * vector.z + matrix.m24,
01403 matrix.m31 * vector.x + matrix.m32 * vector.y + matrix.m33 * vector.z + matrix.m34);
01404 }
01405
01406 template <typename T>
01407 BALL_INLINE
01408 TMatrix4x4<T>TMatrix4x4<T>::operator / (const T& scalar) const
01409 throw(Exception::DivisionByZero)
01410 {
01411 if (scalar == (T)0)
01412 {
01413 throw Exception::DivisionByZero(__FILE__, __LINE__);
01414 }
01415
01416 return (*this * ((T)1 / scalar));
01417 }
01418
01419 template <typename T>
01420 BALL_INLINE
01421 TMatrix4x4<T>& TMatrix4x4<T>::operator /= (const T& scalar)
01422 throw(Exception::DivisionByZero)
01423 {
01424 if (scalar == (T)0)
01425 {
01426 throw Exception::DivisionByZero(__FILE__, __LINE__);
01427 }
01428
01429 return (*this *= (T)1 / scalar);
01430 }
01431
01432 template <typename T>
01433 TMatrix4x4<T> TMatrix4x4<T>::operator * (const TMatrix4x4<T>& m) const
01434
01435 {
01436 return TMatrix4x4<T>
01437 (m11 * m.m11 + m12 * m.m21 + m13 * m.m31 + m14 * m.m41,
01438 m11 * m.m12 + m12 * m.m22 + m13 * m.m32 + m14 * m.m42,
01439 m11 * m.m13 + m12 * m.m23 + m13 * m.m33 + m14 * m.m43,
01440 m11 * m.m14 + m12 * m.m24 + m13 * m.m34 + m14 * m.m44,
01441
01442 m21 * m.m11 + m22 * m.m21 + m23 * m.m31 + m24 * m.m41,
01443 m21 * m.m12 + m22 * m.m22 + m23 * m.m32 + m24 * m.m42,
01444 m21 * m.m13 + m22 * m.m23 + m23 * m.m33 + m24 * m.m43,
01445 m21 * m.m14 + m22 * m.m24 + m23 * m.m34 + m24 * m.m44,
01446
01447 m31 * m.m11 + m32 * m.m21 + m33 * m.m31 + m34 * m.m41,
01448 m31 * m.m12 + m32 * m.m22 + m33 * m.m32 + m34 * m.m42,
01449 m31 * m.m13 + m32 * m.m23 + m33 * m.m33 + m34 * m.m43,
01450 m31 * m.m14 + m32 * m.m24 + m33 * m.m34 + m34 * m.m44,
01451
01452 m41 * m.m11 + m42 * m.m21 + m43 * m.m31 + m44 * m.m41,
01453 m41 * m.m12 + m42 * m.m22 + m43 * m.m32 + m44 * m.m42,
01454 m41 * m.m13 + m42 * m.m23 + m43 * m.m33 + m44 * m.m43,
01455 m41 * m.m14 + m42 * m.m24 + m43 * m.m34 + m44 * m.m44);
01456 }
01457
01458 template <typename T>
01459 TMatrix4x4<T>& TMatrix4x4<T>::operator *= (const TMatrix4x4<T>& m)
01460
01461 {
01462 set(m11 * m.m11 + m12 * m.m21 + m13 * m.m31 + m14 * m.m41,
01463 m11 * m.m12 + m12 * m.m22 + m13 * m.m32 + m14 * m.m42,
01464 m11 * m.m13 + m12 * m.m23 + m13 * m.m33 + m14 * m.m43,
01465 m11 * m.m14 + m12 * m.m24 + m13 * m.m34 + m14 * m.m44,
01466
01467 m21 * m.m11 + m22 * m.m21 + m23 * m.m31 + m24 * m.m41,
01468 m21 * m.m12 + m22 * m.m22 + m23 * m.m32 + m24 * m.m42,
01469 m21 * m.m13 + m22 * m.m23 + m23 * m.m33 + m24 * m.m43,
01470 m21 * m.m14 + m22 * m.m24 + m23 * m.m34 + m24 * m.m44,
01471
01472 m31 * m.m11 + m32 * m.m21 + m33 * m.m31 + m34 * m.m41,
01473 m31 * m.m12 + m32 * m.m22 + m33 * m.m32 + m34 * m.m42,
01474 m31 * m.m13 + m32 * m.m23 + m33 * m.m33 + m34 * m.m43,
01475 m31 * m.m14 + m32 * m.m24 + m33 * m.m34 + m34 * m.m44,
01476
01477 m41 * m.m11 + m42 * m.m21 + m43 * m.m31 + m44 * m.m41,
01478 m41 * m.m12 + m42 * m.m22 + m43 * m.m32 + m44 * m.m42,
01479 m41 * m.m13 + m42 * m.m23 + m43 * m.m33 + m44 * m.m43,
01480 m41 * m.m14 + m42 * m.m24 + m43 * m.m34 + m44 * m.m44);
01481
01482 return *this;
01483 }
01484
01485 template <typename T>
01486 TVector4<T> TMatrix4x4<T>::operator * (const TVector4<T>& v) const
01487
01488 {
01489 return TVector4<T>
01490 (m11 * v.x + m12 * v.y + m13 * v.z + m14 * v.h,
01491 m21 * v.x + m22 * v.y + m23 * v.z + m24 * v.h,
01492 m31 * v.x + m32 * v.y + m33 * v.z + m34 * v.h,
01493 m41 * v.x + m42 * v.y + m43 * v.z + m44 * v.h);
01494 }
01495
01496 template <typename T>
01497 bool TMatrix4x4<T>::invert(TMatrix4x4<T>& inverse) const
01498
01499 {
01507 Index i, j, k;
01508
01509 T a[4][4] =
01510 {
01511 { m11, m12, m13, m14 },
01512 { m21, m22, m23, m24 },
01513 { m31, m32, m33, m34 },
01514 { m41, m42, m43, m44 }
01515 };
01516
01517
01518 T scale, sum_of_squares, sigma, tau;
01519 T c[4], d[4];
01520 for (k=0; k<3; k++)
01521 {
01522 scale = (T)0;
01523
01524 for (i=k; i<4; i++)
01525 scale = Maths::max((T)fabs(a[i][k]), scale);
01526
01527
01528 if (scale == (T)0)
01529 return false;
01530
01531
01532 for (i=k; i<4; i++)
01533 a[i][k] /= scale;
01534
01535 sum_of_squares = (T)0;
01536 for (i=k; i<4; i++)
01537 sum_of_squares += a[i][k]*a[i][k];
01538
01539
01540 sigma = (a[k][k] >= 0) ? sqrt(sum_of_squares) : -sqrt(sum_of_squares);
01541 a[k][k] += sigma;
01542
01543 c[k] = sigma*a[k][k];
01544 d[k] = -scale*sigma;
01545
01546 for (j = k+1; j<4; j++)
01547 {
01548
01549 sum_of_squares = (T)0;
01550 for (i = k; i<4; i++)
01551 sum_of_squares += a[i][k] * a[i][j];
01552
01553 tau = sum_of_squares / c[k];
01554
01555
01556 for (i=k; i<4; i++)
01557 a[i][j] -= tau*a[i][k];
01558 }
01559 }
01560 d[3] = a[3][3];
01561
01562
01563 if (d[3] == (T)0)
01564 return 1;
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574 T result[4][4];
01575 result[0][0] = 1; result[0][1] = 0; result[0][2] = 0; result[0][3] = 0;
01576 result[1][0] = 0; result[1][1] = 1; result[1][2] = 0; result[1][3] = 0;
01577 result[2][0] = 0; result[2][1] = 0; result[2][2] = 1; result[2][3] = 0;
01578 result[3][0] = 0; result[3][1] = 0; result[3][2] = 0; result[3][3] = 1;
01579
01580 for (k=0; k<4; k++)
01581 {
01582
01583 for (j=0; j<3; j++)
01584 {
01585 sum_of_squares = (T)0;
01586 for (i=j; i<4; i++)
01587 sum_of_squares += a[i][j]*result[i][k];
01588
01589 tau = sum_of_squares / c[j];
01590
01591 for (i=j; i<4; i++)
01592 result[i][k] -= tau*a[i][j];
01593 }
01594
01595
01596 result[3][k] /= d[3];
01597 for (i=2; i>=0; i--)
01598 {
01599 sum_of_squares = (T)0;
01600 for (j=i+1; j<4; j++)
01601 sum_of_squares += a[i][j] * result[j][k];
01602
01603 result[i][k] = (result[i][k] - sum_of_squares) / d[i];
01604 }
01605 }
01606
01607 T* k_ptr = *result;
01608 inverse.m11 = *k_ptr++;
01609 inverse.m12 = *k_ptr++;
01610 inverse.m13 = *k_ptr++;
01611 inverse.m14 = *k_ptr++;
01612 inverse.m21 = *k_ptr++;
01613 inverse.m22 = *k_ptr++;
01614 inverse.m23 = *k_ptr++;
01615 inverse.m24 = *k_ptr++;
01616 inverse.m31 = *k_ptr++;
01617 inverse.m32 = *k_ptr++;
01618 inverse.m33 = *k_ptr++;
01619 inverse.m34 = *k_ptr++;
01620 inverse.m41 = *k_ptr++;
01621 inverse.m42 = *k_ptr++;
01622 inverse.m43 = *k_ptr++;
01623 inverse.m44 = *k_ptr;
01624
01625 return true;
01626 }
01627
01628 template <typename T>
01629 BALL_INLINE bool TMatrix4x4<T>::invert()
01630
01631 {
01632 return invert(*this);
01633 }
01634
01635 template <typename T>
01636 T TMatrix4x4<T>::getDeterminant() const
01637
01638 {
01639 Position i;
01640 Position j;
01641 Position k;
01642 T submatrix[3][3];
01643 T matrix[4][4] =
01644 {
01645 { m11, m12, m13, m14 },
01646 { m21, m22, m23, m24 },
01647 { m31, m32, m33, m34 },
01648 { m41, m42, m43, m44 }
01649 };
01650 T determinant = 0;
01651
01652 for (i = 0; i < 4; i++)
01653 {
01654 for (j = 0; j < 3; j++)
01655 {
01656 for (k = 0; k < 3; k++)
01657 {
01658 submatrix[j][k] =
01659 matrix[j + 1][(k < i) ? k : k + 1];
01660 }
01661 }
01662
01663 determinant += matrix[0][i] * (T)(i / 2.0 == (i >> 1) ? 1 : -1)
01664 * (submatrix[0][0] * submatrix[1][1] * submatrix[2][2]
01665 + submatrix[0][1] * submatrix[1][2] * submatrix[2][0]
01666 + submatrix[0][2] * submatrix[1][0] * submatrix[2][1]
01667 - submatrix[0][2] * submatrix[1][1] * submatrix[2][0]
01668 - submatrix[0][0] * submatrix[1][2] * submatrix[2][1]
01669 - submatrix[0][1] * submatrix[1][0] * submatrix[2][2]);
01670 }
01671
01672 return determinant;
01673 }
01674
01675 template <typename T>
01676 void TMatrix4x4<T>::translate(const T& x, const T& y, const T& z)
01677
01678 {
01679 m14 += m11 * x + m12 * y + m13 * z;
01680 m24 += m21 * x + m22 * y + m23 * z;
01681 m34 += m31 * x + m32 * y + m33 * z;
01682 m44 += m41 * x + m42 * y + m43 * z;
01683 }
01684
01685 template <typename T>
01686 void TMatrix4x4<T>::translate(const TVector3<T>& v)
01687
01688 {
01689 m14 += m11 * v.x + m12 * v.y + m13 * v.z;
01690 m24 += m21 * v.x + m22 * v.y + m23 * v.z;
01691 m34 += m31 * v.x + m32 * v.y + m33 * v.z;
01692 m44 += m41 * v.x + m42 * v.y + m43 * v.z;
01693 }
01694
01695 template <typename T>
01696 void TMatrix4x4<T>::setTranslation(const T& x, const T& y, const T& z)
01697
01698 {
01699 m11 = m22 = m33 = m44 = 1;
01700
01701 m12 = m13 =
01702 m21 = m23 =
01703 m31 = m32 =
01704 m41 = m42 = m43 = 0;
01705
01706 m14 = x;
01707 m24 = y;
01708 m34 = z;
01709 }
01710
01711 template <typename T>
01712 void TMatrix4x4<T>::setTranslation(const TVector3<T>& v)
01713
01714 {
01715 m11 = m22 = m33 = m44 = 1;
01716
01717 m12 = m13 =
01718 m21 = m23 =
01719 m31 = m32 =
01720 m41 = m42 = m43 = 0;
01721
01722 m14 = v.x;
01723 m24 = v.y;
01724 m34 = v.z;
01725 }
01726
01727 template <typename T>
01728 void TMatrix4x4<T>::scale(const T& x_scale, const T& y_scale, const T& z_scale)
01729
01730 {
01731 m11 *= x_scale;
01732 m21 *= x_scale;
01733 m31 *= x_scale;
01734 m41 *= x_scale;
01735
01736 m12 *= y_scale;
01737 m22 *= y_scale;
01738 m32 *= y_scale;
01739 m42 *= y_scale;
01740
01741 m13 *= z_scale;
01742 m23 *= z_scale;
01743 m33 *= z_scale;
01744 m43 *= z_scale;
01745 }
01746
01747 template <typename T>
01748 void TMatrix4x4<T>::scale(const T& scale)
01749
01750 {
01751 m11 *= scale;
01752 m21 *= scale;
01753 m31 *= scale;
01754 m41 *= scale;
01755
01756 m12 *= scale;
01757 m22 *= scale;
01758 m32 *= scale;
01759 m42 *= scale;
01760
01761 m13 *= scale;
01762 m23 *= scale;
01763 m33 *= scale;
01764 m43 *= scale;
01765 }
01766
01767 template <typename T>
01768 void TMatrix4x4<T>::scale(const TVector3<T>& v)
01769
01770 {
01771 m11 *= v.x;
01772 m21 *= v.x;
01773 m31 *= v.x;
01774 m41 *= v.x;
01775
01776 m12 *= v.y;
01777 m22 *= v.y;
01778 m32 *= v.y;
01779 m42 *= v.y;
01780
01781 m13 *= v.z;
01782 m23 *= v.z;
01783 m33 *= v.z;
01784 m43 *= v.z;
01785 }
01786
01787 template <typename T>
01788 void TMatrix4x4<T>::setScale(const T& x_scale, const T& y_scale, const T& z_scale)
01789
01790 {
01791 m11 = x_scale;
01792 m22 = y_scale;
01793 m33 = z_scale;
01794 m44 = 1;
01795
01796 m12 = m13 = m14 =
01797 m21 = m23 = m24 =
01798 m31 = m32 = m34 =
01799 m41 = m42 = m43 = 0;
01800 }
01801
01802 template <typename T>
01803 void TMatrix4x4<T>::setScale(const T& scale)
01804
01805 {
01806 m11 = scale;
01807 m22 = scale;
01808 m33 = scale;
01809 m44 = 1;
01810
01811 m12 = m13 = m14 =
01812 m21 = m23 = m24 =
01813 m31 = m32 = m34 =
01814 m41 = m42 = m43 = 0;
01815 }
01816
01817 template <typename T>
01818 void TMatrix4x4<T>::setScale(const TVector3<T>& v)
01819
01820 {
01821 m11 = v.x;
01822 m22 = v.y;
01823 m33 = v.z;
01824 m44 = 1;
01825
01826 m12 = m13 = m14 =
01827 m21 = m23 = m24 =
01828 m31 = m32 = m34 =
01829 m41 = m42 = m43 = 0;
01830 }
01831
01832 template <typename T>
01833 BALL_INLINE
01834 void TMatrix4x4<T>::rotateX(const TAngle<T>& phi)
01835
01836 {
01837 TMatrix4x4<T> rotation;
01838
01839 rotation.setRotationX(phi);
01840 *this *= rotation;
01841 }
01842
01843 template <typename T>
01844 void TMatrix4x4<T>::setRotationX(const TAngle<T>& phi)
01845
01846 {
01847 m11 = m44 = 1;
01848
01849 m12 = m13 = m14
01850 = m21 = m24
01851 = m31 = m34
01852 = m41 = m42 = m43
01853 = 0;
01854
01855 m22 = m33 = cos(phi);
01856 m23 = -(m32 = sin(phi));
01857 }
01858
01859 template <typename T>
01860 BALL_INLINE
01861 void TMatrix4x4<T>::rotateY(const TAngle<T>& phi)
01862
01863 {
01864 TMatrix4x4<T> rotation;
01865
01866 rotation.setRotationY(phi);
01867 *this *= rotation;
01868 }
01869
01870 template <typename T>
01871 void TMatrix4x4<T>::setRotationY(const TAngle<T>& phi)
01872
01873 {
01874 m22 = m44 = 1;
01875
01876 m12 = m14
01877 = m21 = m23 = m24
01878 = m32 = m34
01879 = m41 = m42 = m43
01880 = 0;
01881
01882 m11 = m33 = cos(phi);
01883 m31 = -(m13 = sin(phi));
01884 }
01885
01886 template <typename T>
01887 BALL_INLINE
01888 void TMatrix4x4<T>::rotateZ(const TAngle<T>& phi)
01889
01890 {
01891 TMatrix4x4<T> rotation;
01892
01893 rotation.setRotationZ(phi);
01894 *this *= rotation;
01895 }
01896
01897 template <typename T>
01898 void TMatrix4x4<T>::setRotationZ(const TAngle<T>& phi)
01899
01900 {
01901 m33 = m44 = 1;
01902
01903 m13 = m14 = m23 = m24 = m31 =
01904 m32 = m34 = m41 = m42 = m43 = 0;
01905
01906 m11 = m22 = cos(phi);
01907 m12 = -(m21 = sin(phi));
01908 }
01909
01910 template <typename T>
01911 BALL_INLINE
01912 void TMatrix4x4<T>::rotate(const TAngle<T>& phi, const TVector3<T>& v)
01913
01914 {
01915 rotate(phi, v.x, v.y, v.z);
01916 }
01917
01918 template <typename T>
01919 BALL_INLINE
01920 void TMatrix4x4<T>::rotate(const TAngle<T>& phi, const TVector4<T>& v)
01921
01922 {
01923 rotate(phi, v.x, v.y, v.z);
01924 }
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982 template <typename T>
01983 void TMatrix4x4<T>::rotate(const TAngle<T>& phi, const T& ax, const T& ay, const T& az)
01984
01985 {
01986 T xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
01987 T x = ax;
01988 T y = ay;
01989 T z = az;
01990
01991 double sin_angle = sin(phi);
01992 double cos_angle = cos(phi);
01993
01994 xx = x * x;
01995 yy = y * y;
01996 zz = z * z;
01997
01998 T mag = sqrt(xx + yy + zz);
01999
02000 if (mag == (T)0)
02001 {
02002 m12 = m13 = m14 = m21 = m23 = m24 = m31 = m32 = m34 = m41 = m42 = m43 = 0;
02003 m11 = m22 = m33 = m44 = (T)1;
02004 }
02005
02006 x /= mag;
02007 y /= mag;
02008 z /= mag;
02009
02010
02011
02012
02013 xx = x*x;
02014 yy = y*y;
02015 zz = z*z;
02016
02017 xy = x * y;
02018 yz = y * z;
02019 zx = z * x;
02020 xs = (T) (x * sin_angle);
02021 ys = (T) (y * sin_angle);
02022 zs = (T) (z * sin_angle);
02023 one_c = (T) (1 - cos_angle);
02024
02025 m11 = (T)( (one_c * xx) + cos_angle );
02026 m12 = (one_c * xy) - zs;
02027 m13 = (one_c * zx) + ys;
02028 m14 = 0;
02029
02030 m21 = (one_c * xy) + zs;
02031 m22 = (T) ((one_c * yy) + cos_angle);
02032 m23 = (one_c * yz) - xs;
02033 m24 = 0;
02034
02035 m31 = (one_c * zx) - ys;
02036 m32 = (one_c * yz) + xs;
02037 m33 = (T) ((one_c * zz) + cos_angle);
02038 m34 = 0;
02039
02040 m41 = 0;
02041 m42 = 0;
02042 m43 = 0;
02043 m44 = 1;
02044 }
02045
02046 template <typename T>
02047 void TMatrix4x4<T>::setRotation(const TAngle<T>& phi, const T& x, const T& y, const T& z)
02048
02049 {
02050 m12 = m13 = m14 = m21 = m23 = m24 = m31 = m32 = m34 = m41 = m42 = m43 = 0;
02051 m11 = m22 = m33 = m44 = (T)1;
02052 rotate(phi, x, y, z);
02053 }
02054
02055 template <typename T>
02056 BALL_INLINE
02057 void TMatrix4x4<T>::setRotation(const TAngle<T>& phi, const TVector3<T>& v)
02058
02059 {
02060 m12 = m13 = m14 = m21 = m23 = m24 = m31 = m32 = m34 = m41 = m42 = m43 = 0;
02061 m11 = m22 = m33 = m44 = (T)1;
02062 rotate(phi, v.x, v.y, v.z);
02063 }
02064
02065 template <typename T>
02066 BALL_INLINE
02067 void TMatrix4x4<T>::setRotation(const TAngle<T>& phi, const TVector4<T>& v)
02068
02069 {
02070 m12 = m13 = m14 = m21 = m23 = m24 = m31 = m32 = m34 = m41 = m42 = m43 = 0;
02071 m11 = m22 = m33 = m44 = (T)1;
02072 rotate(phi, v.x, v.y, v.z);
02073 }
02074
02075 template <typename T>
02076 bool TMatrix4x4<T>::operator == (const TMatrix4x4<T>& m) const
02077
02078 {
02079 return
02080 ( m11 == m.m11
02081 && m12 == m.m12
02082 && m13 == m.m13
02083 && m14 == m.m14
02084 && m21 == m.m21
02085 && m22 == m.m22
02086 && m23 == m.m23
02087 && m24 == m.m24
02088 && m31 == m.m31
02089 && m32 == m.m32
02090 && m33 == m.m33
02091 && m34 == m.m34
02092 && m41 == m.m41
02093 && m42 == m.m42
02094 && m43 == m.m43
02095 && m44 == m.m44);
02096 }
02097
02098 template <typename T>
02099 bool TMatrix4x4<T>::operator != (const TMatrix4x4<T>& m) const
02100
02101 {
02102 return
02103 ( m11 != m.m11
02104 || m12 != m.m12
02105 || m13 != m.m13
02106 || m14 != m.m14
02107 || m21 != m.m21
02108 || m22 != m.m22
02109 || m23 != m.m23
02110 || m24 != m.m24
02111 || m31 != m.m31
02112 || m32 != m.m32
02113 || m33 != m.m33
02114 || m34 != m.m34
02115 || m41 != m.m41
02116 || m42 != m.m42
02117 || m43 != m.m43
02118 || m44 != m.m44);
02119 }
02120
02121 template <typename T>
02122 bool TMatrix4x4<T>::isIdentity() const
02123
02124 {
02125 return
02126 ( m11 == (T)1
02127 && m12 == (T)0
02128 && m13 == (T)0
02129 && m14 == (T)0
02130 && m21 == (T)0
02131 && m22 == (T)1
02132 && m23 == (T)0
02133 && m24 == (T)0
02134 && m31 == (T)0
02135 && m32 == (T)0
02136 && m33 == (T)1
02137 && m34 == (T)0
02138 && m41 == (T)0
02139 && m42 == (T)0
02140 && m43 == (T)0
02141 && m44 == (T)1);
02142 }
02143
02144 template <typename T>
02145 BALL_INLINE
02146 bool TMatrix4x4<T>::isRegular() const
02147
02148 {
02149 return (getDeterminant() != (T)0);
02150 }
02151
02152 template <typename T>
02153 BALL_INLINE
02154 bool TMatrix4x4<T>::isSingular() const
02155
02156 {
02157 return (getDeterminant() == (T)0);
02158 }
02159
02160 template <typename T>
02161 bool TMatrix4x4<T>::isSymmetric() const
02162
02163 {
02164 return ( m12 == m21 && m13 == m31
02165 && m14 == m41 && m23 == m32
02166 && m24 == m42 && m34 == m43);
02167 }
02168
02169 template <typename T>
02170 bool TMatrix4x4<T>::isLowerTriangular() const
02171
02172 {
02173 return ( m12 == (T)0
02174 && m13 == (T)0
02175 && m14 == (T)0
02176 && m23 == (T)0
02177 && m24 == (T)0
02178 && m34 == (T)0);
02179 }
02180
02181 template <typename T>
02182 bool TMatrix4x4<T>::isUpperTriangular() const
02183
02184 {
02185 return ( m21 == (T)0
02186 && m31 == (T)0
02187 && m32 == (T)0
02188 && m41 == (T)0
02189 && m42 == (T)0
02190 && m43 == (T)0);
02191 }
02192
02193 template <typename T>
02194 BALL_INLINE
02195 bool TMatrix4x4<T>::isDiagonal() const
02196
02197 {
02198 return ( m12 == (T)0
02199 && m13 == (T)0
02200 && m14 == (T)0
02201 && m21 == (T)0
02202 && m23 == (T)0
02203 && m24 == (T)0
02204 && m31 == (T)0
02205 && m32 == (T)0
02206 && m34 == (T)0
02207 && m41 == (T)0
02208 && m42 == (T)0
02209 && m43 == (T)0);
02210 }
02211
02212 template <typename T>
02213 bool TMatrix4x4<T>::isValid() const
02214
02215 {
02216 T **ptr = (T **)comp_ptr_;
02217
02218 return ( *ptr++ == &m11
02219 && *ptr++ == &m12
02220 && *ptr++ == &m13
02221 && *ptr++ == &m14
02222 && *ptr++ == &m21
02223 && *ptr++ == &m22
02224 && *ptr++ == &m23
02225 && *ptr++ == &m24
02226 && *ptr++ == &m31
02227 && *ptr++ == &m32
02228 && *ptr++ == &m33
02229 && *ptr++ == &m34
02230 && *ptr++ == &m41
02231 && *ptr++ == &m42
02232 && *ptr++ == &m43
02233 && *ptr == &m44);
02234 }
02235
02236 template <typename T>
02237 std::istream& operator >> (std::istream& s, TMatrix4x4<T>& m)
02238
02239 {
02240 char c;
02241 s >> c
02242 >> m.m11 >> m.m12 >> m.m13 >> m.m14 >> c >> c
02243 >> m.m21 >> m.m22 >> m.m23 >> m.m24 >> c >> c
02244 >> m.m31 >> m.m32 >> m.m33 >> m.m34 >> c >> c
02245 >> m.m41 >> m.m42 >> m.m43 >> m.m44 >> c;
02246
02247 return s;
02248 }
02249
02250 template <typename T>
02251 std::ostream& operator << (std::ostream& s, const TMatrix4x4<T>& m)
02252
02253 {
02254 s << '/' << std::setw(14) << m.m11 << ' ' << std::setw(14) << m.m12 << ' ' << std::setw(14) << m.m13 << ' ' << std::setw(14) << m.m14 << " \\" << std::endl
02255 << '|' << std::setw(14) << m.m21 << ' ' << std::setw(14) << m.m22 << ' ' << std::setw(14) << m.m23 << ' ' << std::setw(14) << m.m24 << " |" << std::endl
02256 << '|' << std::setw(14) << m.m31 << ' ' << std::setw(14) << m.m32 << ' ' << std::setw(14) << m.m33 << ' ' << std::setw(14) << m.m34 << " |" << std::endl
02257 << '\\' << std::setw(14) << m.m41 << ' ' << std::setw(14) << m.m42 << ' ' << std::setw(14) << m.m43 << ' ' << std::setw(14) << m.m44 << " /" << std::endl;
02258
02259 return s;
02260 }
02261
02262 template <typename T>
02263 void TMatrix4x4<T>::dump(std::ostream& s, Size depth) const
02264
02265 {
02266 BALL_DUMP_STREAM_PREFIX(s);
02267
02268 BALL_DUMP_HEADER(s, this, this);
02269
02270 BALL_DUMP_DEPTH(s, depth);
02271 s << m11 << " " << m12 << " " << m13 << " " << m14 << std::endl;
02272
02273 BALL_DUMP_DEPTH(s, depth);
02274 s << m21 << " " << m22 << " " << m23 << " " << m24 << std::endl;
02275
02276 BALL_DUMP_DEPTH(s, depth);
02277 s << m31 << " " << m32 << " " << m33 << " " << m34 << std::endl;
02278
02279 BALL_DUMP_DEPTH(s, depth);
02280 s << m41 << " " << m42 << " " << m43 << " " << m44 << std::endl;
02281
02282 BALL_DUMP_STREAM_SUFFIX(s);
02283 }
02284
02286 template <typename T>
02287 TMatrix4x4<T> operator * (const T& scalar, const TMatrix4x4<T>& m)
02288 ;
02289
02291 template <typename T>
02292 TVector3<T> operator * (const TMatrix4x4<T>& matrix, const TVector3<T>& vector)
02293 ;
02294
02299 typedef TMatrix4x4<float> Matrix4x4;
02300
02301 }
02302
02303 #endif // BALL_MATHS_MATRIX44_H