WFMath 0.3.12
|
00001 // vector.h (Vector<> class definition) 00002 // 00003 // The WorldForge Project 00004 // Copyright (C) 2001 The WorldForge Project 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 2 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // This program is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 // 00020 // For information about WorldForge and its authors, please contact 00021 // the Worldforge Web Site at http://www.worldforge.org. 00022 00023 // Author: Ron Steinke 00024 // Created: 2001-12-7 00025 00026 // Extensive amounts of this material come from the Vector2D 00027 // and Vector3D classes from stage/math, written by Bryce W. 00028 // Harrington, Kosh, and Jari Sundell (Rakshasa). 00029 00030 #ifndef WFMATH_VECTOR_H 00031 #define WFMATH_VECTOR_H 00032 00033 #include <wfmath/const.h> 00034 00035 #include <iosfwd> 00036 00037 #include <cmath> 00038 00039 namespace WFMath { 00040 00041 template<int dim> 00042 Vector<dim>& operator+=(Vector<dim>& v1, const Vector<dim>& v2); 00043 template<int dim> 00044 Vector<dim>& operator-=(Vector<dim>& v1, const Vector<dim>& v2); 00045 template<int dim> 00046 Vector<dim>& operator*=(Vector<dim>& v, CoordType d); 00047 template<int dim> 00048 Vector<dim>& operator/=(Vector<dim>& v, CoordType d); 00049 00050 template<int dim> 00051 Vector<dim> operator+(const Vector<dim>& v1, const Vector<dim>& v2); 00052 template<int dim> 00053 Vector<dim> operator-(const Vector<dim>& v1, const Vector<dim>& v2); 00054 template<int dim> 00055 Vector<dim> operator-(const Vector<dim>& v); // Unary minus 00056 template<int dim> 00057 Vector<dim> operator*(CoordType d, const Vector<dim>& v); 00058 template<int dim> 00059 Vector<dim> operator*(const Vector<dim>& v, CoordType d); 00060 template<int dim> 00061 Vector<dim> operator/(const Vector<dim>& v, CoordType d); 00062 00063 template<int dim> 00064 CoordType Dot(const Vector<dim>& v1, const Vector<dim>& v2); 00065 00066 template<int dim> 00067 CoordType Angle(const Vector<dim>& v, const Vector<dim>& u); 00068 00069 // The following are defined in rotmatrix_funcs.h 00071 template<int dim> // m * v 00072 Vector<dim> Prod(const RotMatrix<dim>& m, const Vector<dim>& v); 00074 template<int dim> // m^-1 * v 00075 Vector<dim> InvProd(const RotMatrix<dim>& m, const Vector<dim>& v); 00077 00080 template<int dim> // v * m 00081 Vector<dim> Prod(const Vector<dim>& v, const RotMatrix<dim>& m); 00083 template<int dim> // v * m^-1 00084 Vector<dim> ProdInv(const Vector<dim>& v, const RotMatrix<dim>& m); 00085 00087 template<int dim> 00088 Vector<dim> operator*(const RotMatrix<dim>& m, const Vector<dim>& v); 00090 template<int dim> 00091 Vector<dim> operator*(const Vector<dim>& v, const RotMatrix<dim>& m); 00092 00093 template<int dim> 00094 Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2); 00095 template<int dim> 00096 Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v); 00097 template<int dim> 00098 Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v); 00099 template<int dim> 00100 Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c); 00101 00102 template<int dim> 00103 Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v); 00104 template<int dim> 00105 Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v); 00106 00107 template<int dim> 00108 std::ostream& operator<<(std::ostream& os, const Vector<dim>& v); 00109 template<int dim> 00110 std::istream& operator>>(std::istream& is, Vector<dim>& v); 00111 00112 template<typename Shape> 00113 class ZeroPrimitive; 00114 00116 00120 template<int dim = 3> 00121 class Vector { 00122 friend class ZeroPrimitive<Vector<dim> >; 00123 public: 00125 Vector() : m_valid(false) {} 00127 Vector(const Vector& v); 00129 explicit Vector(const AtlasInType& a); 00131 explicit Vector(const Point<dim>& point); 00132 00136 static const Vector<dim>& ZERO(); 00137 00138 friend std::ostream& operator<< <dim>(std::ostream& os, const Vector& v); 00139 friend std::istream& operator>> <dim>(std::istream& is, Vector& v); 00140 00142 AtlasOutType toAtlas() const; 00144 void fromAtlas(const AtlasInType& a); 00145 00146 Vector& operator=(const Vector& v); 00147 00148 bool isEqualTo(const Vector& v, double epsilon = WFMATH_EPSILON) const; 00149 bool operator==(const Vector& v) const {return isEqualTo(v);} 00150 bool operator!=(const Vector& v) const {return !isEqualTo(v);} 00151 00152 bool isValid() const {return m_valid;} 00154 void setValid(bool valid = true) {m_valid = valid;} 00155 00157 Vector& zero(); 00158 00159 // Math operators 00160 00162 friend Vector& operator+=<dim>(Vector& v1, const Vector& v2); 00164 friend Vector& operator-=<dim>(Vector& v1, const Vector& v2); 00166 friend Vector& operator*=<dim>(Vector& v, CoordType d); 00168 friend Vector& operator/=<dim>(Vector& v, CoordType d); 00169 00171 friend Vector operator+<dim>(const Vector& v1, const Vector& v2); 00173 friend Vector operator-<dim>(const Vector& v1, const Vector& v2); 00175 friend Vector operator-<dim>(const Vector& v); // Unary minus 00177 friend Vector operator*<dim>(CoordType d, const Vector& v); 00179 friend Vector operator*<dim>(const Vector& v, CoordType d); 00181 friend Vector operator/<dim>(const Vector& v, CoordType d); 00182 00183 // documented outside the class definition 00184 friend Vector Prod<dim>(const RotMatrix<dim>& m, const Vector& v); 00185 friend Vector InvProd<dim>(const RotMatrix<dim>& m, const Vector& v); 00186 00188 CoordType operator[](const int i) const {return m_elem[i];} 00190 CoordType& operator[](const int i) {return m_elem[i];} 00191 00193 friend Vector operator-<dim>(const Point<dim>& c1, const Point<dim>& c2); 00195 friend Point<dim> operator+<dim>(const Point<dim>& c, const Vector& v); 00197 friend Point<dim> operator-<dim>(const Point<dim>& c, const Vector& v); 00199 friend Point<dim> operator+<dim>(const Vector& v, const Point<dim>& c); 00200 00202 friend Point<dim>& operator+=<dim>(Point<dim>& p, const Vector& rhs); 00204 friend Point<dim>& operator-=<dim>(Point<dim>& p, const Vector& rhs); 00205 00207 friend CoordType Dot<dim>(const Vector& v1, const Vector& v2); 00209 friend CoordType Angle<dim>(const Vector& v, const Vector& u); 00210 00212 CoordType sqrMag() const; 00214 CoordType mag() const {return std::sqrt(sqrMag());} 00216 Vector& normalize(CoordType norm = 1.0) 00217 {CoordType themag = mag(); return (*this *= norm / themag);} 00218 00220 00231 CoordType sloppyMag() const; 00233 00238 Vector& sloppyNorm(CoordType norm = 1.0); 00239 00240 // Can't seem to implement these as constants, implementing 00241 // inline lookup functions instead. 00243 static const CoordType sloppyMagMax(); 00245 00251 static const CoordType sloppyMagMaxSqrt(); 00252 00254 Vector& rotate(int axis1, int axis2, CoordType theta); 00255 00257 00260 Vector& rotate(const Vector& v1, const Vector& v2, CoordType theta); 00261 00263 Vector& rotate(const RotMatrix<dim>&); 00264 00265 // mirror image functions 00266 00268 Vector& mirror(const int i) { m_elem[i] *= -1; return *this;} 00270 Vector& mirror(const Vector& v) 00271 {return operator-=(*this, 2 * v * Dot(v, *this) / v.sqrMag());} 00273 00276 Vector& mirror() {return operator*=(*this, -1);} 00277 00278 // Specialized 2D/3D stuff starts here 00279 00280 // The following functions are defined only for 00281 // two dimensional (rotate(CoordType), Vector<>(CoordType, CoordType)) 00282 // and three dimensional (the rest of them) vectors. 00283 // Attempting to call these on any other vector will 00284 // result in a linker error. 00285 00287 Vector(CoordType x, CoordType y); 00289 Vector(CoordType x, CoordType y, CoordType z); 00290 00292 Vector& rotate(CoordType theta); 00293 00295 Vector& rotateX(CoordType theta); 00297 Vector& rotateY(CoordType theta); 00299 Vector& rotateZ(CoordType theta); 00300 00302 Vector& rotate(const Vector& axis, CoordType theta); 00304 Vector& rotate(const Quaternion& q); 00305 00306 // Label the first three components of the vector as (x,y,z) for 00307 // 2D/3D convienience 00308 00310 CoordType x() const {return m_elem[0];} 00312 CoordType& x() {return m_elem[0];} 00314 CoordType y() const {return m_elem[1];} 00316 CoordType& y() {return m_elem[1];} 00318 CoordType z() const {return m_elem[2];} 00320 CoordType& z() {return m_elem[2];} 00321 00323 Vector& mirrorX() {return mirror(0);} 00325 Vector& mirrorY() {return mirror(1);} 00327 Vector& mirrorZ() {return mirror(2);} 00328 00330 Vector& polar(CoordType r, CoordType theta); 00332 void asPolar(CoordType& r, CoordType& theta) const; 00333 00335 Vector& polar(CoordType r, CoordType theta, CoordType z); 00337 void asPolar(CoordType& r, CoordType& theta, CoordType& z) const; 00339 Vector& spherical(CoordType r, CoordType theta, CoordType phi); 00341 void asSpherical(CoordType& r, CoordType& theta, CoordType& phi) const; 00342 00343 // FIXME make Cross() a friend function, and make this private 00344 double _scaleEpsilon(const Vector& v, double epsilon = WFMATH_EPSILON) const 00345 {return _ScaleEpsilon(m_elem, v.m_elem, dim, epsilon);} 00346 00347 const CoordType* elements() const {return m_elem;} 00348 00349 private: 00350 CoordType m_elem[dim]; 00351 bool m_valid; 00352 }; 00353 00355 CoordType Cross(const Vector<2>& v1, const Vector<2>& v2); 00357 Vector<3> Cross(const Vector<3>& v1, const Vector<3>& v2); 00358 00360 00365 template<int dim> 00366 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2, bool& same_dir); 00367 00369 00372 template<int dim> 00373 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2); 00374 00376 template<int dim> 00377 bool Perpendicular(const Vector<dim>& v1, const Vector<dim>& v2); 00378 00379 } // namespace WFMath 00380 00381 #endif // WFMATH_VECTOR_H