3es  0.7
3esvector3.h
1 //
2 // author: Kazys Stepanas
3 //
4 #ifndef _3ESVECTOR3_H_
5 #define _3ESVECTOR3_H_
6 
7 #include "3es-core.h"
8 
9 #include <cstdlib>
10 #include <cmath>
11 
12 namespace tes
13 {
14  template <typename T> class Vector3;
16  typedef Vector3<float> Vector3f;
19 
21  template <typename T>
22  class Vector3
23  {
24  public:
25  union
26  {
27  struct
28  {
30  T x, y, z;
31  };
33  T v[3];
34  };
35 
37  static const T Epsilon;
38 
40  static const Vector3<T> zero;
42  static const Vector3<T> one;
44  static const Vector3<T> axisx;
46  static const Vector3<T> axisy;
48  static const Vector3<T> axisz;
49 
51  inline Vector3() {}
54  inline Vector3(const T &scalar) : x(scalar), y(scalar), z(scalar) {}
57  inline Vector3(const Vector3<T> &other) : x(other.x), y(other.y), z(other.z) {}
62  inline Vector3(const T &x, const T &y, const T &z) : x(x), y(y), z(z) {}
66  inline Vector3(const T *array3) : x(array3[0]), y(array3[1]), z(array3[2]) {}
67 
70  template <typename Q>
71  explicit inline Vector3(const Vector3<Q> &other) : x(T(other.x)), y(T(other.y)), z(T(other.z)) {}
72 
76  inline T &operator[](int index) { return v[index]; }
78  inline const T &operator[](int index) const { return v[index]; }
79 
83  inline T &operator[](unsigned index) { return v[index]; }
85  inline const T &operator[](unsigned index) const { return v[index]; }
86 
90  inline Vector3<T> &operator=(const Vector3<T> &other) { x = other.x; y = other.y; z = other.z; return *this; }
91 
95  template <typename Q>
96  inline Vector3<T> &operator=(const Vector3<Q> &other) { x = T(other.x); y = T(other.y); z = T(other.z); return *this; }
97 
101  bool operator==(const Vector3<T> &other) const;
105  bool operator!=(const Vector3<T> &other) const;
106 
109  inline Vector3<T> operator-() const { return negated(); }
110 
118  bool isEqual(const Vector3<T> &other, const T &epsilon = Epsilon) const;
119 
126  bool isZero(const T &epsilon = Epsilon) const;
127 
130  inline Vector3<T> &negate() { x = -x; y = -y; z = -y; return *this; }
131 
134  inline Vector3<T> negated() const { return Vector3<T>(-x, -y, -z); }
135 
143  T normalise(const T &epsilon = Epsilon);
144 
152  Vector3<T> normalised(const T &epsilon = Epsilon) const;
153 
157  Vector3<T> &add(const Vector3<T> &other);
158 
162  Vector3<T> &add(const T &scalar);
163 
167  Vector3<T> &subtract(const Vector3<T> &other);
168 
172  Vector3<T> &subtract(const T &scalar);
173 
177  Vector3<T> &multiply(const T &scalar);
178 
182  inline Vector3<T> &scale(const T &scalar) { return multiply(scalar); }
183 
187  Vector3<T> &divide(const T &scalar);
188 
191  T dot(const Vector3<T> &other) const;
192 
195  Vector3<T> cross(const Vector3<T> &other) const;
196 
199  T magnitude() const;
200 
203  T magnitudeSquared() const;
204 
206  inline Vector3<T> &operator+=(const Vector3 &other) { return add(other); }
208  inline Vector3<T> &operator+=(const T &scalar) { return add(scalar); }
210  inline Vector3<T> &operator-=(const Vector3 &other) { return subtract(other); }
212  inline Vector3<T> &operator-=(const T &scalar) { return subtract(scalar); }
214  inline Vector3<T> &operator*=(const T &scalar) { return multiply(scalar); }
216  inline Vector3<T> &operator/=(const T &scalar) { return divide(scalar); }
217 
218  // Swizzle operations.
219 
221  inline Vector3<T> xyz() const { return Vector3<T>(*this); }
223  inline Vector3<T> xzy() const { return Vector3<T>(x, z, y); }
225  inline Vector3<T> yzx() const { return Vector3<T>(y, z, x); }
227  inline Vector3<T> yxz() const { return Vector3<T>(y, x, z); }
229  inline Vector3<T> zxy() const { return Vector3<T>(z, x, y); }
231  inline Vector3<T> zyx() const { return Vector3<T>(x, y, x); }
232  };
233 
234  template class _3es_coreAPI Vector3<float>;
235  template class _3es_coreAPI Vector3<double>;
236 
237 
238  //---------------------------------------------------------------------------
239  // Arithmetic operators
240  //---------------------------------------------------------------------------
241 
243  template <class T>
244  inline Vector3<T> operator+(const Vector3<T> &a, const Vector3<T> &b)
245  {
246  Vector3<T> v(a);
247  v.add(b);
248  return v;
249  }
250 
252  template <class T>
253  inline Vector3<T> operator+(const Vector3<T> &a, const T &b)
254  {
255  Vector3<T> v(a);
256  v.add(b);
257  return v;
258  }
259 
261  template <class T>
262  inline Vector3<T> operator+(const T &a, const Vector3<T> &b) { return b * a; }
263 
265  template <class T>
266  inline Vector3<T> operator-(const Vector3<T> &a, const Vector3<T> &b)
267  {
268  Vector3<T> v(a);
269  v.subtract(b);
270  return v;
271  }
272 
274  template <class T>
275  inline Vector3<T> operator-(const Vector3<T> &a, const T &b)
276  {
277  Vector3<T> v(a);
278  v.subtract(b);
279  return v;
280  }
281 
283  template <class T>
284  inline Vector3<T> operator*(const Vector3<T> &a, const T &b)
285  {
286  Vector3<T> v(a);
287  v.multiply(b);
288  return v;
289  }
290 
292  template <class T>
293  inline Vector3<T> operator*(const T &a, const Vector3<T> &b) { return b * a; }
294 
296  template <class T>
297  inline Vector3<T> operator/(const Vector3<T> &a, const T &b)
298  {
299  Vector3<T> v(a);
300  v.divide(b);
301  return v;
302  }
303 
304 
305  template <typename T>
306  inline bool Vector3<T>::operator==(const Vector3<T> &other) const
307  {
308  return x == other.x && y == other.y && z == other.z;
309  }
310 
311 
312  template <typename T>
313  inline bool Vector3<T>::operator!=(const Vector3<T> &other) const
314  {
315  return x != other.x || y != other.y || z != other.z;
316  }
317 
318 
319  template <typename T>
320  inline bool Vector3<T>::isEqual(const Vector3<T> &other, const T &epsilon) const
321  {
322  const T distanceSquared = std::abs((*this - other).magnitudeSquared());
323  return distanceSquared <= epsilon * epsilon;
324  }
325 
326 
327  template <typename T>
328  inline bool Vector3<T>::isZero(const T &epsilon) const
329  {
330  return isEqual(zero, epsilon);
331  }
332 
333 
334  template <typename T>
335  inline T Vector3<T>::normalise(const T &epsilon)
336  {
337  T mag = magnitude();
338  if (mag > epsilon)
339  {
340  divide(mag);
341  }
342  return mag;
343  }
344 
345 
346  template <typename T>
347  inline Vector3<T> Vector3<T>::normalised(const T &epsilon) const
348  {
349  T mag = magnitude();
350  if (mag > epsilon)
351  {
352  Vector3<T> v(*this);
353  v.divide(mag);
354  return v;
355  }
356  return zero;
357  }
358 
359 
360  template <typename T>
361  inline Vector3<T> &Vector3<T>::add(const Vector3<T> &other)
362  {
363  x += other.x;
364  y += other.y;
365  z += other.z;
366  return *this;
367  }
368 
369 
370  template <typename T>
371  inline Vector3<T> &Vector3<T>::add(const T &scalar)
372  {
373  x += scalar;
374  y += scalar;
375  z += scalar;
376  return *this;
377  }
378 
379 
380  template <typename T>
382  {
383  x -= other.x;
384  y -= other.y;
385  z -= other.z;
386  return *this;
387  }
388 
389 
390  template <typename T>
391  inline Vector3<T> &Vector3<T>::subtract(const T &scalar)
392  {
393  x -= scalar;
394  y -= scalar;
395  z -= scalar;
396  return *this;
397  }
398 
399 
400  template <typename T>
401  inline Vector3<T> &Vector3<T>::multiply(const T &scalar)
402  {
403  x *= scalar;
404  y *= scalar;
405  z *= scalar;
406  return *this;
407  }
408 
409 
410  template <typename T>
411  inline Vector3<T> &Vector3<T>::divide(const T &scalar)
412  {
413  const T div = T(1) / scalar;
414  x *= div;
415  y *= div;
416  z *= div;
417  return *this;
418  }
419 
420 
421  template <typename T>
422  inline T Vector3<T>::dot(const Vector3<T> &other) const
423  {
424  return x * other.x + y * other.y + z * other.z;
425  }
426 
427 
428  template <typename T>
429  inline Vector3<T> Vector3<T>::cross(const Vector3<T> &other) const
430  {
431  Vector3<T> v;
432  v.x = y * other.z - z * other.y;
433  v.y = z * other.x - x * other.z;
434  v.z = x * other.y - y * other.x;
435  return v;
436  }
437 
438 
439  template <typename T>
440  inline T Vector3<T>::magnitude() const
441  {
442  T mag = magnitudeSquared();
443  mag = std::sqrt(mag);
444  return mag;
445  }
446 
447 
448  template <typename T>
450  {
451  return dot(*this);
452  }
453 
454 
455  template <typename T> const T Vector3<T>::Epsilon = T(1e-6);
456  template <typename T> const Vector3<T> Vector3<T>::zero(T(0));
457  template <typename T> const Vector3<T> Vector3<T>::one(T(1));
458  template <typename T> const Vector3<T> Vector3<T>::axisx(1, 0, 0);
459  template <typename T> const Vector3<T> Vector3<T>::axisy(0, 1, 0);
460  template <typename T> const Vector3<T> Vector3<T>::axisz(0, 0, 1);
461 }
462 
463 #endif // _3ESVECTOR3_H_
Vector3< T > & operator-=(const Vector3 &other)
Arithmetic operator.
Definition: 3esvector3.h:210
static const Vector3< T > axisz
The vector (0, 0, 1).
Definition: 3esvector3.h:48
bool isZero(const T &epsilon=Epsilon) const
Zero test with error.
Definition: 3esvector3.h:328
bool isEqual(const Vector3< T > &other, const T &epsilon=Epsilon) const
Equality test with error.
Definition: 3esvector3.h:320
Vector3< T > & divide(const T &scalar)
Divides all components in this vector by scalar.
Definition: 3esvector3.h:411
static const Vector3< T > axisx
The vector (1, 0, 0).
Definition: 3esvector3.h:44
bool operator!=(const Vector3< T > &other) const
Exact inequality operator.
Definition: 3esvector3.h:313
Vector3< T > yxz() const
Swizzle operation.
Definition: 3esvector3.h:227
Vector3< T > zxy() const
Swizzle operation.
Definition: 3esvector3.h:229
Vector3< T > & multiply(const T &scalar)
Multiplies all components in this vector by scalar.
Definition: 3esvector3.h:401
bool operator==(const Vector3< T > &other) const
Exact equality operator.
Definition: 3esvector3.h:306
static const Vector3< T > zero
A vector with all zero values.
Definition: 3esvector3.h:40
Vector3< T > cross(const Vector3< T > &other) const
Calculates the cross product of this x other.
Definition: 3esvector3.h:429
T & operator[](unsigned index)
Index operator.
Definition: 3esvector3.h:83
Vector3< T > xzy() const
Return a copy of this vector. Provided for swizzle completeness.
Definition: 3esvector3.h:223
Definition: 3esbounds.h:13
Vector3< T > operator-() const
Unarary negation operator.
Definition: 3esvector3.h:109
Vector3< T > & operator+=(const T &scalar)
Arithmetic operator.
Definition: 3esvector3.h:208
Vector3< T > & operator-=(const T &scalar)
Arithmetic operator.
Definition: 3esvector3.h:212
Vector3< float > Vector3f
Defines a single precision vector.
Definition: 3esvector3.h:14
Vector3(const Vector3< Q > &other)
Copy constructor from a different numeric type.
Definition: 3esvector3.h:71
Vector3(const T *array3)
Initialisation from a array of at least length 3.
Definition: 3esvector3.h:66
static const Vector3< T > axisy
The vector (0, 1, 0).
Definition: 3esvector3.h:46
Vector3< T > zyx() const
Swizzle operation.
Definition: 3esvector3.h:231
Matrix3< T > operator*(const Matrix3< T > &a, const Matrix3< T > &b)
Performs the matrix multiplication AB.
T magnitude() const
Calculates the magnitude of this vector.
Definition: 3esvector3.h:440
Vector3< T > & operator=(const Vector3< T > &other)
Simple assignment operator.
Definition: 3esvector3.h:90
Vector3< T > & scale(const T &scalar)
An alias for multiply(const T &).
Definition: 3esvector3.h:182
Vector3< T > & operator+=(const Vector3 &other)
Arithmetic operator.
Definition: 3esvector3.h:206
static const Vector3< T > one
The vector (1, 1, 1).
Definition: 3esvector3.h:42
Vector3< T > & operator/=(const T &scalar)
Arithmetic operator.
Definition: 3esvector3.h:216
const T & operator[](int index) const
Definition: 3esvector3.h:78
Represents a vector in R3.
Definition: 3esvector3.h:14
Vector3< T > xyz() const
Return a copy of this vector. Provided for swizzle completeness.
Definition: 3esvector3.h:221
Vector3< T > & subtract(const Vector3< T > &other)
Subtracts other from this vector (this - other).
Definition: 3esvector3.h:381
Vector3< T > operator/(const Vector3< T > &a, const T &b)
Divides a vector by a scalar.
Definition: 3esvector3.h:297
Vector3< T > & operator*=(const T &scalar)
Arithmetic operator.
Definition: 3esvector3.h:214
T magnitudeSquared() const
Calculates the magnitude squared of this vector.
Definition: 3esvector3.h:449
Vector3< T > normalised(const T &epsilon=Epsilon) const
Returns a normalised copy of this vector.
Definition: 3esvector3.h:347
Vector3< T > & add(const Vector3< T > &other)
Adds other to this vector.
Definition: 3esvector3.h:361
Vector3(const Vector3< T > &other)
Copy constructor.
Definition: 3esvector3.h:57
Vector3< T > & operator=(const Vector3< Q > &other)
Simple assignment operator from a different numeric type.
Definition: 3esvector3.h:96
T normalise(const T &epsilon=Epsilon)
Attempts to normalise this vector.
Definition: 3esvector3.h:335
Vector3(const T &scalar)
Initialises all members to scalar.
Definition: 3esvector3.h:54
T & operator[](int index)
Index operator.
Definition: 3esvector3.h:76
T x
Direct data member access.
Definition: 3esvector3.h:30
T v[3]
Array representation of the vector members.
Definition: 3esvector3.h:33
Vector3< T > operator+(const Vector3< T > &a, const Vector3< T > &b)
Adds two vectors.
Definition: 3esvector3.h:244
Vector3()
Default constructor: undefined initialisation behaviour.
Definition: 3esvector3.h:51
static const T Epsilon
The default epsilon value used comparison operators.
Definition: 3esvector3.h:37
const T & operator[](unsigned index) const
Definition: 3esvector3.h:85
Vector3< T > negated() const
Returns a negated copy of this vector.
Definition: 3esvector3.h:134
Vector3(const T &x, const T &y, const T &z)
Per coordinate initialisation.
Definition: 3esvector3.h:62
Vector3< double > Vector3d
Defines a double precision vector.
Definition: 3esvector3.h:18
Vector3< T > yzx() const
Swizzle operation.
Definition: 3esvector3.h:225
T dot(const Vector3< T > &other) const
Calculates the dot product of this.other.
Definition: 3esvector3.h:422
Vector3< T > & negate()
Negates all components of this vector.
Definition: 3esvector3.h:130