Gamedev Framework (gf)  0.2.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  /**
191  * @brief Iterator.to the first element.
192  *
193  * @return A pointer to the first element.
194  */
195  inline
196  T *begin(void) {
197  return &(data[0]);
198  }
199 
200  /**
201  * @brief Iterator to the element after the last one.
202  *
203  * @return An invalid pointer that is the adress after the last element.
204  */
205  inline
206  T *end(void) {
207  return &(data[N]);
208  }
209 
210  /**
211  * @brief Iterator.to the first element (const version).
212  *
213  * @return A pointer on the first const element.
214  */
215  inline
216  T const *begin(void) const {
217  return &(data[0]);
218  }
219 
220  /**
221  * @brief Iterator on the element after the last one (const version).
222  *
223  * @return An invalid pointer that is the adress after the last const
224  * element.
225  */
226  inline
227  T const *end(void) const {
228  return &(data[N]);
229  }
230  /**
231  * @brief Iterator.on the first element (const version).
232  *
233  * @return A pointer on the first const element.
234  */
235  inline
236  T const *cbegin(void) const {
237  return &(data[0]);
238  }
239 
240  /**
241  * @brief Iterator on the element after the last one (const version).
242  *
243  * @return An invalid pointer that is the adress after the last const
244  * element.
245  */
246  inline
247  T const *cend(void) const {
248  return &(data[N]);
249  }
250 
251  /**
252  * @brief The internal representation of the vector
253  *
254  * A vector is represented with an array of `N` values of type `T`. It
255  * can be accessed directly, like an array or like a pointer, which can
256  * ease interoperability with other libraries.
257  */
258  T data[N];
259  };
260 
261  /**
262  * @ingroup core
263  * @brief A 2D vector
264  *
265  * This specialization of gf::Vector handles the 2-dimension spaces. It can
266  * be accessed with various representations:
267  *
268  * - the generic representation with the `data` member
269  * - the `(x,y)` representation, used for generic coordinates in the 2D space
270  * - the `(u,v)` representation, used for texture coordinates (see [UV mapping](https://en.wikipedia.org/wiki/UV_mapping))
271  * - the `(s,t)` representation, used for texture coordinates
272  * - the size representation with a `width` member and a `height` member, used to represent a 2-dimensional size
273  * - the indices representation with a `col` member and a `row` member, used to access a 2-dimensional array (gf::Array2D)
274  *
275  * Several common typedef are defined:
276  *
277  * - gf::Vector2i with `int` as `T`
278  * - gf::Vector2u with `unsigned` as `T`
279  * - gf::Vector2z with `std::size_t` as `T`
280  * - gf::Vector2f with `float` as `T`
281  * - gf::Vector2d with `double` as `T`
282  * - gf::Vector2b with `bool` as `T`
283  *
284  * Usage example:
285  *
286  * ~~~{.cc}
287  * gf::Vector2f v1(16.5f, 24.0f);
288  * v1.x = 18.2f;
289  *
290  * gf::Vector2f v2 = v1 * 5.0f;
291  * gf::Vector2f v3 = v1 + v2;
292  *
293  * bool different = (v2 != v3);
294  *
295  * gf::Vector2u size;
296  * size.width = 1920;
297  * size.height = 1080;
298  *
299  * gf::Vector2f texCoords;
300  * texCoords.u = 0.0f;
301  * texCoords.v = 0.3f;
302  * ~~~
303  */
304  template <typename T>
305  struct Vector<T, 2> {
306  /**
307  * @brief Default constructor
308  *
309  * This constructor is defaulted so that this type is
310  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
311  */
312  Vector() = default;
313 
314  /**
315  * @brief Constructor that fills the vector with a value.
316  *
317  * This constructor takes a value and fills the entire vector with this
318  * value. Care must be taken when calling this constructor:
319  *
320  * ~~~{.cc}
321  * gf::Vector<int, 2> vecOK(42); // OK, vector is filled with 42
322  * gf::Vector<int, 2> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
323  * ~~~
324  *
325  * @param val The value to fill the vector with
326  */
327  explicit Vector(T val) {
328  std::fill_n(data, 2, val);
329  }
330 
331  /**
332  * @brief Constructor that takes an array
333  *
334  * This constructor can ease conversion from other math libraries. The
335  * array must contain enough data for 2 dimensions.
336  *
337  * ~~~{.cc}
338  * float array[2] = { 1.0f, -1.0f };
339  * gf::Vector<float, 2> vec(array);
340  * ~~~
341  *
342  * @param array An array with the values of the vector
343  */
344  explicit Vector(T *array)
345  {
346  std::copy_n(array, 2, data);
347  }
348 
349  /**
350  * @brief Constructor that takes 2 components
351  *
352  * @param x The first component
353  * @param y The second component
354  */
355  constexpr Vector(T x, T y)
356  : data{ x, y }
357  {
358 
359  }
360 
361  /**
362  * @brief Default copy constructor
363  *
364  * This constructor is defaulted so that this type is
365  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
366  *
367  * @param other The vector to copy from
368  */
369  Vector(const Vector& other) = default;
370 
371 
372  /**
373  * @brief Converting copy constructor
374  *
375  * @param other The vector to copy from
376  */
377  template<typename U>
378  Vector(const Vector<U, 2>& other)
379  : x(other.x)
380  , y(other.y)
381  {
382 
383  }
384 
385  /**
386  * @brief Access to the @f$ i @f$-th coordinate.
387  *
388  * ~~~{.cc}
389  * gf::Vector<int, 2> vec = { 1, 3 };
390  * std::printf("%i", vec[1]); // prints 3
391  * ~~~
392  *
393  * @param i the coordinate number
394  * @return The @f$ i @f$-th coordinate of the vector
395  */
396  T operator[](std::size_t i) const {
397  return data[i];
398  }
399 
400  /**
401  * @brief Access to the @f$ i @f$-th coordinate.
402  *
403  * ~~~{.cc}
404  * gf::Vector<int, 2> vec;
405  * vec[0] = vec[1] = 0;
406  * ~~~
407  *
408  * @param i the coordinate number
409  * @return The @f$ i @f$-th coordinate of the vector
410  */
411  T& operator[](std::size_t i) {
412  return data[i];
413  }
414 
415 
416  /**
417  * @brief Iterator.to the first element.
418  *
419  * @return A pointer to the first element.
420  */
421  inline
422  T *begin(void) {
423  return &(data[0]);
424  }
425 
426  /**
427  * @brief Iterator to the element after the last one.
428  *
429  * @return An invalid pointer that is the adress after the last element.
430  */
431  inline
432  T *end(void) {
433  return &(data[2]);
434  }
435 
436  /**
437  * @brief Iterator.to the first element (const version).
438  *
439  * @return A pointer on the first const element.
440  */
441  inline
442  T const *begin(void) const {
443  return &(data[0]);
444  }
445 
446  /**
447  * @brief Iterator on the element after the last one (const version).
448  *
449  * @return An invalid pointer that is the adress after the last const
450  * element.
451  */
452  inline
453  T const *end(void) const {
454  return &(data[2]);
455  }
456  /**
457  * @brief Iterator.on the first element (const version).
458  *
459  * @return A pointer on the first const element.
460  */
461  inline
462  T const *cbegin(void) const {
463  return &(data[0]);
464  }
465 
466  /**
467  * @brief Iterator on the element after the last one (const version).
468  *
469  * @return An invalid pointer that is the adress after the last const
470  * element.
471  */
472  inline
473  T const *cend(void) const {
474  return &(data[2]);
475  }
476 
477  /**
478  * An anonymous union to handle the various representations
479  */
480  union {
481  T data[2]; ///< Generic representation
482  struct {
483  T x; ///< First coordinate in the `(x,y)` representation. @sa y
484  T y; ///< Second coordinate in the `(x,y)` representation. @sa x
485  };
486  struct {
487  T u; ///< First coordinate in the `(u,v)` representation. @sa v
488  T v; ///< Second coordinate in the `(u,v)` representation. @sa u
489  };
490  struct {
491  T s; ///< First coordinate in the `(s,t)` representation. @sa t
492  T t; ///< Second coordinate in the `(s,t)` representation. @sa s
493  };
494  struct {
495  T width; ///< First coordinate in the size representation. @sa height
496  T height; ///< Second coordinate in the size representation. @sa width
497  };
498  struct {
499  T col; ///< First coordinate in the indices representation @sa row
500  T row; ///< Second coordinate in the indices representation @sa col
501  };
502  };
503  };
504 
505  /**
506  * @ingroup core
507  * @brief A 3D vector
508  *
509  * This specialization of gf::Vector handles the 3-dimension spaces. It can
510  * be accessed with various representations:
511  *
512  * - the generic representation with the `data` member
513  * - the `(x,y,z)` representation, used for generic coordinates in the 3D space
514  * - the `(r,g,b)` representation, used for RGB colors
515  *
516  * Several common typedef are defined:
517  *
518  * - gf::Vector3i with `int` as `T`
519  * - gf::Vector3u with `unsigned` as `T`
520  * - gf::Vector3z with `std::size_t` as `T`
521  * - gf::Vector3f with `float` as `T`
522  * - gf::Vector3d with `double` as `T`
523  * - gf::Vector3b with `bool` as `T`
524  *
525  * For colors, some additional typedef are defined:
526  *
527  * - gf::Color3f with `float` as `T`
528  * - gf::Color3u with `uint8_t` as `T`
529  *
530  * Usage example:
531  *
532  * ~~~{.cc}
533  * gf::Vector3f v1(58.0f, 96.0f, 63.0f);
534  * v1.x = 94.0f;
535  *
536  * gf::Vector3f v2 = v1 * 5.0f;
537  * gf::Vector3f v3 = v1 + v2;
538  *
539  * gf::Color3u green(0x00, 0xFF, 0x00);
540  * ~~~
541  */
542  template <typename T>
543  struct Vector<T, 3> {
544  /**
545  * @brief Default constructor
546  *
547  * This constructor is defaulted so that this type is
548  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
549  */
550  Vector() = default;
551 
552  /**
553  * @brief Constructor that fills the vector with a value.
554  *
555  * This constructor takes a value and fills the entire vector with this
556  * value. Care must be taken when calling this constructor:
557  *
558  * ~~~{.cc}
559  * gf::Vector<int, 3> vecOK(42); // OK, vector is filled with 42
560  * gf::Vector<int, 3> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
561  * ~~~
562  *
563  * @param val The value to fill the vector with
564  */
565  explicit Vector(T val) {
566  std::fill_n(data, 3, val);
567  }
568 
569  /**
570  * @brief Constructor that takes an array
571  *
572  * This constructor can ease conversion from other math libraries. The
573  * array must contain enough data for 3 dimensions.
574  *
575  * ~~~{.cc}
576  * float array[3] = { 1.0f, -1.0f, 0.0f };
577  * gf::Vector<float, 3> vec(array);
578  * ~~~
579  *
580  * @param array An array with the values of the vector
581  */
582  explicit Vector(T *array)
583  {
584  std::copy_n(array, 3, data);
585  }
586 
587  /**
588  * @brief Constructor that takes 3 components
589  *
590  * @param x The first component
591  * @param y The second component
592  * @param z The third component
593  */
594  constexpr Vector(T x, T y, T z)
595  : data{ x, y, z }
596  {
597 
598  }
599 
600  /**
601  * @brief Constructor that takes a 2D vector and a z component
602  *
603  * @param xy The first 2 component, x and y
604  * @param z The z component
605  */
606  constexpr Vector(Vector<T, 2> xy, T z)
607  : data{ xy.x, xy.y, z }
608  {
609 
610  }
611 
612  /**
613  * @brief Default copy constructor
614  *
615  * This constructor is defaulted so that this type is
616  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
617  *
618  * @param other The vector to copy from
619  */
620  Vector(const Vector& other) = default;
621 
622 
623  /**
624  * @brief Converting copy constructor
625  *
626  * @param other The vector to copy from
627  */
628  template<typename U>
629  Vector(const Vector<U, 3>& other)
630  : x(other.x)
631  , y(other.y)
632  , z(other.z)
633  {
634 
635  }
636 
637  /**
638  * @brief Access to the @f$ i @f$-th coordinate.
639  *
640  * ~~~{.cc}
641  * gf::Vector<int, 3> vec = { 1, 3, 5 };
642  * std::printf("%i", vec[1]); // prints 3
643  * ~~~
644  *
645  * @param i the coordinate number
646  * @return The @f$ i @f$-th coordinate of the vector
647  */
648  T operator[](std::size_t i) const {
649  return data[i];
650  }
651 
652  /**
653  * @brief Access to the @f$ i @f$-th coordinate.
654  *
655  * ~~~{.cc}
656  * gf::Vector<int, 3> vec;
657  * vec[0] = vec[1] = vec[2] = 0;
658  * ~~~
659  *
660  * @param i the coordinate number
661  * @return The @f$ i @f$-th coordinate of the vector
662  */
663  T& operator[](std::size_t i) {
664  return data[i];
665  }
666 
667 
668  /**
669  * @brief Iterator.to the first element.
670  *
671  * @return A pointer to the first element.
672  */
673  inline
674  T *begin(void) {
675  return &(data[0]);
676  }
677 
678  /**
679  * @brief Iterator to the element after the last one.
680  *
681  * @return An invalid pointer that is the adress after the last element.
682  */
683  inline
684  T *end(void) {
685  return &(data[3]);
686  }
687 
688  /**
689  * @brief Iterator.to the first element (const version).
690  *
691  * @return A pointer on the first const element.
692  */
693  inline
694  T const *begin(void) const {
695  return &(data[0]);
696  }
697 
698  /**
699  * @brief Iterator on the element after the last one (const version).
700  *
701  * @return An invalid pointer that is the adress after the last const
702  * element.
703  */
704  inline
705  T const *end(void) const {
706  return &(data[3]);
707  }
708  /**
709  * @brief Iterator.on the first element (const version).
710  *
711  * @return A pointer on the first const element.
712  */
713  inline
714  T const *cbegin(void) const {
715  return &(data[0]);
716  }
717 
718  /**
719  * @brief Iterator on the element after the last one (const version).
720  *
721  * @return An invalid pointer that is the adress after the last const
722  * element.
723  */
724  inline
725  T const *cend(void) const {
726  return &(data[3]);
727  }
728 
729  /**
730  * An anonymous union to handle the various representations
731  */
732  union {
733  T data[3]; ///< Generic representation
734  struct {
735  T x; ///< First coordinate in the `(x,y,z)` representation. @sa y, z
736  T y; ///< Second coordinate in the `(x,y,z)` representation. @sa x, z
737  T z; ///< Third coordinate in the `(x,y,z)` representation. @sa x, y
738  };
739  struct {
740  T r; ///< First coordinate in the `(r,g,b)` representation. @sa g, b
741  T g; ///< Second coordinate in the `(r,g,b)` representation. @sa r, b
742  T b; ///< Third coordinate in the `(r,g,b)` representation. @sa r, g
743  };
744  Vector<T, 2> xy; ///< Swizzle to get the first two coordinates as a 2D vector
745  };
746  };
747 
748  /**
749  * @ingroup core
750  * @brief A 4D vector
751  *
752  * This specialization of gf::Vector handles the 4-dimension spaces. It can
753  * be accessed with various representations:
754  *
755  * - the generic representation with the `data` member
756  * - the `(x,y,z,w)` representation, used for generic coordinates in the 4D space
757  * - the `(r,g,b,a)` representation, used for RGBA colors
758  *
759  * Several common typedef are defined:
760  *
761  * - gf::Vector4i with `int` as `T`
762  * - gf::Vector4u with `unsigned` as `T`
763  * - gf::Vector4z with `std::size_t` as `T`
764  * - gf::Vector4f with `float` as `T`
765  * - gf::Vector4d with `double` as `T`
766  * - gf::Vector4b with `bool` as `T`
767  *
768  * For colors, some additional typedef are defined:
769  *
770  * - gf::Color4f with `float` as `T`
771  * - gf::Color4u with `uint8_t` as `T`
772  *
773  * Usage example:
774  *
775  * ~~~{.cc}
776  * gf::Vector4f v1(98.0f, 75.0f, 23.0f);
777  * v1.x = 57.0f;
778  *
779  * gf::Vector4f v2 = v1 * 5.0f;
780  * gf::Vector4f v3 = v1 + v2;
781  *
782  * gf::Color4u opaqueGreen(0x00, 0xFF, 0x00, 0xFF);
783  * ~~~
784  */
785  template <typename T>
786  struct Vector<T, 4> {
787  /**
788  * @brief Default constructor
789  *
790  * This constructor is defaulted so that this type is
791  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
792  */
793  Vector() = default;
794 
795  /**
796  * @brief Constructor that fills the vector with a value.
797  *
798  * This constructor takes a value and fills the entire vector with this
799  * value. Care must be taken when calling this constructor:
800  *
801  * ~~~{.cc}
802  * gf::Vector<int, 4> vecOK(42); // OK, vector is filled with 42
803  * gf::Vector<int, 4> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
804  * ~~~
805  *
806  * @param val The value to fill the vector with
807  */
808  explicit Vector(T val) {
809  std::fill_n(data, 4, val);
810  }
811 
812  /**
813  * @brief Constructor that takes an array
814  *
815  * This constructor can ease conversion from other math libraries. The
816  * array must contain enough data for 4 dimensions.
817  *
818  * ~~~{.cc}
819  * float array[4] = { 1.0f, -1.0f, 0.5f, 0.0f };
820  * gf::Vector<float, 4> vec(array);
821  * ~~~
822  *
823  * @param array An array with the values of the vector
824  */
825  explicit Vector(T *array)
826  {
827  std::copy_n(array, 4, data);
828  }
829 
830  /**
831  * @brief Constructor that takes 4 components
832  *
833  * @param x The first component
834  * @param y The second component
835  * @param z The third component
836  * @param w The fourth component
837  */
838  constexpr Vector(T x, T y, T z, T w)
839  : data{ x, y, z, w }
840  {
841 
842  }
843 
844  /**
845  * @brief Default copy constructor
846  *
847  * This constructor is defaulted so that this type is
848  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
849  *
850  * @param other The vector to copy from
851  */
852  Vector(const Vector& other) = default;
853 
854 
855  /**
856  * @brief Converting copy constructor
857  *
858  * @param other The vector to copy from
859  */
860  template<typename U>
861  Vector(const Vector<U, 4>& other)
862  : x(other.x)
863  , y(other.y)
864  , z(other.z)
865  , w(other.w)
866  {
867 
868  }
869 
870  /**
871  * @brief Access to the @f$ i @f$-th coordinate.
872  *
873  * ~~~{.cc}
874  * gf::Vector<int, 4> vec = { 1, 3, 5, 7 };
875  * std::printf("%i", vec[1]); // prints 3
876  * ~~~
877  *
878  * @param i the coordinate number
879  * @return The @f$ i @f$-th coordinate of the vector
880  */
881  T operator[](std::size_t i) const {
882  return data[i];
883  }
884 
885  /**
886  * @brief Access to the @f$ i @f$-th coordinate.
887  *
888  * ~~~{.cc}
889  * gf::Vector<int, 5> vec;
890  * vec[0] = vec[1] = vec[2] = vec[3] = vec[4] = 0;
891  * ~~~
892  *
893  * @param i the coordinate number
894  * @return The @f$ i @f$-th coordinate of the vector
895  */
896  T& operator[](std::size_t i) {
897  return data[i];
898  }
899 
900 
901  /**
902  * @brief Iterator.to the first element.
903  *
904  * @return A pointer to the first element.
905  */
906  inline
907  T *begin(void) {
908  return &(data[0]);
909  }
910 
911  /**
912  * @brief Iterator to the element after the last one.
913  *
914  * @return An invalid pointer that is the adress after the last element.
915  */
916  inline
917  T *end(void) {
918  return &(data[4]);
919  }
920 
921  /**
922  * @brief Iterator.to the first element (const version).
923  *
924  * @return A pointer on the first const element.
925  */
926  inline
927  T const *begin(void) const {
928  return &(data[0]);
929  }
930 
931  /**
932  * @brief Iterator on the element after the last one (const version).
933  *
934  * @return An invalid pointer that is the adress after the last const
935  * element.
936  */
937  inline
938  T const *end(void) const {
939  return &(data[4]);
940  }
941  /**
942  * @brief Iterator.on the first element (const version).
943  *
944  * @return A pointer on the first const element.
945  */
946  inline
947  T const *cbegin(void) const {
948  return &(data[0]);
949  }
950 
951  /**
952  * @brief Iterator on the element after the last one (const version).
953  *
954  * @return An invalid pointer that is the adress after the last const
955  * element.
956  */
957  inline
958  T const *cend(void) const {
959  return &(data[4]);
960  }
961 
962  /**
963  * An anonymous union to handle the various representations
964  */
965  union {
966  T data[4]; ///< Generic representation
967  struct {
968  T x; ///< First coordinate in the `(x,y,z,w)` representation. @sa y, z, w
969  T y; ///< Second coordinate in the `(x,y,z,w)` representation. @sa x, z, w
970  T z; ///< Third coordinate in the `(x,y,z,w)` representation. @sa x, y, w
971  T w; ///< Fourth coordinate in the `(x,y,z,w)` representation. @sa x, y, z
972  };
973  struct {
974  T r; ///< First coordinate in the `(r,g,b,a)` representation. @sa g, b, a
975  T g; ///< Second coordinate in the `(r,g,b,a)` representation. @sa r, b, a
976  T b; ///< Third coordinate in the `(r,g,b,a)` representation. @sa r, g, a
977  T a; ///< Fourth coordinate in the `(r,g,b,a)` representation. @sa r, g, b
978  };
979  Vector<T, 2> xy; ///< Swizzle to get the first two coordinates as a 2D vector
980  Vector<T, 3> xyz; ///< Swizzle to get the first three coordinates as a 3D vector
981  Vector<T, 3> rgb; ///< Swizzle to get the first three coordinates as a RGB color
982  };
983  };
984 
985  /**
986  * @ingroup core
987  * @brief A float vector with 2 components
988  */
989  using Vector2f = Vector<float, 2>;
990 
991  /**
992  * @ingroup core
993  * @brief A float vector with 3 components
994  */
995  using Vector3f = Vector<float, 3>;
996 
997  /**
998  * @ingroup core
999  * @brief A float vector with 4 components
1000  */
1001  using Vector4f = Vector<float, 4>;
1002 
1003  /**
1004  * @ingroup core
1005  * @brief A double vector with 2 components
1006  */
1007  using Vector2d = Vector<double, 2>;
1008 
1009  /**
1010  * @ingroup core
1011  * @brief A double vector with 3 components
1012  */
1013  using Vector3d = Vector<double, 3>;
1014 
1015  /**
1016  * @ingroup core
1017  * @brief A double vector with 4 components
1018  */
1019  using Vector4d = Vector<double, 4>;
1020 
1021  /**
1022  * @ingroup core
1023  * @brief A int vector with 2 components
1024  */
1025  using Vector2i = Vector<int, 2>;
1026 
1027  /**
1028  * @ingroup core
1029  * @brief A int vector with 3 components
1030  */
1031  using Vector3i = Vector<int, 3>;
1032 
1033  /**
1034  * @ingroup core
1035  * @brief A int vector with 4 components
1036  */
1037  using Vector4i = Vector<int, 4>;
1038 
1039  /**
1040  * @ingroup core
1041  * @brief A unsigned vector with 2 components
1042  */
1043  using Vector2u = Vector<unsigned, 2>;
1044 
1045  /**
1046  * @ingroup core
1047  * @brief A unsigned vector with 3 components
1048  */
1049  using Vector3u = Vector<unsigned, 3>;
1050 
1051  /**
1052  * @ingroup core
1053  * @brief A unsigned vector with 4 components
1054  */
1055  using Vector4u = Vector<unsigned, 4>;
1056 
1057  /**
1058  * @ingroup core
1059  * @brief A std::size_t vector with 2 components
1060  */
1061  using Vector2z = Vector<std::size_t, 2>;
1062 
1063  /**
1064  * @ingroup core
1065  * @brief A std::size_t vector with 3 components
1066  */
1067  using Vector3z = Vector<std::size_t, 3>;
1068 
1069  /**
1070  * @ingroup core
1071  * @brief A std::size_t vector with 4 components
1072  */
1073  using Vector4z = Vector<std::size_t, 4>;
1074 
1075  /**
1076  * @ingroup core
1077  * @brief A bool vector with 2 components
1078  */
1079  using Vector2b = Vector<bool, 2>;
1080 
1081  /**
1082  * @ingroup core
1083  * @brief A bool vector with 3 components
1084  */
1085  using Vector3b = Vector<bool, 3>;
1086 
1087  /**
1088  * @ingroup core
1089  * @brief A bool vector with 4 components
1090  */
1091  using Vector4b = Vector<bool, 4>;
1092 
1093  /**
1094  * @ingroup core
1095  * @brief A float color vector with 3 components
1096  */
1097  using Color3f = Vector<float, 3>;
1098 
1099  /**
1100  * @ingroup core
1101  * @brief A float color vector with 4 components
1102  */
1103  using Color4f = Vector<float, 4>;
1104 
1105  /**
1106  * @ingroup core
1107  * @brief A uint8_t color vector with 3 components
1108  */
1109  using Color3u = Vector<uint8_t, 3>;
1110 
1111  /**
1112  * @ingroup core
1113  * @brief A uint8_t color vector with 4 components
1114  */
1115  using Color4u = Vector<uint8_t, 4>;
1116 
1117 // MSVC does not like extern template
1118 #ifndef _MSC_VER
1119  extern template struct Vector<float, 2>;
1120  extern template struct Vector<float, 3>;
1121  extern template struct Vector<float, 4>;
1122 
1123  extern template struct Vector<double, 2>;
1124  extern template struct Vector<double, 3>;
1125  extern template struct Vector<double, 4>;
1126 
1127  extern template struct Vector<int, 2>;
1128  extern template struct Vector<int, 3>;
1129  extern template struct Vector<int, 4>;
1130 
1131  extern template struct Vector<unsigned, 2>;
1132  extern template struct Vector<unsigned, 3>;
1133  extern template struct Vector<unsigned, 4>;
1134 
1135  extern template struct Vector<bool, 2>;
1136  extern template struct Vector<bool, 3>;
1137  extern template struct Vector<bool, 4>;
1138 
1139  extern template struct Vector<uint8_t, 3>;
1140  extern template struct Vector<uint8_t, 4>;
1141 #endif
1142 
1143  /**
1144  * @relates Vector
1145  * @brief Equality operator between two vectors
1146  */
1147  template<typename T, std::size_t N>
1148  inline
1149  bool operator==(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1150  for (std::size_t i = 0; i < N; ++i) {
1151  if (lhs.data[i] != rhs.data[i]) {
1152  return false;
1153  }
1154  }
1155 
1156  return true;
1157  }
1158 
1159  /**
1160  * @relates Vector
1161  * @brief Inequality operator between two vectors
1162  */
1163  template<typename T, std::size_t N>
1164  inline
1165  bool operator!=(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1166  return !(lhs == rhs);
1167  }
1168 
1169  /**
1170  * @relates Vector
1171  * @brief Component-wise unary minus
1172  */
1173  template<typename T, std::size_t N>
1174  inline
1175  Vector<T, N> operator-(const Vector<T, N>& val) {
1176  Vector<T, N> out;
1177 
1178  for (std::size_t i = 0; i < N; ++i) {
1179  out.data[i] = - val.data[i];
1180  }
1181 
1182  return out;
1183  }
1184 
1185  /**
1186  * @relates Vector
1187  * @brief Component-wise addition
1188  */
1189  template<typename T, typename U, std::size_t N>
1190  inline
1191  Vector<typename std::common_type<T,U>::type, N> operator+(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1192  Vector<typename std::common_type<T,U>::type, N> out;
1193 
1194  for (std::size_t i = 0; i < N; ++i) {
1195  out.data[i] = lhs.data[i] + rhs.data[i];
1196  }
1197 
1198  return out;
1199  }
1200 
1201  /**
1202  * @relates Vector
1203  * @brief Component-wise addition and assignment
1204  */
1205  template<typename T, typename U, std::size_t N>
1206  inline
1207  Vector<T, N>& operator+=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1208  for (std::size_t i = 0; i < N; ++i) {
1209  lhs.data[i] += rhs.data[i];
1210  }
1211 
1212  return lhs;
1213  }
1214 
1215  /**
1216  * @relates Vector
1217  * @brief Right scalar addition
1218  */
1219  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
1220  inline
1221  Vector<typename std::common_type<T,U>::type, N> operator+(const Vector<T, N>& lhs, U rhs) {
1222  Vector<typename std::common_type<T,U>::type, N> out;
1223 
1224  for (std::size_t i = 0; i < N; ++i) {
1225  out.data[i] = lhs.data[i] + rhs;
1226  }
1227 
1228  return out;
1229  }
1230 
1231  /**
1232  * @relates Vector
1233  * @brief Left scalar addition
1234  */
1235  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1236  inline
1237  Vector<typename std::common_type<T,U>::type, N> operator+(T lhs, const Vector<U, N>& rhs) {
1238  Vector<typename std::common_type<T,U>::type, N> out;
1239 
1240  for (std::size_t i = 0; i < N; ++i) {
1241  out.data[i] = lhs + rhs.data[i];
1242  }
1243 
1244  return out;
1245  }
1246 
1247 
1248  /**
1249  * @relates Vector
1250  * @brief Component-wise substraction
1251  */
1252  template<typename T, typename U, std::size_t N>
1253  inline
1254  Vector<typename std::common_type<T,U>::type, N> operator-(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1255  Vector<typename std::common_type<T,U>::type, N> out;
1256 
1257  for (std::size_t i = 0; i < N; ++i) {
1258  out.data[i] = lhs.data[i] - rhs.data[i];
1259  }
1260 
1261  return out;
1262  }
1263 
1264  /**
1265  * @relates Vector
1266  * @brief Component-wise substraction and assignment
1267  */
1268  template<typename T, typename U, std::size_t N>
1269  inline
1270  Vector<T, N>& operator-=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1271  for (std::size_t i = 0; i < N; ++i) {
1272  lhs.data[i] -= rhs.data[i];
1273  }
1274 
1275  return lhs;
1276  }
1277 
1278 
1279  /**
1280  * @relates Vector
1281  * @brief Right scalar substraction
1282  */
1283  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
1284  inline
1285  Vector<typename std::common_type<T,U>::type, N> operator-(const Vector<T, N>& lhs, U rhs) {
1286  Vector<typename std::common_type<T,U>::type, N> out;
1287 
1288  for (std::size_t i = 0; i < N; ++i) {
1289  out.data[i] = lhs.data[i] - rhs;
1290  }
1291 
1292  return out;
1293  }
1294 
1295  /**
1296  * @relates Vector
1297  * @brief Left scalar substraction
1298  */
1299  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1300  inline
1301  Vector<typename std::common_type<T,U>::type, N> operator-(T lhs, const Vector<U, N>& rhs) {
1302  Vector<typename std::common_type<T,U>::type, N> out;
1303 
1304  for (std::size_t i = 0; i < N; ++i) {
1305  out.data[i] = lhs - rhs.data[i];
1306  }
1307 
1308  return out;
1309  }
1310 
1311 
1312  /**
1313  * @relates Vector
1314  * @brief Component-wise multiplication
1315  */
1316  template<typename T, typename U, std::size_t N>
1317  inline
1318  Vector<typename std::common_type<T,U>::type, N> operator*(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1319  Vector<typename std::common_type<T,U>::type, N> out;
1320 
1321  for (std::size_t i = 0; i < N; ++i) {
1322  out.data[i] = lhs.data[i] * rhs.data[i];
1323  }
1324 
1325  return out;
1326  }
1327 
1328  /**
1329  * @relates Vector
1330  * @brief Component-wise multiplication and assignment
1331  */
1332  template<typename T, typename U, std::size_t N>
1333  inline
1334  Vector<T, N>& operator*=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1335  for (std::size_t i = 0; i < N; ++i) {
1336  lhs.data[i] *= rhs.data[i];
1337  }
1338 
1339  return lhs;
1340  }
1341 
1342  /**
1343  * @relates Vector
1344  * @brief Right scalar multiplication
1345  */
1346  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
1347  inline
1348  Vector<typename std::common_type<T,U>::type, N> operator*(const Vector<T, N>& lhs, U rhs) {
1349  Vector<typename std::common_type<T,U>::type, N> out;
1350 
1351  for (std::size_t i = 0; i < N; ++i) {
1352  out.data[i] = lhs.data[i] * rhs;
1353  }
1354 
1355  return out;
1356  }
1357 
1358  /**
1359  * @relates Vector
1360  * @brief Right scalar multiplication and assignment
1361  */
1362  template<typename T, typename U, std::size_t N>
1363  inline
1364  Vector<T, N>& operator*=(Vector<T, N>& lhs, U rhs) {
1365  for (std::size_t i = 0; i < N; ++i) {
1366  lhs.data[i] *= rhs;
1367  }
1368 
1369  return lhs;
1370  }
1371 
1372  /**
1373  * @relates Vector
1374  * @brief Left scalar multiplication
1375  */
1376  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1377  inline
1378  Vector<typename std::common_type<T,U>::type, N> operator*(T lhs, const Vector<U, N>& rhs) {
1379  Vector<typename std::common_type<T,U>::type, N> out;
1380 
1381  for (std::size_t i = 0; i < N; ++i) {
1382  out.data[i] = lhs * rhs.data[i];
1383  }
1384 
1385  return out;
1386  }
1387 
1388  /**
1389  * @relates Vector
1390  * @brief Component-wise division
1391  */
1392  template<typename T, typename U, std::size_t N>
1393  inline
1394  Vector<typename std::common_type<T,U>::type, N> operator/(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1395  Vector<typename std::common_type<T,U>::type, N> out;
1396 
1397  for (std::size_t i = 0; i < N; ++i) {
1398  out.data[i] = lhs.data[i] / rhs.data[i];
1399  }
1400 
1401  return out;
1402  }
1403 
1404  /**
1405  * @relates Vector
1406  * @brief Component-wise division and assignment
1407  */
1408  template<typename T, typename U, std::size_t N>
1409  inline
1410  Vector<T, N>& operator/=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
1411  for (std::size_t i = 0; i < N; ++i) {
1412  lhs.data[i] /= rhs.data[i];
1413  }
1414 
1415  return lhs;
1416  }
1417 
1418  /**
1419  * @relates Vector
1420  * @brief Right scalar division
1421  */
1422  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
1423  inline
1424  Vector<typename std::common_type<T,U>::type, N> operator/(const Vector<T, N>& lhs, U rhs) {
1425  Vector<typename std::common_type<T,U>::type, N> out;
1426 
1427  for (std::size_t i = 0; i < N; ++i) {
1428  out.data[i] = lhs.data[i] / rhs;
1429  }
1430 
1431  return out;
1432  }
1433 
1434  /**
1435  * @relates Vector
1436  * @brief Right scalar division and assignment
1437  */
1438  template<typename T, typename U, std::size_t N>
1439  inline
1440  Vector<T, N>& operator/=(Vector<T, N>& lhs, U rhs) {
1441  for (std::size_t i = 0; i < N; ++i) {
1442  lhs.data[i] /= rhs;
1443  }
1444 
1445  return lhs;
1446  }
1447 
1448  /**
1449  * @relates Vector
1450  * @brief Left scalar division
1451  */
1452  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1453  inline
1454  Vector<typename std::common_type<T,U>::type, N> operator/(T lhs, const Vector<U, N>& rhs) {
1455  Vector<typename std::common_type<T,U>::type, N> out;
1456 
1457  for (std::size_t i = 0; i < N; ++i) {
1458  out.data[i] = lhs / rhs.data[i];
1459  }
1460 
1461  return out;
1462  }
1463 
1464  /**
1465  * @relates Vector
1466  * @brief Component-wise logical or operator
1467  */
1468  template<std::size_t N>
1469  inline
1470  Vector<bool, N> operator||(const Vector<bool, N>& lhs, const Vector<bool, N>& rhs) {
1471  Vector<bool, N> out;
1472 
1473  for (std::size_t i = 0; i < N; ++i) {
1474  out.data[i] = lhs.data[i] || rhs.data[i];
1475  }
1476 
1477  return out;
1478  }
1479 
1480  /**
1481  * @relates Vector
1482  * @brief Component-wise logical and operator
1483  */
1484  template<std::size_t N>
1485  inline
1486  Vector<bool, N> operator&&(const Vector<bool, N>& lhs, const Vector<bool, N>& rhs) {
1487  Vector<bool, N> out;
1488 
1489  for (std::size_t i = 0; i < N; ++i) {
1490  out.data[i] = lhs.data[i] && rhs.data[i];
1491  }
1492 
1493  return out;
1494  }
1495 
1496  /**
1497  * @relates Vector
1498  * @brief Scalar product
1499  */
1500  template<typename T, std::size_t N>
1501  inline
1502  T dot(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1503  T out{0};
1504 
1505  for (std::size_t i = 0; i < N; ++i) {
1506  out += lhs.data[i] * rhs.data[i];
1507  }
1508 
1509  return out;
1510  }
1511 
1512  /**
1513  * @relates Vector
1514  * @brief Component-wise minimum
1515  */
1516  template<typename T, std::size_t N>
1517  inline
1518  Vector<T, N> min(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1519  Vector<T, N> out;
1520 
1521  for (std::size_t i = 0; i < N; ++i) {
1522  out.data[i] = std::min(lhs.data[i], rhs.data[i]);
1523  }
1524 
1525  return out;
1526  }
1527 
1528  /**
1529  * @relates Vector
1530  * @brief Component-wise maximum
1531  */
1532  template<typename T, std::size_t N>
1533  inline
1534  Vector<T, N> max(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1535  Vector<T, N> out;
1536 
1537  for (std::size_t i = 0; i < N; ++i) {
1538  out.data[i] = std::max(lhs.data[i], rhs.data[i]);
1539  }
1540 
1541  return out;
1542  }
1543 
1544  /**
1545  * @relates Vector
1546  * @brief Component-wise absolute value
1547  */
1548  template<typename T, std::size_t N>
1549  inline
1550  Vector<T, N> abs(const Vector<T, N>& val) {
1551  Vector<T, N> out;
1552 
1553  for (std::size_t i = 0; i < N; ++i) {
1554  out.data[i] = std::abs(val.data[i]);
1555  }
1556 
1557  return out;
1558  }
1559 
1560 
1561  /**
1562  * @relates Vector
1563  * @brief Component-wise equality operator
1564  */
1565  template<typename T, std::size_t N>
1566  inline
1567  Vector<bool, N> equals(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1568  Vector<bool, N> out;
1569 
1570  for (std::size_t i = 0; i < N; ++i) {
1571  out.data[i] = (lhs.data[i] == rhs.data[i]);
1572  }
1573 
1574  return out;
1575  }
1576 
1577  /**
1578  * @relates Vector
1579  * @brief Component-wise comparison operator
1580  */
1581  template<typename T, std::size_t N>
1582  inline
1583  Vector<bool, N> lessThan(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1584  Vector<bool, N> out;
1585 
1586  for (std::size_t i = 0; i < N; ++i) {
1587  out.data[i] = (lhs.data[i] < rhs.data[i]);
1588  }
1589 
1590  return out;
1591  }
1592 
1593  /**
1594  * @relates Vector
1595  * @brief Component-wise comparison operator
1596  */
1597  template<typename T, std::size_t N>
1598  inline
1599  Vector<bool, N> greaterThan(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1600  Vector<bool, N> out;
1601 
1602  for (std::size_t i = 0; i < N; ++i) {
1603  out.data[i] = (lhs.data[i] > rhs.data[i]);
1604  }
1605 
1606  return out;
1607  }
1608 
1609  /**
1610  * @relates Vector
1611  * @brief Component-wise selection operator
1612  */
1613  template<typename T, std::size_t N>
1614  inline
1615  Vector<T, N> select(const Vector<bool, N>& cond, const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1616  Vector<T, N> out;
1617 
1618  for (std::size_t i = 0; i < N; ++i) {
1619  out.data[i] = (cond.data[i] ? lhs.data[i] : rhs.data[i]);
1620  }
1621 
1622  return out;
1623  }
1624 
1625  /**
1626  * @relates Vector
1627  * @brief Component-wise clamp function
1628  *
1629  * Relative to two other vectors.
1630  *
1631  */
1632  template<typename T, std::size_t N>
1633  inline
1634  Vector<T, N> clamp(const Vector<T, N>& val, const Vector<T, N>& lo, const Vector<T, N>& hi) {
1635  Vector<T, N> out;
1636 
1637  for (std::size_t i = 0; i < N; ++i) {
1638  out.data[i] = clamp(val.data[i], lo.data[i], hi.data[i]);
1639  }
1640 
1641  return out;
1642  }
1643 
1644  /**
1645  * @relates Vector
1646  * @brief Component-wise clamp function
1647  *
1648  * Relative to two values.
1649  */
1650  template<typename T, std::size_t N>
1651  inline
1652  Vector<T, N> clamp(const Vector<T, N>& val, T lo, T hi) {
1653  Vector<T, N> out;
1654 
1655  for (std::size_t i = 0; i < N; ++i) {
1656  out.data[i] = clamp(val.data[i], lo, hi);
1657  }
1658 
1659  return out;
1660  }
1661 
1662  /**
1663  * @relates Vector
1664  * @brief Component-wise lerp function
1665  */
1666  template<typename T, typename U, std::size_t N>
1667  inline
1668  Vector<typename std::common_type<T,U>::type, N> lerp(const Vector<T, N>& lhs, const Vector<T, N>& rhs, U t) {
1669  return (1 - t) * lhs + t * rhs;
1670  }
1671 
1672  /**
1673  * @relates Vector
1674  * @brief Manhattan length of a vector
1675  *
1676  * The Manhattan length @f$ l @f$ of a vector @f$ (u_1, \ldots, u_N) @f$ is:
1677  *
1678  * @f[ l = \sum_{i = 1}^{N} |u_i| @f]
1679  *
1680  * The Manhattan length is also called the 1-norm.
1681  *
1682  * @param vec A vector.
1683  * @returns The Manhattan length of the vector
1684  *
1685  * @sa manhattanDistance()
1686  */
1687  template<typename T, std::size_t N>
1688  inline
1689  T manhattanLength(const Vector<T, N>& vec) {
1690  T out{0};
1691 
1692  for (std::size_t i = 0; i < N; ++i) {
1693  out += std::abs(vec.data[i]);
1694  }
1695 
1696  return out;
1697  }
1698 
1699  /**
1700  * @relates Vector
1701  * @brief Square Euclidean length of a vector
1702  *
1703  * The square Euclidean length @f$ l @f$ of a vector @f$ (u_1, \ldots, u_N) @f$ is:
1704  *
1705  * @f[ l = \sum_{i = 1}^{N} u_i^2 @f]
1706  *
1707  * @param vec A vector.
1708  * @returns The square Euclidean length of the vector
1709  *
1710  * @sa euclideanLength(), squareDistance()
1711  */
1712  template<typename T, std::size_t N>
1713  inline
1714  T squareLength(const Vector<T, N>& vec) {
1715  T out{0};
1716 
1717  for (std::size_t i = 0; i < N; ++i) {
1718  out += square(vec.data[i]);
1719  }
1720 
1721  return out;
1722  }
1723 
1724  /**
1725  * @relates Vector
1726  * @brief Euclidean length of a vector
1727  *
1728  * The Euclidean length @f$ l @f$ of a vector @f$ (u_1, \ldots, u_N) @f$ is:
1729  *
1730  * @f[ l = \sqrt{\sum_{i = 1}^{N} u_i^2} @f]
1731  *
1732  * The Euclidean length is also called the 2-norm.
1733  *
1734  * @param vec A vector.
1735  * @returns The Euclidean length of the vector
1736  *
1737  * @sa euclideanDistance()
1738  */
1739  template<typename T, std::size_t N>
1740  inline
1741  T euclideanLength(const Vector<T, N>& vec) {
1742  return std::sqrt(squareLength(vec));
1743  }
1744 
1745 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1746  // specializations of euclideanLength for Vector2f and Vector2d using std::hypot
1747 
1748  template<>
1749  inline
1750  float euclideanLength<float, 2>(const Vector<float, 2>& vec) {
1751  return std::hypot(vec.x, vec.y);
1752  }
1753 
1754  template<>
1755  inline
1756  double euclideanLength<double, 2>(const Vector<double, 2>& vec) {
1757  return std::hypot(vec.x, vec.y);
1758  }
1759 #endif
1760 
1761  /**
1762  * @relates Vector
1763  * @brief Chebyshev length of a vector
1764  *
1765  * The Chebyshev length @f$ l @f$ of a vector @f$ (u_1, \ldots, u_N) @f$ is:
1766  *
1767  * @f[ l = \max_{i = 1}^{N} |u_i| @f]
1768  *
1769  * The Chebyshev length is also called the infinity norm or maximum norm.
1770  *
1771  * @param vec A vector.
1772  * @returns The Chebyshev length of the vector
1773  *
1774  * @sa chebyshevDistance()
1775  */
1776  template<typename T, std::size_t N>
1777  inline
1778  T chebyshevLength(const Vector<T, N>& vec) {
1779  T out = std::abs(vec.data[0]);
1780 
1781  for (std::size_t i = 1; i < N; ++i) {
1782  out = std::max(out, std::abs(vec.data[i]));
1783  }
1784 
1785  return out;
1786  }
1787 
1788  /**
1789  * @ingroup core
1790  * @brief A distance function
1791  *
1792  * A distance function is a function that gives the distance between two vectors.
1793  *
1794  * ~~~
1795  * gf::Distance<float, 3> distFn = gf::manhattanDistance<float, 3>;
1796  * Vector3f vec1 = ...;
1797  * Vector3f vec2 = ...;
1798  *
1799  * float distance = distFn(vec1, vec2);
1800  * ~~~
1801  *
1802  * @sa manhattanDistance(), squareDistance(), euclideanDistance(), chebyshevDistance()
1803  * @sa gf::Distance2, gf::Distance3
1804  */
1805  template<typename T, std::size_t N>
1806  using Distance = T (*)(const Vector<T, N>&, const Vector<T, N>&);
1807 
1808  /**
1809  * @ingroup core
1810  * @brief A distance function for 2D vectors
1811  *
1812  * @sa gf::Distance
1813  */
1814  template<typename T>
1815  using Distance2 = Distance<T, 2>;
1816 
1817  /**
1818  * @ingroup core
1819  * @brief A distance function for 3D vectors
1820  *
1821  * @sa gf::Distance
1822  */
1823  template<typename T>
1824  using Distance3 = Distance<T, 3>;
1825 
1826  /**
1827  * @relates Vector
1828  * @brief Manhattan distance between two vectors
1829  *
1830  * The Manhattan distance between two vectors is the Manhattan length of the
1831  * difference of the two vectors.
1832  *
1833  * @param lhs A first vector
1834  * @param rhs A second vector
1835  * @returns The Manhattan distance between the two vectors
1836  *
1837  * @sa manhattanLength()
1838  */
1839  template<typename T, std::size_t N>
1840  inline
1841  T manhattanDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1842  return manhattanLength(lhs - rhs);
1843  }
1844 
1845  /**
1846  * @relates Vector
1847  * @brief Square Euclidean distance between two vectors
1848  *
1849  * The square Euclidean distance between two vectors is the square Euclidean
1850  * length of the difference of the two vectors.
1851  *
1852  * @param lhs A first vector
1853  * @param rhs A second vector
1854  * @returns The square Euclidean distance between the two vectors
1855  *
1856  * @sa squareLength(), euclideanDistance()
1857  */
1858  template<typename T, std::size_t N>
1859  inline
1860  T squareDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1861  return squareLength(lhs - rhs);
1862  }
1863 
1864  /**
1865  * @relates Vector
1866  * @brief Euclidean distance between two vectors
1867  *
1868  * The Euclidean distance between two vectors is the Euclidean length of the
1869  * difference of the two vectors.
1870  *
1871  * @param lhs A first vector
1872  * @param rhs A second vector
1873  * @returns The Euclidean distance between the two vectors
1874  *
1875  * @sa euclideanLength()
1876  */
1877  template<typename T, std::size_t N>
1878  inline
1879  T euclideanDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1880  return euclideanLength(lhs - rhs);
1881  }
1882 
1883  /**
1884  * @relates Vector
1885  * @brief Chebyshev distance between two vectors
1886  *
1887  * The Chebyshev distance between two vectors is the Chebyshev length of the
1888  * difference of the two vectors.
1889  *
1890  * @param lhs A first vector
1891  * @param rhs A second vector
1892  * @returns The Chebyshev distance between the two vectors
1893  *
1894  * @sa chebyshevLength()
1895  */
1896  template<typename T, std::size_t N>
1897  inline
1898  T chebyshevDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
1899  return chebyshevLength(lhs - rhs);
1900  }
1901 
1902  /**
1903  * @relates Vector
1904  * @brief Normalize a vector
1905  *
1906  * The normalized vector of @f$ v @f$ is a vector in the same direction but
1907  * with a (euclidean) length of 1. A normalized vector is also called a
1908  * [unit vector](https://en.wikipedia.org/wiki/Unit_vector).
1909  *
1910  * @param vec A vector
1911  * @returns A normalized vector
1912  */
1913  template<typename T, std::size_t N>
1914  inline
1915  Vector<T, N> normalize(const Vector<T, N>& vec) {
1916  T length = euclideanLength(vec);
1917  return vec / length;
1918  }
1919 
1920  /**
1921  * @relates Vector
1922  * @brief Unit vector in a specified direction
1923  *
1924  * @param angle The angle of the direction
1925  * @return A unit vector
1926  */
1927  template<typename T>
1928  inline
1929  Vector<T, 2> unit(T angle) {
1930  return { std::cos(angle), std::sin(angle) };
1931  }
1932 
1933  /**
1934  * @relates Vector
1935  * @brief Perpendicular vector
1936  *
1937  * @param vec A vector
1938  * @returns A perpendicular vector
1939  */
1940  template<typename T>
1941  constexpr
1942  Vector<T, 2> perp(const Vector<T, 2>& vec) {
1943  return { -vec.y, vec.x };
1944  }
1945 
1946  /**
1947  * @relates Vector
1948  * @brief Cross product
1949  *
1950  * @param lhs A first vector
1951  * @param rhs A second vector
1952  * @return The cross product of the two vectors
1953  */
1954  template<typename T>
1955  constexpr
1956  Vector<T, 3> cross(const Vector<T, 3>& lhs, const Vector<T, 3>& rhs) {
1957  return {
1958  lhs.y * rhs.z - lhs.z * rhs.y,
1959  lhs.z * rhs.x - lhs.x * rhs.z,
1960  lhs.x * rhs.y - lhs.y * rhs.x
1961  };
1962  }
1963 
1964 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1965 }
1966 #endif
1967 }
1968 
1969 #endif // GAME_VECTOR_H
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:582
T const * end(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:227
T const * cbegin(void) const
Iterator.on the first element (const version).
Definition: Vector.h:947
T manhattanLength(const Vector< T, N > &vec)
Manhattan length of a vector.
Definition: Vector.h:1689
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:565
T dot(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Scalar product.
Definition: Vector.h:1502
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:663
Vector< T, N > abs(const Vector< T, N > &val)
Component-wise absolute value.
Definition: Vector.h:1550
Vector< typename std::common_type< T, U >::type, N > operator/(T lhs, const Vector< U, N > &rhs)
Left scalar division.
Definition: Vector.h:1454
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:1615
constexpr Vector< T, 2 > perp(const Vector< T, 2 > &vec)
Perpendicular vector.
Definition: Vector.h:1942
T const * cend(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:725
bool operator==(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Equality operator between two vectors.
Definition: Vector.h:1149
T * begin(void)
Iterator.to the first element.
Definition: Vector.h:907
Vector< typename std::common_type< T, U >::type, N > operator+(T lhs, const Vector< U, N > &rhs)
Left scalar addition.
Definition: Vector.h:1237
T squareLength(const Vector< T, N > &vec)
Square Euclidean length of a vector.
Definition: Vector.h:1714
Vector< T, N > & operator/=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise division and assignment.
Definition: Vector.h:1410
Vector< T, N > clamp(const Vector< T, N > &val, T lo, T hi)
Component-wise clamp function.
Definition: Vector.h:1652
T euclideanLength(const Vector< T, N > &vec)
Euclidean length of a vector.
Definition: Vector.h:1741
Vector< T, N > max(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise maximum.
Definition: Vector.h:1534
Vector< bool, N > greaterThan(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise comparison operator.
Definition: Vector.h:1599
T const * cend(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:958
Vector< T, N > & operator/=(Vector< T, N > &lhs, U rhs)
Right scalar division and assignment.
Definition: Vector.h:1440
Vector< bool, N > equals(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise equality operator.
Definition: Vector.h:1567
constexpr Vector(T x, T y)
Constructor that takes 2 components.
Definition: Vector.h:355
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:1191
friend class RenderTarget
Definition: Shader.h:387
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:1318
T const * end(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:453
Vector< typename std::common_type< T, U >::type, N > operator/(const Vector< T, N > &lhs, U rhs)
Right scalar division.
Definition: Vector.h:1424
T const * end(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:938
Vector< T, N > & operator+=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise addition and assignment.
Definition: Vector.h:1207
Vector()=default
Default constructor.
T chebyshevLength(const Vector< T, N > &vec)
Chebyshev length of a vector.
Definition: Vector.h:1778
Vector< bool, N > operator&&(const Vector< bool, N > &lhs, const Vector< bool, N > &rhs)
Component-wise logical and operator.
Definition: Vector.h:1486
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:896
Vector< bool, N > lessThan(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise comparison operator.
Definition: Vector.h:1583
T const * begin(void) const
Iterator.to the first element (const version).
Definition: Vector.h:216
constexpr Vector(T x, T y, T z)
Constructor that takes 3 components.
Definition: Vector.h:594
T const * cbegin(void) const
Iterator.on the first element (const version).
Definition: Vector.h:714
T data[N]
The internal representation of the vector.
Definition: Vector.h:258
Vector< T, N > operator-(const Vector< T, N > &val)
Component-wise unary minus.
Definition: Vector.h:1175
Vector< typename std::common_type< T, U >::type, N > operator-(T lhs, const Vector< U, N > &rhs)
Left scalar substraction.
Definition: Vector.h:1301
T const * begin(void) const
Iterator.to the first element (const version).
Definition: Vector.h:694
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:1668
constexpr Vector(T x, T y, T z, T w)
Constructor that takes 4 components.
Definition: Vector.h:838
T const * cbegin(void) const
Iterator.on the first element (const version).
Definition: Vector.h:462
T chebyshevDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Chebyshev distance between two vectors.
Definition: Vector.h:1898
Definition: Action.h:34
T squareDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Square Euclidean distance between two vectors.
Definition: Vector.h:1860
Vector< T, 2 > unit(T angle)
Unit vector in a specified direction.
Definition: Vector.h:1929
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:1394
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:1634
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:1254
T const * cend(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:247
Vector & operator=(const Vector &other)=default
Default copy assignment.
T * begin(void)
Iterator.to the first element.
Definition: Vector.h:196
Vector(const Vector &other)=default
Default copy constructor.
T const * end(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:705
T const * begin(void) const
Iterator.to the first element (const version).
Definition: Vector.h:927
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:648
T * end(void)
Iterator to the element after the last one.
Definition: Vector.h:432
T euclideanDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Euclidean distance between two vectors.
Definition: Vector.h:1879
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:881
T * end(void)
Iterator to the element after the last one.
Definition: Vector.h:917
Vector< bool, N > operator||(const Vector< bool, N > &lhs, const Vector< bool, N > &rhs)
Component-wise logical or operator.
Definition: Vector.h:1470
Vector()=default
Default constructor.
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:396
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:411
Vector< typename std::common_type< T, U >::type, N > operator-(const Vector< T, N > &lhs, U rhs)
Right scalar substraction.
Definition: Vector.h:1285
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:825
constexpr Vector(Vector< T, 2 > xy, T z)
Constructor that takes a 2D vector and a z component.
Definition: Vector.h:606
bool operator!=(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Inequality operator between two vectors.
Definition: Vector.h:1165
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:344
Vector< T, N > normalize(const Vector< T, N > &vec)
Normalize a vector.
Definition: Vector.h:1915
Vector(const Vector &other)=default
Default copy constructor.
Vector(const Vector< U, 3 > &other)
Converting copy constructor.
Definition: Vector.h:629
Vector< T, N > min(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise minimum.
Definition: Vector.h:1518
Vector< T, N > & operator*=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise multiplication and assignment.
Definition: Vector.h:1334
Vector< typename std::common_type< T, U >::type, N > operator*(const Vector< T, N > &lhs, U rhs)
Right scalar multiplication.
Definition: Vector.h:1348
Vector()=default
Default constructor.
T const * cend(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:473
Vector(const Vector &other)=default
Default copy constructor.
T const * begin(void) const
Iterator.to the first element (const version).
Definition: Vector.h:442
Vector< T, N > & operator*=(Vector< T, N > &lhs, U rhs)
Right scalar multiplication and assignment.
Definition: Vector.h:1364
Vector(const Vector< U, 4 > &other)
Converting copy constructor.
Definition: Vector.h:861
T manhattanDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Manhattan distance between two vectors.
Definition: Vector.h:1841
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:170
T const * cbegin(void) const
Iterator.on the first element (const version).
Definition: Vector.h:236
Vector(const Vector< U, N > &other)
Converting copy constructor.
Definition: Vector.h:145
Vector(const Vector &other)=default
Default copy constructor.
T * begin(void)
Iterator.to the first element.
Definition: Vector.h:674
General purpose math vector.
Definition: Vector.h:61
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
constexpr Vector< T, 3 > cross(const Vector< T, 3 > &lhs, const Vector< T, 3 > &rhs)
Cross product.
Definition: Vector.h:1956
Vector< typename std::common_type< T, U >::type, N > operator+(const Vector< T, N > &lhs, U rhs)
Right scalar addition.
Definition: Vector.h:1221
Vector< T, N > & operator-=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise substraction and assignment.
Definition: Vector.h:1270
Vector(const Vector< U, 2 > &other)
Converting copy constructor.
Definition: Vector.h:378
Vector< typename std::common_type< T, U >::type, N > operator*(T lhs, const Vector< U, N > &rhs)
Left scalar multiplication.
Definition: Vector.h:1378
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:327
T * end(void)
Iterator to the element after the last one.
Definition: Vector.h:206
T * begin(void)
Iterator.to the first element.
Definition: Vector.h:422
Vector()=default
Default constructor.
T * end(void)
Iterator to the element after the last one.
Definition: Vector.h:684
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:808