C++ utility library for linear algebra, etc.
vec4.h
- Committer:
- gltest26
- Date:
- 2012-07-23
- Revision:
- 0:189617a75df4
File content as of revision 0:189617a75df4:
#ifndef CPPLIB_VEC4_H #define CPPLIB_VEC4_H /** \file * \brief Definition of simple vector in 4-dimension. * * It also declares constants of vectors and friend operators that * enable vector arithmetics of arbitrary order. */ #include <math.h> #include <assert.h> namespace cpplib{ template<typename T> class Vec3; /** \brief Vector in 4-dimension with arbitrary elements. * * Collaborates with Vec3, Quatd and Mat4. */ template<typename T> class Vec4{ typedef Vec4<T> tt; T a[4]; public: typedef T intype[4]; Vec4(){} Vec4(const T o[4]){a[0] = o[0], a[1] = o[1], a[2] = o[2], a[3] = o[3];} Vec4(T x, T y, T z, T w){a[0] = x, a[1] = y, a[2] = z, a[3] = w;} Vec4(const Vec3<T> &vec3, T w){a[0] = vec3[0], a[1] = vec3[1], a[2] = vec3[2], a[3] = w;} void clear(){a[0] = a[1] = a[2] = a[3] = 0;} // assign zero element tt &addin(const tt &o){ a[0] += o.a[0], a[1] += o.a[1], a[2] += o.a[2], a[3] += o.a[3]; return *this; } tt add(const tt &o)const{ return tt(a[0] + o.a[0], a[1] + o.a[1], a[2] + o.a[2], a[3] + o.a[3]); } T len()const{ return ::sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]); } T slen()const{ return a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]; } tt norm()const{ double s = len(); return tt(a[0]/s,a[1]/s,a[2]/s,a[3]/s); } tt &normin(){ double s = len(); a[0] /= s, a[1] /= s, a[2] /= s, a[3] /= s; return *this; } tt operator-()const{return tt(-a[0], -a[1], -a[2], -a[3]);} tt &operator+=(const tt &o){return addin(o);} tt operator+(const tt &o)const{return add(o);} tt &operator-=(const tt &o){return addin(-o);} tt operator-(const tt &o)const{return add(-o);} tt &scalein(T s){ a[0] *= s, a[1] *= s, a[2] *= s, a[3] *= s; return *this; } tt scale(T s)const{ tt ret = *this; ret.scalein(s); return ret; } T sp(const tt &o)const{ return a[0] * o.a[0] + a[1] * o.a[1] + a[2] * o.a[2] + a[3] * o.a[3]; } tt &operator*=(const T s){return scalein(s);} tt operator*(const T s)const{return scale(s);} tt &operator/=(const T s); ///< \brief Divide by a scalar. tt operator/(const T s)const; ///< \brief Create divided version of this by given scalar. friend tt operator*(const T s, const tt &o){return o * s;} operator T*(){return a;} operator const T*()const{return a;} bool operator==(const tt &o)const{return a[0] == o.a[0] && a[1] == o.a[1] && a[2] == o.a[2] && a[3] == o.a[3];} bool operator!=(const tt &o)const{return !operator==(o);} /// cast to T* do the job, but range is not checked. T operator[](int i)const{assert(0 <= i && i < 4); return a[i];} T &operator[](int i){assert(0 <= i && i < 4); return a[i];} /// cast to T(*[4]) do not cope with cast to T*, so here is a unary operator to explicitly do this. intype *operator ~(){return &a;} const intype *operator ~()const{return &a;} /// Converting elements to a given type requires explicit call. template<typename T2> Vec4<T2> cast()const; operator Vec3<T>()const{return Vec3<T>(a[0],a[1],a[2]);} /// Array to Class pointer converter static tt &atoc(T *a){return *reinterpret_cast<tt*>(a);} }; typedef Vec4<double> Vec4d; ///< Type definition for double vector. typedef Vec4<float> Vec4f; ///< Type definition for float vector. typedef Vec4<int> Vec4i; ///< Type definition for int vector. extern const Vec4d &vec4_0001(); extern const Vec4d &vec4_0010(); extern const Vec4d &vec4_0100(); extern const Vec4d &vec4_1000(); //----------------------------------------------------------------------------- // Implementation //----------------------------------------------------------------------------- /// Division is not equivalent to scale with inverse in case of integral component type. template<typename T> inline Vec4<T> &Vec4<T>::operator/=(const T s){ a[0] /= s, a[1] /= s, a[2] /= s, a[3] /= s; return *this; } /// Division is not equivalent to scale with inverse in case of integral component type. template<typename T> inline Vec4<T> Vec4<T>::operator/(const T s)const{ return Vec4<T>(a[0] / s, a[1] / s, a[2] / s, a[3] / s); } template<typename T> template<typename T2> Vec4<T2> Vec4<T>::cast()const{ return Vec4<T2>( static_cast<T2>(a[0]), static_cast<T2>(a[1]), static_cast<T2>(a[2]), static_cast<T2>(a[3])); } } using namespace cpplib; #endif