3D Vector C++ Class
My template handles most cases with generic 3d vectors; specific behavior is defined for the floating point and integer types of vectors. You can see the latest version of the entire math package at GitHub or visit my downloadable code page./**************************************** * By Will Perone * Original: 9-16-2002 * Revised: 19-11-2003 * 11-12-2003 * 18-12-2003 * 06-06-2004 * * Dependancies: My 2D Vector class * * Notes: * if a*b = 0 then a & b are orthogonal * a%b = -b%a * a*(b%c) = (a%b)*c * a%b = a(cast to matrix)*b * (a%b).length() = area of parallelogram formed by a & b * (a%b).length() = a.length()*b.length() * sin(angle between a & b) * (a%b).length() = 0 if angle between a & b = 0 or a.length() = 0 or b.length() = 0 * a * (b%c) = volume of parallelpiped formed by a, b, c * vector triple product: a%(b%c) = b*(a*c) - c*(a*b) * scalar triple product: a*(b%c) = c*(a%b) = b*(c%a) * vector quadruple product: (a%b)*(c%d) = (a*c)*(b*d) - (a*d)*(b*c) * if a is unit vector along b then a%b = -b%a = -b(cast to matrix)*a = 0 * vectors a1...an are linearly dependant if there exists a vector of scalars (b) where a1*b1 + ... + an*bn = 0 * or if the matrix (A) * b = 0 * ****************************************/ #pragma once #include "vector2.h" template <typename T> struct vector3: public vector2<T> { T z; //! trivial ctor vector3<T>() {} //! setting ctor vector3<T>(const T x0, const T y0, const T z0): vector2<T>(x0, y0), z(z0) {} //! function call operator void operator ()(const T x0, const T y0, const T z0) { x= x0; y= y0; z= z0; } //! test for equality bool operator==(const vector3<T> &v) { return (x==v.x && y==v.y && z==v.z); } //! test for inequality bool operator!=(const vector3<T> &v) { return (x!=v.x || y!=v.y || z!=v.z); } //! set to value const vector3<T> &operator =(const vector3<T> &v) { x= v.x; y= v.y; z= v.z; return *this; } //! negation const vector3<T> operator -(void) const { return vector3<T>(-x,-y,-z); } //! addition const vector3<T> operator +(const vector3<T> &v) const { return vector3<T>(x+v.x, y+v.y, z+v.z); } //! subtraction const vector3<T> operator -(const vector3<T> &v) const { return vector3<T>(x-v.x, y-v.y, z-v.z); } //! uniform scaling const vector3<T> operator *(const T num) const { vector3<T> temp(*this); return temp*=num; } //! uniform scaling const vector3<T> operator /(const T num) const { vector3<T> temp(*this); return temp/=num; } //! addition const vector3<T> &operator +=(const vector3<T> &v) { x+=v.x; y+=v.y; z+=v.z; return *this; } //! subtraction const vector3<T> &operator -=(const vector3<T> &v) { x-=v.x; y-=v.y; z-=v.z; return *this; } //! uniform scaling const vector3<T> &operator *=(const T num) { x*=num; y*=num; z*=num; return *this; } //! uniform scaling const vector3<T> &operator /=(const T num) { x/=num; y/=num; z/=num; return *this; } //! dot product T operator *(const vector3<T> &v) const { return x*v.x + y*v.y + z*v.z; } //! cross product const vector3<T> operator %(const vector3<T> &v) const { vector3<T> temp(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); return temp; } }; // macro to make creating the ctors for derived vectors easier #define VECTOR3_CTORS(name, type) \ /* trivial ctor */ \ name() {} \ /* down casting ctor */ \ name(const vector3<type> &v): vector3<type>(v.x, v.y, v.z) {} \ /* make x,y,z combination into a vector */ \ name(type x0, type y0, type z0): vector3<type>(x0, y0, z0) {} struct vector3i: public vector3<int> { VECTOR3_CTORS(vector3i, int) }; struct vector3ui: public vector3<unsigned int> { VECTOR3_CTORS(vector3ui, unsigned int) }; struct vector3f: public vector3<float> { VECTOR3_CTORS(vector3f, float) //! gets the length of this vector squared float length_squared() const { return (float)(*this * *this); } //! gets the length of this vector float length() const { return (float)sqrt(*this * *this); } //! normalizes this vector void normalize() { *this/=length(); } //! returns the normalized version of this vector vector3f normalized() const { return *this/length(); } //! reflects this vector about n void reflect(const vector3f &n) { vector3f orig(*this); project(n); *this= *this*2 - orig; } //! projects this vector onto v void project(const vector3f &v) { *this= v * (*this * v)/(v*v); } //! returns this vector projected onto v vector3f projected(const vector3f &v) { return v * (*this * v)/(v*v); } //! computes the angle between 2 arbitrary vectors static inline float angle(const vector3f &v1, const vector3f &v2) { return acosf((v1*v2) / (v1.length()*v2.length())); } //! computes the angle between 2 arbitrary normalized vectors static inline float angle_normalized(const vector3f &v1, const vector3f &v2) { return acosf(v1*v2); } };
No Comments yet, be the first!



