00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "omatrix.h"
00018
00019 namespace NUM
00020 {
00021
00022
00023
00024
00025 void _OMatrixInstantiationDummy()
00026 {
00027 {
00028 OMatrix<dbl> *a=NULL,b(OMatrix<dbl>::Mul,*a,*a);
00029 *a*=b; *a/=b;
00030 Vector3<dbl> *v=NULL;
00031 OMatrix<dbl> c(OMatrix<dbl>::Rotate,*v,0.1);
00032 OMatrix<dbl> d(OMatrix<dbl>::Invers,c);
00033 }
00034 {
00035 OMatrix<flt> *a=NULL,b(OMatrix<flt>::Mul,*a,*a);
00036 *a*=b; *a/=b;
00037 Vector3<flt> *v=NULL;
00038 OMatrix<flt> c(OMatrix<flt>::Rotate,*v,0.1);
00039 OMatrix<flt> d(OMatrix<flt>::Invers,c);
00040 }
00041 }
00042
00043
00044 template<typename T>OMatrix<T>::OMatrix(
00045 enum OMatrix<T>::_Mul,const OMatrix<T> &a,const OMatrix<T> &b)
00046 {
00047 for(short int i=0; i<3; i++)
00048 {
00049 for(short int j=0; j<3; j++)
00050 { m[i][j] = a.m[i][0]*b.m[0][j]
00051 + a.m[i][1]*b.m[1][j]
00052 + a.m[i][2]*b.m[2][j]; }
00053 m[i][3] = a.m[i][0]*b.m[0][3]
00054 + a.m[i][1]*b.m[1][3]
00055 + a.m[i][2]*b.m[2][3]
00056 + a.m[i][3];
00057 }
00058 }
00059
00060
00061 template<typename T>OMatrix<T> &OMatrix<T>::operator*=(const OMatrix<T> &b)
00062 {
00063 T tmp[4];
00064
00065 for(short int i=0; i<3; i++)
00066 {
00067
00068 tmp[0]=m[i][0]; tmp[1]=m[i][1]; tmp[2]=m[i][2]; tmp[3]=m[i][3];
00069
00070 for(short int j=0; j<3; j++)
00071 { m[i][j] = tmp[0]*b.m[0][j]
00072 + tmp[1]*b.m[1][j]
00073 + tmp[2]*b.m[2][j]; }
00074
00075 m[i][3] = tmp[0]*b.m[0][3]
00076 + tmp[1]*b.m[1][3]
00077 + tmp[2]*b.m[2][3]
00078 + tmp[3];
00079 }
00080
00081 return(*this);
00082 }
00083
00084
00085 template<typename T>OMatrix<T> &OMatrix<T>::operator/=(const OMatrix<T> &a)
00086 {
00087 T tmp[3];
00088
00089 for(short int j=0; j<3; j++)
00090 {
00091
00092 tmp[0]=m[0][j]; tmp[1]=m[1][j]; tmp[2]=m[2][j];
00093
00094 for(short int i=0; i<3; i++)
00095 { m[i][j] = a.m[i][0]*tmp[0]
00096 + a.m[i][1]*tmp[1]
00097 + a.m[i][2]*tmp[2]; }
00098 }
00099
00100
00101 tmp[0]=m[0][3]; tmp[1]=m[1][3]; tmp[2]=m[2][3];
00102 for(short int j=0; j<3; j++)
00103 {
00104 m[j][3] = a.m[j][0]*tmp[0]
00105 + a.m[j][1]*tmp[1]
00106 + a.m[j][2]*tmp[2]
00107 + a.m[j][3];
00108 }
00109
00110 return(*this);
00111 }
00112
00113
00114 template<typename T>OMatrix<T>::OMatrix(
00115 enum OMatrix<T>::_Rotate,const Vector3<T> &axis,T angle)
00116 {
00117 T s,c;
00118 sincos(angle,&s,&c);
00119 T c1=1-c;
00120
00126
00127 T sq;
00128 sq=sqr(axis[0]); m[0][0] = sq + c*(1-sq);
00129 sq=sqr(axis[1]); m[1][1] = sq + c*(1-sq);
00130 sq=sqr(axis[2]); m[2][2] = sq + c*(1-sq);
00131
00132 T tmp = axis[0]*axis[1]*c1;
00133 T tmp2 = axis[2]*s;
00134 m[0][1] = tmp + tmp2;
00135 m[1][0] = tmp - tmp2;
00136
00137 tmp = axis[0]*axis[2]*c1;
00138 tmp2 = axis[1]*s;
00139 m[0][2] = tmp - tmp2;
00140 m[2][0] = tmp + tmp2;
00141
00142 tmp = axis[1]*axis[2]*c1;
00143 tmp2 = axis[0]*s;
00144 m[1][2] = tmp + tmp2;
00145 m[2][1] = tmp - tmp2;
00146 }
00147
00148
00149 template<typename T>OMatrix<T>::OMatrix(
00150 enum OMatrix<T>::_Invers,const OMatrix<T> &a)
00151 {
00152
00153
00154
00155
00156
00157
00158 T a0211 = a[0][2]*a[1][1];
00159 T a2201 = a[2][2]*a[0][1];
00160 T a1221 = a[1][2]*a[2][1];
00161 T a0022 = a[0][0]*a[2][2];
00162 T a2012 = a[2][0]*a[1][2];
00163 T a1002 = a[1][0]*a[0][2];
00164
00165 T fact = a0022*a[1][1] - a0211*a[2][0]
00166 + a2012*a[0][1] - a2201*a[1][0]
00167 + a1002*a[2][1] - a1221*a[0][0];
00168 fact=1/fact;
00169
00170
00171 m[0][0] = (a[1][1]*a[2][2] - a1221)*fact;
00172 m[0][1] = (a[2][1]*a[0][2] - a2201)*fact;
00173 m[0][2] = (a[0][1]*a[1][2] - a0211)*fact;
00174
00175
00176 m[1][0] = (a2012 - a[1][0]*a[2][2])*fact;
00177 m[1][1] = (a0022 - a[2][0]*a[0][2])*fact;
00178 m[1][2] = (a1002 - a[0][0]*a[1][2])*fact;
00179
00180
00181 m[2][0] = (a[1][0]*a[2][1] - a[2][0]*a[1][1])*fact;
00182 m[2][1] = (a[2][0]*a[0][1] - a[0][0]*a[2][1])*fact;
00183 m[2][2] = (a[0][0]*a[1][1] - a[1][0]*a[0][1])*fact;
00184
00185
00186
00187
00188 m[0][3] = - m[0][0] * a[0][3] - m[0][1] * a[1][3] - m[0][2] * a[2][3];
00189 m[1][3] = - m[1][0] * a[0][3] - m[1][1] * a[1][3] - m[1][2] * a[2][3];
00190 m[2][3] = - m[2][0] * a[0][3] - m[2][1] * a[1][3] - m[2][2] * a[2][3];
00191 }
00192
00193 }
00194
00195
00196 #if 0
00197
00198
00199 typedef NUM::OMatrix<dbl> OMatrix;
00200
00201 #include <stdio.h>
00202 #include <stdlib.h>
00203
00204 static void Print(const OMatrix &m)
00205 {
00206 for(int r=0; r<3; r++)
00207 {
00208 for(int c=0; c<4; c++)
00209 {
00210 char tmp[32];
00211 snprintf(tmp,32,"%g",m[r][c]);
00212 printf("%12s ",tmp);
00213 }
00214 printf("\n");
00215 }
00216 }
00217
00218 int main()
00219 {
00220 OMatrix a,b;
00221 for(int i=0; i<20; i++)
00222 {
00223
00224 for(int i=0; i<12; i++)
00225 {
00226 a[0][i]=dbl(rand())/RAND_MAX*10;
00227 b[0][i]=dbl(rand())/RAND_MAX*10;
00228 }
00229
00230 OMatrix p1=a*b;
00231 OMatrix p2=a; p2*=b;
00232 OMatrix p3=b; p3/=a;
00233
00234 if(!NUM::equal(p1,p2,1e-10) || !NUM::equal(p1,p3,1e-10))
00235 { printf("OOPS: NEQ\n"); }
00236 }
00237
00238 for(int _i=0; _i<20; _i++)
00239 {
00240
00241 for(int i=0; i<12; i++)
00242 { a[0][i]=dbl(rand())/RAND_MAX*10; }
00243
00244 OMatrix inv(OMatrix::Invers,a);
00245
00246 b=inv*a-OMatrix(OMatrix::Ident);
00247 if(!b.IsNull(1e-12))
00248 { printf("OOPS(INV)\n"); Print(b); }
00249
00250 b=a*inv-OMatrix(OMatrix::Ident);
00251 if(!b.IsNull(1e-12))
00252 { printf("OOPS(INV)\n"); Print(b); }
00253 }
00254
00255 printf("DONE\n");
00256 }
00257 #endif