/*************************************************************************** file : v4_t.h created : Due Apr 5 13:51:00 CET 2005 copyright : (C) 2005 by Bernhard Wymann email : berniw@bluewin.ch version : $Id: v4_t.h,v 1.2 2005/08/05 09:04:53 berniw Exp $ ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* Template for 4d vector of primitive types (float, double). This template is NOT intended to work with classes which allocate memory. Be aware that there are more efficient methods for doing most of the operations (avoiding temp verctors and make better use of registers). Later I will try to improve the performance (SSE, "abuse" of templates to avoid temporaries). */ #ifndef _LINALG_V4_T_H_ #define _LINALG_V4_T_H_ template class v4t; #ifndef _MSC_VER template v4t operator* (const T s, const v4t & src); #endif //_MSC_VER template class v4t { public: // Friends. #ifndef _MSC_VER friend v4t operator* <>(const T s, const v4t &src); // Multiply by scalar. #endif //_MSC_VER // Constructors. v4t() {} v4t(const v4t &src):x(src.x), y(src.y), z(src.z), w(src.w) {} v4t(const T x, const T y, const T z, const T w):x(x), y(y), z(z), w(w) {} v4t(const T s):x(s), y(s), z(s), w(s) {} // Operators. v4t& operator=(const v4t &src); // Assignment. v4t& operator+=(const v4t &src); // Addition. v4t& operator-=(const v4t &src); // Subtraction. v4t& operator*=(const T s); // Multiply with scalar. v4t& operator/=(const T s); // Divide by scalar. v4t operator-(void) const; // Negation. v4t operator+(const v4t &src) const; // Addition. v4t operator-(const v4t &src) const; // Subtraction. v4t operator*(const T s) const; // Multiply with scalar. T operator*(const v4t &src) const; // Dot product. v4t operator/(const T s) const; // Divide by scalar. int operator==(const v4t &src) const; // all fields equal? int operator!=(const v4t &src) const; // not all fields equal? // Other methods. T len(void) const; void normalize(void); T dist(const v4t &p) const; int approxEquals(const v4t &cmp, T eps); // Approximately equality per component, eps > 0.0. TODO: Test // Data. union { struct { T x, y, z, w; }; T vec[4]; }; }; // Assignment template inline v4t& v4t::operator=(const v4t &src) { x = src.x; y = src.y; z = src.z; w = src.w; return *this; } // Addition template inline v4t& v4t::operator+=(const v4t &src) { x += src.x; y += src.y; z += src.z; w += src.w; return *this; } // Subtraction. template inline v4t& v4t::operator-=(const v4t &src) { x -= src.x; y -= src.y; z -= src.z; w -= src.w; return *this; } // Multiply with scalar. template inline v4t& v4t::operator*=(const T s) { x *= s; y *= s; z *= s; w *= s; return *this; } // Divide by scalar. template inline v4t& v4t::operator/=(const T s) { x /= s; y /= s; z /= s; w /= s; return *this; } // Add *this + src (vector addition) */ template inline v4t v4t::operator+(const v4t &src) const { return v4t(x + src.x, y + src.y, z + src.z, w + src.w); } // Negation of *this template inline v4t v4t::operator-(void) const { return v4t(-x, -y, -z, -w); } // Compute *this - src (vector subtraction). template inline v4t v4t::operator-(const v4t &src) const { return v4t(x - src.x, y - src.y, z - src.z, w - src.w); } template inline int v4t::operator==(const v4t &s) const { if (this->x == s.x && this->y == s.y && this->z == s.z && this->w == s.w) { return 1; } else { return 0; } } template inline int v4t::operator!=(const v4t &s) const { return !(*this == s); } // Approximately equality per component. template inline int v4t::approxEquals(const v4t &cmp, T eps) { if (fabs(cmp.x - this->x) < eps && fabs(cmp.y - this->y) < eps && fabs(cmp.z - this->z) < eps && fabs(cmp.w - this->w) < eps) { return 1; } else { return 0; } } // Dot (scalar) product. template inline T v4t::operator*(const v4t &src) const { return src.x*x + src.y*y + src.z*z + src.w*w; } // Multiply vector with scalar (v4t*T) template inline v4t v4t::operator*(const T s) const { return v4t(s*x, s*y, s*z, s*w); } // friend, Multiply scalar with vector (T*v4t). template inline v4t operator*(const T s, const v4t & src) { return v4t(s*src.x, s*src.y, s*src.z, s*src.w); } template inline v4t v4t::operator/(const T s) const { return v4t(this->x/s, this->y/s, this->z/s, this->w/s); } // Compute the length of the vector. template inline T v4t::len(void) const { return sqrt(x*x + y*y + z*z + w*w); } // Distance between *this and p. template inline T v4t::dist(const v4t &p) const { return sqrt((p.x-x)*(p.x-x) + (p.y-y)*(p.y-y) + (p.z-z)*(p.z-z) + (p.w-w)*(p.w-w)); } // Normalize the vector. template inline void v4t::normalize(void) { T l = this->len(); x /= l; y /= l; z /= l; w /= l; } #endif // _LINALG_V4_T_H_