Gamedev Framework (gf)  0.1.0
A C++11 framework for 2D games
Vector.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 #ifndef GF_VECTOR_H
22 #define GF_VECTOR_H
23 
24 #include <cmath>
25 #include <cstddef>
26 #include <cstdint>
27 #include <algorithm>
28 #include <initializer_list>
29 #include <type_traits>
30 
31 #include "Math.h"
32 #include "Portability.h"
33 
34 namespace gf {
35 #ifndef DOXYGEN_SHOULD_SKIP_THIS
36 inline namespace v1 {
37 #endif
38 
39  /**
40  * @ingroup core
41  * @brief General purpose math vector
42  *
43  * gf::Vector is a class that represents an element of a `N`-dimensional
44  * space. It is used throughout the library for different purposes.
45  *
46  * The template parameter `T` is the type of coordinates. . It can be any
47  * type that supports arithmetic operations (+, -, *, /) and relational
48  * operators (==, !=, <, >).
49  *
50  * Several specializations are defined for common use cases:
51  *
52  * - For dimension 2: gf::Vector<T, 2>
53  * - For dimension 3: gf::Vector<T, 3>
54  * - For dimension 4: gf::Vector<T, 4>
55  *
56  * This class was designed according to the article
57  * [On Vector Math Libraries](http://www.reedbeta.com/blog/2013/12/28/on-vector-math-libraries/)
58  * by Nathan Reed.
59  */
60  template<typename T, std::size_t N>
61  struct Vector {
62  #ifndef DOXYGEN_SHOULD_SKIP_THIS
63  static_assert(N > 0, "N must be strictly positive");
64  #endif
65 
66  /**
67  * @brief Default constructor
68  *
69  * This constructor is defaulted so that this type is
70  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
71  */
72  Vector() = default;
73 
74  /**
75  * @brief Constructor that fills the vector with a value.
76  *
77  * This constructor takes a value and fills the entire vector with this
78  * value. Care must be taken when calling this constructor:
79  *
80  * ~~~{.cc}
81  * gf::Vector<int, 5> vecOK(42); // OK, vector is filled with 42
82  * gf::Vector<int, 5> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
83  * ~~~
84  *
85  * @param val The value to fill the vector with
86  */
87  explicit Vector(T val)
88  {
89  std::fill_n(data, N, val);
90  }
91 
92  /**
93  * @brief Constructor that takes an array
94  *
95  * This constructor can ease conversion from other math libraries. The
96  * array must contain enough data for `N` dimensions.
97  *
98  * ~~~{.cc}
99  * float array[5] = { 1.0f, -1.0f, 0.5f, -2.0f, 0.0f };
100  * gf::Vector<float, 5> vec(array);
101  * ~~~
102  *
103  * @param array An array with the values of the vector
104  */
105  explicit Vector(T *array)
106  {
107  std::copy_n(array, N, data);
108  }
109 
110  /**
111  * @brief Constructor that takes an initializer list
112  *
113  * This constructor allows to use an initializer list to define the
114  * coordinates of the vector.
115  *
116  * ~~~{.cc}
117  * gf::Vector<bool, 5> vec1{ true, true, false, true, false };
118  * gf::Vector<bool, 5> vec2 = { false, true, true, false, true };
119  * ~~~
120  *
121  * @param list An initializer list.
122  */
123  Vector(std::initializer_list<T> list)
124  {
125  std::copy_n(list.begin(), std::min(list.size(), N), data);
126  }
127 
128  /**
129  * @brief Default copy constructor
130  *
131  * This constructor is defaulted so that this type is
132  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
133  *
134  * @param other The vector to copy from
135  */
136  Vector(const Vector& other) = default;
137 
138 
139  /**
140  * @brief Converting copy constructor
141  *
142  * @param other The vector to copy from
143  */
144  template<typename U>
145  Vector(const Vector<U, N>& other)
146  {
147  static_assert(std::is_convertible<U,T>::value, "");
148  std::transform(data, data + N, other.data, [](U val) { return static_cast<T>(val); });
149  }
150 
151  /**
152  * @brief Default copy assignment
153  *
154  * This operator is defaulted so that this type is
155  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
156  */
157  Vector& operator=(const Vector& other) = default;
158 
159  /**
160  * @brief Access to the @f$ i @f$-th coordinate.
161  *
162  * ~~~{.cc}
163  * gf::Vector<int, 5> vec = { 1, 3, 5, 7, 9 };
164  * std::printf("%i", vec[1]); // prints 3
165  * ~~~
166  *
167  * @param i the coordinate number
168  * @return The @f$ i @f$-th coordinate of the vector
169  */
170  T operator[](std::size_t i) const {
171  return data[i];
172  }
173 
174  /**
175  * @brief Access to the @f$ i @f$-th coordinate.
176  *
177  * ~~~{.cc}
178  * gf::Vector<int, 5> vec;
179  * vec[0] = vec[1] = vec[2] = vec[3] = vec[4] = 0;
180  * ~~~
181  *
182  * @param i the coordinate number
183  * @return The @f$ i @f$-th coordinate of the vector
184  */
185  T& operator[](std::size_t i) {
186  return data[i];
187  }
188 
189  /**
190  * @brief The internal representation of the vector
191  *
192  * A vector is represented with an array of `N` values of type `T`. It
193  * can be accessed directly, like an array or like a pointer, which can
194  * ease interoperability with other libraries.
195  */
196  T data[N];
197  };
198 
199  /**
200  * @ingroup core
201  * @brief A 2D vector
202  *
203  * This specialization of gf::Vector handles the 2-dimension spaces. It can
204  * be accessed with various representations:
205  *
206  * - the generic representation with the `data` member
207  * - the `(x,y)` representation, used for generic coordinates in the 2D space
208  * - the `(u,v)` representation, used for texture coordinates (see [UV mapping](https://en.wikipedia.org/wiki/UV_mapping))
209  * - the `(s,t)` representation, used for texture coordinates
210  * - the size representation with a `width` member and a `height` member, used to represent a 2-dimensional size
211  * - the indices representation with a `col` member and a `row` member, used to access a 2-dimensional array (gf::Array2D)
212  *
213  * Several common typedef are defined:
214  *
215  * - gf::Vector2i with `int` as `T`
216  * - gf::Vector2u with `unsigned` as `T`
217  * - gf::Vector2z with `std::size_t` as `T`
218  * - gf::Vector2f with `float` as `T`
219  * - gf::Vector2d with `double` as `T`
220  * - gf::Vector2b with `bool` as `T`
221  *
222  * Usage example:
223  *
224  * ~~~{.cc}
225  * gf::Vector2f v1(16.5f, 24.0f);
226  * v1.x = 18.2f;
227  *
228  * gf::Vector2f v2 = v1 * 5.0f;
229  * gf::Vector2f v3 = v1 + v2;
230  *
231  * bool different = (v2 != v3);
232  *
233  * gf::Vector2u size;
234  * size.width = 1920;
235  * size.height = 1080;
236  *
237  * gf::Vector2f texCoords;
238  * texCoords.u = 0.0f;
239  * texCoords.v = 0.3f;
240  * ~~~
241  */
242  template <typename T>
243  struct Vector<T, 2> {
244  /**
245  * @brief Default constructor
246  *
247  * This constructor is defaulted so that this type is
248  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
249  */
250  Vector() = default;
251 
252  /**
253  * @brief Constructor that fills the vector with a value.
254  *
255  * This constructor takes a value and fills the entire vector with this
256  * value. Care must be taken when calling this constructor:
257  *
258  * ~~~{.cc}
259  * gf::Vector<int, 2> vecOK(42); // OK, vector is filled with 42
260  * gf::Vector<int, 2> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
261  * ~~~
262  *
263  * @param val The value to fill the vector with
264  */
265  explicit Vector(T val) {
266  std::fill_n(data, 2, val);
267  }
268 
269  /**
270  * @brief Constructor that takes an array
271  *
272  * This constructor can ease conversion from other math libraries. The
273  * array must contain enough data for 2 dimensions.
274  *
275  * ~~~{.cc}
276  * float array[2] = { 1.0f, -1.0f };
277  * gf::Vector<float, 2> vec(array);
278  * ~~~
279  *
280  * @param array An array with the values of the vector
281  */
282  explicit Vector(T *array)
283  {
284  std::copy_n(array, 2, data);
285  }
286 
287  /**
288  * @brief Constructor that takes 2 components
289  *
290  * @param x The first component
291  * @param y The second component
292  */
293  constexpr Vector(T x, T y)
294  : data{ x, y }
295  {
296 
297  }
298 
299  /**
300  * @brief Default copy constructor
301  *
302  * This constructor is defaulted so that this type is
303  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
304  *
305  * @param other The vector to copy from
306  */
307  Vector(const Vector& other) = default;
308 
309 
310  /**
311  * @brief Converting copy constructor
312  *
313  * @param other The vector to copy from
314  */
315  template<typename U>
316  Vector(const Vector<U, 2>& other)
317  : x(other.x)
318  , y(other.y)
319  {
320 
321  }
322 
323  /**
324  * @brief Access to the @f$ i @f$-th coordinate.
325  *
326  * ~~~{.cc}
327  * gf::Vector<int, 2> vec = { 1, 3 };
328  * std::printf("%i", vec[1]); // prints 3
329  * ~~~
330  *
331  * @param i the coordinate number
332  * @return The @f$ i @f$-th coordinate of the vector
333  */
334  T operator[](std::size_t i) const {
335  return data[i];
336  }
337 
338  /**
339  * @brief Access to the @f$ i @f$-th coordinate.
340  *
341  * ~~~{.cc}
342  * gf::Vector<int, 2> vec;
343  * vec[0] = vec[1] = 0;
344  * ~~~
345  *
346  * @param i the coordinate number
347  * @return The @f$ i @f$-th coordinate of the vector
348  */
349  T& operator[](std::size_t i) {
350  return data[i];
351  }
352 
353  /**
354  * An anonymous union to handle the various representations
355  */
356  union {
357  T data[2]; ///< Generic representation
358  struct {
359  T x; ///< First coordinate in the `(x,y)` representation. @sa y
360  T y; ///< Second coordinate in the `(x,y)` representation. @sa x
361  };
362  struct {
363  T u; ///< First coordinate in the `(u,v)` representation. @sa v
364  T v; ///< Second coordinate in the `(u,v)` representation. @sa u
365  };
366  struct {
367  T s; ///< First coordinate in the `(s,t)` representation. @sa t
368  T t; ///< Second coordinate in the `(s,t)` representation. @sa s
369  };
370  struct {
371  T width; ///< First coordinate in the size representation. @sa height
372  T height; ///< Second coordinate in the size representation. @sa width
373  };
374  struct {
375  T col; ///< First coordinate in the indices representation @sa row
376  T row; ///< Second coordinate in the indices representation @sa col
377  };
378  };
379  };
380 
381  /**
382  * @ingroup core
383  * @brief A 3D vector
384  *
385  * This specialization of gf::Vector handles the 3-dimension spaces. It can
386  * be accessed with various representations:
387  *
388  * - the generic representation with the `data` member
389  * - the `(x,y,z)` representation, used for generic coordinates in the 3D space
390  * - the `(r,g,b)` representation, used for RGB colors
391  *
392  * Several common typedef are defined:
393  *
394  * - gf::Vector3i with `int` as `T`
395  * - gf::Vector3u with `unsigned` as `T`
396  * - gf::Vector3z with `std::size_t` as `T`
397  * - gf::Vector3f with `float` as `T`
398  * - gf::Vector3d with `double` as `T`
399  * - gf::Vector3b with `bool` as `T`
400  *
401  * For colors, some additional typedef are defined:
402  *
403  * - gf::Color3f with `float` as `T`
404  * - gf::Color3u with `uint8_t` as `T`
405  *
406  * Usage example:
407  *
408  * ~~~{.cc}
409  * gf::Vector3f v1(58.0f, 96.0f, 63.0f);
410  * v1.x = 94.0f;
411  *
412  * gf::Vector3f v2 = v1 * 5.0f;
413  * gf::Vector3f v3 = v1 + v2;
414  *
415  * gf::Color3u green(0x00, 0xFF, 0x00);
416  * ~~~
417  */
418  template <typename T>
419  struct Vector<T, 3> {
420  /**
421  * @brief Default constructor
422  *
423  * This constructor is defaulted so that this type is
424  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
425  */
426  Vector() = default;
427 
428  /**
429  * @brief Constructor that fills the vector with a value.
430  *
431  * This constructor takes a value and fills the entire vector with this
432  * value. Care must be taken when calling this constructor:
433  *
434  * ~~~{.cc}
435  * gf::Vector<int, 3> vecOK(42); // OK, vector is filled with 42
436  * gf::Vector<int, 3> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
437  * ~~~
438  *
439  * @param val The value to fill the vector with
440  */
441  explicit Vector(T val) {
442  std::fill_n(data, 3, val);
443  }
444 
445  /**
446  * @brief Constructor that takes an array
447  *
448  * This constructor can ease conversion from other math libraries. The
449  * array must contain enough data for 3 dimensions.
450  *
451  * ~~~{.cc}
452  * float array[3] = { 1.0f, -1.0f, 0.0f };
453  * gf::Vector<float, 3> vec(array);
454  * ~~~
455  *
456  * @param array An array with the values of the vector
457  */
458  explicit Vector(T *array)
459  {
460  std::copy_n(array, 3, data);
461  }
462 
463  /**
464  * @brief Constructor that takes 3 components
465  *
466  * @param x The first component
467  * @param y The second component
468  * @param z The third component
469  */
470  constexpr Vector(T x, T y, T z)
471  : data{ x, y, z }
472  {
473 
474  }
475 
476  /**
477  * @brief Constructor that takes a 2D vector and a z component
478  *
479  * @param xy The first 2 component, x and y
480  * @param z The z component
481  */
482  constexpr Vector(Vector<T, 2> xy, T z)
483  : data{ xy.x, xy.y, z }
484  {
485 
486  }
487 
488  /**
489  * @brief Default copy constructor
490  *
491  * This constructor is defaulted so that this type is
492  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
493  *
494  * @param other The vector to copy from
495  */
496  Vector(const Vector& other) = default;
497 
498 
499  /**
500  * @brief Converting copy constructor
501  *
502  * @param other The vector to copy from
503  */
504  template<typename U>
505  Vector(const Vector<U, 3>& other)
506  : x(other.x)
507  , y(other.y)
508  , z(other.z)
509  {
510 
511  }
512 
513  /**
514  * @brief Access to the @f$ i @f$-th coordinate.
515  *
516  * ~~~{.cc}
517  * gf::Vector<int, 3> vec = { 1, 3, 5 };
518  * std::printf("%i", vec[1]); // prints 3
519  * ~~~
520  *
521  * @param i the coordinate number
522  * @return The @f$ i @f$-th coordinate of the vector
523  */
524  T operator[](std::size_t i) const {
525  return data[i];
526  }
527 
528  /**
529  * @brief Access to the @f$ i @f$-th coordinate.
530  *
531  * ~~~{.cc}
532  * gf::Vector<int, 3> vec;
533  * vec[0] = vec[1] = vec[2] = 0;
534  * ~~~
535  *
536  * @param i the coordinate number
537  * @return The @f$ i @f$-th coordinate of the vector
538  */
539  T& operator[](std::size_t i) {
540  return data[i];
541  }
542 
543  /**
544  * An anonymous union to handle the various representations
545  */
546  union {
547  T data[3]; ///< Generic representation
548  struct {
549  T x; ///< First coordinate in the `(x,y,z)` representation. @sa y, z
550  T y; ///< Second coordinate in the `(x,y,z)` representation. @sa x, z
551  T z; ///< Third coordinate in the `(x,y,z)` representation. @sa x, y
552  };
553  struct {
554  T r; ///< First coordinate in the `(r,g,b)` representation. @sa g, b
555  T g; ///< Second coordinate in the `(r,g,b)` representation. @sa r, b
556  T b; ///< Third coordinate in the `(r,g,b)` representation. @sa r, g
557  };
558  Vector<T, 2> xy; ///< Swizzle to get the first two coordinates as a 2D vector
559  };
560  };
561 
562  /**
563  * @ingroup core
564  * @brief A 4D vector
565  *
566  * This specialization of gf::Vector handles the 4-dimension spaces. It can
567  * be accessed with various representations:
568  *
569  * - the generic representation with the `data` member
570  * - the `(x,y,z,w)` representation, used for generic coordinates in the 4D space
571  * - the `(r,g,b,a)` representation, used for RGBA colors
572  *
573  * Several common typedef are defined:
574  *
575  * - gf::Vector4i with `int` as `T`
576  * - gf::Vector4u with `unsigned` as `T`
577  * - gf::Vector4z with `std::size_t` as `T`
578  * - gf::Vector4f with `float` as `T`
579  * - gf::Vector4d with `double` as `T`
580  * - gf::Vector4b with `bool` as `T`
581  *
582  * For colors, some additional typedef are defined:
583  *
584  * - gf::Color4f with `float` as `T`
585  * - gf::Color4u with `uint8_t` as `T`
586  *
587  * Usage example:
588  *
589  * ~~~{.cc}
590  * gf::Vector4f v1(98.0f, 75.0f, 23.0f);
591  * v1.x = 57.0f;
592  *
593  * gf::Vector4f v2 = v1 * 5.0f;
594  * gf::Vector4f v3 = v1 + v2;
595  *
596  * gf::Color4u opaqueGreen(0x00, 0xFF, 0x00, 0xFF);
597  * ~~~
598  */
599  template <typename T>
600  struct Vector<T, 4> {
601  /**
602  * @brief Default constructor
603  *
604  * This constructor is defaulted so that this type is
605  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
606  */
607  Vector() = default;
608 
609  /**
610  * @brief Constructor that fills the vector with a value.
611  *
612  * This constructor takes a value and fills the entire vector with this
613  * value. Care must be taken when calling this constructor:
614  *
615  * ~~~{.cc}
616  * gf::Vector<int, 4> vecOK(42); // OK, vector is filled with 42
617  * gf::Vector<int, 4> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
618  * ~~~
619  *
620  * @param val The value to fill the vector with
621  */
622  explicit Vector(T val) {
623  std::fill_n(data, 4, val);
624  }
625 
626  /**
627  * @brief Constructor that takes an array
628  *
629  * This constructor can ease conversion from other math libraries. The
630  * array must contain enough data for 4 dimensions.
631  *
632  * ~~~{.cc}
633  * float array[4] = { 1.0f, -1.0f, 0.5f, 0.0f };
634  * gf::Vector<float, 4> vec(array);
635  * ~~~
636  *
637  * @param array An array with the values of the vector
638  */
639  explicit Vector(T *array)
640  {
641  std::copy_n(array, 4, data);
642  }
643 
644  /**
645  * @brief Constructor that takes 4 components
646  *
647  * @param x The first component
648  * @param y The second component
649  * @param z The third component
650  * @param w The fourth component
651  */
652  constexpr Vector(T x, T y, T z, T w)
653  : data{ x, y, z, w }
654  {
655 
656  }
657 
658  /**
659  * @brief Default copy constructor
660  *
661  * This constructor is defaulted so that this type is
662  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
663  *
664  * @param other The vector to copy from
665  */
666  Vector(const Vector& other) = default;
667 
668 
669  /**
670  * @brief Converting copy constructor
671  *
672  * @param other The vector to copy from
673  */
674  template<typename U>
675  Vector(const Vector<U, 4>& other)
676  : x(other.x)
677  , y(other.y)
678  , z(other.z)
679  , w(other.w)
680  {
681 
682  }
683 
684  /**
685  * @brief Access to the @f$ i @f$-th coordinate.
686  *
687  * ~~~{.cc}
688  * gf::Vector<int, 4> vec = { 1, 3, 5, 7 };
689  * std::printf("%i", vec[1]); // prints 3
690  * ~~~
691  *
692  * @param i the coordinate number
693  * @return The @f$ i @f$-th coordinate of the vector
694  */
695  T operator[](std::size_t i) const {
696  return data[i];
697  }
698 
699  /**
700  * @brief Access to the @f$ i @f$-th coordinate.
701  *
702  * ~~~{.cc}
703  * gf::Vector<int, 5> vec;
704  * vec[0] = vec[1] = vec[2] = vec[3] = vec[4] = 0;
705  * ~~~
706  *
707  * @param i the coordinate number
708  * @return The @f$ i @f$-th coordinate of the vector
709  */
710  T& operator[](std::size_t i) {
711  return data[i];
712  }
713 
714  /**
715  * An anonymous union to handle the various representations
716  */
717  union {
718  T data[4]; ///< Generic representation
719  struct {
720  T x; ///< First coordinate in the `(x,y,z,w)` representation. @sa y, z, w
721  T y; ///< Second coordinate in the `(x,y,z,w)` representation. @sa x, z, w
722  T z; ///< Third coordinate in the `(x,y,z,w)` representation. @sa x, y, w
723  T w; ///< Fourth coordinate in the `(x,y,z,w)` representation. @sa x, y, z
724  };
725  struct {
726  T r; ///< First coordinate in the `(r,g,b,a)` representation. @sa g, b, a
727  T g; ///< Second coordinate in the `(r,g,b,a)` representation. @sa r, b, a
728  T b; ///< Third coordinate in the `(r,g,b,a)` representation. @sa r, g, a
729  T a; ///< Fourth coordinate in the `(r,g,b,a)` representation. @sa r, g, b
730  };
731  Vector<T, 2> xy; ///< Swizzle to get the first two coordinates as a 2D vector
732  Vector<T, 3> xyz; ///< Swizzle to get the first three coordinates as a 3D vector
733  Vector<T, 3> rgb; ///< Swizzle to get the first three coordinates as a RGB color
734  };
735  };
736 
737  /**
738  * @ingroup core
739  * @brief A float vector with 2 components
740  */
741  typedef Vector<float, 2> Vector2f;
742 
743  /**
744  * @ingroup core
745  * @brief A float vector with 3 components
746  */
747  typedef Vector<float, 3> Vector3f;
748 
749  /**
750  * @ingroup core
751  * @brief A float vector with 4 components
752  */
753  typedef Vector<float, 4> Vector4f;
754 
755  /**
756  * @ingroup core
757  * @brief A double vector with 2 components
758  */
759  typedef Vector<double, 2> Vector2d;
760 
761  /**
762  * @ingroup core
763  * @brief A double vector with 3 components
764  */
765  typedef Vector<double, 3> Vector3d;
766 
767  /**
768  * @ingroup core
769  * @brief A double vector with 4 components
770  */
771  typedef Vector<double, 4> Vector4d;
772 
773  /**
774  * @ingroup core
775  * @brief A int vector with 2 components
776  */
777  typedef Vector<int, 2> Vector2i;
778 
779  /**
780  * @ingroup core
781  * @brief A int vector with 3 components
782  */
783  typedef Vector<int, 3> Vector3i;
784 
785  /**
786  * @ingroup core
787  * @brief A int vector with 4 components
788  */
789  typedef Vector<int, 4> Vector4i;
790 
791  /**
792  * @ingroup core
793  * @brief A unsigned vector with 2 components
794  */
795  typedef Vector<unsigned, 2> Vector2u;
796 
797  /**
798  * @ingroup core
799  * @brief A unsigned vector with 3 components
800  */
801  typedef Vector<unsigned, 3> Vector3u;
802 
803  /**
804  * @ingroup core
805  * @brief A unsigned vector with 4 components
806  */
807  typedef Vector<unsigned, 4> Vector4u;
808 
809  /**
810  * @ingroup core
811  * @brief A std::size_t vector with 2 components
812  */
813  typedef Vector<std::size_t, 2> Vector2z;
814 
815  /**
816  * @ingroup core
817  * @brief A std::size_t vector with 3 components
818  */
819  typedef Vector<std::size_t, 3> Vector3z;
820 
821  /**
822  * @ingroup core
823  * @brief A std::size_t vector with 4 components
824  */
825  typedef Vector<std::size_t, 4> Vector4z;
826 
827  /**
828  * @ingroup core
829  * @brief A bool vector with 2 components
830  */
831  typedef Vector<bool, 2> Vector2b;
832 
833  /**
834  * @ingroup core
835  * @brief A bool vector with 3 components
836  */
837  typedef Vector<bool, 3> Vector3b;
838 
839  /**
840  * @ingroup core
841  * @brief A bool vector with 4 components
842  */
843  typedef Vector<bool, 4> Vector4b;
844 
845  /**
846  * @ingroup core
847  * @brief A float color vector with 3 components
848  */
849  typedef Vector<float, 3> Color3f;
850 
851  /**
852  * @ingroup core
853  * @brief A float color vector with 4 components
854  */
855  typedef Vector<float, 4> Color4f;
856 
857  /**
858  * @ingroup core
859  * @brief A uint8_t color vector with 3 components
860  */
861  typedef Vector<uint8_t, 3> Color3u;
862 
863  /**
864  * @ingroup core
865  * @brief A uint8_t color vector with 4 components
866  */
867  typedef Vector<uint8_t, 4> Color4u;
868 
869 // MSVC does not like extern template
870 #ifndef _MSC_VER
871  extern template struct Vector<float, 2>;
872  extern template struct Vector<float, 3>;
873  extern template struct Vector<float, 4>;
874 
875  extern template struct Vector<double, 2>;
876  extern template struct Vector<double, 3>;
877  extern template struct Vector<double, 4>;
878 
879  extern template struct Vector<int, 2>;
880  extern template struct Vector<int, 3>;
881  extern template struct Vector<int, 4>;
882 
883  extern template struct Vector<unsigned, 2>;
884  extern template struct Vector<unsigned, 3>;
885  extern template struct Vector<unsigned, 4>;
886 
887  extern template struct Vector<std::size_t, 2>;
888  extern template struct Vector<std::size_t, 3>;
889  extern template struct Vector<std::size_t, 4>;
890 
891  extern template struct Vector<bool, 2>;
892  extern template struct Vector<bool, 3>;
893  extern template struct Vector<bool, 4>;
894 
895  extern template struct Vector<uint8_t, 3>;
896  extern template struct Vector<uint8_t, 4>;
897 #endif
898 
899  /**
900  * @relates Vector
901  * @brief Equality operator between two vectors
902  */
903  template<typename T, std::size_t N>
904  GF_API inline
905  bool operator==(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
906  for (std::size_t i = 0; i < N; ++i) {
907  if (lhs.data[i] != rhs.data[i]) {
908  return false;
909  }
910  }
911 
912  return true;
913  }
914 
915  /**
916  * @relates Vector
917  * @brief Inequality operator between two vectors
918  */
919  template<typename T, std::size_t N>
920  GF_API inline
921  bool operator!=(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
922  return !(lhs == rhs);
923  }
924 
925  /**
926  * @relates Vector
927  * @brief Component-wise unary minus
928  */
929  template<typename T, std::size_t N>
930  GF_API inline
931  Vector<T, N> operator-(const Vector<T, N>& val) {
932  Vector<T, N> out;
933 
934  for (std::size_t i = 0; i < N; ++i) {
935  out.data[i] = - val.data[i];
936  }
937 
938  return out;
939  }
940 
941  /**
942  * @relates Vector
943  * @brief Component-wise addition
944  */
945  template<typename T, typename U, std::size_t N>
946  GF_API inline
947  Vector<typename std::common_type<T,U>::type, N> operator+(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
948  Vector<typename std::common_type<T,U>::type, N> out;
949 
950  for (std::size_t i = 0; i < N; ++i) {
951  out.data[i] = lhs.data[i] + rhs.data[i];
952  }
953 
954  return out;
955  }
956 
957  /**
958  * @relates Vector
959  * @brief Component-wise addition and assignment
960  */
961  template<typename T, typename U, std::size_t N>
962  GF_API inline
963  Vector<T, N>& operator+=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
964  for (std::size_t i = 0; i < N; ++i) {
965  lhs.data[i] += rhs.data[i];
966  }
967 
968  return lhs;
969  }
970 
971  /**
972  * @relates Vector
973  * @brief Right scalar addition
974  */
975  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
976  GF_API inline
977  Vector<typename std::common_type<T,U>::type, N> operator+(const Vector<T, N>& lhs, U rhs) {
978  Vector<typename std::common_type<T,U>::type, N> out;
979 
980  for (std::size_t i = 0; i < N; ++i) {
981  out.data[i] = lhs.data[i] + rhs;
982  }
983 
984  return out;
985  }
986 
987  /**
988  * @relates Vector
989  * @brief Left scalar addition
990  */
991  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
992  GF_API inline
993  Vector<typename std::common_type<T,U>::type, N> operator+(T lhs, const Vector<U, N>& rhs) {
994  Vector<typename std::common_type<T,U>::type, N> out;
995 
996  for (std::size_t i = 0; i < N; ++i) {
997  out.data[i] = lhs + rhs.data[i];
998  }
999 
1000  return out;
1001  }
1002 
1003 
1004  /**
1005  * @relates Vector
1006  * @brief Component-wise substraction
1007  */
1008  template<typename T, typename U, std::size_t N>
1009  GF_API inline
1010  Vector<typename std::common_type<T,U>::type, N> operator-(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1011  Vector<typename std::common_type<T,U>::type, N> out;
1012 
1013  for (std::size_t i = 0; i < N; ++i) {
1014  out.data[i] = lhs.data[i] - rhs.data[i];
1015  }
1016 
1017  return out;
1018  }
1019 
1020  /**
1021  * @relates Vector
1022  * @brief Component-wise substraction and assignment
1023  */
1024  template<typename T, typename U, std::size_t N>
1025  GF_API inline
1026  Vector<T, N>& operator-=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1027  for (std::size_t i = 0; i < N; ++i) {
1028  lhs.data[i] -= rhs.data[i];
1029  }
1030 
1031  return lhs;
1032  }
1033 
1034 
1035  /**
1036  * @relates Vector
1037  * @brief Right scalar substraction
1038  */
1039  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
1040  GF_API inline
1041  Vector<typename std::common_type<T,U>::type, N> operator-(const Vector<T, N>& lhs, U rhs) {
1042  Vector<typename std::common_type<T,U>::type, N> out;
1043 
1044  for (std::size_t i = 0; i < N; ++i) {
1045  out.data[i] = lhs.data[i] - rhs;
1046  }
1047 
1048  return out;
1049  }
1050 
1051  /**
1052  * @relates Vector
1053  * @brief Left scalar substraction
1054  */
1055  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1056  GF_API inline
1057  Vector<typename std::common_type<T,U>::type, N> operator-(T lhs, const Vector<U, N>& rhs) {
1058  Vector<typename std::common_type<T,U>::type, N> out;
1059 
1060  for (std::size_t i = 0; i < N; ++i) {
1061  out.data[i] = lhs - rhs.data[i];
1062  }
1063 
1064  return out;
1065  }
1066 
1067 
1068  /**
1069  * @relates Vector
1070  * @brief Component-wise multiplication
1071  */
1072  template<typename T, typename U, std::size_t N>
1073  GF_API inline
1074  Vector<typename std::common_type<T,U>::type, N> operator*(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1075  Vector<typename std::common_type<T,U>::type, N> out;
1076 
1077  for (std::size_t i = 0; i < N; ++i) {
1078  out.data[i] = lhs.data[i] * rhs.data[i];
1079  }
1080 
1081  return out;
1082  }
1083 
1084  /**
1085  * @relates Vector
1086  * @brief Component-wise multiplication and assignment
1087  */
1088  template<typename T, typename U, std::size_t N>
1089  GF_API inline
1090  Vector<T, N>& operator*=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1091  for (std::size_t i = 0; i < N; ++i) {
1092  lhs.data[i] *= rhs.data[i];
1093  }
1094 
1095  return lhs;
1096  }
1097 
1098  /**
1099  * @relates Vector
1100  * @brief Right scalar multiplication
1101  */
1102  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
1103  GF_API inline
1104  Vector<typename std::common_type<T,U>::type, N> operator*(const Vector<T, N>& lhs, U rhs) {
1105  Vector<typename std::common_type<T,U>::type, N> out;
1106 
1107  for (std::size_t i = 0; i < N; ++i) {
1108  out.data[i] = lhs.data[i] * rhs;
1109  }
1110 
1111  return out;
1112  }
1113 
1114  /**
1115  * @relates Vector
1116  * @brief Right scalar multiplication and assignment
1117  */
1118  template<typename T, typename U, std::size_t N>
1119  GF_API inline
1120  Vector<T, N>& operator*=(Vector<T, N>& lhs, U rhs) {
1121  for (std::size_t i = 0; i < N; ++i) {
1122  lhs.data[i] *= rhs;
1123  }
1124 
1125  return lhs;
1126  }
1127 
1128  /**
1129  * @relates Vector
1130  * @brief Left scalar multiplication
1131  */
1132  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1133  GF_API inline
1134  Vector<typename std::common_type<T,U>::type, N> operator*(T lhs, const Vector<U, N>& rhs) {
1135  Vector<typename std::common_type<T,U>::type, N> out;
1136 
1137  for (std::size_t i = 0; i < N; ++i) {
1138  out.data[i] = lhs * rhs.data[i];
1139  }
1140 
1141  return out;
1142  }
1143 
1144  /**
1145  * @relates Vector
1146  * @brief Component-wise division
1147  */
1148  template<typename T, typename U, std::size_t N>
1149  GF_API inline
1150  Vector<typename std::common_type<T,U>::type, N> operator/(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1151  Vector<typename std::common_type<T,U>::type, N> out;
1152 
1153  for (std::size_t i = 0; i < N; ++i) {
1154  out.data[i] = lhs.data[i] / rhs.data[i];
1155  }
1156 
1157  return out;
1158  }
1159 
1160  /**
1161  * @relates Vector
1162  * @brief Component-wise division and assignment
1163  */
1164  template<typename T, typename U, std::size_t N>
1165  GF_API inline
1166  Vector<T, N>& operator/=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1167  for (std::size_t i = 0; i < N; ++i) {
1168  lhs.data[i] /= rhs.data[i];
1169  }
1170 
1171  return lhs;
1172  }
1173 
1174  /**
1175  * @relates Vector
1176  * @brief Right scalar division
1177  */
1178  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
1179  GF_API inline
1180  Vector<typename std::common_type<T,U>::type, N> operator/(const Vector<T, N>& lhs, U rhs) {
1181  Vector<typename std::common_type<T,U>::type, N> out;
1182 
1183  for (std::size_t i = 0; i < N; ++i) {
1184  out.data[i] = lhs.data[i] / rhs;
1185  }
1186 
1187  return out;
1188  }
1189 
1190  /**
1191  * @relates Vector
1192  * @brief Right scalar division and assignment
1193  */
1194  template<typename T, typename U, std::size_t N>
1195  GF_API inline
1196  Vector<T, N>& operator/=(Vector<T, N>& lhs, U rhs) {
1197  for (std::size_t i = 0; i < N; ++i) {
1198  lhs.data[i] /= rhs;
1199  }
1200 
1201  return lhs;
1202  }
1203 
1204  /**
1205  * @relates Vector
1206  * @brief Left scalar division
1207  */
1208  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1209  GF_API inline
1210  Vector<typename std::common_type<T,U>::type, N> operator/(T lhs, const Vector<U, N>& rhs) {
1211  Vector<typename std::common_type<T,U>::type, N> out;
1212 
1213  for (std::size_t i = 0; i < N; ++i) {
1214  out.data[i] = lhs / rhs.data[i];
1215  }
1216 
1217  return out;
1218  }
1219 
1220  /**
1221  * @relates Vector
1222  * @brief Component-wise logical or operator
1223  */
1224  template<std::size_t N>
1225  GF_API inline
1226  Vector<bool, N> operator||(const Vector<bool, N>& lhs, const Vector<bool, N>& rhs) {
1227  Vector<bool, N> out;
1228 
1229  for (std::size_t i = 0; i < N; ++i) {
1230  out.data[i] = lhs.data[i] || rhs.data[i];
1231  }
1232 
1233  return out;
1234  }
1235 
1236  /**
1237  * @relates Vector
1238  * @brief Component-wise logical and operator
1239  */
1240  template<std::size_t N>
1241  GF_API inline
1242  Vector<bool, N> operator&&(const Vector<bool, N>& lhs, const Vector<bool, N>& rhs) {
1243  Vector<bool, N> out;
1244 
1245  for (std::size_t i = 0; i < N; ++i) {
1246  out.data[i] = lhs.data[i] && rhs.data[i];
1247  }
1248 
1249  return out;
1250  }
1251 
1252  /**
1253  * @relates Vector
1254  * @brief Scalar product
1255  */
1256  template<typename T, std::size_t N>
1257  GF_API inline
1258  T dot(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1259  T out{0};
1260 
1261  for (std::size_t i = 0; i < N; ++i) {
1262  out += lhs.data[i] * rhs.data[i];
1263  }
1264 
1265  return out;
1266  }
1267 
1268  /**
1269  * @relates Vector
1270  * @brief Component-wise minimum
1271  */
1272  template<typename T, std::size_t N>
1273  GF_API inline
1274  Vector<T, N> min(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1275  Vector<T, N> out;
1276 
1277  for (std::size_t i = 0; i < N; ++i) {
1278  out.data[i] = std::min(lhs.data[i], rhs.data[i]);
1279  }
1280 
1281  return out;
1282  }
1283 
1284  /**
1285  * @relates Vector
1286  * @brief Component-wise maximum
1287  */
1288  template<typename T, std::size_t N>
1289  GF_API inline
1290  Vector<T, N> max(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1291  Vector<T, N> out;
1292 
1293  for (std::size_t i = 0; i < N; ++i) {
1294  out.data[i] = std::max(lhs.data[i], rhs.data[i]);
1295  }
1296 
1297  return out;
1298  }
1299 
1300  /**
1301  * @relates Vector
1302  * @brief Component-wise absolute value
1303  */
1304  template<typename T, std::size_t N>
1305  GF_API inline
1306  Vector<T, N> abs(const Vector<T, N>& val) {
1307  Vector<T, N> out;
1308 
1309  for (std::size_t i = 0; i < N; ++i) {
1310  out.data[i] = std::abs(val.data[i]);
1311  }
1312 
1313  return out;
1314  }
1315 
1316 
1317  /**
1318  * @relates Vector
1319  * @brief Component-wise equality operator
1320  */
1321  template<typename T, std::size_t N>
1322  GF_API inline
1323  Vector<bool, N> equals(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1324  Vector<bool, N> out;
1325 
1326  for (std::size_t i = 0; i < N; ++i) {
1327  out.data[i] = (lhs.data[i] == rhs.data[i]);
1328  }
1329 
1330  return out;
1331  }
1332 
1333  /**
1334  * @relates Vector
1335  * @brief Component-wise comparison operator
1336  */
1337  template<typename T, std::size_t N>
1338  GF_API inline
1339  Vector<bool, N> lessThan(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1340  Vector<bool, N> out;
1341 
1342  for (std::size_t i = 0; i < N; ++i) {
1343  out.data[i] = (lhs.data[i] < rhs.data[i]);
1344  }
1345 
1346  return out;
1347  }
1348 
1349  /**
1350  * @relates Vector
1351  * @brief Component-wise comparison operator
1352  */
1353  template<typename T, std::size_t N>
1354  inline
1355  GF_API Vector<bool, N> greaterThan(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1356  Vector<bool, N> out;
1357 
1358  for (std::size_t i = 0; i < N; ++i) {
1359  out.data[i] = (lhs.data[i] > rhs.data[i]);
1360  }
1361 
1362  return out;
1363  }
1364 
1365  /**
1366  * @relates Vector
1367  * @brief Component-wise selection operator
1368  */
1369  template<typename T, std::size_t N>
1370  GF_API inline
1371  Vector<T, N> select(const Vector<bool, N>& cond, const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1372  Vector<T, N> out;
1373 
1374  for (std::size_t i = 0; i < N; ++i) {
1375  out.data[i] = (cond.data[i] ? lhs.data[i] : rhs.data[i]);
1376  }
1377 
1378  return out;
1379  }
1380 
1381  /**
1382  * @relates Vector
1383  * @brief Component-wise clamp function
1384  *
1385  * Relative to two other vectors.
1386  *
1387  */
1388  template<typename T, std::size_t N>
1389  GF_API inline
1390  Vector<T, N> clamp(const Vector<T, N>& val, const Vector<T, N>& lo, const Vector<T, N>& hi) {
1391  Vector<T, N> out;
1392 
1393  for (std::size_t i = 0; i < N; ++i) {
1394  out.data[i] = clamp(val.data[i], lo.data[i], hi.data[i]);
1395  }
1396 
1397  return out;
1398  }
1399 
1400  /**
1401  * @relates Vector
1402  * @brief Component-wise clamp function
1403  *
1404  * Relative to two values.
1405  */
1406  template<typename T, std::size_t N>
1407  GF_API inline
1408  Vector<T, N> clamp(const Vector<T, N>& val, T lo, T hi) {
1409  Vector<T, N> out;
1410 
1411  for (std::size_t i = 0; i < N; ++i) {
1412  out.data[i] = clamp(val.data[i], lo, hi);
1413  }
1414 
1415  return out;
1416  }
1417 
1418  /**
1419  * @relates Vector
1420  * @brief Component-wise lerp function
1421  */
1422  template<typename T, typename U, std::size_t N>
1423  GF_API inline
1424  Vector<typename std::common_type<T,U>::type, N> lerp(const Vector<T, N>& lhs, const Vector<T, N>& rhs, U t) {
1425  return t * lhs + (1 - t) * rhs;
1426  }
1427 
1428  /**
1429  * @relates Vector
1430  * @brief Manhattan length of a vector
1431  *
1432  * The Manhattan length @f$ l @f$ of a vector @f$ (u_1, \ldots, u_N) @f$ is:
1433  *
1434  * @f[ l = \sum_{i = 1}^{N} |u_i| @f]
1435  *
1436  * The Manhattan length is also called the 1-norm.
1437  *
1438  * @param vec A vector.
1439  * @returns The Manhattan length of the vector
1440  *
1441  * @sa manhattanDistance
1442  */
1443  template<typename T, std::size_t N>
1444  GF_API inline
1445  T manhattanLength(const Vector<T, N>& vec) {
1446  T out{0};
1447 
1448  for (std::size_t i = 0; i < N; ++i) {
1449  out += std::abs(vec.data[i]);
1450  }
1451 
1452  return out;
1453  }
1454 
1455  /**
1456  * @relates Vector
1457  * @brief Square Euclidean length of a vector
1458  *
1459  * The square Euclidean length @f$ l @f$ of a vector @f$ (u_1, \ldots, u_N) @f$ is:
1460  *
1461  * @f[ l = \sum_{i = 1}^{N} u_i^2 @f]
1462  *
1463  * @param vec A vector.
1464  * @returns The square Euclidean length of the vector
1465  *
1466  * @sa euclideanLength, squareDistance
1467  */
1468  template<typename T, std::size_t N>
1469  GF_API inline
1470  T squareLength(const Vector<T, N>& vec) {
1471  T out{0};
1472 
1473  for (std::size_t i = 0; i < N; ++i) {
1474  out += square(vec.data[i]);
1475  }
1476 
1477  return out;
1478  }
1479 
1480  /**
1481  * @relates Vector
1482  * @brief Euclidean length of a vector
1483  *
1484  * The Euclidean length @f$ l @f$ of a vector @f$ (u_1, \ldots, u_N) @f$ is:
1485  *
1486  * @f[ l = \sqrt{\sum_{i = 1}^{N} u_i^2} @f]
1487  *
1488  * The Euclidean length is also called the 2-norm.
1489  *
1490  * @param vec A vector.
1491  * @returns The Euclidean length of the vector
1492  *
1493  * @sa euclideanDistance
1494  */
1495  template<typename T, std::size_t N>
1496  GF_API inline
1497  T euclideanLength(const Vector<T, N>& vec) {
1498  return std::sqrt(squareLength(vec));
1499  }
1500 
1501  /**
1502  * @relates Vector
1503  * @brief Chebyshev length of a vector
1504  *
1505  * The Chebyshev length @f$ l @f$ of a vector @f$ (u_1, \ldots, u_N) @f$ is:
1506  *
1507  * @f[ l = \max_{i = 1}^{N} |u_i| @f]
1508  *
1509  * The Chebyshev length is also called the infinity norm or maximum norm.
1510  *
1511  * @param vec A vector.
1512  * @returns The Chebyshev length of the vector
1513  *
1514  * @sa chebyshevDistance
1515  */
1516  template<typename T, std::size_t N>
1517  GF_API inline
1518  T chebyshevLength(const Vector<T, N>& vec) {
1519  T out = std::abs(vec.data[0]);
1520 
1521  for (std::size_t i = 1; i < N; ++i) {
1522  out = std::max(out, std::abs(vec.data[i]));
1523  }
1524 
1525  return out;
1526  }
1527 
1528 
1529  /**
1530  * @relates Vector
1531  * @brief Manhattan distance between two vectors
1532  *
1533  * The Manhattan distance between two vectors is the Manhattan length of the
1534  * difference of the two vectors.
1535  *
1536  * @param lhs A first vector
1537  * @param rhs A second vector
1538  * @returns The Manhattan distance between the two vectors
1539  *
1540  * @sa manhattanLength
1541  */
1542  template<typename T, std::size_t N>
1543  GF_API inline
1544  T manhattanDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1545  return manhattanLength(lhs - rhs);
1546  }
1547 
1548  /**
1549  * @relates Vector
1550  * @brief Square Euclidean distance between two vectors
1551  *
1552  * The square Euclidean distance between two vectors is the square Euclidean
1553  * length of the difference of the two vectors.
1554  *
1555  * @param lhs A first vector
1556  * @param rhs A second vector
1557  * @returns The square Euclidean distance between the two vectors
1558  *
1559  * @sa squareLength, euclideanDistance
1560  */
1561  template<typename T, std::size_t N>
1562  GF_API inline
1563  T squareDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1564  return squareLength(lhs - rhs);
1565  }
1566 
1567  /**
1568  * @relates Vector
1569  * @brief Euclidean distance between two vectors
1570  *
1571  * The Euclidean distance between two vectors is the Euclidean length of the
1572  * difference of the two vectors.
1573  *
1574  * @param lhs A first vector
1575  * @param rhs A second vector
1576  * @returns The Euclidean distance between the two vectors
1577  *
1578  * @sa euclideanLength
1579  */
1580  template<typename T, std::size_t N>
1581  GF_API inline
1582  T euclideanDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1583  return euclideanLength(lhs - rhs);
1584  }
1585 
1586  /**
1587  * @relates Vector
1588  * @brief Chebyshev distance between two vectors
1589  *
1590  * The Chebyshev distance between two vectors is the Chebyshev length of the
1591  * difference of the two vectors.
1592  *
1593  * @param lhs A first vector
1594  * @param rhs A second vector
1595  * @returns The Chebyshev distance between the two vectors
1596  *
1597  * @sa chebyshevLength
1598  */
1599  template<typename T, std::size_t N>
1600  GF_API inline
1601  T chebyshevDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1602  return chebyshevDistance(lhs - rhs);
1603  }
1604 
1605  /**
1606  * @relates Vector
1607  * @brief Normalize a vector
1608  *
1609  * The normalized vector of @f$ v @f$ is a vector in the same direction but
1610  * with a (euclidean) length of 1. A normalized vector is also called a
1611  * [unit vector](https://en.wikipedia.org/wiki/Unit_vector).
1612  *
1613  * @param vec A vector
1614  * @returns A normalized vector
1615  */
1616  template<typename T, std::size_t N>
1617  GF_API inline
1618  Vector<T, N> normalize(const Vector<T, N>& vec) {
1619  T length = euclideanLength(vec);
1620  return vec / length;
1621  }
1622 
1623  /**
1624  * @relates Vector
1625  * @brief Unit vector in a specified direction
1626  *
1627  * @param angle The angle of the direction
1628  * @return A unit vector
1629  */
1630  template<typename T>
1631  GF_API inline
1632  Vector<T, 2> unit(T angle) {
1633  return { std::cos(angle), std::sin(angle) };
1634  }
1635 
1636  /**
1637  * @relates Vector
1638  * @brief Perpendicular vector
1639  *
1640  * @param vec A vector
1641  * @returns A perpendicular vector
1642  */
1643  template<typename T>
1644  GF_API constexpr
1645  Vector<T, 2> perp(const Vector<T, 2>& vec) {
1646  return { -vec.y, vec.x };
1647  }
1648 
1649  /**
1650  * @relates Vector
1651  * @brief Cross product
1652  *
1653  * @param lhs A first vector
1654  * @param rhs A second vector
1655  * @return The cross product of the two vectors
1656  */
1657  template<typename T>
1658  GF_API constexpr
1659  Vector<T, 3> cross(const Vector<T, 3>& lhs, const Vector<T, 3>& rhs) {
1660  return {
1661  lhs.y * rhs.z - lhs.z * rhs.y,
1662  lhs.z * rhs.x - lhs.x * rhs.z,
1663  lhs.x * rhs.y - lhs.y * rhs.x
1664  };
1665  }
1666 
1667 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1668 }
1669 #endif
1670 }
1671 
1672 #endif // GAME_VECTOR_H
Vector< std::size_t, 3 > Vector3z
A std::size_t vector with 3 components.
Definition: Vector.h:819
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:458
Vector< unsigned, 2 > Vector2u
A unsigned vector with 2 components.
Definition: Vector.h:795
T manhattanLength(const Vector< T, N > &vec)
Manhattan length of a vector.
Definition: Vector.h:1445
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:441
T dot(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Scalar product.
Definition: Vector.h:1258
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:539
Vector< T, N > abs(const Vector< T, N > &val)
Component-wise absolute value.
Definition: Vector.h:1306
Vector< typename std::common_type< T, U >::type, N > operator/(T lhs, const Vector< U, N > &rhs)
Left scalar division.
Definition: Vector.h:1210
Vector< T, N > select(const Vector< bool, N > &cond, const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise selection operator.
Definition: Vector.h:1371
constexpr Vector< T, 2 > perp(const Vector< T, 2 > &vec)
Perpendicular vector.
Definition: Vector.h:1645
Vector< float, 2 > Vector2f
A float vector with 2 components.
Definition: Vector.h:741
bool operator==(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Equality operator between two vectors.
Definition: Vector.h:905
Vector< typename std::common_type< T, U >::type, N > operator+(T lhs, const Vector< U, N > &rhs)
Left scalar addition.
Definition: Vector.h:993
T squareLength(const Vector< T, N > &vec)
Square Euclidean length of a vector.
Definition: Vector.h:1470
Vector< T, N > & operator/=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise division and assignment.
Definition: Vector.h:1166
Vector< T, N > clamp(const Vector< T, N > &val, T lo, T hi)
Component-wise clamp function.
Definition: Vector.h:1408
T euclideanLength(const Vector< T, N > &vec)
Euclidean length of a vector.
Definition: Vector.h:1497
Vector< T, N > max(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise maximum.
Definition: Vector.h:1290
Vector< int, 2 > Vector2i
A int vector with 2 components.
Definition: Vector.h:777
Vector< bool, N > greaterThan(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise comparison operator.
Definition: Vector.h:1355
Vector< T, N > & operator/=(Vector< T, N > &lhs, U rhs)
Right scalar division and assignment.
Definition: Vector.h:1196
Vector< bool, N > equals(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise equality operator.
Definition: Vector.h:1323
constexpr Vector(T x, T y)
Constructor that takes 2 components.
Definition: Vector.h:293
Vector< typename std::common_type< T, U >::type, N > operator+(const Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise addition.
Definition: Vector.h:947
friend class RenderTarget
Definition: Shader.h:387
Vector< unsigned, 4 > Vector4u
A unsigned vector with 4 components.
Definition: Vector.h:807
Vector< typename std::common_type< T, U >::type, N > operator*(const Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise multiplication.
Definition: Vector.h:1074
Vector< typename std::common_type< T, U >::type, N > operator/(const Vector< T, N > &lhs, U rhs)
Right scalar division.
Definition: Vector.h:1180
Vector< T, N > & operator+=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise addition and assignment.
Definition: Vector.h:963
Vector< bool, 2 > Vector2b
A bool vector with 2 components.
Definition: Vector.h:831
Vector()=default
Default constructor.
T chebyshevLength(const Vector< T, N > &vec)
Chebyshev length of a vector.
Definition: Vector.h:1518
Vector< bool, N > operator&&(const Vector< bool, N > &lhs, const Vector< bool, N > &rhs)
Component-wise logical and operator.
Definition: Vector.h:1242
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:710
Vector< bool, N > lessThan(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise comparison operator.
Definition: Vector.h:1339
Vector< bool, 3 > Vector3b
A bool vector with 3 components.
Definition: Vector.h:837
constexpr Vector(T x, T y, T z)
Constructor that takes 3 components.
Definition: Vector.h:470
T data[N]
The internal representation of the vector.
Definition: Vector.h:196
Vector< int, 4 > Vector4i
A int vector with 4 components.
Definition: Vector.h:789
Vector< T, N > operator-(const Vector< T, N > &val)
Component-wise unary minus.
Definition: Vector.h:931
Vector< typename std::common_type< T, U >::type, N > operator-(T lhs, const Vector< U, N > &rhs)
Left scalar substraction.
Definition: Vector.h:1057
Vector< bool, 4 > Vector4b
A bool vector with 4 components.
Definition: Vector.h:843
Vector< typename std::common_type< T, U >::type, N > lerp(const Vector< T, N > &lhs, const Vector< T, N > &rhs, U t)
Component-wise lerp function.
Definition: Vector.h:1424
Vector< double, 3 > Vector3d
A double vector with 3 components.
Definition: Vector.h:765
constexpr Vector(T x, T y, T z, T w)
Constructor that takes 4 components.
Definition: Vector.h:652
T chebyshevDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Chebyshev distance between two vectors.
Definition: Vector.h:1601
Definition: Action.h:34
Vector< uint8_t, 3 > Color3u
A uint8_t color vector with 3 components.
Definition: Vector.h:861
T squareDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Square Euclidean distance between two vectors.
Definition: Vector.h:1563
Vector< std::size_t, 4 > Vector4z
A std::size_t vector with 4 components.
Definition: Vector.h:825
Vector< T, 2 > unit(T angle)
Unit vector in a specified direction.
Definition: Vector.h:1632
Vector< unsigned, 3 > Vector3u
A unsigned vector with 3 components.
Definition: Vector.h:801
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:185
Vector< typename std::common_type< T, U >::type, N > operator/(const Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise division.
Definition: Vector.h:1150
Vector< T, N > clamp(const Vector< T, N > &val, const Vector< T, N > &lo, const Vector< T, N > &hi)
Component-wise clamp function.
Definition: Vector.h:1390
Vector< typename std::common_type< T, U >::type, N > operator-(const Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise substraction.
Definition: Vector.h:1010
Vector & operator=(const Vector &other)=default
Default copy assignment.
Vector(const Vector &other)=default
Default copy constructor.
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:524
T euclideanDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Euclidean distance between two vectors.
Definition: Vector.h:1582
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:695
Vector< bool, N > operator||(const Vector< bool, N > &lhs, const Vector< bool, N > &rhs)
Component-wise logical or operator.
Definition: Vector.h:1226
Vector()=default
Default constructor.
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:334
Vector< uint8_t, 4 > Color4u
A uint8_t color vector with 4 components.
Definition: Vector.h:867
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:349
Vector< typename std::common_type< T, U >::type, N > operator-(const Vector< T, N > &lhs, U rhs)
Right scalar substraction.
Definition: Vector.h:1041
Vector< int, 3 > Vector3i
A int vector with 3 components.
Definition: Vector.h:783
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:639
constexpr Vector(Vector< T, 2 > xy, T z)
Constructor that takes a 2D vector and a z component.
Definition: Vector.h:482
bool operator!=(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Inequality operator between two vectors.
Definition: Vector.h:921
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:282
Vector< float, 3 > Color3f
A float color vector with 3 components.
Definition: Vector.h:849
Vector< T, N > normalize(const Vector< T, N > &vec)
Normalize a vector.
Definition: Vector.h:1618
Vector(const Vector &other)=default
Default copy constructor.
Vector(const Vector< U, 3 > &other)
Converting copy constructor.
Definition: Vector.h:505
Vector< T, N > min(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise minimum.
Definition: Vector.h:1274
Vector< T, N > & operator*=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise multiplication and assignment.
Definition: Vector.h:1090
Vector< typename std::common_type< T, U >::type, N > operator*(const Vector< T, N > &lhs, U rhs)
Right scalar multiplication.
Definition: Vector.h:1104
Vector()=default
Default constructor.
Vector(const Vector &other)=default
Default copy constructor.
Vector< float, 4 > Color4f
A float color vector with 4 components.
Definition: Vector.h:855
Vector< T, N > & operator*=(Vector< T, N > &lhs, U rhs)
Right scalar multiplication and assignment.
Definition: Vector.h:1120
Vector< std::size_t, 2 > Vector2z
A std::size_t vector with 2 components.
Definition: Vector.h:813
Vector(const Vector< U, 4 > &other)
Converting copy constructor.
Definition: Vector.h:675
Vector< float, 4 > Vector4f
A float vector with 4 components.
Definition: Vector.h:753
T manhattanDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Manhattan distance between two vectors.
Definition: Vector.h:1544
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:170
Vector(const Vector< U, N > &other)
Converting copy constructor.
Definition: Vector.h:145
Vector(const Vector &other)=default
Default copy constructor.
Vector< double, 2 > Vector2d
A double vector with 2 components.
Definition: Vector.h:759
#define GF_API
Definition: Portability.h:35
General purpose math vector.
Definition: Vector.h:61
Vector< double, 4 > Vector4d
A double vector with 4 components.
Definition: Vector.h:771
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:87
Vector(std::initializer_list< T > list)
Constructor that takes an initializer list.
Definition: Vector.h:123
Vector< float, 3 > Vector3f
A float vector with 3 components.
Definition: Vector.h:747
constexpr Vector< T, 3 > cross(const Vector< T, 3 > &lhs, const Vector< T, 3 > &rhs)
Cross product.
Definition: Vector.h:1659
Vector< typename std::common_type< T, U >::type, N > operator+(const Vector< T, N > &lhs, U rhs)
Right scalar addition.
Definition: Vector.h:977
Vector< T, N > & operator-=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise substraction and assignment.
Definition: Vector.h:1026
Vector(const Vector< U, 2 > &other)
Converting copy constructor.
Definition: Vector.h:316
Vector< typename std::common_type< T, U >::type, N > operator*(T lhs, const Vector< U, N > &rhs)
Left scalar multiplication.
Definition: Vector.h:1134
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:265
Vector()=default
Default constructor.
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:105
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:622