view include/Vector.h @ 11:398894c52b69

Changed mind. Sticking with current design. Matrix22<T> is done.
author Eris Caffee <discordia@eldalin.com>
date Fri, 07 Oct 2011 13:33:48 -0500
parents 81d2aa42a860
children 1d2b25d4517f
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 // getstring(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 vecor.
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> class Vector2
107 {
108 public:
109 T x, y;
111 // Constructors
112 Vector2() {}
113 explicit Vector2(const T a) : x (a), y(a) {}
114 Vector2(const T a, const T b) : x (a), y(b) {}
116 // Array indexing
117 inline T& operator[](unsigned int i)
118 { assert (i<2); if (i==0) return x; return y; }
119 inline T operator[](unsigned int i) const
120 { assert (i<2); if (i==0) return x; return y; }
122 // Assignment
123 inline Vector2<T>& operator=(const Vector2<T>& v2)
124 { x = v2.x; y = v2.y; return *this; }
125 inline Vector2<T>& assign(const T a, const T b)
126 { x = a; y = b; return *this; }
128 // Comparison
129 inline bool operator==(Vector2<T>& v2) const
130 { return ((x == v2.x) && (y == v2.y)); }
131 inline bool operator!=(Vector2<T>& v2) const
132 { return ! (*this == v2); }
134 // Vector addition
135 inline Vector2<T>& operator+=(const Vector2<T>& v2)
136 { x += v2.x; y += v2.y; return *this; }
137 inline Vector2<T> operator+(const Vector2<T>& v2) const
138 { return Vector2<T>(*this) += v2; }
140 // Vector subtraction
141 inline Vector2<T>& operator-=(const Vector2<T>& v2)
142 { x -= v2.x; y -= v2.y; return *this; }
143 inline Vector2<T> operator-(const Vector2<T>& v2) const
144 { return Vector2<T>(*this) -= v2; }
146 // Scalar multiplication
147 inline Vector2<T>& operator*=(const int a)
148 { x *= a; y *= a; return *this; }
149 inline Vector2<T>& operator*=(const float a)
150 { x *= a; y *= a; return *this; }
151 inline Vector2<T>& operator*=(const double a)
152 { x *= a; y *= a; return *this; }
153 inline Vector2<T> operator*(const int a)
154 { return Vector2<T>(*this) *= a;}
155 inline Vector2<T> operator*(const float a)
156 { return Vector2<T>(*this) *= a;}
157 inline Vector2<T> operator*(const double a)
158 { return Vector2<T>(*this) *= a;}
160 // Scalar division
161 inline Vector2<T>& operator/=(const int a)
162 { assert(a!=0); x /= a; y /= a; return *this; }
163 inline Vector2<T>& operator/=(const float a)
164 { assert(a!=0); x /= a; y /= a; return *this; }
165 inline Vector2<T>& operator/=(const double a)
166 { assert(a!=0); x /= a; y /= a; return *this; }
167 inline Vector2<T> operator/(const int a)
168 { return Vector2<T>(*this) /= a;}
169 inline Vector2<T> operator/(const float a)
170 { return Vector2<T>(*this) /= a;}
171 inline Vector2<T> operator/(const double a)
172 { return Vector2<T>(*this) /= a;}
175 // methods
177 inline T dot(const Vector2<T>& v2) const
178 { return x*v2.x + y*v2.y; }
180 inline double get_angle(Vector2<T>& v2)
181 {
182 double tmp = dot(v2);
183 return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2))));
184 }
186 inline double get_anglen(Vector2<T>& v2)
187 { return acos((double) dot(v2)); }
189 std::string & getstring(std::string & s) const;
191 inline double length(void) const
192 { return sqrt((dot(*this))); }
194 inline Vector2<T>& normalize()
195 { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; return *this; }
197 inline Vector2<T> proj(Vector2<T>& v2)
198 { Vector2<T> vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; }
199 inline Vector2<T>& proj(Vector2<T>& v2, Vector2<T>& vres)
200 { vres = v2 * dot(v2)/v2.dot(v2); return vres; }
201 };
203 // Scalar multiplication, continued
204 template <typename T> inline Vector2<T> operator*(const int a, const Vector2<T>& v)
205 { return Vector2<T>(v) *= a;}
206 template <typename T> inline Vector2<T> operator*(const float a, const Vector2<T> v)
207 { return Vector2<T>(v) *= a;}
208 template <typename T> inline Vector2<T> operator*(const double a, const Vector2<T>& v)
209 { return Vector2<T>(v) *= a;}
212 /////////////////////////////////////////////////////////////////////////////
213 template <typename T> class Vector3
214 {
215 public:
216 T x, y, z;
218 // Constructors
219 Vector3() {}
220 explicit Vector3(const T a) : x (a), y(a), z(a) {}
221 Vector3(const T a, const T b, const T c) : x (a), y(b), z(c) {}
223 // Array indexing
224 inline T& operator[](unsigned int i)
225 { assert (i<3); if (i==0) return x; if (i==1) return y; return z; }
226 inline T operator[](unsigned int i) const
227 { assert (i<3); if (i==0) return x; if (i==1) return y; return z; }
229 // Assignment
230 inline Vector3<T>& operator=(const Vector3<T>& v2)
231 { x = v2.x; y = v2.y; z = v2.z; return *this; }
232 inline Vector3<T>& assign(const T a, const T b, const T c)
233 { x = a; y = b; z = c; return *this; }
235 // Comparison
236 inline bool operator==(Vector3<T>& v2) const
237 { return ((x == v2.x) && (y == v2.y) && (z == v2.z)); }
238 inline bool operator!=(Vector3<T>& v2) const
239 { return ! (*this == v2); }
241 // Vector addition
242 inline Vector3<T>& operator+=(const Vector3<T>& v2)
243 { x += v2.x; y += v2.y; z += v2.z; return *this; }
244 inline Vector3<T> operator+(const Vector3<T>& v2) const
245 { return Vector3<T>(*this) += v2; }
247 // Vector subtraction
248 inline Vector3<T>& operator-=(const Vector3<T>& v2)
249 { x -= v2.x; y -= v2.y; z -= v2.z; return *this; }
250 inline Vector3<T> operator-(const Vector3<T>& v2) const
251 { return Vector3<T>(*this) -= v2; }
253 // Scalar multiplication
254 inline Vector3<T>& operator*=(const int a)
255 { x *= a; y *= a; z *= a; return *this; }
256 inline Vector3<T>& operator*=(const float a)
257 { x *= a; y *= a; z *= a; return *this; }
258 inline Vector3<T>& operator*=(const double a)
259 { x *= a; y *= a; z *= a; return *this; }
260 inline Vector3<T> operator*(const int a)
261 { return Vector3<T>(*this) *= a;}
262 inline Vector3<T> operator*(const float a)
263 { return Vector3<T>(*this) *= a;}
264 inline Vector3<T> operator*(const double a)
265 { return Vector3<T>(*this) *= a;}
267 // Scalar division
268 inline Vector3<T>& operator/=(const int a)
269 { assert(a!=0); x /= a; y /= a; z /= a; return *this; }
270 inline Vector3<T>& operator/=(const float a)
271 { assert(a!=0); x /= a; y /= a; z /= a; return *this; }
272 inline Vector3<T>& operator/=(const double a)
273 { assert(a!=0); x /= a; y /= a; z /= a; return *this; }
274 inline Vector3<T> operator/(const int a)
275 { return Vector3<T>(*this) /= a;}
276 inline Vector3<T> operator/(const float a)
277 { return Vector3<T>(*this) /= a;}
278 inline Vector3<T> operator/(const double a)
279 { return Vector3<T>(*this) /= a;}
282 // methods
284 inline Vector3<T>& cross(Vector3<T>& v2, Vector3<T>& vres)
285 {
286 vres.x = y*v2.z - v2.y*z;
287 vres.y = -x*v2.z + v2.x*z;
288 vres.z = x*v2.y - v2.x*y;
289 return vres;
290 }
291 inline Vector3<T> cross(Vector3<T>& v2)
292 {
293 Vector3<T> vres;
294 vres.x = y*v2.z - v2.y*z;
295 vres.y = -x*v2.z + v2.x*z;
296 vres.z = x*v2.y - v2.x*y;
297 return vres;
298 }
300 inline T dot(const Vector3<T>& v2) const
301 { return x*v2.x + y*v2.y + z*v2.z; }
303 inline double get_angle(Vector3<T>& v2)
304 {
305 double tmp = dot(v2);
306 return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2))));
307 }
309 inline double get_anglen(Vector3<T>& v2)
310 { return acos((double) dot(v2)); }
312 std::string & getstring(std::string & s) const;
314 inline double length(void) const
315 { return sqrt((dot(*this))); }
317 inline Vector3<T>& normalize()
318 { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; return *this; }
320 inline Vector3<T> proj(Vector3<T>& v2)
321 { Vector3<T> vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; }
322 inline Vector3<T>& proj(Vector3<T>& v2, Vector3<T>& vres)
323 { vres = v2 * dot(v2)/v2.dot(v2); return vres; }
324 };
326 // Scalar multiplication, continued
327 template <typename T> inline Vector3<T> operator*(const int a, const Vector3<T>& v)
328 { return Vector3<T>(v) *= a;}
329 template <typename T> inline Vector3<T> operator*(const float a, const Vector3<T> v)
330 { return Vector3<T>(v) *= a;}
331 template <typename T> inline Vector3<T> operator*(const double a, const Vector3<T>& v)
332 { return Vector3<T>(v) *= a;}
334 /////////////////////////////////////////////////////////////////////////////
335 template <typename T> class Vector4
336 {
337 public:
338 T x, y, z, w;
340 // Constructors
341 Vector4() {}
342 explicit Vector4(const T a) : x (a), y(a), z(a), w(a) {}
343 Vector4(const T a, const T b, const T c, const T d) : x (a), y(b), z(c), w(d) {}
345 // Array indexing
346 inline T& operator[](unsigned int i)
347 { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; }
348 inline T operator[](unsigned int i) const
349 { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; }
351 // Assignment
352 inline Vector4<T>& operator=(const Vector4<T>& v2)
353 { x = v2.x; y = v2.y; z = v2.z; w = v2.w; return *this; }
354 inline Vector4<T>& assign(const T a, const T b, const T c, const T d)
355 { x = a; y = b; z = c; w = d; return *this; }
357 // Comparison
358 inline bool operator==(Vector4<T>& v2) const
359 { return ((x == v2.x) && (y == v2.y) && (z == v2.z) && (w == v2.w)); }
360 inline bool operator!=(Vector4<T>& v2) const
361 { return ! (*this == v2); }
363 // Vector addition
364 inline Vector4<T>& operator+=(const Vector4<T>& v2)
365 { x += v2.x; y += v2.y; z += v2.z; w += v2.w; return *this; }
366 inline Vector4<T> operator+(const Vector4<T>& v2) const
367 { return Vector4<T>(*this) += v2; }
369 // Vector subtraction
370 inline Vector4<T>& operator-=(const Vector4<T>& v2)
371 { x -= v2.x; y -= v2.y; z -= v2.z; w -= v2.w; return *this; }
372 inline Vector4<T> operator-(const Vector4<T>& v2) const
373 { return Vector4<T>(*this) -= v2; }
375 // Scalar multiplication
376 inline Vector4<T>& operator*=(const int a)
377 { x *= a; y *= a; z *= a; w *= a; return *this; }
378 inline Vector4<T>& operator*=(const float a)
379 { x *= a; y *= a; z *= a; w *= a; return *this; }
380 inline Vector4<T>& operator*=(const double a)
381 { x *= a; y *= a; z *= a; w *= a; return *this; }
382 inline Vector4<T> operator*(const int a)
383 { return Vector4<T>(*this) *= a;}
384 inline Vector4<T> operator*(const float a)
385 { return Vector4<T>(*this) *= a;}
386 inline Vector4<T> operator*(const double a)
387 { return Vector4<T>(*this) *= a;}
389 // Scalar division
390 inline Vector4<T>& operator/=(const int a)
391 { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; }
392 inline Vector4<T>& operator/=(const float a)
393 { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; }
394 inline Vector4<T>& operator/=(const double a)
395 { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; }
396 inline Vector4<T> operator/(const int a)
397 { return Vector4<T>(*this) /= a;}
398 inline Vector4<T> operator/(const float a)
399 { return Vector4<T>(*this) /= a;}
400 inline Vector4<T> operator/(const double a)
401 { return Vector4<T>(*this) /= a;}
404 // methods
406 inline T dot(const Vector4<T>& v2) const
407 { return x*v2.x + y*v2.y + z*v2.z + w*v2.w; }
409 inline double get_angle(Vector4<T>& v2)
410 {
411 double tmp = dot(v2);
412 return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2))));
413 }
415 inline double get_anglen(Vector4<T>& v2)
416 { return acos((double) dot(v2)); }
418 std::string & getstring(std::string & s) const;
420 inline double length(void) const
421 { return sqrt((dot(*this))); }
423 inline Vector4<T>& normalize()
424 { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; w /= l; return *this; }
426 inline Vector4<T> proj(Vector4<T>& v2)
427 { Vector4<T> vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; }
428 inline Vector4<T>& proj(Vector4<T>& v2, Vector4<T>& vres)
429 { vres = v2 * dot(v2)/v2.dot(v2); return vres; }
430 };
432 // Scalar multiplication, continued
433 template <typename T> inline Vector4<T> operator*(const int a, const Vector4<T>& v)
434 { return Vector4<T>(v) *= a;}
435 template <typename T> inline Vector4<T> operator*(const float a, const Vector4<T> v)
436 { return Vector4<T>(v) *= a;}
437 template <typename T> inline Vector4<T> operator*(const double a, const Vector4<T>& v)
438 { return Vector4<T>(v) *= a;}
440 /////////////////////////////////////////////////////////////////////////////
442 typedef Vector2<int> Vector2i;
443 typedef Vector2<float> Vector2f;
444 typedef Vector2<double> Vector2d;
446 typedef Vector3<int> Vector3i;
447 typedef Vector3<float> Vector3f;
448 typedef Vector3<double> Vector3d;
450 typedef Vector4<int> Vector4i;
451 typedef Vector4<float> Vector4f;
452 typedef Vector4<double> Vector4d;
454 } // namespace Math
456 } // namespace arda
458 ////////////////////////////////////////////////////////////////////////////////
459 template <typename T> std::string & arda::Math::Vector2<T>::getstring(std::string & s) const
460 {
461 s.clear();
462 std::stringstream ss;
463 ss << "[ " << x << ", " << y << " ]";
464 s = ss.str();
465 return s;
466 }
468 ////////////////////////////////////////////////////////////////////////////////
469 template <typename T> std::string & arda::Math::Vector3<T>::getstring(std::string & s) const
470 {
471 s.clear();
472 std::stringstream ss;
473 ss << "[ " << x << ", " << y << ", " << z << " ]";
474 s = ss.str();
475 return s;
476 }
478 ////////////////////////////////////////////////////////////////////////////////
479 template <typename T> std::string & arda::Math::Vector4<T>::getstring(std::string & s) const
480 {
481 s.clear();
482 std::stringstream ss;
483 ss << "[ " << x << ", " << y << ", " << z << ", " << w << " ]";
484 s = ss.str();
485 return s;
486 }
489 #endif // VECTOR_H_