Gamedev Framework (gf)  0.7.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 <algorithm>
26 #include <type_traits>
27 
28 #include "Math.h"
29 #include "Vector.h"
30 
31 namespace gf {
32 #ifndef DOXYGEN_SHOULD_SKIP_THIS
33 inline namespace v1 {
34 #endif
35 
40  template<typename T, std::size_t N>
41  constexpr
43  for (std::size_t i = 0; i < N; ++i) {
44  if (lhs[i] != rhs[i]) {
45  return false;
46  }
47  }
48 
49  return true;
50  }
51 
56  template<typename T, std::size_t N>
57  constexpr
59  return !(lhs == rhs);
60  }
61 
66  template<typename T, std::size_t N>
67  constexpr
69  Vector<T, N> out = gf::Zero;
70 
71  for (std::size_t i = 0; i < N; ++i) {
72  out[i] = - val[i];
73  }
74 
75  return out;
76  }
77 
82  template<typename T, typename U, std::size_t N>
83  constexpr
86 
87  for (std::size_t i = 0; i < N; ++i) {
88  out[i] = lhs[i] + rhs[i];
89  }
90 
91  return out;
92  }
93 
98  template<typename T, typename U, std::size_t N>
99  constexpr
101  for (std::size_t i = 0; i < N; ++i) {
102  lhs[i] += rhs[i];
103  }
104 
105  return lhs;
106  }
107 
112  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
113  constexpr
116 
117  for (std::size_t i = 0; i < N; ++i) {
118  out[i] = lhs[i] + rhs;
119  }
120 
121  return out;
122  }
123 
128  template<typename T, typename U, std::size_t N>
129  constexpr
131  for (std::size_t i = 0; i < N; ++i) {
132  lhs[i] += rhs;
133  }
134 
135  return lhs;
136  }
137 
142  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
143  constexpr
146 
147  for (std::size_t i = 0; i < N; ++i) {
148  out[i] = lhs + rhs[i];
149  }
150 
151  return out;
152  }
153 
154 
159  template<typename T, typename U, std::size_t N>
160  constexpr
163 
164  for (std::size_t i = 0; i < N; ++i) {
165  out[i] = lhs[i] - rhs[i];
166  }
167 
168  return out;
169  }
170 
175  template<typename T, typename U, std::size_t N>
176  constexpr
178  for (std::size_t i = 0; i < N; ++i) {
179  lhs[i] -= rhs[i];
180  }
181 
182  return lhs;
183  }
184 
185 
190  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
191  constexpr
194 
195  for (std::size_t i = 0; i < N; ++i) {
196  out[i] = lhs[i] - rhs;
197  }
198 
199  return out;
200  }
201 
206  template<typename T, typename U, std::size_t N>
207  constexpr
209  for (std::size_t i = 0; i < N; ++i) {
210  lhs[i] -= rhs;
211  }
212 
213  return lhs;
214  }
215 
220  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
221  constexpr
224 
225  for (std::size_t i = 0; i < N; ++i) {
226  out[i] = lhs - rhs[i];
227  }
228 
229  return out;
230  }
231 
232 
237  template<typename T, typename U, std::size_t N>
238  constexpr
241 
242  for (std::size_t i = 0; i < N; ++i) {
243  out[i] = lhs[i] * rhs[i];
244  }
245 
246  return out;
247  }
248 
253  template<typename T, typename U, std::size_t N>
254  constexpr
256  for (std::size_t i = 0; i < N; ++i) {
257  lhs[i] *= rhs[i];
258  }
259 
260  return lhs;
261  }
262 
267  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
268  constexpr
271 
272  for (std::size_t i = 0; i < N; ++i) {
273  out[i] = lhs[i] * rhs;
274  }
275 
276  return out;
277  }
278 
283  template<typename T, typename U, std::size_t N>
284  constexpr
286  for (std::size_t i = 0; i < N; ++i) {
287  lhs[i] *= rhs;
288  }
289 
290  return lhs;
291  }
292 
297  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
298  constexpr
301 
302  for (std::size_t i = 0; i < N; ++i) {
303  out[i] = lhs * rhs[i];
304  }
305 
306  return out;
307  }
308 
313  template<typename T, typename U, std::size_t N>
314  constexpr
317 
318  for (std::size_t i = 0; i < N; ++i) {
319  out[i] = lhs[i] / rhs[i];
320  }
321 
322  return out;
323  }
324 
329  template<typename T, typename U, std::size_t N>
330  constexpr
332  for (std::size_t i = 0; i < N; ++i) {
333  lhs[i] /= rhs[i];
334  }
335 
336  return lhs;
337  }
338 
343  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
344  constexpr
347 
348  for (std::size_t i = 0; i < N; ++i) {
349  out[i] = lhs[i] / rhs;
350  }
351 
352  return out;
353  }
354 
359  template<typename T, typename U, std::size_t N>
360  constexpr
362  for (std::size_t i = 0; i < N; ++i) {
363  lhs[i] /= rhs;
364  }
365 
366  return lhs;
367  }
368 
373  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
374  constexpr
377 
378  for (std::size_t i = 0; i < N; ++i) {
379  out[i] = lhs / rhs[i];
380  }
381 
382  return out;
383  }
384 
389  template<std::size_t N>
390  constexpr
393 
394  for (std::size_t i = 0; i < N; ++i) {
395  out[i] = lhs[i] || rhs[i];
396  }
397 
398  return out;
399  }
400 
405  template<std::size_t N>
406  constexpr
409 
410  for (std::size_t i = 0; i < N; ++i) {
411  out[i] = lhs[i] && rhs[i];
412  }
413 
414  return out;
415  }
416 
429  template<typename T, std::size_t N>
430  constexpr
432  T out{0};
433 
434  for (std::size_t i = 0; i < N; ++i) {
435  out += lhs[i] * rhs[i];
436  }
437 
438  return out;
439  }
440 
445  template<typename T, std::size_t N>
446  constexpr
448  Vector<T, N> out = gf::Zero;
449 
450  for (std::size_t i = 0; i < N; ++i) {
451  out[i] = std::min(lhs[i], rhs[i]);
452  }
453 
454  return out;
455  }
456 
461  template<typename T, std::size_t N>
462  constexpr
464  Vector<T, N> out = gf::Zero;
465 
466  for (std::size_t i = 0; i < N; ++i) {
467  out[i] = std::max(lhs[i], rhs[i]);
468  }
469 
470  return out;
471  }
472 
477  template<typename T, std::size_t N>
478  inline
480  Vector<T, N> out;
481 
482  for (std::size_t i = 0; i < N; ++i) {
483  out[i] = std::abs(val[i]);
484  }
485 
486  return out;
487  }
488 
493  template<typename T, std::size_t N>
494  constexpr
496  Vector<int, N> out = gf::Zero;
497 
498  for (std::size_t i = 0; i < N; ++i) {
499  out[i] = gf::sign(val[i]);
500  }
501 
502  return out;
503  }
504 
509  template<typename T, std::size_t N>
510  constexpr
513 
514  for (std::size_t i = 0; i < N; ++i) {
515  out[i] = (lhs[i] == rhs[i]);
516  }
517 
518  return out;
519  }
520 
525  template<typename T, std::size_t N>
526  constexpr
529 
530  for (std::size_t i = 0; i < N; ++i) {
531  out[i] = (lhs[i] < rhs[i]);
532  }
533 
534  return out;
535  }
536 
541  template<typename T, std::size_t N>
542  constexpr
545 
546  for (std::size_t i = 0; i < N; ++i) {
547  out[i] = (lhs[i] > rhs[i]);
548  }
549 
550  return out;
551  }
552 
557  template<typename T, std::size_t N>
558  constexpr
560  Vector<T, N> out = gf::Zero;
561 
562  for (std::size_t i = 0; i < N; ++i) {
563  out[i] = (cond[i] ? lhs[i] : rhs[i]);
564  }
565 
566  return out;
567  }
568 
576  template<typename T, std::size_t N>
577  constexpr
579  Vector<T, N> out = gf::Zero;
580 
581  for (std::size_t i = 0; i < N; ++i) {
582  out[i] = clamp(val[i], lo[i], hi[i]);
583  }
584 
585  return out;
586  }
587 
594  template<typename T, std::size_t N>
595  constexpr
597  Vector<T, N> out = gf::Zero;
598 
599  for (std::size_t i = 0; i < N; ++i) {
600  out[i] = clamp(val[i], lo, hi);
601  }
602 
603  return out;
604  }
605 
610  template<typename T, typename U, std::size_t N>
611  constexpr
613  Vector<T, N> out = gf::Zero;
614 
615  for (std::size_t i = 0; i < N; ++i) {
616  out[i] = lerp(lhs[i], rhs[i], t);
617  }
618 
619  return out;
620  // return (1 - t) * lhs + t * rhs;
621  }
622 
639  template<typename T, std::size_t N>
640  inline
642  T out{0};
643 
644  for (std::size_t i = 0; i < N; ++i) {
645  out += std::abs(vec[i]);
646  }
647 
648  return out;
649  }
650 
665  template<typename T, std::size_t N>
666  inline
668  T out{0};
669 
670  for (std::size_t i = 0; i < N; ++i) {
671  out += square(vec[i]);
672  }
673 
674  return out;
675  }
676 
693  template<typename T, std::size_t N>
694  inline
696  return std::sqrt(squareLength(vec));
697  }
698 
699 #ifndef DOXYGEN_SHOULD_SKIP_THIS
700  // specializations of euclideanLength for Vector2f and Vector2d using std::hypot
701 
702  template<>
703  inline
704  float euclideanLength<float, 2>(Vector<float, 2> vec) {
705  return std::hypot(vec.x, vec.y);
706  }
707 
708  template<>
709  inline
710  double euclideanLength<double, 2>(Vector<double, 2> vec) {
711  return std::hypot(vec.x, vec.y);
712  }
713 #endif
714 
731  template<typename T, std::size_t N>
732  inline
734  T out = std::abs(vec[0]);
735 
736  for (std::size_t i = 1; i < N; ++i) {
737  out = std::max(out, std::abs(vec[i]));
738  }
739 
740  return out;
741  }
742 
760  template<typename T, std::size_t N>
761  inline
763  return manhattanLength(vec) + squareLength(vec);
764  }
765 
779  template<typename T, std::size_t N>
780  inline
782  return manhattanLength(lhs - rhs);
783  }
784 
798  template<typename T, std::size_t N>
799  inline
801  return squareLength(lhs - rhs);
802  }
803 
817  template<typename T, std::size_t N>
818  inline
820  return euclideanLength(lhs - rhs);
821  }
822 
836  template<typename T, std::size_t N>
837  inline
839  return chebyshevLength(lhs - rhs);
840  }
841 
855  template<typename T, std::size_t N>
856  inline
858  return naturalLength(lhs - rhs);
859  }
860 
876  template<typename T, std::size_t N>
877  inline
879  T length = euclideanLength(vec);
880  return vec / length;
881  }
882 
890  template<typename T>
891  inline
893  return { std::cos(angle), std::sin(angle) };
894  }
895 
903  template<typename T>
904  inline
905  float angle(Vector<T, 2> vec) {
906  return std::atan2(vec.y, vec.x);
907  }
908 
920  template<typename T>
921  constexpr
923  return { -vec.y, vec.x };
924  }
925 
939  template<typename T>
940  constexpr
942  return dot(a, c) * b - dot(a, b) * c;
943  }
944 
959  template<typename T>
960  constexpr
962  return - dot(c, b) * a + dot(c, a) * b;
963  }
964 
982  template<typename T>
983  constexpr
985  return lhs.x * rhs.y - lhs.y * rhs.x;
986  }
987 
988 
997  template<typename T>
998  constexpr
1000  return {
1001  lhs.y * rhs.z - lhs.z * rhs.y,
1002  lhs.z * rhs.x - lhs.x * rhs.z,
1003  lhs.x * rhs.y - lhs.y * rhs.x
1004  };
1005  }
1006 
1007 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1008 }
1009 #endif
1010 }
1011 
1012 #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:543
constexpr Vector< T, N > max(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise maximum.
Definition: VectorOps.h:463
T euclideanLength(Vector< T, N > vec)
Euclidean length of a vector.
Definition: VectorOps.h:695
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:375
constexpr T dot(Vector< T, N > lhs, Vector< T, N > rhs)
Scalar product.
Definition: VectorOps.h:431
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:559
constexpr Vector< std::common_type_t< T, U >, N > operator*(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise multiplication.
Definition: VectorOps.h:239
constexpr Vector< T, 3 > cross(Vector< T, 3 > lhs, Vector< T, 3 > rhs)
Cross product for 3D vectors.
Definition: VectorOps.h:999
constexpr Vector< std::common_type_t< T, U >, N > operator-(T lhs, Vector< U, N > rhs)
Left scalar substraction.
Definition: VectorOps.h:222
constexpr Vector< std::common_type_t< T, U >, N > operator/(Vector< T, N > lhs, U rhs)
Right scalar division.
Definition: VectorOps.h:345
constexpr Vector< T, N > & operator+=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise addition and assignment.
Definition: VectorOps.h:100
constexpr Vector< std::common_type_t< T, U >, N > operator/(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise division.
Definition: VectorOps.h:315
constexpr Vector< std::common_type_t< T, U >, N > operator+(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise addition.
Definition: VectorOps.h:84
constexpr bool operator!=(Vector< T, N > lhs, Vector< T, N > rhs)
Inequality operator between two vectors.
Definition: VectorOps.h:58
constexpr Vector< T, N > & operator*=(Vector< T, N > &lhs, U rhs)
Right scalar multiplication and assignment.
Definition: VectorOps.h:285
constexpr Vector< T, 2 > vectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Regular vector triple product.
Definition: VectorOps.h:941
Vector< T, N > normalize(Vector< T, N > vec)
Normalize a vector.
Definition: VectorOps.h:878
constexpr Vector< T, N > & operator-=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise substraction and assignment.
Definition: VectorOps.h:177
constexpr Vector< T, 2 > inverseVectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Inverse vector triple product.
Definition: VectorOps.h:961
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:612
constexpr Vector< T, N > & operator+=(Vector< T, N > &lhs, U rhs)
Right scalar addition and assignment.
Definition: VectorOps.h:130
constexpr Vector< std::common_type_t< T, U >, N > operator+(T lhs, Vector< U, N > rhs)
Left scalar addition.
Definition: VectorOps.h:144
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:905
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:161
constexpr Vector< T, N > & operator/=(Vector< T, N > &lhs, U rhs)
Right scalar division and assignment.
Definition: VectorOps.h:361
T squareDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Square Euclidean distance between two vectors.
Definition: VectorOps.h:800
constexpr bool operator==(Vector< T, N > lhs, Vector< T, N > rhs)
Equality operator between two vectors.
Definition: VectorOps.h:42
constexpr Vector< bool, N > lessThan(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise comparison operator.
Definition: VectorOps.h:527
constexpr Vector< T, N > & operator*=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise multiplication and assignment.
Definition: VectorOps.h:255
constexpr Vector< bool, N > equals(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise equality operator.
Definition: VectorOps.h:511
constexpr Vector< std::common_type_t< T, U >, N > operator-(Vector< T, N > lhs, U rhs)
Right scalar substraction.
Definition: VectorOps.h:192
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:68
Vector< T, 2 > unit(T angle)
Unit vector in a specified direction.
Definition: VectorOps.h:892
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:447
constexpr Vector< T, N > & operator/=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise division and assignment.
Definition: VectorOps.h:331
constexpr Vector< std::common_type_t< T, U >, N > operator*(Vector< T, N > lhs, U rhs)
Right scalar multiplication.
Definition: VectorOps.h:269
constexpr Vector< T, N > clamp(Vector< T, N > val, T lo, T hi)
Component-wise clamp function.
Definition: VectorOps.h:596
T manhattanDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Manhattan distance between two vectors.
Definition: VectorOps.h:781
constexpr Vector< bool, N > operator||(Vector< bool, N > lhs, Vector< bool, N > rhs)
Component-wise logical or operator.
Definition: VectorOps.h:391
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:733
T euclideanDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Euclidean distance between two vectors.
Definition: VectorOps.h:819
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:641
constexpr Vector< T, N > clamp(Vector< T, N > val, Vector< T, N > lo, Vector< T, N > hi)
Component-wise clamp function.
Definition: VectorOps.h:578
Vector< T, N > abs(Vector< T, N > val)
Component-wise absolute value.
Definition: VectorOps.h:479
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:299
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:922
constexpr Vector< int, N > sign(Vector< T, N > val)
Component-wise sign value.
Definition: VectorOps.h:495
T naturalDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Natural distance between two vectors.
Definition: VectorOps.h:857
T naturalLength(Vector< T, N > vec)
Natural length of a vector.
Definition: VectorOps.h:762
constexpr Vector< T, N > & operator-=(Vector< T, N > &lhs, U rhs)
Right scalar substraction and assignment.
Definition: VectorOps.h:208
T squareLength(Vector< T, N > vec)
Square Euclidean length of a vector.
Definition: VectorOps.h:667
constexpr Vector< std::common_type_t< T, U >, N > operator+(Vector< T, N > lhs, U rhs)
Right scalar addition.
Definition: VectorOps.h:114
constexpr T cross(Vector< T, 2 > lhs, Vector< T, 2 > rhs)
Cross product for 2D vectors.
Definition: VectorOps.h:984
T chebyshevDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Chebyshev distance between two vectors.
Definition: VectorOps.h:838