Gamedev Framework (gf)  0.10.0
A C++14 framework for 2D games
VectorOps.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2018 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_OPS_H
22 #define GF_VECTOR_OPS_H
23 
24 #include <cmath>
25 #include <cstdlib>
26 #include <algorithm>
27 #include <type_traits>
28 
29 #include "Math.h"
30 #include "Vector.h"
31 
32 namespace gf {
33 #ifndef DOXYGEN_SHOULD_SKIP_THIS
34 inline namespace v1 {
35 #endif
36 
41  template<typename T, std::size_t N>
42  constexpr
44  for (std::size_t i = 0; i < N; ++i) {
45  if (lhs[i] != rhs[i]) {
46  return false;
47  }
48  }
49 
50  return true;
51  }
52 
57  template<typename T, std::size_t N>
58  constexpr
60  return !(lhs == rhs);
61  }
62 
67  template<typename T, std::size_t N>
68  constexpr
70  Vector<T, N> out = { };
71 
72  for (std::size_t i = 0; i < N; ++i) {
73  out[i] = - val[i];
74  }
75 
76  return out;
77  }
78 
83  template<typename T, typename U, std::size_t N>
84  constexpr
87 
88  for (std::size_t i = 0; i < N; ++i) {
89  out[i] = lhs[i] + rhs[i];
90  }
91 
92  return out;
93  }
94 
99  template<typename T, typename U, std::size_t N>
100  constexpr
102  for (std::size_t i = 0; i < N; ++i) {
103  lhs[i] += rhs[i];
104  }
105 
106  return lhs;
107  }
108 
113  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
114  constexpr
116  Vector<std::common_type_t<T,U>, N> out = { };
117 
118  for (std::size_t i = 0; i < N; ++i) {
119  out[i] = lhs[i] + rhs;
120  }
121 
122  return out;
123  }
124 
129  template<typename T, typename U, std::size_t N>
130  constexpr
132  for (std::size_t i = 0; i < N; ++i) {
133  lhs[i] += rhs;
134  }
135 
136  return lhs;
137  }
138 
143  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
144  constexpr
146  Vector<std::common_type_t<T,U>, N> out = { };
147 
148  for (std::size_t i = 0; i < N; ++i) {
149  out[i] = lhs + rhs[i];
150  }
151 
152  return out;
153  }
154 
155 
160  template<typename T, typename U, std::size_t N>
161  constexpr
163  Vector<std::common_type_t<T,U>, N> out = { };
164 
165  for (std::size_t i = 0; i < N; ++i) {
166  out[i] = lhs[i] - rhs[i];
167  }
168 
169  return out;
170  }
171 
176  template<typename T, typename U, std::size_t N>
177  constexpr
179  for (std::size_t i = 0; i < N; ++i) {
180  lhs[i] -= rhs[i];
181  }
182 
183  return lhs;
184  }
185 
186 
191  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
192  constexpr
194  Vector<std::common_type_t<T,U>, N> out = { };
195 
196  for (std::size_t i = 0; i < N; ++i) {
197  out[i] = lhs[i] - rhs;
198  }
199 
200  return out;
201  }
202 
207  template<typename T, typename U, std::size_t N>
208  constexpr
210  for (std::size_t i = 0; i < N; ++i) {
211  lhs[i] -= rhs;
212  }
213 
214  return lhs;
215  }
216 
221  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
222  constexpr
224  Vector<std::common_type_t<T,U>, N> out = { };
225 
226  for (std::size_t i = 0; i < N; ++i) {
227  out[i] = lhs - rhs[i];
228  }
229 
230  return out;
231  }
232 
233 
238  template<typename T, typename U, std::size_t N>
239  constexpr
241  Vector<std::common_type_t<T,U>, N> out = { };
242 
243  for (std::size_t i = 0; i < N; ++i) {
244  out[i] = lhs[i] * rhs[i];
245  }
246 
247  return out;
248  }
249 
254  template<typename T, typename U, std::size_t N>
255  constexpr
257  for (std::size_t i = 0; i < N; ++i) {
258  lhs[i] *= rhs[i];
259  }
260 
261  return lhs;
262  }
263 
268  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
269  constexpr
271  Vector<std::common_type_t<T,U>, N> out = { };
272 
273  for (std::size_t i = 0; i < N; ++i) {
274  out[i] = lhs[i] * rhs;
275  }
276 
277  return out;
278  }
279 
284  template<typename T, typename U, std::size_t N>
285  constexpr
287  for (std::size_t i = 0; i < N; ++i) {
288  lhs[i] *= rhs;
289  }
290 
291  return lhs;
292  }
293 
298  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
299  constexpr
301  Vector<std::common_type_t<T,U>, N> out = { };
302 
303  for (std::size_t i = 0; i < N; ++i) {
304  out[i] = lhs * rhs[i];
305  }
306 
307  return out;
308  }
309 
314  template<typename T, typename U, std::size_t N>
315  constexpr
317  Vector<std::common_type_t<T,U>, N> out = { };
318 
319  for (std::size_t i = 0; i < N; ++i) {
320  out[i] = lhs[i] / rhs[i];
321  }
322 
323  return out;
324  }
325 
330  template<typename T, typename U, std::size_t N>
331  constexpr
333  for (std::size_t i = 0; i < N; ++i) {
334  lhs[i] /= rhs[i];
335  }
336 
337  return lhs;
338  }
339 
344  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
345  constexpr
347  Vector<std::common_type_t<T,U>, N> out = { };
348 
349  for (std::size_t i = 0; i < N; ++i) {
350  out[i] = lhs[i] / rhs;
351  }
352 
353  return out;
354  }
355 
360  template<typename T, typename U, std::size_t N>
361  constexpr
363  for (std::size_t i = 0; i < N; ++i) {
364  lhs[i] /= rhs;
365  }
366 
367  return lhs;
368  }
369 
374  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
375  constexpr
377  Vector<std::common_type_t<T,U>, N> out = { };
378 
379  for (std::size_t i = 0; i < N; ++i) {
380  out[i] = lhs / rhs[i];
381  }
382 
383  return out;
384  }
385 
390  template<std::size_t N>
391  constexpr
393  Vector<bool, N> out = { };
394 
395  for (std::size_t i = 0; i < N; ++i) {
396  out[i] = lhs[i] || rhs[i];
397  }
398 
399  return out;
400  }
401 
406  template<std::size_t N>
407  constexpr
409  Vector<bool, N> out = { };
410 
411  for (std::size_t i = 0; i < N; ++i) {
412  out[i] = lhs[i] && rhs[i];
413  }
414 
415  return out;
416  }
417 
430  template<typename T, std::size_t N>
431  constexpr
433  T out{0};
434 
435  for (std::size_t i = 0; i < N; ++i) {
436  out += lhs[i] * rhs[i];
437  }
438 
439  return out;
440  }
441 
446  template<typename T, std::size_t N>
447  constexpr
449  Vector<T, N> out = { };
450 
451  for (std::size_t i = 0; i < N; ++i) {
452  out[i] = std::min(lhs[i], rhs[i]);
453  }
454 
455  return out;
456  }
457 
462  template<typename T, std::size_t N>
463  constexpr
465  Vector<T, N> out = { };
466 
467  for (std::size_t i = 0; i < N; ++i) {
468  out[i] = std::max(lhs[i], rhs[i]);
469  }
470 
471  return out;
472  }
473 
478  template<typename T, std::size_t N>
479  inline
481  Vector<T, N> out;
482 
483  for (std::size_t i = 0; i < N; ++i) {
484  out[i] = std::abs(val[i]);
485  }
486 
487  return out;
488  }
489 
494  template<typename T, std::size_t N>
495  constexpr
497  Vector<int, N> out = { };
498 
499  for (std::size_t i = 0; i < N; ++i) {
500  out[i] = gf::sign(val[i]);
501  }
502 
503  return out;
504  }
505 
510  template<typename T, std::size_t N>
511  constexpr
513  Vector<bool, N> out = { };
514 
515  for (std::size_t i = 0; i < N; ++i) {
516  out[i] = (lhs[i] == rhs[i]);
517  }
518 
519  return out;
520  }
521 
526  template<typename T, std::size_t N>
527  constexpr
529  Vector<bool, N> out = { };
530 
531  for (std::size_t i = 0; i < N; ++i) {
532  out[i] = (lhs[i] < rhs[i]);
533  }
534 
535  return out;
536  }
537 
542  template<typename T, std::size_t N>
543  constexpr
545  Vector<bool, N> out = { };
546 
547  for (std::size_t i = 0; i < N; ++i) {
548  out[i] = (lhs[i] > rhs[i]);
549  }
550 
551  return out;
552  }
553 
558  template<typename T, std::size_t N>
559  constexpr
561  Vector<T, N> out = { };
562 
563  for (std::size_t i = 0; i < N; ++i) {
564  out[i] = (cond[i] ? lhs[i] : rhs[i]);
565  }
566 
567  return out;
568  }
569 
577  template<typename T, std::size_t N>
578  constexpr
580  Vector<T, N> out = { };
581 
582  for (std::size_t i = 0; i < N; ++i) {
583  out[i] = clamp(val[i], lo[i], hi[i]);
584  }
585 
586  return out;
587  }
588 
595  template<typename T, std::size_t N>
596  constexpr
598  Vector<T, N> out = { };
599 
600  for (std::size_t i = 0; i < N; ++i) {
601  out[i] = clamp(val[i], lo, hi);
602  }
603 
604  return out;
605  }
606 
611  template<typename T, typename U, std::size_t N>
612  constexpr
614  Vector<T, N> out = { };
615 
616  for (std::size_t i = 0; i < N; ++i) {
617  out[i] = lerp(lhs[i], rhs[i], t);
618  }
619 
620  return out;
621  // return (1 - t) * lhs + t * rhs;
622  }
623 
640  template<typename T, std::size_t N>
641  inline
643  T out{0};
644 
645  for (std::size_t i = 0; i < N; ++i) {
646  out += std::abs(vec[i]);
647  }
648 
649  return out;
650  }
651 
666  template<typename T, std::size_t N>
667  inline
669  T out{0};
670 
671  for (std::size_t i = 0; i < N; ++i) {
672  out += square(vec[i]);
673  }
674 
675  return out;
676  }
677 
694  template<typename T, std::size_t N>
695  inline
697  return std::sqrt(squareLength(vec));
698  }
699 
700 #ifndef DOXYGEN_SHOULD_SKIP_THIS
701  // specializations of euclideanLength for Vector2f and Vector2d using std::hypot
702 
703  template<>
704  inline
705  float euclideanLength<float, 2>(Vector<float, 2> vec) {
706  return std::hypot(vec.x, vec.y);
707  }
708 
709  template<>
710  inline
711  double euclideanLength<double, 2>(Vector<double, 2> vec) {
712  return std::hypot(vec.x, vec.y);
713  }
714 #endif
715 
732  template<typename T, std::size_t N>
733  inline
735  T out = std::abs(vec[0]);
736 
737  for (std::size_t i = 1; i < N; ++i) {
738  out = std::max(out, std::abs(vec[i]));
739  }
740 
741  return out;
742  }
743 
761  template<typename T, std::size_t N>
762  inline
764  return manhattanLength(vec) + squareLength(vec);
765  }
766 
780  template<typename T, std::size_t N>
781  inline
783  return manhattanLength(lhs - rhs);
784  }
785 
799  template<typename T, std::size_t N>
800  inline
802  return squareLength(lhs - rhs);
803  }
804 
818  template<typename T, std::size_t N>
819  inline
821  return euclideanLength(lhs - rhs);
822  }
823 
837  template<typename T, std::size_t N>
838  inline
840  return chebyshevLength(lhs - rhs);
841  }
842 
856  template<typename T, std::size_t N>
857  inline
859  return naturalLength(lhs - rhs);
860  }
861 
877  template<typename T, std::size_t N>
878  inline
880  T length = euclideanLength(vec);
881  return vec / length;
882  }
883 
891  template<typename T>
892  inline
894  return { std::cos(angle), std::sin(angle) };
895  }
896 
904  template<typename T>
905  inline
906  float angle(Vector<T, 2> vec) {
907  return std::atan2(vec.y, vec.x);
908  }
909 
921  template<typename T>
922  constexpr
924  return { -vec.y, vec.x };
925  }
926 
940  template<typename T>
941  constexpr
943  return dot(a, c) * b - dot(a, b) * c;
944  }
945 
960  template<typename T>
961  constexpr
963  return - dot(c, b) * a + dot(c, a) * b;
964  }
965 
983  template<typename T>
984  constexpr
986  return lhs.x * rhs.y - lhs.y * rhs.x;
987  }
988 
989 
998  template<typename T>
999  constexpr
1001  return {
1002  lhs.y * rhs.z - lhs.z * rhs.y,
1003  lhs.z * rhs.x - lhs.x * rhs.z,
1004  lhs.x * rhs.y - lhs.y * rhs.x
1005  };
1006  }
1007 
1008 
1017  template<typename Archive, typename T, std::size_t N>
1018  inline
1019  Archive& operator|(Archive& ar, Vector<T,N>& vec) {
1020  for (std::size_t i = 0; i < N; ++i) {
1021  ar | vec[i];
1022  }
1023 
1024  return ar;
1025  }
1026 
1027 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1028 }
1029 #endif
1030 }
1031 
1032 #endif // GF_VECTOR_OPS_H
constexpr Vector< bool, N > greaterThan(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise comparison operator.
Definition: VectorOps.h:544
constexpr Vector< T, N > max(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise maximum.
Definition: VectorOps.h:464
T euclideanLength(Vector< T, N > vec)
Euclidean length of a vector.
Definition: VectorOps.h:696
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:509
constexpr Vector< std::common_type_t< T, U >, N > operator/(T lhs, Vector< U, N > rhs)
Left scalar division.
Definition: VectorOps.h:376
constexpr T dot(Vector< T, N > lhs, Vector< T, N > rhs)
Scalar product.
Definition: VectorOps.h:432
constexpr T lerp(T lhs, T rhs, U t)
Linear interpolation function.
Definition: Math.h:242
constexpr Vector< T, N > select(Vector< bool, N > cond, Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise selection operator.
Definition: VectorOps.h:560
constexpr Vector< std::common_type_t< T, U >, N > operator*(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise multiplication.
Definition: VectorOps.h:240
constexpr Vector< T, 3 > cross(Vector< T, 3 > lhs, Vector< T, 3 > rhs)
Cross product for 3D vectors.
Definition: VectorOps.h:1000
constexpr Vector< std::common_type_t< T, U >, N > operator-(T lhs, Vector< U, N > rhs)
Left scalar substraction.
Definition: VectorOps.h:223
constexpr Vector< std::common_type_t< T, U >, N > operator/(Vector< T, N > lhs, U rhs)
Right scalar division.
Definition: VectorOps.h:346
constexpr Vector< T, N > & operator+=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise addition and assignment.
Definition: VectorOps.h:101
constexpr Vector< std::common_type_t< T, U >, N > operator/(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise division.
Definition: VectorOps.h:316
constexpr Vector< std::common_type_t< T, U >, N > operator+(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise addition.
Definition: VectorOps.h:85
constexpr bool operator!=(Vector< T, N > lhs, Vector< T, N > rhs)
Inequality operator between two vectors.
Definition: VectorOps.h:59
constexpr Vector< T, N > & operator*=(Vector< T, N > &lhs, U rhs)
Right scalar multiplication and assignment.
Definition: VectorOps.h:286
constexpr Vector< T, 2 > vectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Regular vector triple product.
Definition: VectorOps.h:942
Vector< T, N > normalize(Vector< T, N > vec)
Normalize a vector.
Definition: VectorOps.h:879
Archive & operator|(Archive &ar, Vector< T, N > &vec)
Serialize and deserialize a vector.
Definition: VectorOps.h:1019
constexpr Vector< T, N > & operator-=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise substraction and assignment.
Definition: VectorOps.h:178
constexpr Vector< T, 2 > inverseVectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Inverse vector triple product.
Definition: VectorOps.h:962
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:520
T x
First coordinate in the (x,y,z) representation.
Definition: Vector.h:786
constexpr Vector< T, N > lerp(Vector< T, N > lhs, Vector< T, N > rhs, U t)
Component-wise lerp function.
Definition: VectorOps.h:613
constexpr Vector< T, N > & operator+=(Vector< T, N > &lhs, U rhs)
Right scalar addition and assignment.
Definition: VectorOps.h:131
constexpr Vector< std::common_type_t< T, U >, N > operator+(T lhs, Vector< U, N > rhs)
Left scalar addition.
Definition: VectorOps.h:145
constexpr T square(T val)
Square function.
Definition: Math.h:275
float angle(Vector< T, 2 > vec)
Angle of a vector relative to the x-axis.
Definition: VectorOps.h:906
constexpr T clamp(T val, T lo, T hi)
Clamping function.
Definition: Math.h:260
constexpr Vector< std::common_type_t< T, U >, N > operator-(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise substraction.
Definition: VectorOps.h:162
constexpr Vector< T, N > & operator/=(Vector< T, N > &lhs, U rhs)
Right scalar division and assignment.
Definition: VectorOps.h:362
T squareDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Square Euclidean distance between two vectors.
Definition: VectorOps.h:801
constexpr bool operator==(Vector< T, N > lhs, Vector< T, N > rhs)
Equality operator between two vectors.
Definition: VectorOps.h:43
constexpr Vector< bool, N > lessThan(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise comparison operator.
Definition: VectorOps.h:528
constexpr Vector< T, N > & operator*=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise multiplication and assignment.
Definition: VectorOps.h:256
constexpr Vector< bool, N > equals(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise equality operator.
Definition: VectorOps.h:512
constexpr Vector< std::common_type_t< T, U >, N > operator-(Vector< T, N > lhs, U rhs)
Right scalar substraction.
Definition: VectorOps.h:193
The namespace for gf classes.
Definition: Action.h:34
constexpr Vector< T, N > operator-(Vector< T, N > val)
Component-wise unary minus.
Definition: VectorOps.h:69
Vector< T, 2 > unit(T angle)
Unit vector in a specified direction.
Definition: VectorOps.h:893
float angle(Direction direction)
Get an angle from a direction.
constexpr Vector< T, N > min(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise minimum.
Definition: VectorOps.h:448
constexpr Vector< T, N > & operator/=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise division and assignment.
Definition: VectorOps.h:332
constexpr Vector< std::common_type_t< T, U >, N > operator*(Vector< T, N > lhs, U rhs)
Right scalar multiplication.
Definition: VectorOps.h:270
constexpr Vector< T, N > clamp(Vector< T, N > val, T lo, T hi)
Component-wise clamp function.
Definition: VectorOps.h:597
T manhattanDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Manhattan distance between two vectors.
Definition: VectorOps.h:782
constexpr Vector< bool, N > operator||(Vector< bool, N > lhs, Vector< bool, N > rhs)
Component-wise logical or operator.
Definition: VectorOps.h:392
A 2D vector.
Definition: Vector.h:316
T y
Second coordinate in the (x,y,z) representation.
Definition: Vector.h:794
T chebyshevLength(Vector< T, N > vec)
Chebyshev length of a vector.
Definition: VectorOps.h:734
T euclideanDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Euclidean distance between two vectors.
Definition: VectorOps.h:820
constexpr int sign(T val)
Sign function.
Definition: Math.h:295
T manhattanLength(Vector< T, N > vec)
Manhattan length of a vector.
Definition: VectorOps.h:642
constexpr Vector< T, N > clamp(Vector< T, N > val, Vector< T, N > lo, Vector< T, N > hi)
Component-wise clamp function.
Definition: VectorOps.h:579
Vector< T, N > abs(Vector< T, N > val)
Component-wise absolute value.
Definition: VectorOps.h:480
A 3D vector.
Definition: Vector.h:565
General purpose math vector.
Definition: Vector.h:61
constexpr Vector< std::common_type_t< T, U >, N > operator*(T lhs, Vector< U, N > rhs)
Left scalar multiplication.
Definition: VectorOps.h:300
T z
Third coordinate in the (x,y,z) representation.
Definition: Vector.h:802
constexpr Vector< T, 2 > perp(Vector< T, 2 > vec)
Perpendicular vector.
Definition: VectorOps.h:923
constexpr Vector< int, N > sign(Vector< T, N > val)
Component-wise sign value.
Definition: VectorOps.h:496
T naturalDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Natural distance between two vectors.
Definition: VectorOps.h:858
T naturalLength(Vector< T, N > vec)
Natural length of a vector.
Definition: VectorOps.h:763
constexpr Vector< T, N > & operator-=(Vector< T, N > &lhs, U rhs)
Right scalar substraction and assignment.
Definition: VectorOps.h:209
T squareLength(Vector< T, N > vec)
Square Euclidean length of a vector.
Definition: VectorOps.h:668
constexpr Vector< std::common_type_t< T, U >, N > operator+(Vector< T, N > lhs, U rhs)
Right scalar addition.
Definition: VectorOps.h:115
constexpr T cross(Vector< T, 2 > lhs, Vector< T, 2 > rhs)
Cross product for 2D vectors.
Definition: VectorOps.h:985
T chebyshevDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Chebyshev distance between two vectors.
Definition: VectorOps.h:839