#ifndef __GEOMETRY_H__ #define __GEOMETRY_H__ #include #include #include template class mat; template struct vec { vec() { for (size_t i=DIM; i--; data_[i] = T()); } T& operator[](const size_t i) { assert(i struct vec<2,T> { vec() : x(T()), y(T()) {} vec(T X, T Y) : x(X), y(Y) {} template vec<2,T>(const vec<2,U> &v); T& operator[](const size_t i) { assert(i<2); return i<=0 ? x : y; } const T& operator[](const size_t i) const { assert(i<2); return i<=0 ? x : y; } T x,y; }; ///////////////////////////////////////////////////////////////////////////////// template struct vec<3,T> { vec() : x(T()), y(T()), z(T()) {} vec(T X, T Y, T Z) : x(X), y(Y), z(Z) {} template vec<3,T>(const vec<3,U> &v); T& operator[](const size_t i) { assert(i<3); return i<=0 ? x : (1==i ? y : z); } const T& operator[](const size_t i) const { assert(i<3); return i<=0 ? x : (1==i ? y : z); } float norm() { return std::sqrt(x*x+y*y+z*z); } vec<3,T> & normalize(T l=1) { *this = (*this)*(l/norm()); return *this; } T x,y,z; }; ///////////////////////////////////////////////////////////////////////////////// template T operator*(const vec& lhs, const vec& rhs) { T ret = T(); for (size_t i=DIM; i--; ret+=lhs[i]*rhs[i]); return ret; } templatevec operator+(vec lhs, const vec& rhs) { for (size_t i=DIM; i--; lhs[i]+=rhs[i]); return lhs; } templatevec operator-(vec lhs, const vec& rhs) { for (size_t i=DIM; i--; lhs[i]-=rhs[i]); return lhs; } template vec operator*(vec lhs, const U& rhs) { for (size_t i=DIM; i--; lhs[i]*=rhs); return lhs; } template vec operator/(vec lhs, const U& rhs) { for (size_t i=DIM; i--; lhs[i]/=rhs); return lhs; } template vec embed(const vec &v, T fill=1) { vec ret; for (size_t i=LEN; i--; ret[i]=(i vec proj(const vec &v) { vec ret; for (size_t i=LEN; i--; ret[i]=v[i]); return ret; } template vec<3,T> cross(vec<3,T> v1, vec<3,T> v2) { return vec<3,T>(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x); } #if 0 template std::ostream& operator<<(std::ostream& out, vec& v) { for(unsigned int i=0; i struct dt { static T det(const mat& src) { T ret=0; for (size_t i=DIM; i--; ret += src[0][i]*src.cofactor(0,i)); return ret; } }; template struct dt<1,T> { static T det(const mat<1,1,T>& src) { return src[0][0]; } }; ///////////////////////////////////////////////////////////////////////////////// template class mat { vec rows[DimRows]; public: mat() {} vec& operator[] (const size_t idx) { assert(idx& operator[] (const size_t idx) const { assert(idx col(const size_t idx) const { assert(idx ret; for (size_t i=DimRows; i--; ret[i]=rows[i][idx]); return ret; } void set_col(size_t idx, vec v) { assert(idx identity() { mat ret; for (size_t i=DimRows; i--; ) for (size_t j=DimCols;j--; ret[i][j]=(i==j)); return ret; } T det() const { return dt::det(*this); } mat get_minor(size_t row, size_t col) const { mat ret; for (size_t i=DimRows-1; i--; ) for (size_t j=DimCols-1;j--; ret[i][j]=rows[i adjugate() const { mat ret; for (size_t i=DimRows; i--; ) for (size_t j=DimCols; j--; ret[i][j]=cofactor(i,j)); return ret; } mat invert_transpose() { mat ret = adjugate(); T tmp = ret[0]*rows[0]; return ret/tmp; } mat invert() { return invert_transpose().transpose(); } mat transpose() { mat ret; for (size_t i=DimCols; i--; ret[i]=this->col(i)); return ret; } }; ///////////////////////////////////////////////////////////////////////////////// template vec operator*(const mat& lhs, const vec& rhs) { vec ret; for (size_t i=DimRows; i--; ret[i]=lhs[i]*rhs); return ret; } templatemat operator*(const mat& lhs, const mat& rhs) { mat result; for (size_t i=R1; i--; ) for (size_t j=C2; j--; result[i][j]=lhs[i]*rhs.col(j)); return result; } templatemat operator/(mat lhs, const T& rhs) { for (size_t i=DimRows; i--; lhs[i]=lhs[i]/rhs); return lhs; } #if 0 template std::ostream& operator<<(std::ostream& out, mat& m) { for (size_t i=0; i Vec2f; typedef vec<2, int> Vec2i; typedef vec<3, float> Vec3f; typedef vec<3, int> Vec3i; typedef vec<4, float> Vec4f; typedef mat<4,4,float> Matrix; #endif //__GEOMETRY_H__