#ifndef __DTSVECTOR_H #define __DTSVECTOR_H #include #include #include #include namespace DTS { //! Defines a generic vector class template class Vector { public: //! Create a null vector Vector () { // No initialization. Derivated classes have no overhead. } //! Create a vector from a data array Vector (const type *d) { for (int n = 0 ; n < size ; n++) members[n] = d[n] ; } //! Create a point with given space coordinates Vector (const Vector &v) { for (int n = 0 ; n < size ; n++) members[n] = v.members[n] ; } //! Member access const type & get (int n) const { return members[n] ; } type & operator[] (int n) { return members[n] ; } const type & operator[] (int n) const { return members[n] ; } void set (int n, type value) { members[n] = value ; } //!{ Member operators ************************************************* Vector operator - () const { Vector r ; for (int n = 0 ; n < size ; n++) r.members[n] = -members[n]; return r ; } Vector & operator = (const Vector &v) { for (int n = 0 ; n < size ; n++) members[n] = v.members[n] ; return *this ; } Vector & operator += (const Vector &r) { for (int n = 0 ; n < size ; n++) members[n] += r.members[n]; return *this ; } Vector & operator -= (const Vector &r) { for (int n = 0 ; n < size ; n++) members[n] -= r.members[n]; return *this ; } Vector & operator *= (const type r) { for (int n = 0 ; n < size ; n++) members[n] *= r; return *this ; } Vector & operator /= (const type r) { for (int n = 0 ; n < size ; n++) members[n] /= r; return *this ; } //!} //!{ Non-member operators ********************************************* friend bool operator < (const Vector &a, const Vector &b) { for (int n = 0 ; n < size ; n++) if (a.members[n] < b.members[n]) return true ; return false ; } friend bool operator > (const Vector &a, const Vector &b) { int n; for (n = 0 ; n < size ; n++) if (a.members[n] < b.members[n]) return false ; return a[n] != b[n] ; } friend bool operator == (const Vector &a, const Vector &b) { for (int n = 0 ; n < size ; n++) if (a.members[n] != b.members[n]) return false ; return true ; } friend bool operator != (const Vector &a, const Vector &b) { for (int n = 0 ; n < size ; n++) if (a.members[n] != b.members[n]) return true ; return false ; } //!} //!{ Vector utilities ************************************************* //! Normalize the vector (reduce it to 1 unit in length) void normalize() ; //! Length of the vector type length(int nc = size) const ; //! Dot product type dot (const Vector &r) const ; //! Angle in radians between two vectors type angle (const Vector &r) const ; //! Middle point between two points/vectors Vector midpoint (const Vector & p) const ; //! Some sintactic sugar stuff bool isPerpendicular (Vector &r) const { return dot(r) == 0.0f ; } //! Returns true if all members are 0 (do not use operator (bool)) bool isNull() const ; private: type members[size] ; }; // ----------------------------------------------------------------------- // Implementation // ----------------------------------------------------------------------- template inline Vector operator + (const Vector &a, const Vector &b) { Vector result ; for (int n = 0 ; n < size ; n++) result.set (n, a.get(n) + b.get(n)) ; return result ; } template inline Vector operator - (const Vector &a, const Vector &b) { Vector result ; for (int n = 0 ; n < size ; n++) result.set (n, a.get(n) - b.get(n)) ; return result ; } template inline bool operator == (const Vector &a, const Vector &b) { for (int n = 0 ; n < size ; n++) if (a.members[n] != b.members[n]) return false ; return true ; } template inline bool operator != (const Vector &a, const Vector &b) { for (int n = 0 ; n < size ; n++) if (a.members[n] != b.members[n]) return true ; return false ; } //! Multiply by constant template inline Vector operator * (const Vector &p, float c) { Vector result ; for (int n = 0 ; n < size ; n++) result.set (n, p.get(n) * c) ; return result ; } //! Divide by constant template inline Vector operator / (const Vector &p, float c) { Vector result ; for (int n = 0 ; n < size ; n++) result.set (n, p.get(n) / c) ; return result ; } //! Dot product template inline type Vector::dot (const Vector &r) const { type result = r.members[0] * members[0] ; for (int n = 1 ; n < size ; n++) result += r.members[n] * members[n] ; return result ; } //! Length template inline type Vector::length(int nc) const { type result = members[0] * members[0] ; for (int n = 1 ; n < nc ; n++) result += members[n] * members[n] ; return sqrt(result) ; } //! Angle between two vectors template inline type Vector::angle (const Vector &r) const { return acos (dot(r) / length() / r.length()) ; } //! Angle between two vectors template inline Vector Vector::midpoint (const Vector &r) const { Vector result ; for (int n = 0 ; n < size ; n++) result.set (n, (r.members[n] - members[n])/2 + members[n]) ; return result ; } //! Normalices a vector. If it is a null vector (0, 0, 0) then it is left untouched template inline void Vector::normalize() { float dist = length() ; if (dist != 0.0f) { for (int n = 0 ; n < size ; n++) members[n] /= dist ; } } template inline bool Vector::isNull() const { for (int n = 0 ; n < size ; n++) if (members[n] != 0) return false ; return true ; } } #endif