WFMath  0.3.12
vector.h
1 // vector.h (Vector<> class definition)
2 //
3 // The WorldForge Project
4 // Copyright (C) 2001 The WorldForge Project
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 //
20 // For information about WorldForge and its authors, please contact
21 // the Worldforge Web Site at http://www.worldforge.org.
22 
23 // Author: Ron Steinke
24 // Created: 2001-12-7
25 
26 // Extensive amounts of this material come from the Vector2D
27 // and Vector3D classes from stage/math, written by Bryce W.
28 // Harrington, Kosh, and Jari Sundell (Rakshasa).
29 
30 #ifndef WFMATH_VECTOR_H
31 #define WFMATH_VECTOR_H
32 
33 #include <wfmath/const.h>
34 
35 #include <iosfwd>
36 
37 #include <cmath>
38 
39 namespace WFMath {
40 
41 template<int dim>
42 Vector<dim>& operator+=(Vector<dim>& v1, const Vector<dim>& v2);
43 template<int dim>
44 Vector<dim>& operator-=(Vector<dim>& v1, const Vector<dim>& v2);
45 template<int dim>
46 Vector<dim>& operator*=(Vector<dim>& v, CoordType d);
47 template<int dim>
48 Vector<dim>& operator/=(Vector<dim>& v, CoordType d);
49 
50 template<int dim>
51 Vector<dim> operator+(const Vector<dim>& v1, const Vector<dim>& v2);
52 template<int dim>
53 Vector<dim> operator-(const Vector<dim>& v1, const Vector<dim>& v2);
54 template<int dim>
55 Vector<dim> operator-(const Vector<dim>& v); // Unary minus
56 template<int dim>
57 Vector<dim> operator*(CoordType d, const Vector<dim>& v);
58 template<int dim>
59 Vector<dim> operator*(const Vector<dim>& v, CoordType d);
60 template<int dim>
61 Vector<dim> operator/(const Vector<dim>& v, CoordType d);
62 
63 template<int dim>
64 CoordType Dot(const Vector<dim>& v1, const Vector<dim>& v2);
65 
66 template<int dim>
67 CoordType Angle(const Vector<dim>& v, const Vector<dim>& u);
68 
69 // The following are defined in rotmatrix_funcs.h
71 template<int dim> // m * v
72 Vector<dim> Prod(const RotMatrix<dim>& m, const Vector<dim>& v);
74 template<int dim> // m^-1 * v
75 Vector<dim> InvProd(const RotMatrix<dim>& m, const Vector<dim>& v);
77 
80 template<int dim> // v * m
81 Vector<dim> Prod(const Vector<dim>& v, const RotMatrix<dim>& m);
83 template<int dim> // v * m^-1
84 Vector<dim> ProdInv(const Vector<dim>& v, const RotMatrix<dim>& m);
85 
87 template<int dim>
88 Vector<dim> operator*(const RotMatrix<dim>& m, const Vector<dim>& v);
90 template<int dim>
91 Vector<dim> operator*(const Vector<dim>& v, const RotMatrix<dim>& m);
92 
93 template<int dim>
94 Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2);
95 template<int dim>
96 Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v);
97 template<int dim>
98 Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v);
99 template<int dim>
100 Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c);
101 
102 template<int dim>
103 Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v);
104 template<int dim>
105 Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v);
106 
107 template<int dim>
108 std::ostream& operator<<(std::ostream& os, const Vector<dim>& v);
109 template<int dim>
110 std::istream& operator>>(std::istream& is, Vector<dim>& v);
111 
112 template<typename Shape>
113 class ZeroPrimitive;
114 
116 
120 template<int dim = 3>
121 class Vector {
122  friend class ZeroPrimitive<Vector<dim> >;
123  public:
125  Vector() : m_valid(false) {}
127  Vector(const Vector& v);
129  explicit Vector(const AtlasInType& a);
131  explicit Vector(const Point<dim>& point);
132 
136  static const Vector<dim>& ZERO();
137 
138  friend std::ostream& operator<< <dim>(std::ostream& os, const Vector& v);
139  friend std::istream& operator>> <dim>(std::istream& is, Vector& v);
140 
142  AtlasOutType toAtlas() const;
144  void fromAtlas(const AtlasInType& a);
145 
146  Vector& operator=(const Vector& v);
147 
148  bool isEqualTo(const Vector& v, double epsilon = WFMATH_EPSILON) const;
149  bool operator==(const Vector& v) const {return isEqualTo(v);}
150  bool operator!=(const Vector& v) const {return !isEqualTo(v);}
151 
152  bool isValid() const {return m_valid;}
154  void setValid(bool valid = true) {m_valid = valid;}
155 
157  Vector& zero();
158 
159  // Math operators
160 
162  friend Vector& operator+=<dim>(Vector& v1, const Vector& v2);
164  friend Vector& operator-=<dim>(Vector& v1, const Vector& v2);
166  friend Vector& operator*=<dim>(Vector& v, CoordType d);
168  friend Vector& operator/=<dim>(Vector& v, CoordType d);
169 
171  friend Vector operator+<dim>(const Vector& v1, const Vector& v2);
173  friend Vector operator-<dim>(const Vector& v1, const Vector& v2);
175  friend Vector operator-<dim>(const Vector& v); // Unary minus
177  friend Vector operator*<dim>(CoordType d, const Vector& v);
179  friend Vector operator*<dim>(const Vector& v, CoordType d);
181  friend Vector operator/<dim>(const Vector& v, CoordType d);
182 
183  // documented outside the class definition
184  friend Vector Prod<dim>(const RotMatrix<dim>& m, const Vector& v);
185  friend Vector InvProd<dim>(const RotMatrix<dim>& m, const Vector& v);
186 
188  CoordType operator[](const int i) const {return m_elem[i];}
190  CoordType& operator[](const int i) {return m_elem[i];}
191 
193  friend Vector operator-<dim>(const Point<dim>& c1, const Point<dim>& c2);
195  friend Point<dim> operator+<dim>(const Point<dim>& c, const Vector& v);
197  friend Point<dim> operator-<dim>(const Point<dim>& c, const Vector& v);
199  friend Point<dim> operator+<dim>(const Vector& v, const Point<dim>& c);
200 
202  friend Point<dim>& operator+=<dim>(Point<dim>& p, const Vector& rhs);
204  friend Point<dim>& operator-=<dim>(Point<dim>& p, const Vector& rhs);
205 
207  friend CoordType Dot<dim>(const Vector& v1, const Vector& v2);
209  friend CoordType Angle<dim>(const Vector& v, const Vector& u);
210 
212  CoordType sqrMag() const;
214  CoordType mag() const {return std::sqrt(sqrMag());}
216  Vector& normalize(CoordType norm = 1.0)
217  {CoordType themag = mag(); return (*this *= norm / themag);}
218 
220 
231  CoordType sloppyMag() const;
233 
238  Vector& sloppyNorm(CoordType norm = 1.0);
239 
240  // Can't seem to implement these as constants, implementing
241  // inline lookup functions instead.
243  static const CoordType sloppyMagMax();
245 
251  static const CoordType sloppyMagMaxSqrt();
252 
254  Vector& rotate(int axis1, int axis2, CoordType theta);
255 
257 
260  Vector& rotate(const Vector& v1, const Vector& v2, CoordType theta);
261 
263  Vector& rotate(const RotMatrix<dim>&);
264 
265  // mirror image functions
266 
268  Vector& mirror(const int i) { m_elem[i] *= -1; return *this;}
270  Vector& mirror(const Vector& v)
271  {return operator-=(*this, 2 * v * Dot(v, *this) / v.sqrMag());}
273 
276  Vector& mirror() {return operator*=(*this, -1);}
277 
278  // Specialized 2D/3D stuff starts here
279 
280  // The following functions are defined only for
281  // two dimensional (rotate(CoordType), Vector<>(CoordType, CoordType))
282  // and three dimensional (the rest of them) vectors.
283  // Attempting to call these on any other vector will
284  // result in a linker error.
285 
290 
292  Vector& rotate(CoordType theta);
293 
295  Vector& rotateX(CoordType theta);
297  Vector& rotateY(CoordType theta);
299  Vector& rotateZ(CoordType theta);
300 
302  Vector& rotate(const Vector& axis, CoordType theta);
304  Vector& rotate(const Quaternion& q);
305 
306  // Label the first three components of the vector as (x,y,z) for
307  // 2D/3D convienience
308 
310  CoordType x() const {return m_elem[0];}
312  CoordType& x() {return m_elem[0];}
314  CoordType y() const {return m_elem[1];}
316  CoordType& y() {return m_elem[1];}
318  CoordType z() const {return m_elem[2];}
320  CoordType& z() {return m_elem[2];}
321 
323  Vector& mirrorX() {return mirror(0);}
325  Vector& mirrorY() {return mirror(1);}
327  Vector& mirrorZ() {return mirror(2);}
328 
330  Vector& polar(CoordType r, CoordType theta);
332  void asPolar(CoordType& r, CoordType& theta) const;
333 
335  Vector& polar(CoordType r, CoordType theta, CoordType z);
337  void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
339  Vector& spherical(CoordType r, CoordType theta, CoordType phi);
341  void asSpherical(CoordType& r, CoordType& theta, CoordType& phi) const;
342 
343  // FIXME make Cross() a friend function, and make this private
344  double _scaleEpsilon(const Vector& v, double epsilon = WFMATH_EPSILON) const
345  {return _ScaleEpsilon(m_elem, v.m_elem, dim, epsilon);}
346 
347  const CoordType* elements() const {return m_elem;}
348 
349  private:
350  CoordType m_elem[dim];
351  bool m_valid;
352 };
353 
355 CoordType Cross(const Vector<2>& v1, const Vector<2>& v2);
357 Vector<3> Cross(const Vector<3>& v1, const Vector<3>& v2);
358 
360 
365 template<int dim>
366 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2, bool& same_dir);
367 
369 
372 template<int dim>
373 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2);
374 
376 template<int dim>
377 bool Perpendicular(const Vector<dim>& v1, const Vector<dim>& v2);
378 
379 } // namespace WFMath
380 
381 #endif // WFMATH_VECTOR_H