wfmath 1.0.3
A math library for the Worldforge system.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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
39namespace WFMath {
40
41template<int dim>
42Vector<dim>& operator+=(Vector<dim>& v1, const Vector<dim>& v2);
43template<int dim>
44Vector<dim>& operator-=(Vector<dim>& v1, const Vector<dim>& v2);
45template<int dim>
46Vector<dim>& operator*=(Vector<dim>& v, CoordType d);
47template<int dim>
48Vector<dim>& operator/=(Vector<dim>& v, CoordType d);
49
50template<int dim>
51Vector<dim> operator+(const Vector<dim>& v1, const Vector<dim>& v2);
52template<int dim>
53Vector<dim> operator-(const Vector<dim>& v1, const Vector<dim>& v2);
54template<int dim>
55Vector<dim> operator-(const Vector<dim>& v); // Unary minus
56template<int dim>
57Vector<dim> operator*(CoordType d, const Vector<dim>& v);
58template<int dim>
59Vector<dim> operator*(const Vector<dim>& v, CoordType d);
60template<int dim>
61Vector<dim> operator/(const Vector<dim>& v, CoordType d);
62
63template<int dim>
64CoordType Dot(const Vector<dim>& v1, const Vector<dim>& v2);
65
66template<int dim>
67CoordType Angle(const Vector<dim>& v, const Vector<dim>& u);
68
69// The following are defined in rotmatrix_funcs.h
71template<int dim> // m * v
72Vector<dim> Prod(const RotMatrix<dim>& m, const Vector<dim>& v);
74template<int dim> // m^-1 * v
75Vector<dim> InvProd(const RotMatrix<dim>& m, const Vector<dim>& v);
77
80template<int dim> // v * m
81Vector<dim> Prod(const Vector<dim>& v, const RotMatrix<dim>& m);
83template<int dim> // v * m^-1
84Vector<dim> ProdInv(const Vector<dim>& v, const RotMatrix<dim>& m);
85
87template<int dim>
88Vector<dim> operator*(const RotMatrix<dim>& m, const Vector<dim>& v);
90template<int dim>
91Vector<dim> operator*(const Vector<dim>& v, const RotMatrix<dim>& m);
92
93template<int dim>
94Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2);
95template<int dim>
96Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v);
97template<int dim>
98Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v);
99template<int dim>
100Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c);
101
102template<int dim>
103Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v);
104template<int dim>
105Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v);
106
107template<int dim>
108std::ostream& operator<<(std::ostream& os, const Vector<dim>& v);
109template<int dim>
110std::istream& operator>>(std::istream& is, Vector<dim>& v);
111
112template<typename Shape>
113class ZeroPrimitive;
114
116
120template<int dim = 3>
121class Vector {
122 friend class ZeroPrimitive<Vector<dim> >;
123 public:
125 Vector() : m_elem{}, m_valid(false) { }
127 Vector(const Vector&) = default;
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) = default;
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());}
220 {CoordType themag = mag(); return (*this *= norm / themag);}
221
223
236
241 Vector& sloppyNorm(CoordType norm = 1.0);
242
243 // Can't seem to implement these as constants, implementing
244 // inline lookup functions instead.
248
255
257 Vector& rotate(int axis1, int axis2, CoordType theta);
258
260
263 Vector& rotate(const Vector& v1, const Vector& v2, CoordType theta);
264
267
268 // mirror image functions
269
271 Vector& mirror(const int i) { m_elem[i] *= -1; return *this;}
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
296
303
305 Vector& rotate(const Vector& axis, CoordType theta);
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;
324
326 Vector& mirrorX() {return mirror(0);}
328 Vector& mirrorY() {return mirror(1);}
331
335 void asPolar(CoordType& r, CoordType& theta) const;
336
340 void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
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
356template<>
357inline CoordType Vector<3>::z() const
358{
359 return m_elem[2];
360}
361
362template<>
363inline CoordType& Vector<3>::z()
364{
365 return m_elem[2];
366}
367
368template<>
369inline Vector<3>& Vector<3>::mirrorZ()
370{
371 return mirror(2);
372}
373
375CoordType Cross(const Vector<2>& v1, const Vector<2>& v2);
377Vector<3> Cross(const Vector<3>& v1, const Vector<3>& v2);
378
380
385template<int dim>
386bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2, bool& same_dir);
387
389
392template<int dim>
393bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2);
394
396template<int dim>
397bool Perpendicular(const Vector<dim>& v1, const Vector<dim>& v2);
398
399template <int dim>
400inline 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
409template <int dim>
410inline 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
419template <int dim>
421{
422 Vector<dim> ans(v);
423
424 ans *= d;
425
426 return ans;
427}
428
429template<int dim>
431{
432 Vector<dim> ans(v);
433
434 ans *= d;
435
436 return ans;
437}
438
439template <int dim>
440inline Vector<dim> operator/(const Vector<dim>& v, CoordType d)
441{
442 Vector<dim> ans(v);
443
444 ans /= d;
445
446 return ans;
447}
448
449template<int dim>
450inline 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
461template<int dim>
462inline 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
469template<>
470inline CoordType Vector<1>::sloppyMagMax()
471{
472 return 1.f;
473}
474
475template<>
477{
478 return 1.082392200292393968799446410733f;
479}
480
481template<>
483{
484 return 1.145934719303161490541433900265f;
485}
486
487template<>
488inline CoordType Vector<1>::sloppyMagMaxSqrt()
489{
490 return 1.f;
491}
492
493template<>
495{
496 return 1.040380795811030899095785063701f;
497}
498
499template<>
501{
502 return 1.070483404496847625250328653179f;
503}
504
505} // namespace WFMath
506
507#endif // WFMATH_VECTOR_H
A normalized quaternion.
Definition: quaternion.h:36
A dim dimensional rotation matrix. Technically, a member of the group O(dim).
Definition: rotmatrix.h:87
A dim dimensional vector.
Definition: vector.h:121
Vector & rotateZ(CoordType theta)
3D only: rotate a vector about the z axis by an angle theta
CoordType & z()
Access the third component of a vector.
CoordType z() const
Access the third component of a vector.
void asPolar(CoordType &r, CoordType &theta) const
2D only: convert a vector to polar coordinates
Vector & mirror()
Reflect a vector in all directions simultaneously.
Definition: vector.h:279
Vector & mirror(const int i)
Reflect a vector in the direction of the i'th axis.
Definition: vector.h:271
CoordType & x()
Access the first component of a vector.
Definition: vector.h:315
friend CoordType Cross(const Vector< 2 > &v1, const Vector< 2 > &v2)
2D only: get the z component of the cross product of two vectors
Definition: vector.cpp:102
Vector()
Construct an uninitialized vector.
Definition: vector.h:125
void asSpherical(CoordType &r, CoordType &theta, CoordType &phi) const
3D only: convert a vector to shperical coordinates
friend Vector & operator*=(Vector &v, CoordType d)
Multiply the magnitude of v by d.
Definition: vector_funcs.h:103
static CoordType sloppyMagMax()
The maximum ratio of the return value of sloppyMag() to the true magnitude.
Vector & spherical(CoordType r, CoordType theta, CoordType phi)
3D only: construct a vector from shperical coordinates
Vector & mirrorZ()
Flip the z component of a vector.
Vector(CoordType x, CoordType y, CoordType z)
3D only: construct a vector from (x, y, z) coordinates
Vector(CoordType x, CoordType y)
2D only: construct a vector from (x, y) coordinates
Vector & zero()
Zero the components of a vector.
Definition: vector_funcs.h:148
static CoordType sloppyMagMaxSqrt()
The square root of sloppyMagMax()
static const Vector< dim > & ZERO()
Provides a global instance preset to zero.
Definition: vector_funcs.h:54
Vector & polar(CoordType r, CoordType theta, CoordType z)
3D only: construct a vector from polar coordinates
CoordType & y()
Access the second component of a vector.
Definition: vector.h:319
Vector & rotate(CoordType theta)
2D only: rotate a vector by an angle theta
Vector & sloppyNorm(CoordType norm=1.0)
Approximately normalize a vector.
Definition: vector_funcs.h:138
void asPolar(CoordType &r, CoordType &theta, CoordType &z) const
3D only: convert a vector to polar coordinates
Vector & mirrorY()
Flip the y component of a vector.
Definition: vector.h:328
CoordType sloppyMag() const
An approximation to the magnitude of a vector.
CoordType x() const
Access the first component of a vector.
Definition: vector.h:313
void setValid(bool valid=true)
make isValid() return true if you've initialized the vector by hand
Definition: vector.h:154
AtlasOutType toAtlas() const
Create an Atlas object from the vector.
Definition: atlasconv.h:122
friend CoordType Dot(const Vector &v1, const Vector &v2)
The dot product of two vectors.
Definition: vector_funcs.h:206
friend Vector & operator-=(Vector &v1, const Vector &v2)
Subtract the second vector from the first.
Definition: vector_funcs.h:91
Vector & mirror(const Vector &v)
Reflect a vector in the direction specified by v.
Definition: vector.h:273
CoordType mag() const
The magnitude of a vector.
Definition: vector.h:217
Vector & rotate(int axis1, int axis2, CoordType theta)
Rotate the vector in the (axis1, axis2) plane by the angle theta.
Definition: vector_funcs.h:174
Vector(const Vector &)=default
Construct a copy of a vector.
Vector & rotate(const Vector &axis, CoordType theta)
3D only: rotate a vector about the i'th axis by an angle theta
CoordType y() const
Access the second component of a vector.
Definition: vector.h:317
CoordType sqrMag() const
The squared magnitude of a vector.
Definition: vector_funcs.h:220
CoordType operator[](const int i) const
Get the i'th element of the vector.
Definition: vector.h:188
CoordType & operator[](const int i)
Get the i'th element of the vector.
Definition: vector.h:190
void fromAtlas(const AtlasInType &a)
Set the vector's value to that given by an Atlas object.
Definition: atlasconv.h:109
Vector & rotateX(CoordType theta)
3D only: rotate a vector about the x axis by an angle theta
Vector & rotate(const Quaternion &q)
3D only: rotate a vector using a Quaternion
Vector & rotateY(CoordType theta)
3D only: rotate a vector about the y axis by an angle theta
Vector & mirrorX()
Flip the x component of a vector.
Definition: vector.h:326
Vector & polar(CoordType r, CoordType theta)
2D only: construct a vector from polar coordinates
Vector & normalize(CoordType norm=1.0)
Normalize a vector.
Definition: vector.h:219
Utility class for providing zero primitives. This class will only work with simple structures such as...
Definition: zero.h:35
Generic library namespace.
Definition: shape.h:41
double CoordType
Basic floating point type.
Definition: const.h:140
RotMatrix< dim > InvProd(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1^-1 * m2
CoordType Cross(const Vector< 2 > &v1, const Vector< 2 > &v2)
2D only: get the z component of the cross product of two vectors
Definition: vector.cpp:102
RotMatrix< dim > Prod(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2
bool Parallel(const Vector< dim > &v1, const Vector< dim > &v2, bool &same_dir)
Check if two vectors are parallel.
Definition: vector.h:450
RotMatrix< dim > ProdInv(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2^-1
bool Perpendicular(const Vector< dim > &v1, const Vector< dim > &v2)
Check if two vectors are perpendicular.
Definition: vector_funcs.h:233
RotMatrix< dim > operator*(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2