WFMath 0.3.11

vector.h

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 #include <wfmath/zero.h>
00035 
00036 #include <iosfwd>
00037 
00038 namespace WFMath {
00039 
00040 template<const int dim>
00041 Vector<dim>& operator+=(Vector<dim>& v1, const Vector<dim>& v2);
00042 template<const int dim>
00043 Vector<dim>& operator-=(Vector<dim>& v1, const Vector<dim>& v2);
00044 template<const int dim>
00045 Vector<dim>& operator*=(Vector<dim>& v, CoordType d);
00046 template<const int dim>
00047 Vector<dim>& operator/=(Vector<dim>& v, CoordType d);
00048 
00049 template<const int dim>
00050 Vector<dim> operator+(const Vector<dim>& v1, const Vector<dim>& v2);
00051 template<const int dim>
00052 Vector<dim> operator-(const Vector<dim>& v1, const Vector<dim>& v2);
00053 template<const int dim>
00054 Vector<dim> operator-(const Vector<dim>& v); // Unary minus
00055 template<const int dim>
00056 Vector<dim> operator*(CoordType d, const Vector<dim>& v);
00057 template<const int dim>
00058 Vector<dim> operator*(const Vector<dim>& v, CoordType d);
00059 template<const int dim>
00060 Vector<dim> operator/(const Vector<dim>& v, CoordType d);
00061 
00062 template<const int dim>
00063 CoordType Dot(const Vector<dim>& v1, const Vector<dim>& v2);
00064 
00065 template<const int dim>
00066 CoordType Angle(const Vector<dim>& v, const Vector<dim>& u);
00067 
00068 // The following are defined in rotmatrix_funcs.h
00070 template<const int dim> // m * v
00071 Vector<dim> Prod(const RotMatrix<dim>& m, const Vector<dim>& v);
00073 template<const int dim> // m^-1 * v
00074 Vector<dim> InvProd(const RotMatrix<dim>& m, const Vector<dim>& v);
00076 
00079 template<const int dim> // v * m
00080 Vector<dim> Prod(const Vector<dim>& v, const RotMatrix<dim>& m);
00082 template<const int dim> // v * m^-1
00083 Vector<dim> ProdInv(const Vector<dim>& v, const RotMatrix<dim>& m);
00084 
00086 template<const int dim>
00087 Vector<dim> operator*(const RotMatrix<dim>& m, const Vector<dim>& v);
00089 template<const int dim>
00090 Vector<dim> operator*(const Vector<dim>& v, const RotMatrix<dim>& m);
00091 
00092 template<const int dim>
00093 Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2);
00094 template<const int dim>
00095 Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v);
00096 template<const int dim>
00097 Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v);
00098 template<const int dim>
00099 Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c);
00100 
00101 template<const int dim>
00102 Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v);
00103 template<const int dim>
00104 Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v);
00105 
00106 template<const int dim>
00107 std::ostream& operator<<(std::ostream& os, const Vector<dim>& v);
00108 template<const int dim>
00109 std::istream& operator>>(std::istream& is, Vector<dim>& v);
00110 
00112 
00116 template<const int dim = 3>
00117 class Vector {
00118  friend class ZeroPrimitive<Vector<dim> >;
00119  public:
00121   Vector() : m_valid(false) {}
00123   Vector(const Vector& v);
00125   explicit Vector(const AtlasInType& a);
00127   explicit Vector(const Point<dim>& point);
00128 
00132   static const Vector<dim>& ZERO()
00133   {
00134     static ZeroPrimitive<Vector<dim> > zeroVector(dim);
00135     return zeroVector.getShape();
00136   }
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 (CoordType) 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<const int dim>
00366 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2, bool& same_dir);
00367 
00369 
00372 template<const int dim>
00373 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2);
00374 
00376 template<const int dim>
00377 bool Perpendicular(const Vector<dim>& v1, const Vector<dim>& v2);
00378 
00379 } // namespace WFMath
00380 
00381 #endif // WFMATH_VECTOR_H