3es  0.7
3esvector4.h
1 //
2 // author: Kazys Stepanas
3 //
4 #ifndef _3ESVECTOR4_H_
5 #define _3ESVECTOR4_H_
6 
7 #include "3es-core.h"
8 
9 #include "3esvector3.h"
10 
11 namespace tes
12 {
13  template <typename T> class Vector4;
14 
16  typedef Vector4<float> Vector4f;
19 
21  template <typename T>
22  class Vector4
23  {
24  public:
25  union
26  {
27  struct
28  {
30  T x, y, z, w;
31  };
33  T v[4];
34  };
35 
37  static const T Epsilon;
38 
40  static const Vector4<T> zero;
42  static const Vector4<T> one;
44  static const Vector4<T> axisx;
46  static const Vector4<T> axisy;
48  static const Vector4<T> axisz;
50  static const Vector4<T> axisw;
51 
53  inline Vector4() {}
56  inline Vector4(const T &scalar) : x(scalar), y(scalar), z(scalar), w(scalar) {}
59  inline Vector4(const Vector4<T> &other) : x(other.x), y(other.y), z(other.z), w(other.w) {}
63  inline Vector4(const Vector3<T> &other, const T &w) : x(other.x), y(other.y), z(other.z), w(w) {}
68  inline Vector4(const T &x, const T &y, const T &z, const T &w) : x(x), y(y), z(z), w(w) {}
72  inline Vector4(const T *array4) : x(array4[0]), y(array4[1]), z(array4[2]), w(array4[3]) {}
73 
76  template <typename Q>
77  explicit inline Vector4(const Vector4<Q> &other) : x(other.x), y(other.y), z(other.z), w(other.w) {}
78 
82  template <typename Q>
83  explicit inline Vector4(const Vector3<Q> &other, const T &w) : x(other.x), y(other.y), z(other.z), w(w) {}
84 
88  inline T &operator[](int index) { return v[index]; }
90  inline const T &operator[](int index) const { return v[index]; }
91 
95  inline Vector4<T> &operator=(const Vector4<T> &other) { x = other.x; y = other.y; z = other.z; w = other.w; return *this; }
96 
100  template <typename Q>
101  inline Vector4<T> &operator=(const Vector4<Q> &other) { x = T(other.x); y = T(other.y); z = T(other.z); w = T(other.w); return *this; }
102 
106  bool operator==(const Vector4<T> &other) const;
110  bool operator!=(const Vector4<T> &other) const;
111 
114  inline Vector4<T> operator-() const { return negated(); }
115 
123  bool isEqual(const Vector4<T> &other, const T &epsilon = Epsilon) const;
124 
131  bool isZero(const T &epsilon = Epsilon) const;
132 
135  inline Vector4<T> &negate() { x = -x; y = -y; z = -y; w = -w; return *this; }
136 
139  inline Vector4<T> negated() const { return Vector4<T>(-x, -y, -z, -w); }
140 
148  T normalise(const T &epsilon = Epsilon);
149 
157  Vector4<T> normalised(const T &epsilon = Epsilon) const;
158 
162  Vector4<T> &add(const Vector4<T> &other);
163 
167  Vector4<T> &add(const T &scalar);
168 
172  Vector4<T> &subtract(const Vector4<T> &other);
173 
177  Vector4<T> &subtract(const T &scalar);
178 
182  Vector4<T> &multiply(const T &scalar);
183 
187  inline Vector4<T> &scale(const T &scalar) { return multiply(scalar); }
188 
192  Vector4<T> &divide(const T &scalar);
193 
196  T dot(const Vector4<T> &other) const;
197 
200  T dot3(const Vector4<T> &other) const;
201 
204  Vector4<T> cross3(const Vector4<T> &other) const;
205 
208  T magnitude() const;
209 
212  T magnitudeSquared() const;
213 
215  inline Vector4<T> &operator+=(const Vector4 &other) { return add(other); }
217  inline Vector4<T> &operator+=(const T &scalar) { return add(scalar); }
219  inline Vector4<T> &operator-=(const Vector4 &other) { return subtract(other); }
221  inline Vector4<T> &operator-=(const T &scalar) { return subtract(scalar); }
223  inline Vector4<T> &operator*=(const T &scalar) { return multiply(scalar); }
225  inline Vector4<T> &operator/=(const T &scalar) { return divide(scalar); }
226 
229  inline Vector3<T> xyz() const { return Vector3<T>(x, y, z); }
230  };
231 
232  template class _3es_coreAPI Vector4<float>;
233  template class _3es_coreAPI Vector4<double>;
234 
235  //---------------------------------------------------------------------------
236  // Arithmetic operators
237  //---------------------------------------------------------------------------
238 
240  template <class T>
241  inline Vector4<T> operator+(const Vector4<T> &a, const Vector4<T> &b)
242  {
243  Vector4<T> v(a);
244  v.add(b);
245  return v;
246  }
247 
249  template <class T>
250  inline Vector4<T> operator+(const Vector4<T> &a, const T &b)
251  {
252  Vector4<T> v(a);
253  v.add(b);
254  return v;
255  }
256 
258  template <class T>
259  inline Vector4<T> operator+(const T &a, const Vector4<T> &b) { return b * a; }
260 
262  template <class T>
263  inline Vector4<T> operator-(const Vector4<T> &a, const Vector4<T> &b)
264  {
265  Vector4<T> v(a);
266  v.subtract(b);
267  return v;
268  }
269 
271  template <class T>
272  inline Vector4<T> operator-(const Vector4<T> &a, const T &b)
273  {
274  Vector4<T> v(a);
275  v.subtract(b);
276  return v;
277  }
278 
280  template <class T>
281  inline Vector4<T> operator*(const Vector4<T> &a, const T &b)
282  {
283  Vector4<T> v(a);
284  v.multiply(b);
285  return v;
286  }
287 
289  template <class T>
290  inline Vector4<T> operator*(const T &a, const Vector4<T> &b) { return b * a; }
291 
293  template <class T>
294  inline Vector4<T> operator/(const Vector4<T> &a, const T &b)
295  {
296  Vector4<T> v(a);
297  v.divide(b);
298  return v;
299  }
300 
301 
302  template <typename T>
303  inline bool Vector4<T>::operator==(const Vector4<T> &other) const
304  {
305  return x == other.x && y == other.y && z == other.z && w == other.w;
306  }
307 
308 
309  template <typename T>
310  inline bool Vector4<T>::operator!=(const Vector4<T> &other) const
311  {
312  return x != other.x || y != other.y || z != other.z || w != other.w;
313  }
314 
315 
316  template <typename T>
317  inline bool Vector4<T>::isEqual(const Vector4<T> &other, const T &epsilon) const
318  {
319  const T distanceSquared = std::abs((*this - other).magnitudeSquared());
320  return distanceSquared <= epsilon * epsilon;
321  }
322 
323 
324  template <typename T>
325  inline bool Vector4<T>::isZero(const T &epsilon) const
326  {
327  return isEqual(zero, epsilon);
328  }
329 
330 
331  template <typename T>
332  inline T Vector4<T>::normalise(const T &epsilon)
333  {
334  T mag = magnitude();
335  if (mag > epsilon)
336  {
337  divide(mag);
338  }
339  return mag;
340  }
341 
342 
343  template <typename T>
344  inline Vector4<T> Vector4<T>::normalised(const T &epsilon) const
345  {
346  T mag = magnitude();
347  if (mag > epsilon)
348  {
349  Vector4<T> v(*this);
350  v.divide(mag);
351  return v;
352  }
353  return zero;
354  }
355 
356 
357  template <typename T>
358  inline Vector4<T> &Vector4<T>::add(const Vector4<T> &other)
359  {
360  x += other.x;
361  y += other.y;
362  z += other.z;
363  w += other.w;
364  return *this;
365  }
366 
367 
368  template <typename T>
369  inline Vector4<T> &Vector4<T>::add(const T &scalar)
370  {
371  x += scalar;
372  y += scalar;
373  z += scalar;
374  w += scalar;
375  return *this;
376  }
377 
378 
379  template <typename T>
381  {
382  x -= other.x;
383  y -= other.y;
384  z -= other.z;
385  w -= other.w;
386  return *this;
387  }
388 
389 
390  template <typename T>
391  inline Vector4<T> &Vector4<T>::subtract(const T &scalar)
392  {
393  x -= scalar;
394  y -= scalar;
395  z -= scalar;
396  w -= scalar;
397  return *this;
398  }
399 
400 
401  template <typename T>
403  {
404  x *= scalar;
405  y *= scalar;
406  z *= scalar;
407  w *= scalar;
408  return *this;
409  }
410 
411 
412  template <typename T>
413  Vector4<T> &Vector4<T>::divide(const T &scalar)
414  {
415  const T div = T(1) / scalar;
416  x *= div;
417  y *= div;
418  z *= div;
419  w *= div;
420  return *this;
421  }
422 
423 
424  template <typename T>
425  T Vector4<T>::dot(const Vector4<T> &other) const
426  {
427  return x * other.x + y * other.y + z * other.z + w * other.w;
428  }
429 
430 
431  template <typename T>
432  T Vector4<T>::dot3(const Vector4<T> &other) const
433  {
434  return x * other.x + y * other.y + z * other.z + w * other.w;
435  }
436 
437 
438  template <typename T>
440  {
441  Vector4<T> v;
442  v.x = y * other.z - z * other.y;
443  v.y = z * other.x - x * other.z;
444  v.z = x * other.y - y * other.x;
445  v.w = T(1);
446  return v;
447  }
448 
449 
450  template <typename T>
452  {
453  T mag = magnitudeSquared();
454  mag = std::sqrt(mag);
455  return mag;
456  }
457 
458 
459  template <typename T>
461  {
462  return dot(*this);
463  }
464 
465 
466  template <typename T> const T Vector4<T>::Epsilon = T(1e-6);
467  template <typename T> const Vector4<T> Vector4<T>::zero(T(0));
468  template <typename T> const Vector4<T> Vector4<T>::one(T(1));
469  template <typename T> const Vector4<T> Vector4<T>::axisx(1, 0, 0, 0);
470  template <typename T> const Vector4<T> Vector4<T>::axisy(0, 1, 0, 0);
471  template <typename T> const Vector4<T> Vector4<T>::axisz(0, 0, 1, 0);
472  template <typename T> const Vector4<T> Vector4<T>::axisw(0, 0, 0, 1);
473 }
474 
475 #endif // _3ESVECTOR4_H_
T normalise(const T &epsilon=Epsilon)
Attempts to normalise this vector.
Definition: 3esvector4.h:332
static const Vector4< T > axisx
The vector (1, 0, 0, 0).
Definition: 3esvector4.h:44
static const Vector4< T > axisw
The vector (0, 0, 0, 1).
Definition: 3esvector4.h:50
Vector4< T > & multiply(const T &scalar)
Multiplies all components in this vector by scalar.
Definition: 3esvector4.h:402
bool operator!=(const Vector4< T > &other) const
Exact inequality operator.
Definition: 3esvector4.h:310
Vector4< T > & operator-=(const T &scalar)
Arithmetic operator.
Definition: 3esvector4.h:221
Vector4< T > & subtract(const Vector4< T > &other)
Subtracts other from this vector (this - other).
Definition: 3esvector4.h:380
Vector4< T > operator-() const
Unarary negation operator.
Definition: 3esvector4.h:114
Vector3< T > xyz() const
Downcast this vector to a Vector3.
Definition: 3esvector4.h:229
bool operator==(const Vector4< T > &other) const
Exact equality operator.
Definition: 3esvector4.h:303
T dot3(const Vector4< T > &other) const
Calculates the dot as if using vectors in R3.
Definition: 3esvector4.h:432
bool isZero(const T &epsilon=Epsilon) const
Zero test with error.
Definition: 3esvector4.h:325
Vector4(const T *array4)
Initialisation from a array of at least length 4.
Definition: 3esvector4.h:72
Vector4(const T &scalar)
Initialises all members to scalar.
Definition: 3esvector4.h:56
Vector4< T > & operator/=(const T &scalar)
Arithmetic operator.
Definition: 3esvector4.h:225
const T & operator[](int index) const
Definition: 3esvector4.h:90
Vector4< T > & scale(const T &scalar)
An alias for multiply(const T &).
Definition: 3esvector4.h:187
T dot(const Vector4< T > &other) const
Calculates the dot product of this.other.
Definition: 3esvector4.h:425
T magnitude() const
Calculates the magnitude of this vector.
Definition: 3esvector4.h:451
bool isEqual(const Vector4< T > &other, const T &epsilon=Epsilon) const
Equality test with error.
Definition: 3esvector4.h:317
Vector4< T > & operator+=(const T &scalar)
Arithmetic operator.
Definition: 3esvector4.h:217
Definition: 3esbounds.h:13
static const Vector4< T > zero
A vector with all zero values.
Definition: 3esvector4.h:40
Vector4(const Vector3< Q > &other, const T &w)
Copy constructor from a Vector3 of a different numeric type.
Definition: 3esvector4.h:83
Represents a vector in R4.
Definition: 3esvector4.h:13
T & operator[](int index)
Index operator.
Definition: 3esvector4.h:88
Matrix3< T > operator*(const Matrix3< T > &a, const Matrix3< T > &b)
Performs the matrix multiplication AB.
Vector4(const Vector3< T > &other, const T &w)
Copy constructor from a Vector3.
Definition: 3esvector4.h:63
Vector4< T > & divide(const T &scalar)
Divides all components in this vector by scalar.
Definition: 3esvector4.h:413
Vector4< T > & operator*=(const T &scalar)
Arithmetic operator.
Definition: 3esvector4.h:223
static const Vector4< T > axisz
The vector (0, 0, 1, 0).
Definition: 3esvector4.h:48
Represents a vector in R3.
Definition: 3esvector3.h:14
Vector4< T > cross3(const Vector4< T > &other) const
Calculates the dot product with other in R3.
Definition: 3esvector4.h:439
Vector4()
Default constructor: undefined initialisation behaviour.
Definition: 3esvector4.h:53
Vector3< T > operator/(const Vector3< T > &a, const T &b)
Divides a vector by a scalar.
Definition: 3esvector3.h:297
Vector4< T > & operator-=(const Vector4 &other)
Arithmetic operator.
Definition: 3esvector4.h:219
Vector4(const Vector4< T > &other)
Copy constructor.
Definition: 3esvector4.h:59
T x
Direct data member access.
Definition: 3esvector4.h:30
static const Vector4< T > one
The vector (1, 1, 1, 1).
Definition: 3esvector4.h:42
Vector3< T > operator+(const Vector3< T > &a, const Vector3< T > &b)
Adds two vectors.
Definition: 3esvector3.h:244
Vector4< float > Vector4f
Defines a single precision vector.
Definition: 3esvector4.h:13
Vector4< T > & negate()
Negates all components of this vector.
Definition: 3esvector4.h:135
Vector4< T > & operator+=(const Vector4 &other)
Arithmetic operator.
Definition: 3esvector4.h:215
Vector4< T > negated() const
Returns a negated copy of this vector.
Definition: 3esvector4.h:139
T magnitudeSquared() const
Calculates the magnitude squared of this vector.
Definition: 3esvector4.h:460
Vector4< T > normalised(const T &epsilon=Epsilon) const
Returns a normalised copy of this vector.
Definition: 3esvector4.h:344
static const T Epsilon
The default epsilon value used comparison operators.
Definition: 3esvector4.h:37
Vector4< T > & add(const Vector4< T > &other)
Adds other to this vector.
Definition: 3esvector4.h:358
Vector4< double > Vector4d
Defines a double precision vector.
Definition: 3esvector4.h:18
T v[4]
Array representation of the vector members.
Definition: 3esvector4.h:33
Vector4(const T &x, const T &y, const T &z, const T &w)
Per coordinate initialisation.
Definition: 3esvector4.h:68
static const Vector4< T > axisy
The vector (0, 1, 0, 0).
Definition: 3esvector4.h:46
Vector4< T > & operator=(const Vector4< Q > &other)
Simple assignment operator from a different numeric type.
Definition: 3esvector4.h:101
Vector4< T > & operator=(const Vector4< T > &other)
Simple assignment operator.
Definition: 3esvector4.h:95
Vector4(const Vector4< Q > &other)
Copy constructor from a different numeric type.
Definition: 3esvector4.h:77