WFMath  1.0.2
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, CoordType epsilon = numeric_constants<CoordType>::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 
206  friend CoordType Cross(const Vector<2>& v1, const Vector<2>& v2);
207  friend Vector<3> Cross(const Vector<3>& v1, const Vector<3>& v2);
208 
210  friend CoordType Dot<dim>(const Vector& v1, const Vector& v2);
212  friend CoordType Angle<dim>(const Vector& v, const Vector& u);
213 
215  CoordType sqrMag() const;
217  CoordType mag() const {return std::sqrt(sqrMag());}
219  Vector& normalize(CoordType norm = 1.0)
220  {CoordType themag = mag(); return (*this *= norm / themag);}
221 
223 
234  CoordType sloppyMag() const;
236 
241  Vector& sloppyNorm(CoordType norm = 1.0);
242 
243  // Can't seem to implement these as constants, implementing
244  // inline lookup functions instead.
246  static CoordType sloppyMagMax();
248 
254  static CoordType sloppyMagMaxSqrt();
255 
257  Vector& rotate(int axis1, int axis2, CoordType theta);
258 
260 
263  Vector& rotate(const Vector& v1, const Vector& v2, CoordType theta);
264 
266  Vector& rotate(const RotMatrix<dim>&);
267 
268  // mirror image functions
269 
271  Vector& mirror(const int i) { m_elem[i] *= -1; return *this;}
273  Vector& mirror(const Vector& v)
274  {return operator-=(*this, 2 * v * Dot(v, *this) / v.sqrMag());}
276 
279  Vector& mirror() {return operator*=(*this, -1);}
280 
281  // Specialized 2D/3D stuff starts here
282 
283  // The following functions are defined only for
284  // two dimensional (rotate(CoordType), Vector<>(CoordType, CoordType))
285  // and three dimensional (the rest of them) vectors.
286  // Attempting to call these on any other vector will
287  // result in a linker error.
288 
293 
295  Vector& rotate(CoordType theta);
296 
298  Vector& rotateX(CoordType theta);
300  Vector& rotateY(CoordType theta);
302  Vector& rotateZ(CoordType theta);
303 
305  Vector& rotate(const Vector& axis, CoordType theta);
307  Vector& rotate(const Quaternion& q);
308 
309  // Label the first three components of the vector as (x,y,z) for
310  // 2D/3D convienience
311 
313  CoordType x() const {return m_elem[0];}
315  CoordType& x() {return m_elem[0];}
317  CoordType y() const {return m_elem[1];}
319  CoordType& y() {return m_elem[1];}
321  CoordType z() const;
323  CoordType& z();
324 
326  Vector& mirrorX() {return mirror(0);}
328  Vector& mirrorY() {return mirror(1);}
330  Vector& mirrorZ();
331 
333  Vector& polar(CoordType r, CoordType theta);
335  void asPolar(CoordType& r, CoordType& theta) const;
336 
338  Vector& polar(CoordType r, CoordType theta, CoordType z);
340  void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
342  Vector& spherical(CoordType r, CoordType theta, CoordType phi);
344  void asSpherical(CoordType& r, CoordType& theta, CoordType& phi) const;
345 
346  const CoordType* elements() const {return m_elem;}
347 
348  private:
349  double _scaleEpsilon(const Vector& v, CoordType epsilon = numeric_constants<CoordType>::epsilon()) const
350  {return _ScaleEpsilon(m_elem, v.m_elem, dim, epsilon);}
351 
352  CoordType m_elem[dim];
353  bool m_valid;
354 };
355 
356 template<>
357 inline CoordType Vector<3>::z() const
358 {
359  return m_elem[2];
360 }
361 
362 template<>
363 inline CoordType& Vector<3>::z()
364 {
365  return m_elem[2];
366 }
367 
368 template<>
370 {
371  return mirror(2);
372 }
373 
375 CoordType Cross(const Vector<2>& v1, const Vector<2>& v2);
377 Vector<3> Cross(const Vector<3>& v1, const Vector<3>& v2);
378 
380 
385 template<int dim>
386 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2, bool& same_dir);
387 
389 
392 template<int dim>
393 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2);
394 
396 template<int dim>
397 bool Perpendicular(const Vector<dim>& v1, const Vector<dim>& v2);
398 
399 template <int dim>
400 inline Vector<dim> operator+(const Vector<dim>& v1, const Vector<dim>& v2)
401 {
402  Vector<dim> ans(v1);
403 
404  ans += v2;
405 
406  return ans;
407 }
408 
409 template <int dim>
410 inline Vector<dim> operator-(const Vector<dim>& v1, const Vector<dim>& v2)
411 {
412  Vector<dim> ans(v1);
413 
414  ans -= v2;
415 
416  return ans;
417 }
418 
419 template <int dim>
421 {
422  Vector<dim> ans(v);
423 
424  ans *= d;
425 
426  return ans;
427 }
428 
429 template<int dim>
431 {
432  Vector<dim> ans(v);
433 
434  ans *= d;
435 
436  return ans;
437 }
438 
439 template <int dim>
441 {
442  Vector<dim> ans(v);
443 
444  ans /= d;
445 
446  return ans;
447 }
448 
449 template<int dim>
450 inline bool Parallel(const Vector<dim>& v1,
451  const Vector<dim>& v2,
452  bool& same_dir)
453 {
454  CoordType dot = Dot(v1, v2);
455 
456  same_dir = (dot > 0);
457 
458  return Equal(dot * dot, v1.sqrMag() * v2.sqrMag());
459 }
460 
461 template<int dim>
462 inline bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2)
463 {
464  bool same_dir;
465 
466  return Parallel(v1, v2, same_dir);
467 }
468 
469 template<>
471 {
472  return 1.f;
473 }
474 
475 template<>
477 {
478  return 1.082392200292393968799446410733f;
479 }
480 
481 template<>
483 {
484  return 1.145934719303161490541433900265f;
485 }
486 
487 template<>
489 {
490  return 1.f;
491 }
492 
493 template<>
495 {
496  return 1.040380795811030899095785063701f;
497 }
498 
499 template<>
501 {
502  return 1.070483404496847625250328653179f;
503 }
504 
505 } // namespace WFMath
506 
507 #endif // WFMATH_VECTOR_H
Vector()
Construct an uninitialized vector.
Definition: vector.h:125
bool Equal(const C &c1, const C &c2, CoordType epsilon=numeric_constants< CoordType >::epsilon())
Test for equality up to precision epsilon.
Definition: const.h:158
Generic library namespace.
Definition: atlasconv.h:45
Vector & mirror(const int i)
Reflect a vector in the direction of the i&#39;th axis.
Definition: vector.h:271
static const Vector< dim > & ZERO()
Provides a global instance preset to zero.
Definition: vector_funcs.h:62
Vector & rotateZ(CoordType theta)
3D only: rotate a vector about the z axis by an angle theta
CoordType y() const
Access the second component of a vector.
Definition: vector.h:317
Vector & polar(CoordType r, CoordType theta)
2D only: construct a vector from polar coordinates
CoordType z() const
Access the third component of a vector.
void asSpherical(CoordType &r, CoordType &theta, CoordType &phi) const
3D only: convert a vector to shperical coordinates
Vector & mirror()
Reflect a vector in all directions simultaneously.
Definition: vector.h:279
A dim dimensional rotation matrix. Technically, a member of the group O(dim).
Definition: const.h:53
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:328
Vector & mirror(const Vector &v)
Reflect a vector in the direction specified by v.
Definition: vector.h:273
friend Vector operator/(const Vector &v, CoordType d)
Divide a vector by a scalar.
Definition: vector.h:440
CoordType sqrMag() const
The squared magnitude of a vector.
Definition: vector_funcs.h:237
Vector & rotate(int axis1, int axis2, CoordType theta)
Rotate the vector in the (axis1, axis2) plane by the angle theta.
Definition: vector_funcs.h:191
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:250
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:326
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&#39;ve initialized the vector by hand
Definition: vector.h:154
friend Vector operator*(CoordType d, const Vector &v)
Multiply a vector by a scalar.
Definition: vector.h:430
Vector & sloppyNorm(CoordType norm=1.0)
Approximately normalize a vector.
Definition: vector_funcs.h:155
CoordType & y()
Access the second component of a vector.
Definition: vector.h:319
void asPolar(CoordType &r, CoordType &theta) const
2D only: convert a vector to polar coordinates
A dim dimensional vector.
Definition: const.h:55
CoordType & x()
Access the first component of a vector.
Definition: vector.h:315
Vector & zero()
Zero the components of a vector.
Definition: vector_funcs.h:165
float CoordType
Basic floating point type.
Definition: const.h:140
friend CoordType Dot(const Vector &v1, const Vector &v2)
The dot product of two vectors.
Definition: vector_funcs.h:223
friend CoordType Cross(const Vector< 2 > &v1, const Vector< 2 > &v2)
2D only: get the z component of the cross product of two vectors
CoordType sloppyMag() const
An approximation to the magnitude of a vector.
static CoordType sloppyMagMaxSqrt()
The square root of sloppyMagMax()
friend Vector operator-(const Vector &v1, const Vector &v2)
Take the difference of two vectors.
Definition: vector.h:410
AtlasOutType toAtlas() const
Create an Atlas object from the vector.
Definition: atlasconv.h:116
Vector & normalize(CoordType norm=1.0)
Normalize a vector.
Definition: vector.h:219
friend Vector & operator-=(Vector &v1, const Vector &v2)
Subtract the second vector from the first.
Definition: vector_funcs.h:108
CoordType mag() const
The magnitude of a vector.
Definition: vector.h:217
static CoordType sloppyMagMax()
The maximum ratio of the return value of sloppyMag() to the true magnitude.
CoordType x() const
Access the first component of a vector.
Definition: vector.h:313
RotMatrix< dim > operator*(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2
Definition: rotmatrix_funcs.h:223
friend Vector & operator*=(Vector &v, CoordType d)
Multiply the magnitude of v by d.
Definition: vector_funcs.h:120
CoordType & operator[](const int i)
Get the i&#39;th element of the vector.
Definition: vector.h:190
Vector & mirrorZ()
Flip the z component of a vector.
void fromAtlas(const AtlasInType &a)
Set the vector&#39;s value to that given by an Atlas object.
Definition: atlasconv.h:109
CoordType operator[](const int i) const
Get the i&#39;th element of the vector.
Definition: vector.h:188
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:35
RotMatrix< dim > Prod(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2
Definition: rotmatrix_funcs.h:89
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.h:450
friend Vector operator+(const Vector &v1, const Vector &v2)
Take the sum of two vectors.
Definition: vector.h:400