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 
00035 namespace WFMath {
00036 
00037 template<const int dim> class RotMatrix;
00038 template<const int dim> class Vector;
00039 template<const int dim> class Point;
00040 class Quaternion;
00041 
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>& v1, const Vector<dim>& v2);
00046 template<const int dim>
00047 Vector<dim>& operator*=(Vector<dim>& v, CoordType d);
00048 template<const int dim>
00049 Vector<dim>& operator/=(Vector<dim>& v, CoordType d);
00050 
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>& v1, const Vector<dim>& v2);
00055 template<const int dim>
00056 Vector<dim> operator-(const Vector<dim>& v); // Unary minus
00057 template<const int dim>
00058 Vector<dim> operator*(CoordType d, const Vector<dim>& v);
00059 template<const int dim>
00060 Vector<dim> operator*(const Vector<dim>& v, CoordType d);
00061 template<const int dim>
00062 Vector<dim> operator/(const Vector<dim>& v, CoordType d);
00063 
00064 template<const int dim>
00065 CoordType Dot(const Vector<dim>& v1, const Vector<dim>& v2);
00066 
00067 template<const int dim>
00068 CoordType Angle(const Vector<dim>& v, const Vector<dim>& u);
00069 
00070 // The following are defined in rotmatrix_funcs.h
00072 template<const int dim> // m * v
00073 Vector<dim> Prod(const RotMatrix<dim>& m, const Vector<dim>& v);
00075 template<const int dim> // m^-1 * v
00076 Vector<dim> InvProd(const RotMatrix<dim>& m, const Vector<dim>& v);
00078 
00081 template<const int dim> // v * m
00082 Vector<dim> Prod(const Vector<dim>& v, const RotMatrix<dim>& m);
00084 template<const int dim> // v * m^-1
00085 Vector<dim> ProdInv(const Vector<dim>& v, const RotMatrix<dim>& m);
00086 
00088 template<const int dim>
00089 Vector<dim> operator*(const RotMatrix<dim>& m, const Vector<dim>& v);
00091 template<const int dim>
00092 Vector<dim> operator*(const Vector<dim>& v, const RotMatrix<dim>& m);
00093 
00094 template<const int dim>
00095 Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2);
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 Point<dim>& c, const Vector<dim>& v);
00100 template<const int dim>
00101 Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c);
00102 
00103 template<const int dim>
00104 Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v);
00105 template<const int dim>
00106 Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v);
00107 
00108 template<const int dim>
00109 std::ostream& operator<<(std::ostream& os, const Vector<dim>& v);
00110 template<const int dim>
00111 std::istream& operator>>(std::istream& is, Vector<dim>& v);
00112 
00114 
00118 template<const int dim>
00119 class Vector {
00120  public:
00122   Vector() : m_valid(false) {}
00124   Vector(const Vector& v);
00126   explicit Vector(const AtlasInType& a) {fromAtlas(a);}
00127 
00128   friend std::ostream& operator<< <dim>(std::ostream& os, const Vector& v);
00129   friend std::istream& operator>> <dim>(std::istream& is, Vector& v);
00130 
00132   AtlasOutType toAtlas() const;
00134   void fromAtlas(const AtlasInType& a);
00135 
00136   Vector& operator=(const Vector& v);
00137 
00138   bool isEqualTo(const Vector& v, double epsilon = WFMATH_EPSILON) const;
00139   bool operator==(const Vector& v) const {return isEqualTo(v);}
00140   bool operator!=(const Vector& v) const {return !isEqualTo(v);}
00141 
00142   bool isValid() const {return m_valid;}
00144   void setValid(bool valid = true) {m_valid = valid;}
00145 
00147   Vector& zero();
00148 
00149   // Math operators
00150 
00152   friend Vector& operator+=<dim>(Vector& v1, const Vector& v2);
00154   friend Vector& operator-=<dim>(Vector& v1, const Vector& v2);
00156   friend Vector& operator*=<dim>(Vector& v, CoordType d);
00158   friend Vector& operator/=<dim>(Vector& v, CoordType d);
00159 
00161   friend Vector operator+<dim>(const Vector& v1, const Vector& v2);
00163   friend Vector operator-<dim>(const Vector& v1, const Vector& v2);
00165   friend Vector operator-<dim>(const Vector& v); // Unary minus
00167   friend Vector operator*<dim>(CoordType d, const Vector& v);
00169   friend Vector operator*<dim>(const Vector& v, CoordType d);
00171   friend Vector operator/<dim>(const Vector& v, CoordType d);
00172 
00173   // documented outside the class definition
00174   friend Vector Prod<dim>       (const RotMatrix<dim>& m,
00175                                  const Vector& v);
00176   friend Vector InvProd<dim>    (const RotMatrix<dim>& m,
00177                                  const Vector& v);
00178 
00180   CoordType operator[](const int i) const {assert(0 <= i && i < dim); return m_elem[i];}
00182   CoordType& operator[](const int i)      {assert(0 <= i && i < dim); return m_elem[i];}
00183 
00185   friend Vector operator-<dim>(const Point<dim>& c1, const Point<dim>& c2);
00187   friend Point<dim> operator+<dim>(const Point<dim>& c, const Vector& v);
00189   friend Point<dim> operator-<dim>(const Point<dim>& c, const Vector& v);
00191   friend Point<dim> operator+<dim>(const Vector& v, const Point<dim>& c);
00192 
00194   friend Point<dim>& operator+=<dim>(Point<dim>& p, const Vector& rhs);
00196   friend Point<dim>& operator-=<dim>(Point<dim>& p, const Vector& rhs);
00197 
00199   friend CoordType Dot<dim>(const Vector& v1, const Vector& v2);
00201   friend CoordType Angle<dim>(const Vector& v, const Vector& u);
00202 
00204   CoordType sqrMag() const;
00206   CoordType mag() const         {return (CoordType) sqrt(sqrMag());}
00208   Vector& normalize(CoordType norm = 1.0)
00209         {CoordType themag = mag(); assert(themag > 0); return (*this *= norm / themag);}
00210 
00212 
00223   CoordType sloppyMag() const;
00225 
00230   Vector& sloppyNorm(CoordType norm = 1.0);
00231 
00232   // Can't seem to implement these as constants, implementing
00233   // inline lookup functions instead.
00235   static const CoordType sloppyMagMax();
00237 
00243   static const CoordType sloppyMagMaxSqrt();
00244 
00246   Vector& rotate(int axis1, int axis2, CoordType theta);
00247 
00249 
00252   Vector& rotate(const Vector& v1, const Vector& v2, CoordType theta);
00253 
00255   Vector& rotate(const RotMatrix<dim>&);
00256 
00257   // mirror image functions
00258 
00260   Vector& mirror(const int i) {assert(0 <= i && i < dim); m_elem[i] *= -1; return *this;}
00262   Vector& mirror(const Vector& v)
00263         {return operator-=(2 * v * Dot(v, *this) / v.sqrMag());}
00265 
00268   Vector& mirror()              {return operator*=(*this, -1);}
00269 
00270   // Specialized 2D/3D stuff starts here
00271 
00272   // The following functions are defined only for
00273   // two dimensional (rotate(CoordType), Vector<>(CoordType, CoordType))
00274   // and three dimensional (the rest of them) vectors.
00275   // Attempting to call these on any other vector will
00276   // result in a linker error.
00277 
00279   Vector(CoordType x, CoordType y);
00281   Vector(CoordType x, CoordType y, CoordType z);
00282 
00284   Vector<2>& rotate(CoordType theta);
00285 
00287   Vector<3>& rotateX(CoordType theta);
00289   Vector<3>& rotateY(CoordType theta);
00291   Vector<3>& rotateZ(CoordType theta);
00292 
00294   Vector<3>& rotate(const Vector<3>& axis, CoordType theta);
00296   Vector<3>& rotate(const Quaternion& q);
00297 
00298   // Label the first three components of the vector as (x,y,z) for
00299   // 2D/3D convienience
00300 
00302   CoordType x() const   {assert(dim > 0); return m_elem[0];}
00304   CoordType& x()        {assert(dim > 0); return m_elem[0];}
00306   CoordType y() const   {assert(dim > 1); return m_elem[1];}
00308   CoordType& y()        {assert(dim > 1); return m_elem[1];}
00310   CoordType z() const   {assert(dim > 2); return m_elem[2];}
00312   CoordType& z()        {assert(dim > 2); return m_elem[2];}
00313 
00314   // Don't need asserts here, they're taken care of in the general function
00316   Vector& mirrorX()     {return mirror(0);}
00318   Vector& mirrorY()     {return mirror(1);}
00320   Vector& mirrorZ()     {return mirror(2);}
00321 
00323   Vector<2>& polar(CoordType r, CoordType theta);
00325   void asPolar(CoordType& r, CoordType& theta) const;
00326 
00328   Vector<3>& polar(CoordType r, CoordType theta, CoordType z);
00330   void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
00332   Vector<3>& spherical(CoordType r, CoordType theta, CoordType phi);
00334   void asSpherical(CoordType& r, CoordType& theta, CoordType& phi) const;
00335 
00336   // FIXME make Cross() a friend function, and make this private
00337   double _scaleEpsilon(const Vector& v, double epsilon = WFMATH_EPSILON) const
00338         {return _ScaleEpsilon(m_elem, v.m_elem, dim, epsilon);}
00339 
00340   const CoordType* elements() const {return m_elem;}
00341 
00342  private:
00343   CoordType m_elem[dim];
00344   bool m_valid;
00345 };
00346 
00348 CoordType Cross(const Vector<2>& v1, const Vector<2>& v2);
00350 Vector<3> Cross(const Vector<3>& v1, const Vector<3>& v2);
00351 
00353 
00358 template<const int dim>
00359 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2, bool& same_dir);
00360 
00362 
00365 template<const int dim>
00366 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2);
00367 
00369 template<const int dim>
00370 bool Perpendicular(const Vector<dim>& v1, const Vector<dim>& v2);
00371 
00372 } // namespace WFMath
00373 
00374 #include <wfmath/vector_funcs.h>
00375 
00376 #endif // WFMATH_VECTOR_H

Generated on Tue Dec 11 06:29:46 2007 for WFMath by  doxygen 1.5.4