C++ utility library for linear algebra, etc.

Committer:
gltest26
Date:
Mon Jul 23 00:15:20 2012 +0000
Revision:
0:189617a75df4
Imported cpplib frequently used headers

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gltest26 0:189617a75df4 1 #ifndef CPPLIB_VEC4_H
gltest26 0:189617a75df4 2 #define CPPLIB_VEC4_H
gltest26 0:189617a75df4 3 /** \file
gltest26 0:189617a75df4 4 * \brief Definition of simple vector in 4-dimension.
gltest26 0:189617a75df4 5 *
gltest26 0:189617a75df4 6 * It also declares constants of vectors and friend operators that
gltest26 0:189617a75df4 7 * enable vector arithmetics of arbitrary order.
gltest26 0:189617a75df4 8 */
gltest26 0:189617a75df4 9 #include <math.h>
gltest26 0:189617a75df4 10 #include <assert.h>
gltest26 0:189617a75df4 11
gltest26 0:189617a75df4 12 namespace cpplib{
gltest26 0:189617a75df4 13
gltest26 0:189617a75df4 14 template<typename T> class Vec3;
gltest26 0:189617a75df4 15
gltest26 0:189617a75df4 16 /** \brief Vector in 4-dimension with arbitrary elements.
gltest26 0:189617a75df4 17 *
gltest26 0:189617a75df4 18 * Collaborates with Vec3, Quatd and Mat4.
gltest26 0:189617a75df4 19 */
gltest26 0:189617a75df4 20 template<typename T> class Vec4{
gltest26 0:189617a75df4 21 typedef Vec4<T> tt;
gltest26 0:189617a75df4 22 T a[4];
gltest26 0:189617a75df4 23 public:
gltest26 0:189617a75df4 24 typedef T intype[4];
gltest26 0:189617a75df4 25 Vec4(){}
gltest26 0:189617a75df4 26 Vec4(const T o[4]){a[0] = o[0], a[1] = o[1], a[2] = o[2], a[3] = o[3];}
gltest26 0:189617a75df4 27 Vec4(T x, T y, T z, T w){a[0] = x, a[1] = y, a[2] = z, a[3] = w;}
gltest26 0:189617a75df4 28 Vec4(const Vec3<T> &vec3, T w){a[0] = vec3[0], a[1] = vec3[1], a[2] = vec3[2], a[3] = w;}
gltest26 0:189617a75df4 29 void clear(){a[0] = a[1] = a[2] = a[3] = 0;} // assign zero element
gltest26 0:189617a75df4 30 tt &addin(const tt &o){
gltest26 0:189617a75df4 31 a[0] += o.a[0], a[1] += o.a[1], a[2] += o.a[2], a[3] += o.a[3];
gltest26 0:189617a75df4 32 return *this;
gltest26 0:189617a75df4 33 }
gltest26 0:189617a75df4 34 tt add(const tt &o)const{
gltest26 0:189617a75df4 35 return tt(a[0] + o.a[0], a[1] + o.a[1], a[2] + o.a[2], a[3] + o.a[3]);
gltest26 0:189617a75df4 36 }
gltest26 0:189617a75df4 37 T len()const{
gltest26 0:189617a75df4 38 return ::sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
gltest26 0:189617a75df4 39 }
gltest26 0:189617a75df4 40 T slen()const{
gltest26 0:189617a75df4 41 return a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
gltest26 0:189617a75df4 42 }
gltest26 0:189617a75df4 43 tt norm()const{
gltest26 0:189617a75df4 44 double s = len();
gltest26 0:189617a75df4 45 return tt(a[0]/s,a[1]/s,a[2]/s,a[3]/s);
gltest26 0:189617a75df4 46 }
gltest26 0:189617a75df4 47 tt &normin(){
gltest26 0:189617a75df4 48 double s = len(); a[0] /= s, a[1] /= s, a[2] /= s, a[3] /= s;
gltest26 0:189617a75df4 49 return *this;
gltest26 0:189617a75df4 50 }
gltest26 0:189617a75df4 51 tt operator-()const{return tt(-a[0], -a[1], -a[2], -a[3]);}
gltest26 0:189617a75df4 52 tt &operator+=(const tt &o){return addin(o);}
gltest26 0:189617a75df4 53 tt operator+(const tt &o)const{return add(o);}
gltest26 0:189617a75df4 54 tt &operator-=(const tt &o){return addin(-o);}
gltest26 0:189617a75df4 55 tt operator-(const tt &o)const{return add(-o);}
gltest26 0:189617a75df4 56 tt &scalein(T s){
gltest26 0:189617a75df4 57 a[0] *= s, a[1] *= s, a[2] *= s, a[3] *= s;
gltest26 0:189617a75df4 58 return *this;
gltest26 0:189617a75df4 59 }
gltest26 0:189617a75df4 60 tt scale(T s)const{
gltest26 0:189617a75df4 61 tt ret = *this;
gltest26 0:189617a75df4 62 ret.scalein(s);
gltest26 0:189617a75df4 63 return ret;
gltest26 0:189617a75df4 64 }
gltest26 0:189617a75df4 65 T sp(const tt &o)const{
gltest26 0:189617a75df4 66 return a[0] * o.a[0] + a[1] * o.a[1] + a[2] * o.a[2] + a[3] * o.a[3];
gltest26 0:189617a75df4 67 }
gltest26 0:189617a75df4 68 tt &operator*=(const T s){return scalein(s);}
gltest26 0:189617a75df4 69 tt operator*(const T s)const{return scale(s);}
gltest26 0:189617a75df4 70 tt &operator/=(const T s); ///< \brief Divide by a scalar.
gltest26 0:189617a75df4 71 tt operator/(const T s)const; ///< \brief Create divided version of this by given scalar.
gltest26 0:189617a75df4 72 friend tt operator*(const T s, const tt &o){return o * s;}
gltest26 0:189617a75df4 73 operator T*(){return a;} operator const T*()const{return a;}
gltest26 0:189617a75df4 74 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];}
gltest26 0:189617a75df4 75 bool operator!=(const tt &o)const{return !operator==(o);}
gltest26 0:189617a75df4 76
gltest26 0:189617a75df4 77 /// cast to T* do the job, but range is not checked.
gltest26 0:189617a75df4 78 T operator[](int i)const{assert(0 <= i && i < 4); return a[i];}
gltest26 0:189617a75df4 79 T &operator[](int i){assert(0 <= i && i < 4); return a[i];}
gltest26 0:189617a75df4 80
gltest26 0:189617a75df4 81 /// cast to T(*[4]) do not cope with cast to T*, so here is a unary operator to explicitly do this.
gltest26 0:189617a75df4 82 intype *operator ~(){return &a;} const intype *operator ~()const{return &a;}
gltest26 0:189617a75df4 83
gltest26 0:189617a75df4 84 /// Converting elements to a given type requires explicit call.
gltest26 0:189617a75df4 85 template<typename T2> Vec4<T2> cast()const;
gltest26 0:189617a75df4 86 operator Vec3<T>()const{return Vec3<T>(a[0],a[1],a[2]);}
gltest26 0:189617a75df4 87
gltest26 0:189617a75df4 88 /// Array to Class pointer converter
gltest26 0:189617a75df4 89 static tt &atoc(T *a){return *reinterpret_cast<tt*>(a);}
gltest26 0:189617a75df4 90 };
gltest26 0:189617a75df4 91
gltest26 0:189617a75df4 92 typedef Vec4<double> Vec4d; ///< Type definition for double vector.
gltest26 0:189617a75df4 93 typedef Vec4<float> Vec4f; ///< Type definition for float vector.
gltest26 0:189617a75df4 94 typedef Vec4<int> Vec4i; ///< Type definition for int vector.
gltest26 0:189617a75df4 95
gltest26 0:189617a75df4 96 extern const Vec4d &vec4_0001();
gltest26 0:189617a75df4 97 extern const Vec4d &vec4_0010();
gltest26 0:189617a75df4 98 extern const Vec4d &vec4_0100();
gltest26 0:189617a75df4 99 extern const Vec4d &vec4_1000();
gltest26 0:189617a75df4 100
gltest26 0:189617a75df4 101
gltest26 0:189617a75df4 102
gltest26 0:189617a75df4 103
gltest26 0:189617a75df4 104 //-----------------------------------------------------------------------------
gltest26 0:189617a75df4 105 // Implementation
gltest26 0:189617a75df4 106 //-----------------------------------------------------------------------------
gltest26 0:189617a75df4 107
gltest26 0:189617a75df4 108 /// Division is not equivalent to scale with inverse in case of integral component type.
gltest26 0:189617a75df4 109 template<typename T>
gltest26 0:189617a75df4 110 inline Vec4<T> &Vec4<T>::operator/=(const T s){
gltest26 0:189617a75df4 111 a[0] /= s, a[1] /= s, a[2] /= s, a[3] /= s; return *this;
gltest26 0:189617a75df4 112 }
gltest26 0:189617a75df4 113
gltest26 0:189617a75df4 114 /// Division is not equivalent to scale with inverse in case of integral component type.
gltest26 0:189617a75df4 115 template<typename T>
gltest26 0:189617a75df4 116 inline Vec4<T> Vec4<T>::operator/(const T s)const{
gltest26 0:189617a75df4 117 return Vec4<T>(a[0] / s, a[1] / s, a[2] / s, a[3] / s);
gltest26 0:189617a75df4 118 }
gltest26 0:189617a75df4 119
gltest26 0:189617a75df4 120
gltest26 0:189617a75df4 121 template<typename T> template<typename T2> Vec4<T2> Vec4<T>::cast()const{
gltest26 0:189617a75df4 122 return Vec4<T2>(
gltest26 0:189617a75df4 123 static_cast<T2>(a[0]),
gltest26 0:189617a75df4 124 static_cast<T2>(a[1]),
gltest26 0:189617a75df4 125 static_cast<T2>(a[2]),
gltest26 0:189617a75df4 126 static_cast<T2>(a[3]));
gltest26 0:189617a75df4 127 }
gltest26 0:189617a75df4 128
gltest26 0:189617a75df4 129 }
gltest26 0:189617a75df4 130
gltest26 0:189617a75df4 131 using namespace cpplib;
gltest26 0:189617a75df4 132
gltest26 0:189617a75df4 133 #endif