C++ utility library for linear algebra, etc.
vec4.h@0:189617a75df4, 2012-07-23 (annotated)
- 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?
User | Revision | Line number | New 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 |