// -*- C++ -*- /* * Simple MultimEdia LiTerator(SMELT) * by Chris Xiong 2015 * Math header & implementation * * WARNING: This library is in development and interfaces would be very * unstable. * */ #ifndef SMMATH_H #define SMMATH_H #include #include #define sqr(x) ((x)*(x)) #define EPS 1e-8 #ifndef PI #define PI 3.14159265358979323846f #endif templateconst T& min(const T& a,const T& b){return aconst T& max(const T& a,const T& b){return a>b?a:b;} class smMath { public: static double deg2rad(double deg){return deg/180.*PI;} static double rad2deg(double rad){return rad/PI*180.;} static double clamprad(double a){while(a<0)a+=2*PI;while(a>2*PI)a-=2*PI;return a;} static double clampdeg(double a){while(a<0)a+=360.;while(a>360)a-=360.;return a;} }; class smvec2d { public: double x,y; smvec2d(double _x,double _y){x=_x;y=_y;} smvec2d(){x=y=.0;} double l(){return sqrt(sqr(x)+sqr(y));} void normalize(){double L=l();if(L=0&&s<4)return m+s*4;else return NULL;} void clear(){for(int i=0;i<16;++i)m[i]=.0;} void loadIdentity(){clear();m[0]=m[5]=m[10]=m[15]=1.;} void rotate(double a,double x,double y,double z) { if(smvec3d(x,y,z).l()<=EPS)return; if(fabs(smvec3d(x,y,z).l()-1)>EPS) { smvec3d a(x,y,z);a.normalize(); x=a.x;y=a.y;z=a.z; } smMatrix tmp; tmp[0][0]=x*x*(1-cos(a))+cos(a); tmp[1][0]=x*y*(1-cos(a))-z*sin(a); tmp[2][0]=x*z*(1-cos(a))+y*sin(a); tmp[0][1]=y*x*(1-cos(a))+z*sin(a); tmp[1][1]=y*y*(1-cos(a))+cos(a); tmp[2][1]=y*z*(1-cos(a))-x*sin(a); tmp[0][2]=x*z*(1-cos(a))-y*sin(a); tmp[1][2]=y*z*(1-cos(a))+x*sin(a); tmp[2][2]=z*z*(1-cos(a))+cos(a); tmp[3][3]=1; *this=*this*tmp; } void lookat(smvec3d eye,smvec3d at,smvec3d up) { smvec3d f=at-eye;f.normalize();up.normalize(); smvec3d s=f*up;smvec3d u=s.getNormalized()*f; m[0]= s.x;m[4]= s.y;m[ 8]= s.z;m[12]=0; m[1]= u.x;m[5]= u.y;m[ 9]= u.z;m[13]=0; m[2]=-f.x;m[6]=-f.y;m[10]=-f.z;m[14]=0; m[3]= 0;m[7]= 0;m[11]= 0;m[15]=1; } friend smMatrix operator *(smMatrix a,smMatrix b) { smMatrix ret; for(int i=0;i<4;++i) for(int j=0;j<4;++j) for(int k=0;k<4;++k) ret[i][j]+=a[i][k]*b[k][j]; return ret; } friend smvec3d operator *(smMatrix a,smvec3d b) { return smvec3d(a[0][0]*b.x+a[1][0]*b.y+a[2][0]*b.z, a[0][1]*b.x+a[1][1]*b.y+a[2][1]*b.z, a[0][2]*b.x+a[1][2]*b.y+a[2][2]*b.z); } friend smvec4d operator *(smMatrix a,smvec4d b) { return smvec4d(a[0][0]*b.x+a[1][0]*b.y+a[2][0]*b.z+a[3][0]*b.w, a[0][1]*b.x+a[1][1]*b.y+a[2][1]*b.z+a[3][1]*b.w, a[0][2]*b.x+a[1][2]*b.y+a[2][2]*b.z+a[3][2]*b.w, a[0][3]*b.x+a[1][3]*b.y+a[2][3]*b.z+a[3][3]*b.w); } }; #endif