#ifndef __GEOMETRY_H__ #define __GEOMETRY_H__ #include #include #include #include template struct vec { vec() { for (size_t i=DIM; i--; data_[i] = T()); } T& operator[](const size_t i) { assert(i Vec2f; typedef vec<3, float> Vec3f; typedef vec<3, int > Vec3i; typedef vec<4, float> Vec4f; template 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) {} 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 struct vec<4,T> { vec() : x(T()), y(T()), z(T()), w(T()) {} vec(T X, T Y, T Z, T W) : x(X), y(Y), z(Z), w(W) {} T& operator[](const size_t i) { assert(i<4); return i<=0 ? x : (1==i ? y : (2==i ? z : w)); } const T& operator[](const size_t i) const { assert(i<4); return i<=0 ? x : (1==i ? y : (2==i ? z : w)); } T x,y,z,w; }; 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*(const vec &lhs, const U& rhs) { vec ret; for (size_t i=DIM; i--; ret[i]=lhs[i]*rhs); return ret; } template vec operator-(const vec &lhs) { return lhs*T(-1); } 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); } template std::ostream& operator<<(std::ostream& out, const vec& v) { for(unsigned int i=0; i