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());}
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 
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
Vector()
Construct an uninitialized vector.
Definition: vector.h:125
Vector & mirror(const int i)
Reflect a vector in the direction of the i'th axis.
Definition: vector.h:268
static const Vector< dim > & ZERO()
Provides a global instance preset to zero.
Definition: vector_funcs.h:60
Vector & rotateZ(CoordType theta)
3D only: rotate a vector about the z axis by an angle theta
Vector & polar(CoordType r, CoordType theta)
2D only: construct a vector from polar coordinates
CoordType operator[](const int i) const
Get the i'th element of the vector.
Definition: vector.h:188
Vector & mirror()
Reflect a vector in all directions simultaneously.
Definition: vector.h:276
A dim dimensional rotation matrix. Technically, a member of the group O(dim).
Definition: const.h:53
CoordType sqrMag() const
The squared magnitude of a vector.
Definition: vector_funcs.h:284
Vector & rotateY(CoordType theta)
3D only: rotate a vector about the y axis by an angle theta
Vector & mirrorY()
Flip the y component of a vector.
Definition: vector.h:325
Vector & mirror(const Vector &v)
Reflect a vector in the direction specified by v.
Definition: vector.h:270
static const CoordType sloppyMagMaxSqrt()
The square root of sloppyMagMax()
Vector & rotate(int axis1, int axis2, CoordType theta)
Rotate the vector in the (axis1, axis2) plane by the angle theta.
Definition: vector_funcs.h:238
Vector & rotateX(CoordType theta)
3D only: rotate a vector about the x axis by an angle theta
bool Perpendicular(const Vector< dim > &v1, const Vector< dim > &v2)
Check if two vectors are perpendicular.
Definition: vector_funcs.h:315
RotMatrix< dim > InvProd(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1^-1 * m2
Definition: rotmatrix_funcs.h:133
Vector & mirrorX()
Flip the x component of a vector.
Definition: vector.h:323
Vector & spherical(CoordType r, CoordType theta, CoordType phi)
3D only: construct a vector from shperical coordinates
void setValid(bool valid=true)
make isValid() return true if you've initialized the vector by hand
Definition: vector.h:154
Vector & sloppyNorm(CoordType norm=1.0)
Approximately normalize a vector.
Definition: vector_funcs.h:202
CoordType & y()
Access the second component of a vector.
Definition: vector.h:316
CoordType Cross(const Vector< 2 > &v1, const Vector< 2 > &v2)
2D only: get the z component of the cross product of two vectors
A dim dimensional vector.
Definition: const.h:55
CoordType & z()
Access the third component of a vector.
Definition: vector.h:320
CoordType & x()
Access the first component of a vector.
Definition: vector.h:312
Vector & zero()
Zero the components of a vector.
Definition: vector_funcs.h:212
void asSpherical(CoordType &r, CoordType &theta, CoordType &phi) const
3D only: convert a vector to shperical coordinates
void asPolar(CoordType &r, CoordType &theta) const
2D only: convert a vector to polar coordinates
float CoordType
Basic floating point type.
Definition: const.h:79
friend CoordType Dot(const Vector &v1, const Vector &v2)
The dot product of two vectors.
Definition: vector_funcs.h:270
Vector & normalize(CoordType norm=1.0)
Normalize a vector.
Definition: vector.h:216
friend Vector & operator-=(Vector &v1, const Vector &v2)
Subtract the second vector from the first.
Definition: vector_funcs.h:106
RotMatrix< dim > operator*(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2
Definition: rotmatrix_funcs.h:223
CoordType x() const
Access the first component of a vector.
Definition: vector.h:310
friend Vector & operator*=(Vector &v, CoordType d)
Multiply the magnitude of v by d.
Definition: vector_funcs.h:118
CoordType & operator[](const int i)
Get the i'th element of the vector.
Definition: vector.h:190
AtlasOutType toAtlas() const
Create an Atlas object from the vector.
Definition: atlasconv.h:124
CoordType y() const
Access the second component of a vector.
Definition: vector.h:314
Vector & mirrorZ()
Flip the z component of a vector.
Definition: vector.h:327
void fromAtlas(const AtlasInType &a)
Set the vector's value to that given by an Atlas object.
Definition: atlasconv.h:117
RotMatrix< dim > ProdInv(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2^-1
Definition: rotmatrix_funcs.h:111
A normalized quaterion.
Definition: quaternion.h:39
RotMatrix< dim > Prod(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2
Definition: rotmatrix_funcs.h:89
CoordType z() const
Access the third component of a vector.
Definition: vector.h:318
A dim dimensional point.
Definition: const.h:50
bool Parallel(const Vector< dim > &v1, const Vector< dim > &v2, bool &same_dir)
Check if two vectors are parallel.
Definition: vector_funcs.h:297
CoordType sloppyMag() const
An approximation to the magnitude of a vector.
CoordType mag() const
The magnitude of a vector.
Definition: vector.h:214
static const CoordType sloppyMagMax()
The maximum ratio of the return value of sloppyMag() to the true magnitude.