Made it possible to display normals in output channels 4-6 (A,B,C)
[tecorrec.git] / maths / VarVector.h
blob51d2266391986ef6c018912b5a8c92c4cd92f8bb
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 VarVector.h
22 * @brief Resizable vector of values, designed for spacial coordinate vectors.
23 * @author James Hogan <james@albanarts.com>
24 * @note Copyright (C) 2008
27 #ifndef _maths_VarVector_h
28 #define _maths_VarVector_h
30 #include "TemplateMaths.h"
31 #include "Vector.h"
33 #include <QtGlobal>
35 #include <ostream>
36 #include <sstream>
38 namespace maths
41 /// VarVector.
42 /**
43 * @param N int Number of components in the vector.
44 * @param T typename Type of the components of the vector.
46 template <typename T>
47 class VarVector
49 private:
50 int m_length;
51 T* v;
53 public:
54 typedef T Scalar;
56 /// Default constructor (zero length, use setLength before doing anything)
57 inline explicit VarVector()
58 : m_length(0)
59 , v(0)
63 /// Default constructor (Does not initialise the values!)
64 inline explicit VarVector(int components)
65 : m_length(components)
66 , v(new T[components])
70 inline VarVector(int components, T value)
71 : m_length(components)
72 , v(new T[components])
74 for (int i = 0; i < m_length; ++i)
76 v[i] = value;
79 inline VarVector(int components, const T * vec)
80 : m_length(components)
81 , v(new T[components])
83 for (int i = 0; i < m_length; ++i)
85 v[i] = vec[i];
89 /// Copy constructor
90 inline VarVector(const VarVector & copy)
91 : m_length(copy.m_length)
92 , v(new T[m_length])
94 for (int i = 0; i < m_length; ++i)
96 v[i] = copy[i];
99 template <typename U> inline explicit VarVector(const VarVector<U> & copy)
100 : m_length(copy.m_length)
101 , v(new T[m_length])
103 for (int i = 0; i < m_length; ++i)
105 v[i] = copy[i];
108 template <int M, typename U> inline explicit VarVector(const Vector<M,U> & copy)
109 : m_length(M)
110 , v(new T[M])
112 for (int i = 0; i < M; ++i)
114 v[i] = copy[i];
118 /// Destructor
119 inline ~VarVector()
121 delete [] v;
124 /// Get the length of the vector.
125 int length() const
127 return m_length;
130 /// Resize of the vector (values are lost).
131 void setLength(int newLength)
133 if (newLength != m_length)
135 Q_ASSERT(newLength > 0);
136 delete [] v;
137 m_length = newLength;
138 v = new T [newLength];
142 /// Assignment operator.
143 VarVector& operator = (const VarVector& other)
145 setLength(other.m_length);
146 for (int i = 0; i < m_length; ++i)
148 v[i] = other.v[i];
150 return *this;
153 /// Assignment operator.
154 template <typename U>
155 VarVector& operator = (const VarVector<U>& other)
157 setLength(other.m_length);
158 for (int i = 0; i < m_length; ++i)
160 v[i] = other.v[i];
162 return *this;
165 /// Setter for specific component.
166 template <int X>
167 inline void setComponent(const T newValue)
169 v[X] = newValue;
172 /// Getter for specific component.
173 template <int X>
174 inline T getComponent() const
176 return v[X];
179 inline T & operator [] (int index)
181 return v[index];
183 inline const T & operator [] (int index) const
185 return v[index];
188 inline operator T * ()
190 return v;
192 inline operator const T * () const
194 return v;
197 inline VarVector operator - () const
199 VarVector ret(m_length);
200 for (int i = 0; i < m_length; ++i)
202 ret[i] = -v[i];
204 return ret;
207 template <typename U>
208 inline VarVector & operator += (const VarVector<U> & rhs)
210 Q_ASSERT(m_length == rhs.m_length);
211 for (int i = 0; i < m_length; ++i)
213 v[i] += rhs.v[i];
215 return *this;
217 template <typename U>
218 inline VarVector operator + (const VarVector<U> & rhs) const
220 VarVector ret = *this;
221 return ret += rhs;
224 inline VarVector & operator -= (const VarVector & rhs)
226 Q_ASSERT(m_length == rhs.m_length);
227 for (int i = 0; i < m_length; ++i)
229 v[i] -= rhs.v[i];
231 return *this;
233 inline VarVector operator - (const VarVector & rhs) const
235 VarVector ret = *this;
236 return ret -= rhs;
239 inline VarVector & operator *= (const T rhs)
241 for (int i = 0; i < m_length; ++i)
243 v[i] *= rhs;
245 return *this;
247 inline VarVector operator * (const T rhs) const
249 VarVector ret = *this;
250 return ret *= rhs;
252 inline friend VarVector operator * (const T lhs, const VarVector & rhs)
254 return rhs * lhs;
257 /// Dot product
258 inline T operator * (const VarVector & rhs) const
260 Q_ASSERT(m_length == rhs.m_length);
261 T fDot = maths::zero<T>();
262 for (int i = 0; i < m_length; ++i)
264 fDot += v[i]*rhs.v[i];
266 return fDot;
269 /// Dot quotient
270 inline T operator / (const VarVector & rhs) const
272 // a = B/C = (B*C)/(C*C)
273 return operator * (rhs) / rhs.sqr();
276 inline VarVector & operator /= (const T rhs)
278 for (int i = 0; i < m_length; ++i)
280 v[i] /= rhs;
282 return *this;
284 inline VarVector operator / (const T rhs) const
286 VarVector ret = *this;
287 return ret /= rhs;
289 inline friend VarVector operator / (const T lhs, const VarVector & rhs)
291 return rhs * (lhs / rhs.sqr());
294 inline T sqr() const
296 return tsqr<T>();
298 template <typename U>
299 inline U tsqr() const
301 U ret = maths::zero<U>();
302 for (int i = 0; i < m_length; ++i)
304 ret += maths::sqr<U>(v[i]);
306 return ret;
309 inline VarVector inv() const
311 return *this / sqr();
314 inline T mag() const
316 return tmag<T>();
318 template <typename U>
319 inline U tmag() const
321 return maths::sqrt<U>(tsqr<U>());
325 inline VarVector & normalize()
327 return operator /= (mag());
329 inline VarVector normalized() const
331 return operator / (mag());
333 inline VarVector & resize(T tLength)
335 return operator *= (tLength / mag());
337 inline VarVector resized(T tLength) const
339 return operator * (tLength / mag());
343 // predicates
345 /// Equality
346 inline bool operator == (const VarVector & rhs) const
348 Q_ASSERT(m_length == rhs.m_length);
349 for (int i = 0; i < m_length; ++i)
351 if (v[i] != rhs.v[i])
353 return false;
356 return true;
358 /// Nonequality
359 inline bool operator != (const VarVector & rhs) const
361 Q_ASSERT(m_length == rhs.m_length);
362 for (int i = 0; i < m_length; ++i)
364 if (v[i] != rhs.v[i])
366 return true;
369 return false;
372 /// Compare the magnitude of vectors.
373 inline bool operator < (const VarVector & rhs) const
375 return sqr() < rhs.sqr();
377 /// Compare the magnitude of the vector with a scalar magnitude.
378 inline bool operator < (const T & rhs) const
380 return sqr() < rhs*rhs;
382 /// Compare the magnitude of the vector with a scalar magnitude.
383 inline friend bool operator < (const T & lhs, const VarVector & rhs)
385 return lhs*lhs < rhs.sqr();
387 /// Compare the magnitude of vectors.
388 inline bool operator <= (const VarVector & rhs) const
390 return sqr() <= rhs.sqr();
392 /// Compare the magnitude of the vector with a scalar magnitude.
393 inline bool operator <= (const T & rhs) const
395 return sqr() <= rhs*rhs;
397 /// Compare the magnitude of the vector with a scalar magnitude.
398 inline friend bool operator <= (const T & lhs, const VarVector & rhs)
400 return lhs*lhs <= rhs.sqr();
402 /// Compare the magnitude of vectors.
403 inline bool operator > (const VarVector & rhs) const
405 return sqr() > rhs.sqr();
407 /// Compare the magnitude of the vector with a scalar magnitude.
408 inline bool operator > (const T & rhs) const
410 return sqr() > rhs*rhs;
412 /// Compare the magnitude of the vector with a scalar magnitude.
413 inline friend bool operator > (const T & lhs, const VarVector & rhs)
415 return lhs*lhs > rhs.sqr();
417 /// Compare the magnitude of vectors.
418 inline bool operator >= (const VarVector & rhs) const
420 return sqr() >= rhs.sqr();
422 /// Compare the magnitude of the vector with a scalar magnitude.
423 inline bool operator >= (const T & rhs) const
425 return sqr() >= rhs*rhs;
427 /// Compare the magnitude of the vector with a scalar magnitude.
428 inline friend bool operator >= (const T & lhs, const VarVector & rhs)
430 return lhs*lhs >= rhs.sqr();
433 /// Find whether the vector zero.
434 inline bool zero() const
436 for (int i = 0; i < m_length; ++i)
438 if (v[i])
440 return false;
443 return true;
446 inline operator std::string() const;
447 }; // ::maths::VarVector
449 /// Write a vector to an output stream.
450 template <typename T>
451 inline std::ostream & operator << (std::ostream & out, const VarVector<T> & v)
453 out << "(" << v[0];
454 for (int i = 1; i < v.length(); ++i)
456 out << ", " << v[i];
458 return out << ")";
460 /// Convert to a string using the above stream operator
461 template <typename T>
462 inline VarVector<T>::operator std::string() const
464 std::stringstream ss;
465 ss << v;
466 return ss.str();
469 } // ::maths
471 #endif // _maths_VarVector_h