view include/Vector.h @ 12:1d2b25d4517f

Lot's of updates, some quite old since I guess I forgot to commit a while back. But I just added rotation matrix related things.
author Eris Caffee <discordia@eldalin.com>
date Mon, 06 May 2013 01:06:12 -0500
parents 398894c52b69
children e00321d11fe1
line source
1 #ifndef VECTOR_H_
2 #define VECTOR_H_
4 #include <cassert>
5 #include <cmath>
6 #include <string>
7 #include <iostream>
8 #include <sstream>
11 namespace arda
12 {
13 namespace Math
14 {
15 ////////////////////////////////////////////////////////////////////////////////
16 // Vectors
17 //
18 // Templated classes for 2, 3, and 4 dimensional vectors of any type,
19 // although these types are really intended to be int, float, and double
20 // only. (i.e. if you roll your own base type, it had better act like
21 // a numeric scalar.)
22 //
23 // Supported operations on vectors
24 //
25 // Construction
26 // Vector v; // Default zero vector.
27 // Vector v2(v); // Construct from other vector.
28 // T a, b;
29 // Vector v(a, b) // Construct from values.
30 // []
31 // If you have a Vector named v you can access it's member elements as
32 // v[0], v[1], v[2], and v[3]. in addtion to v.x, v.y, v.z, and v.w
33 // == != + += - -=
34 // Defined for operations on two vectors of the same type.
35 // * *= / /=
36 // Defined for scalar multiplication/division with int, float, and double.
37 // * is defined as a standalone template operator for the scalar * Vector form.
38 // assign(T a, T b [, T b [, T d]])
39 // Directly assign values to the vector.
40 // cross(Vector3& v2)
41 // cross(Vector3& v2, Vector3& vres)
42 // Cross product of the vector with v2. Only defined for Vector3 types.
43 // The version that takes two arguments stores the result in the second
44 // argument. This may be faster since no temporary object is created
45 // during the operation.
46 // dot(Vector& v2)
47 // The dot product of the vector with v2.
48 // get_angle(Vector& v2)
49 // Returns the angle (in radians) between the vector and v2.
50 // Not meaningful for int vectors.
51 // get_anglen(Vector& v2)
52 // Like get_angle(), but the vectors must already be normalized.
53 // Not meaningful for int vectors.
54 // to_string(std::string & s)
55 // Returns a C string representation of the vector.
56 // This is one of the few non-inline Vector functions.
57 // length()
58 // Get the length of a vector.
59 // Returns a double for all vector types.
60 // normalize()
61 // Normalizes the vector.
62 // Not meaningful for int vectors.
63 // proj(Vector& v2, Vector& vres)
64 // Calculates the projection of the vector onto v2 and returns the result
65 // in vres.
66 // Not meaningful for int vectors.
67 // Returns vres.
68 //
69 //
70 // Note that the following typedefs are defined for convenience:
71 //
72 // typedef Vector2<int> Vector2i;
73 // typedef Vector2<float> Vector2f;
74 // typedef Vector2<double> Vector2d;
75 // typedef Vector3<int> Vector3i;
76 // typedef Vector3<float> Vector3f;
77 // typedef Vector3<double> Vector3d;
78 // typedef Vector4<int> Vector4i;
79 // typedef Vector4<float> Vector4f;
80 // typedef Vector4<double> Vector4d;
81 //
82 //
83 //
84 // Scalar multiplication and division are overloaded. Why?
85 // I'm not sure I need this. The idea is to support all likely scalar
86 // types without having to rely on implicit or explicit type conversion,
87 // especially not a conversion that might result in loss of precision.
88 // Multiplying a float Vector by a double scalar, for example.
89 //
90 // Is there a better way to do this? Am I worrying about nothing?
91 //
92 //
93 //
94 // I suppose I could make this into a single Vector template on two parameters
95 // template <typename T, unsigned int N> class Vector
96 // {
97 // T v[N];
98 //
99 // etc...
100 //
101 // This might buy perfect generality, but it would come at the expense of
102 // loops in all of the code, so I don't think it would really be worth it.
105 /////////////////////////////////////////////////////////////////////////////
106 template <typename T>
107 class Vector2
108 {
109 public:
110 T x, y;
112 // Constructors
113 Vector2() {}
114 explicit Vector2(T a) : x (a), y(a) {}
115 Vector2(T a, T b) : x (a), y(b) {}
117 // Array indexing
118 inline T& operator[](unsigned int const i)
119 { assert (i<2); if (i==0) return x; return y; }
120 inline T operator[](unsigned int const i) const
121 { assert (i<2); if (i==0) return x; return y; }
123 // Assignment
124 inline Vector2<T>& operator=(Vector2<T> const & v2)
125 { x = v2.x; y = v2.y; return *this; }
126 inline Vector2<T>& assign(T const a, T const b)
127 { x = a; y = b; return *this; }
129 // Comparison
130 inline bool operator==(Vector2<T> const & v2) const
131 { return ((x == v2.x) && (y == v2.y)); }
132 inline bool operator!=(Vector2<T> const & v2) const
133 { return ! (*this == v2); }
135 // Vector addition
136 inline Vector2<T>& operator+=(Vector2<T> const & v2)
137 { x += v2.x; y += v2.y; return *this; }
138 inline Vector2<T> operator+(Vector2<T> const & v2) const
139 { return Vector2<T>(*this) += v2; }
141 // Vector subtraction
142 inline Vector2<T>& operator-=(Vector2<T> const & v2)
143 { x -= v2.x; y -= v2.y; return *this; }
144 inline Vector2<T> operator-(Vector2<T> const & v2) const
145 { return Vector2<T>(*this) -= v2; }
147 // Scalar multiplication
148 inline Vector2<T>& operator*=(int const a)
149 { x *= a; y *= a; return *this; }
150 inline Vector2<T>& operator*=(float const a)
151 { x *= a; y *= a; return *this; }
152 inline Vector2<T>& operator*=(double const a)
153 { x *= a; y *= a; return *this; }
155 inline Vector2<T> operator*(int const a) const
156 { return Vector2<T>(*this) *= a;}
157 inline Vector2<T> operator*(float const a) const
158 { return Vector2<T>(*this) *= a;}
159 inline Vector2<T> operator*(double const a) const
160 { return Vector2<T>(*this) *= a;}
162 // Scalar division
163 inline Vector2<T>& operator/=(int const a)
164 { assert(a!=0); x /= a; y /= a; return *this; }
165 inline Vector2<T>& operator/=(float const a)
166 { assert(a!=0); x /= a; y /= a; return *this; }
167 inline Vector2<T>& operator/=(double const a)
168 { assert(a!=0); x /= a; y /= a; return *this; }
170 inline Vector2<T> operator/(int const a) const
171 { return Vector2<T>(*this) /= a;}
172 inline Vector2<T> operator/(float const a) const
173 { return Vector2<T>(*this) /= a;}
174 inline Vector2<T> operator/(double const a) const
175 { return Vector2<T>(*this) /= a;}
178 // methods
180 inline T dot(Vector2<T> const & v2) const
181 { return x*v2.x + y*v2.y; }
183 inline double get_angle(Vector2<T> const & v2)
184 {
185 double tmp = dot(v2);
186 return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2))));
187 }
189 inline double get_anglen(Vector2<T> const & v2)
190 { return acos((double) dot(v2)); }
192 std::string & to_string(std::string & s) const;
194 inline double length(void) const
195 { return sqrt((dot(*this))); }
197 inline Vector2<T>& normalize()
198 {
199 double l = length();
200 if (l == 0.0) return *this;
201 x /= l; y /= l;
202 return *this; }
204 inline Vector2<T> proj(Vector2<T> const & v2)
205 { Vector2<T> vres; vres = v2 * (dot(v2)/v2.dot(v2)); return vres; }
206 inline Vector2<T>& proj(Vector2<T> const & v2, Vector2<T>& vres)
207 { vres = v2 * dot(v2)/v2.dot(v2); return vres; }
208 };
210 // Scalar multiplication, continued
211 template <typename T>
212 inline Vector2<T> operator*(int const a, Vector2<T> const & v)
213 { return Vector2<T>(v) *= a;}
215 template <typename T>
216 inline Vector2<T> operator*(float const a, Vector2<T> const & v)
217 { return Vector2<T>(v) *= a;}
219 template <typename T>
220 inline Vector2<T> operator*(double const a, Vector2<T> const & v)
221 { return Vector2<T>(v) *= a;}
224 /////////////////////////////////////////////////////////////////////////////
225 template <typename T>
226 class Vector3
227 {
228 public:
229 T x, y, z;
231 // Constructors
232 Vector3() {}
233 explicit Vector3(T a) : x (a), y(a), z(a) {}
234 Vector3(T a, T b, T c) : x (a), y(b), z(c) {}
236 // Array indexing
237 inline T& operator[](unsigned int const i)
238 { assert (i<3); if (i==0) return x; if (i==1) return y; return z; }
239 inline T operator[](unsigned int const i) const
240 { assert (i<3); if (i==0) return x; if (i==1) return y; return z; }
242 // Assignment
243 inline Vector3<T>& operator=(Vector3<T> const & v2)
244 { x = v2.x; y = v2.y; z = v2.z; return *this; }
245 inline Vector3<T>& assign(T const a, T const b, T const c)
246 { x = a; y = b; z = c; return *this; }
248 // Comparison
249 inline bool operator==(Vector3<T> const & v2) const
250 { return ((x == v2.x) && (y == v2.y) && (z == v2.z)); }
251 inline bool operator!=(Vector3<T> const & v2) const
252 { return ! (*this == v2); }
254 // Vector addition
255 inline Vector3<T>& operator+=(Vector3<T> const & v2)
256 { x += v2.x; y += v2.y; z += v2.z; return *this; }
257 inline Vector3<T> operator+(Vector3<T> const & v2) const
258 { return Vector3<T>(*this) += v2; }
260 // Vector subtraction
261 inline Vector3<T>& operator-=(Vector3<T> const & v2)
262 { x -= v2.x; y -= v2.y; z -= v2.z; return *this; }
263 inline Vector3<T> operator-(Vector3<T> const & v2) const
264 { return Vector3<T>(*this) -= v2; }
266 // Scalar multiplication
267 inline Vector3<T>& operator*=(int const a)
268 { x *= a; y *= a; z *= a; return *this; }
269 inline Vector3<T>& operator*=(float const a)
270 { x *= a; y *= a; z *= a; return *this; }
271 inline Vector3<T>& operator*=(double const a)
272 { x *= a; y *= a; z *= a; return *this; }
274 inline Vector3<T> operator*(int const a) const
275 { return Vector3<T>(*this) *= a;}
276 inline Vector3<T> operator*(float const a) const
277 { return Vector3<T>(*this) *= a;}
278 inline Vector3<T> operator*(double const a) const
279 { return Vector3<T>(*this) *= a;}
281 // Scalar division
282 inline Vector3<T>& operator/=(int const a)
283 { assert(a!=0); x /= a; y /= a; z /= a; return *this; }
284 inline Vector3<T>& operator/=(float const a)
285 { assert(a!=0); x /= a; y /= a; z /= a; return *this; }
286 inline Vector3<T>& operator/=(double const a)
287 { assert(a!=0); x /= a; y /= a; z /= a; return *this; }
289 inline Vector3<T> operator/(int const a) const
290 { return Vector3<T>(*this) /= a;}
291 inline Vector3<T> operator/(float const a) const
292 { return Vector3<T>(*this) /= a;}
293 inline Vector3<T> operator/(double const a) const
294 { return Vector3<T>(*this) /= a;}
297 // methods
299 inline Vector3<T>& cross(Vector3<T> const & v2, Vector3<T>& vres)
300 {
301 vres.x = y*v2.z - v2.y*z;
302 vres.y = -x*v2.z + v2.x*z;
303 vres.z = x*v2.y - v2.x*y;
304 return vres;
305 }
306 inline Vector3<T> cross(Vector3<T> const & v2)
307 {
308 Vector3<T> vres;
309 vres.x = y*v2.z - v2.y*z;
310 vres.y = -x*v2.z + v2.x*z;
311 vres.z = x*v2.y - v2.x*y;
312 return vres;
313 }
315 inline T dot(Vector3<T> const & v2) const
316 { return x*v2.x + y*v2.y + z*v2.z; }
318 inline double get_angle(Vector3<T> const & v2)
319 {
320 double tmp = dot(v2);
321 return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2))));
322 }
324 inline double get_anglen(Vector3<T> const & v2)
325 { return acos((double) dot(v2)); }
327 std::string & to_string(std::string & s) const;
329 inline double length(void) const
330 { return sqrt((dot(*this))); }
332 inline Vector3<T>& normalize()
333 { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; return *this; }
335 inline Vector3<T> proj(Vector3<T> const & v2)
336 { Vector3<T> vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; }
337 inline Vector3<T>& proj(Vector3<T> const & v2, Vector3<T>& vres)
338 { vres = v2 * dot(v2)/v2.dot(v2); return vres; }
339 };
341 // Scalar multiplication, continued
342 template <typename T>
343 inline Vector3<T> operator*(int const a, Vector3<T> const & v)
344 { return Vector3<T>(v) *= a;}
346 template <typename T>
347 inline Vector3<T> operator*(float const a, Vector3<T> const & v)
348 { return Vector3<T>(v) *= a;}
350 template <typename T>
351 inline Vector3<T> operator*(double const a, Vector3<T> const & v)
352 { return Vector3<T>(v) *= a;}
354 /////////////////////////////////////////////////////////////////////////////
355 template <typename T>
356 class Vector4
357 {
358 public:
359 T x, y, z, w;
361 // Constructors
362 Vector4() {}
363 explicit Vector4(T a) : x (a), y(a), z(a), w(a) {}
364 Vector4(T a, T b, T c, T d) : x (a), y(b), z(c), w(d) {}
366 // Array indexing
367 inline T& operator[](unsigned int const i)
368 { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; }
369 inline T operator[](unsigned int const i) const
370 { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; }
372 // Assignment
373 inline Vector4<T>& operator=(Vector4<T> const & v2)
374 { x = v2.x; y = v2.y; z = v2.z; w = v2.w; return *this; }
375 inline Vector4<T>& assign(T const a, T const b, T const c, T const d)
376 { x = a; y = b; z = c; w = d; return *this; }
378 // Comparison
379 inline bool operator==(Vector4<T> const & v2) const
380 { return ((x == v2.x) && (y == v2.y) && (z == v2.z) && (w == v2.w)); }
381 inline bool operator!=(Vector4<T> const & v2) const
382 { return ! (*this == v2); }
384 // Vector addition
385 inline Vector4<T>& operator+=(Vector4<T> const & v2)
386 { x += v2.x; y += v2.y; z += v2.z; w += v2.w; return *this; }
387 inline Vector4<T> operator+(Vector4<T> const & v2) const
388 { return Vector4<T>(*this) += v2; }
390 // Vector subtraction
391 inline Vector4<T>& operator-=(Vector4<T> const & v2)
392 { x -= v2.x; y -= v2.y; z -= v2.z; w -= v2.w; return *this; }
393 inline Vector4<T> operator-(Vector4<T> const & v2) const
394 { return Vector4<T>(*this) -= v2; }
396 // Scalar multiplication
397 inline Vector4<T>& operator*=(int const a)
398 { x *= a; y *= a; z *= a; w *= a; return *this; }
399 inline Vector4<T>& operator*=(float const a)
400 { x *= a; y *= a; z *= a; w *= a; return *this; }
401 inline Vector4<T>& operator*=(double const a)
402 { x *= a; y *= a; z *= a; w *= a; return *this; }
404 inline Vector4<T> operator*(int const a) const
405 { return Vector4<T>(*this) *= a;}
406 inline Vector4<T> operator*(float const a) const
407 { return Vector4<T>(*this) *= a;}
408 inline Vector4<T> operator*(double const a) const
409 { return Vector4<T>(*this) *= a;}
411 // Scalar division
412 inline Vector4<T>& operator/=(int const a)
413 { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; }
414 inline Vector4<T>& operator/=(float const a)
415 { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; }
416 inline Vector4<T>& operator/=(double const a)
417 { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; }
419 inline Vector4<T> operator/(int const a) const
420 { return Vector4<T>(*this) /= a;}
421 inline Vector4<T> operator/(float const a) const
422 { return Vector4<T>(*this) /= a;}
423 inline Vector4<T> operator/(double const a) const
424 { return Vector4<T>(*this) /= a;}
427 // methods
429 inline T dot(Vector4<T> const & v2) const
430 { return x*v2.x + y*v2.y + z*v2.z + w*v2.w; }
432 inline double get_angle(Vector4<T> const & v2)
433 {
434 double tmp = dot(v2);
435 return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2))));
436 }
438 inline double get_anglen(Vector4<T> const & v2)
439 { return acos((double) dot(v2)); }
441 std::string & to_string(std::string & s) const;
443 inline double length(void) const
444 { return sqrt((dot(*this))); }
446 inline Vector4<T>& normalize()
447 { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; w /= l; return *this; }
449 inline Vector4<T> proj(Vector4<T> const & v2)
450 { Vector4<T> vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; }
451 inline Vector4<T>& proj(Vector4<T> const & v2, Vector4<T>& vres)
452 { vres = v2 * dot(v2)/v2.dot(v2); return vres; }
453 };
455 // Scalar multiplication, continued
456 template <typename T>
457 inline Vector4<T> operator*(int const a, Vector4<T> const & v)
458 { return Vector4<T>(v) *= a;}
460 template <typename T>
461 inline Vector4<T> operator*(float const a, Vector4<T> const & v)
462 { return Vector4<T>(v) *= a;}
464 template <typename T>
465 inline Vector4<T> operator*(double const a, Vector4<T> const & v)
466 { return Vector4<T>(v) *= a;}
468 /////////////////////////////////////////////////////////////////////////////
470 typedef Vector2<int> Vector2i;
471 typedef Vector2<float> Vector2f;
472 typedef Vector2<double> Vector2d;
474 typedef Vector3<int> Vector3i;
475 typedef Vector3<float> Vector3f;
476 typedef Vector3<double> Vector3d;
478 typedef Vector4<int> Vector4i;
479 typedef Vector4<float> Vector4f;
480 typedef Vector4<double> Vector4d;
482 } // namespace Math
484 } // namespace arda
486 ////////////////////////////////////////////////////////////////////////////////
487 template <typename T>
488 std::string & arda::Math::Vector2<T>::to_string(std::string & s) const
489 {
490 s.clear();
491 std::stringstream ss;
492 ss << "[ " << x << ", " << y << " ]";
493 s = ss.str();
494 return s;
495 }
497 ////////////////////////////////////////////////////////////////////////////////
498 template <typename T>
499 std::string & arda::Math::Vector3<T>::to_string(std::string & s) const
500 {
501 s.clear();
502 std::stringstream ss;
503 ss << "[ " << x << ", " << y << ", " << z << " ]";
504 s = ss.str();
505 return s;
506 }
508 ////////////////////////////////////////////////////////////////////////////////
509 template <typename T>
510 std::string & arda::Math::Vector4<T>::to_string(std::string & s) const
511 {
512 s.clear();
513 std::stringstream ss;
514 ss << "[ " << x << ", " << y << ", " << z << ", " << w << " ]";
515 s = ss.str();
516 return s;
517 }
520 #endif // VECTOR_H_