tcElevationOptimization::loadSnapShot: simplify reliability expression
[tecorrec.git] / maths / Vector.h
blob6e2dc347e6b3f4b1723ad7d435aa1a81b16a22a7
1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
20 /**
21 * @file Vector.h
22 * @brief Vector of values, designed for spacial coordinate vectors.
23 * @author James Hogan <james@albanarts.com>
24 * @note Copyright (C) 2007
26 * @version 1 : From Computer Graphics and Visualisation Open Assessment.
29 #ifndef _maths_Vector_h
30 #define _maths_Vector_h
32 #include "TemplateMaths.h"
34 #include <ostream>
35 #include <sstream>
37 namespace maths
40 /// Vector.
41 /**
42 * @param N int Number of components in the vector.
43 * @param T typename Type of the components of the vector.
45 template <int N, typename T>
46 class Vector
48 public:
49 T v[N];
51 enum {
52 length = N
54 typedef T Scalar;
56 /// Default constructor (Does not initialise the values!)
57 inline Vector()
61 inline explicit Vector(T value)
63 for (int i = 0; i < N; ++i)
65 v[i] = value;
68 inline Vector(T x, T y)
70 v[0] = x;
71 v[1] = y;
72 if (N > 2)
74 for (int i = 2; i < N; ++i)
76 v[i] = maths::zero<T>();
80 inline Vector(T x, T y, T z)
82 v[0] = x;
83 v[1] = y;
84 if (N > 2)
86 v[2] = z;
87 if (N > 3)
89 for (int i = 3; i < N; ++i)
91 v[i] = maths::zero<T>();
96 inline Vector(T x, T y, T z, T w)
98 v[0] = x;
99 v[1] = y;
100 if (N > 2)
102 v[2] = z;
103 if (N > 3)
105 v[3] = w;
106 if (N > 4)
108 for (int i = 4; i < N; ++i)
110 v[i] = maths::zero<T>();
116 inline explicit Vector(const T * vec)
118 for (int i = 0; i < N; ++i)
120 v[i] = vec[i];
123 template <int M, typename U> inline explicit Vector(const Vector<M,U> & copy)
125 int i = 0;
126 for (; i < N && i < M; ++i)
128 v[i] = (T)copy.v[i];
130 for (; i < N; ++i)
132 v[i] = maths::zero<T>();
136 inline const Vector & set()
138 for (int i = 0; i < N; ++i)
140 v[i] = maths::zero<T>();
142 return *this;
144 inline const Vector & set(T all)
146 for (int i = 0; i < N; ++i)
148 v[i] = all;
150 return *this;
152 inline const Vector & set(T x, T y)
154 v[0] = x;
155 v[1] = y;
156 if (N > 2)
158 for (int i = 2; i < N; ++i)
160 v[i] = maths::zero<T>();
163 return *this;
165 inline const Vector & set(T x, T y, T z)
167 v[0] = x;
168 v[1] = y;
169 if (N > 2)
171 v[2] = z;
172 if (N > 3)
174 for (int i = 3; i < N; ++i)
176 v[i] = maths::zero<T>();
180 return *this;
182 inline const Vector & set(T x, T y, T z, T w)
184 v[0] = x;
185 v[1] = y;
186 if (N > 2)
188 v[2] = z;
189 if (N > 3)
191 v[3] = w;
192 if (N > 4)
194 for (int i = 4; i < N; ++i)
196 v[i] = maths::zero<T>();
201 return *this;
203 inline const Vector & set(const Vector<3,T> xyz, T w)
205 v[0] = xyz[0];
206 v[1] = xyz[1];
207 if (N > 2)
209 v[2] = xyz[2];
210 if (N > 3)
212 v[3] = w;
213 if (N > 4)
215 for (int i = 4; i < N; ++i)
217 v[i] = maths::zero<T>();
222 return *this;
225 /// Setter for specific component.
226 template <int X>
227 inline void setComponent(const T newValue)
229 v[X] = newValue;
232 /// Getter for specific component.
233 template <int X>
234 inline T getComponent() const
236 return v[X];
239 /// Concatination operator, append a number.
240 inline Vector<N+1, T> operator , (T f) const
242 Vector<N+1,T> result;
243 for (int i = 0; i < N; ++i)
245 result[i] = v[i];
247 result[N] = f;
248 return result;
251 /// Concatination operator, prepend a number.
252 inline friend Vector<N+1, T> operator , (T f, const Vector & vector)
254 Vector<N+1,T> result;
255 result[0] = f;
256 for (int i = 0; i < N; ++i)
258 result[i+1] = vector[i];
260 return result;
263 /// Concatination operator, append a vector.
264 template <int M>
265 inline Vector<N+M, T> operator , (const Vector<M,T> & vector) const
267 Vector<N+M,T> result;
268 for (int i = 0; i < N; ++i)
270 result[i] = v[i];
272 for (int i = 0; i < M; ++i)
274 result[N+i] = vector[i];
276 return result;
279 /// Slice out of the vector a reference.
280 template <int S, int L>
281 inline Vector<L, T> & slice()
283 return *(Vector<L,T>*)(v+S);
286 /// Slice out of the vector a reference.
287 template <int S, int L>
288 inline const Vector<L, T> & slice() const
290 return *(Vector<L,T>*)(v+S);
293 inline T & operator [] (int index)
295 return v[index];
297 inline const T & operator [] (int index) const
299 return v[index];
302 inline operator T * ()
304 return v;
306 inline operator const T * () const
308 return v;
311 inline Vector operator - () const
313 Vector ret;
314 for (int i = 0; i < N; ++i)
316 ret[i] = -v[i];
318 return ret;
321 template <typename U>
322 inline Vector & operator += (const Vector<N,U> & rhs)
324 for (int i = 0; i < N; ++i)
326 v[i] += rhs.v[i];
328 return *this;
330 template <typename U>
331 inline Vector operator + (const Vector<N,U> & rhs) const
333 Vector ret = *this;
334 return ret += rhs;
337 inline Vector & operator -= (const Vector & rhs)
339 for (int i = 0; i < N; ++i)
341 v[i] -= rhs.v[i];
343 return *this;
345 inline Vector operator - (const Vector & rhs) const
347 Vector ret = *this;
348 return ret -= rhs;
351 inline Vector & operator *= (const T rhs)
353 for (int i = 0; i < N; ++i)
355 v[i] *= rhs;
357 return *this;
359 inline Vector operator * (const T rhs) const
361 Vector ret = *this;
362 return ret *= rhs;
364 inline friend Vector operator * (const T lhs, const Vector & rhs)
366 return rhs * lhs;
369 /// Dot product
370 inline T operator * (const Vector & rhs) const
372 T fDot = maths::zero<T>();
373 for (int i = 0; i < N; ++i)
375 fDot += v[i]*rhs.v[i];
377 return fDot;
380 /// Dot quotient
381 inline T operator / (const Vector & rhs) const
383 // a = B/C = (B*C)/(C*C)
384 return operator * (rhs) / rhs.sqr();
387 inline Vector & operator /= (const T rhs)
389 for (int i = 0; i < N; ++i)
391 v[i] /= rhs;
393 return *this;
395 inline Vector operator / (const T rhs) const
397 Vector ret = *this;
398 return ret /= rhs;
400 inline friend Vector operator / (const T lhs, const Vector & rhs)
402 return rhs * (lhs / rhs.sqr());
405 inline T sqr() const
407 return tsqr<T>();
409 template <typename U>
410 inline U tsqr() const
412 U ret = maths::zero<U>();
413 for (int i = 0; i < N; ++i)
415 ret += maths::sqr<U>(v[i]);
417 return ret;
420 inline Vector inv() const
422 return *this / sqr();
425 inline T mag() const
427 return tmag<T>();
429 template <typename U>
430 inline U tmag() const
432 return maths::sqrt<U>(tsqr<U>());
436 inline Vector & normalize()
438 return operator /= (mag());
440 inline Vector normalized() const
442 return operator / (mag());
444 inline Vector & resize(T tLength)
446 return operator *= (tLength / mag());
448 inline Vector resized(T tLength) const
450 return operator * (tLength / mag());
454 // predicates
456 /// Equality
457 inline bool operator == (const Vector & rhs) const
459 for (int i = 0; i < N; ++i)
461 if (v[i] != rhs.v[i])
463 return false;
466 return true;
468 /// Nonequality
469 inline bool operator != (const Vector & rhs) const
471 for (int i = 0; i < N; ++i)
473 if (v[i] != rhs.v[i])
475 return true;
478 return false;
481 /// Compare the magnitude of vectors.
482 inline bool operator < (const Vector & rhs) const
484 return sqr() < rhs.sqr();
486 /// Compare the magnitude of the vector with a scalar magnitude.
487 inline bool operator < (const T & rhs) const
489 return sqr() < rhs*rhs;
491 /// Compare the magnitude of the vector with a scalar magnitude.
492 inline friend bool operator < (const T & lhs, const Vector & rhs)
494 return lhs*lhs < rhs.sqr();
496 /// Compare the magnitude of vectors.
497 inline bool operator <= (const Vector & rhs) const
499 return sqr() <= rhs.sqr();
501 /// Compare the magnitude of the vector with a scalar magnitude.
502 inline bool operator <= (const T & rhs) const
504 return sqr() <= rhs*rhs;
506 /// Compare the magnitude of the vector with a scalar magnitude.
507 inline friend bool operator <= (const T & lhs, const Vector & rhs)
509 return lhs*lhs <= rhs.sqr();
511 /// Compare the magnitude of vectors.
512 inline bool operator > (const Vector & rhs) const
514 return sqr() > rhs.sqr();
516 /// Compare the magnitude of the vector with a scalar magnitude.
517 inline bool operator > (const T & rhs) const
519 return sqr() > rhs*rhs;
521 /// Compare the magnitude of the vector with a scalar magnitude.
522 inline friend bool operator > (const T & lhs, const Vector & rhs)
524 return lhs*lhs > rhs.sqr();
526 /// Compare the magnitude of vectors.
527 inline bool operator >= (const Vector & rhs) const
529 return sqr() >= rhs.sqr();
531 /// Compare the magnitude of the vector with a scalar magnitude.
532 inline bool operator >= (const T & rhs) const
534 return sqr() >= rhs*rhs;
536 /// Compare the magnitude of the vector with a scalar magnitude.
537 inline friend bool operator >= (const T & lhs, const Vector & rhs)
539 return lhs*lhs >= rhs.sqr();
542 /// Find whether the vector zero.
543 inline bool zero() const
545 for (int i = 0; i < N; ++i)
547 if (v[i])
549 return false;
552 return true;
556 inline operator std::string() const;
557 }; // ::maths::Vector
559 template <int N, typename T>
560 inline Vector<N,T> & add (Vector<N,T> & dest, const Vector<N,T> & lhs, const Vector<N,T> & rhs)
562 for (int i = 0; i < N; ++i)
564 dest.v[i] = lhs.v[i] + rhs.v[i];
566 return dest;
569 template <int N, typename T>
570 inline Vector<N,T> & sub (Vector<N,T> & dest, const Vector<N,T> & lhs, const Vector<N,T> & rhs)
572 for (int i = 0; i < N; ++i)
574 dest.v[i] = lhs.v[i] - rhs.v[i];
576 return dest;
579 template <typename T>
580 inline Vector<3,T> & cross (Vector<3,T> & dest, const Vector<3,T> & lhs, const Vector<3,T> & rhs)
582 dest.v[0] = lhs.v[1]*rhs.v[2] - lhs.v[2]*rhs.v[1];
583 dest.v[1] = lhs.v[2]*rhs.v[0] - lhs.v[0]*rhs.v[2];
584 dest.v[2] = lhs.v[0]*rhs.v[1] - lhs.v[1]*rhs.v[0];
585 return dest;
588 template <typename T>
589 inline Vector<3,T> cross (const Vector<3,T> & lhs, const Vector<3,T> & rhs)
591 Vector<3, T> dest;
592 dest.v[0] = lhs.v[1]*rhs.v[2] - lhs.v[2]*rhs.v[1];
593 dest.v[1] = lhs.v[2]*rhs.v[0] - lhs.v[0]*rhs.v[2];
594 dest.v[2] = lhs.v[0]*rhs.v[1] - lhs.v[1]*rhs.v[0];
595 return dest;
598 template <typename T>
599 inline Vector<4,T> homogenous(Vector<3,T> & vec, T homogenousness = (T)1)
601 Vector<4,T> ret(vec);
602 ret[3] = homogenousness;
603 return ret;
606 /// Get the distance from a plane.
607 template <typename T>
608 inline T plane(const Vector<4, T> & plane, const Vector<3, T> & point)
610 return plane[0]*point[0] + plane[1]*point[1] + plane[2]*point[2] + plane[3];
614 /// Write a vector to an output stream.
615 template <int N, typename T>
616 inline std::ostream & operator << (std::ostream & out, const Vector<N,T> & v)
618 out << "(" << v[0];
619 for (int i = 1; i < N; ++i)
621 out << ", " << v[i];
623 return out << ")";
625 /// Convert to a string using the above stream operator
626 template <int N, typename T>
627 inline Vector<N,T>::operator std::string() const
629 std::stringstream ss;
630 ss << v;
631 return ss.str();
634 /// Basic function to create a one dimentional vector (scalar) which can then be expanded by concatination.
635 template <typename T>
636 inline maths::Vector<1,T> Scalar(const T a)
638 return maths::Vector<1,T>(a);
641 } // ::maths
643 #endif // _maths_vector_h