/*************************************************************************** file : v3_t.h created : Due Apr 5 13:51:00 CET 2005 copyright : (C) 2005 by Bernhard Wymann email : berniw@bluewin.ch version : $Id: v3_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 3d 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_V3_T_H_ #define _LINALG_V3_T_H_ template class v3t; #ifndef _MSC_VER template v3t operator*(const T s, const v3t & src); template v3t crossProduct(const v3t &a, const v3t &b); #endif //_MSC_VER template class v3t { public: // Friends. #ifndef _MSC_VER friend v3t operator*<>(const T s, const v3t & src); // Multiply by scalar. friend v3t crossProduct<>(const v3t &a, const v3t &b); // return a X b #endif //_MSC_VER // Constructors. v3t() {} v3t(const v3t &src):x(src.x), y(src.y), z(src.z) {} v3t(const T x, const T y, const T z):x(x), y(y), z(z) {} v3t(const T s):x(s), y(s), z(s) {} // Operators. v3t& operator=(const v3t &src); // Assignment. v3t& operator+=(const v3t &src); // Addition. v3t& operator-=(const v3t &src); // Subtraction. v3t& operator*=(const T s); // Multiply with scalar. v3t& operator/=(const T s); // Divide by scalar. v3t operator-(void) const; // Negation. v3t operator+(const v3t &src) const; // Addition. v3t operator-(const v3t &src) const; // Subtraction. v3t operator*(const T s) const; // Multiply by scalar. T operator*(const v3t &src) const; // Dot product. v3t operator/(const T s) const; // Divide by scalar. int operator==(const v3t &src) const; // all fields equal? int operator!=(const v3t &src) const; // not all fields equal? // Other methods. T len(void); void normalize(void); void crossProduct(const v3t &b, v3t &r) const; // r := this X b void dirVector(const v3t* b, v3t* r); // r := this - b int approxEquals(const v3t &cmp, T eps); // Approximately equality per component, eps > 0.0. TODO: Test union { struct { T x, y, z; }; T vec[3]; }; }; template inline v3t & v3t::operator=(const v3t &src) { x = src.x; y = src.y; z = src.z; return *this; } // Addition template inline v3t& v3t::operator+=(const v3t &src) { x += src.x; y += src.y; z += src.z; return *this; } // Subtraction. template inline v3t& v3t::operator-=(const v3t &src) { x -= src.x; y -= src.y; z -= src.z; return *this; } // Multiply with scalar. template inline v3t& v3t::operator*=(const T s) { x *= s; y *= s; z *= s; return *this; } // Divide by scalar. template inline v3t& v3t::operator/=(const T s) { x /= s; y /= s; z /= s; return *this; } template inline v3t v3t::operator-(void) const { return v3t(-this->x, -this->y, -this->z); } template inline v3t v3t::operator-(const v3t &src) const { return v3t(this->x - src.x, this->y - src.y, this->z - src.z); } template inline v3t v3t::operator+(const v3t &src) const { return v3t(this->x + src.x, this->y + src.y, this->z + src.z); } template inline int v3t::operator==(const v3t &s) const { if (this->x == s.x && this->y == s.y && this->z == s.z) { return 1; } else { return 0; } } template inline int v3t::operator!=(const v3t &s) const { return !(*this == s); } // Approximately equality per component. template inline int v3t::approxEquals(const v3t &cmp, T eps) { if (fabs(cmp.x - this->x) < eps && fabs(cmp.y - this->y) < eps && fabs(cmp.z - this->z) < eps) { return 1; } else { return 0; } } template inline v3t v3t::operator*(const T s) const { return v3t(s*this->x, s*this->y, s*this->z); } template inline T v3t::operator*(const v3t &src) const { return this->x*src.x + this->y*src.y + this->z*src.z; } template inline v3t v3t::operator/(const T s) const { return v3t(this->x/s, this->y/s, this->z/s); } template inline T v3t::len(void) { return sqrt(x*x + y*y + z*z); } template inline void v3t::normalize(void) { T len = this->len(); x /= len; y /= len; z /= len; } template inline void v3t::crossProduct(const v3t& b, v3t& r) const { r.x = this->y*b.z - this->z*b.y; r.y = this->z*b.x - this->x*b.z; r.z = this->x*b.y - this->y*b.x; } template inline void v3t::dirVector(const v3t* b, v3t* r) { r->x = this->x - b->x; r->y = this->y - b->y; r->z = this->z - b->z; } // Friends. // Friend, scalar*vector. template inline v3t operator*(const T s, const v3t & src) { return v3t(s*src.x, s*src.y, s*src.z); } // Friend, Vector cross product. template inline v3t crossProduct(const v3t& a, const v3t& b) { return v3t(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); } #endif // _LINALG_V3_T_H_