Gamedev Framework (gf)  0.5.0
A C++11 framework for 2D games
VectorOps.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2017 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  inline
43  for (std::size_t i = 0; i < N; ++i) {
44  if (lhs.data[i] != rhs.data[i]) {
45  return false;
46  }
47  }
48 
49  return true;
50  }
51 
56  template<typename T, std::size_t N>
57  inline
59  return !(lhs == rhs);
60  }
61 
66  template<typename T, std::size_t N>
67  inline
69  Vector<T, N> out;
70 
71  for (std::size_t i = 0; i < N; ++i) {
72  out.data[i] = - val.data[i];
73  }
74 
75  return out;
76  }
77 
82  template<typename T, typename U, std::size_t N>
83  inline
86 
87  for (std::size_t i = 0; i < N; ++i) {
88  out.data[i] = lhs.data[i] + rhs.data[i];
89  }
90 
91  return out;
92  }
93 
98  template<typename T, typename U, std::size_t N>
99  inline
101  for (std::size_t i = 0; i < N; ++i) {
102  lhs.data[i] += rhs.data[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  inline
116 
117  for (std::size_t i = 0; i < N; ++i) {
118  out.data[i] = lhs.data[i] + rhs;
119  }
120 
121  return out;
122  }
123 
128  template<typename T, typename U, std::size_t N>
129  inline
131  for (std::size_t i = 0; i < N; ++i) {
132  lhs.data[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  inline
146 
147  for (std::size_t i = 0; i < N; ++i) {
148  out.data[i] = lhs + rhs.data[i];
149  }
150 
151  return out;
152  }
153 
154 
159  template<typename T, typename U, std::size_t N>
160  inline
163 
164  for (std::size_t i = 0; i < N; ++i) {
165  out.data[i] = lhs.data[i] - rhs.data[i];
166  }
167 
168  return out;
169  }
170 
175  template<typename T, typename U, std::size_t N>
176  inline
178  for (std::size_t i = 0; i < N; ++i) {
179  lhs.data[i] -= rhs.data[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  inline
194 
195  for (std::size_t i = 0; i < N; ++i) {
196  out.data[i] = lhs.data[i] - rhs;
197  }
198 
199  return out;
200  }
201 
206  template<typename T, typename U, std::size_t N>
207  inline
209  for (std::size_t i = 0; i < N; ++i) {
210  lhs.data[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  inline
224 
225  for (std::size_t i = 0; i < N; ++i) {
226  out.data[i] = lhs - rhs.data[i];
227  }
228 
229  return out;
230  }
231 
232 
237  template<typename T, typename U, std::size_t N>
238  inline
241 
242  for (std::size_t i = 0; i < N; ++i) {
243  out.data[i] = lhs.data[i] * rhs.data[i];
244  }
245 
246  return out;
247  }
248 
253  template<typename T, typename U, std::size_t N>
254  inline
256  for (std::size_t i = 0; i < N; ++i) {
257  lhs.data[i] *= rhs.data[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  inline
271 
272  for (std::size_t i = 0; i < N; ++i) {
273  out.data[i] = lhs.data[i] * rhs;
274  }
275 
276  return out;
277  }
278 
283  template<typename T, typename U, std::size_t N>
284  inline
286  for (std::size_t i = 0; i < N; ++i) {
287  lhs.data[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  inline
301 
302  for (std::size_t i = 0; i < N; ++i) {
303  out.data[i] = lhs * rhs.data[i];
304  }
305 
306  return out;
307  }
308 
313  template<typename T, typename U, std::size_t N>
314  inline
317 
318  for (std::size_t i = 0; i < N; ++i) {
319  out.data[i] = lhs.data[i] / rhs.data[i];
320  }
321 
322  return out;
323  }
324 
329  template<typename T, typename U, std::size_t N>
330  inline
332  for (std::size_t i = 0; i < N; ++i) {
333  lhs.data[i] /= rhs.data[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  inline
347 
348  for (std::size_t i = 0; i < N; ++i) {
349  out.data[i] = lhs.data[i] / rhs;
350  }
351 
352  return out;
353  }
354 
359  template<typename T, typename U, std::size_t N>
360  inline
362  for (std::size_t i = 0; i < N; ++i) {
363  lhs.data[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  inline
377 
378  for (std::size_t i = 0; i < N; ++i) {
379  out.data[i] = lhs / rhs.data[i];
380  }
381 
382  return out;
383  }
384 
389  template<std::size_t N>
390  inline
392  Vector<bool, N> out;
393 
394  for (std::size_t i = 0; i < N; ++i) {
395  out.data[i] = lhs.data[i] || rhs.data[i];
396  }
397 
398  return out;
399  }
400 
405  template<std::size_t N>
406  inline
408  Vector<bool, N> out;
409 
410  for (std::size_t i = 0; i < N; ++i) {
411  out.data[i] = lhs.data[i] && rhs.data[i];
412  }
413 
414  return out;
415  }
416 
429  template<typename T, std::size_t N>
430  inline
432  T out{0};
433 
434  for (std::size_t i = 0; i < N; ++i) {
435  out += lhs.data[i] * rhs.data[i];
436  }
437 
438  return out;
439  }
440 
445  template<typename T, std::size_t N>
446  inline
448  Vector<T, N> out;
449 
450  for (std::size_t i = 0; i < N; ++i) {
451  out.data[i] = std::min(lhs.data[i], rhs.data[i]);
452  }
453 
454  return out;
455  }
456 
461  template<typename T, std::size_t N>
462  inline
464  Vector<T, N> out;
465 
466  for (std::size_t i = 0; i < N; ++i) {
467  out.data[i] = std::max(lhs.data[i], rhs.data[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.data[i] = std::abs(val.data[i]);
484  }
485 
486  return out;
487  }
488 
489 
494  template<typename T, std::size_t N>
495  inline
497  Vector<bool, N> out;
498 
499  for (std::size_t i = 0; i < N; ++i) {
500  out.data[i] = (lhs.data[i] == rhs.data[i]);
501  }
502 
503  return out;
504  }
505 
510  template<typename T, std::size_t N>
511  inline
513  Vector<bool, N> out;
514 
515  for (std::size_t i = 0; i < N; ++i) {
516  out.data[i] = (lhs.data[i] < rhs.data[i]);
517  }
518 
519  return out;
520  }
521 
526  template<typename T, std::size_t N>
527  inline
529  Vector<bool, N> out;
530 
531  for (std::size_t i = 0; i < N; ++i) {
532  out.data[i] = (lhs.data[i] > rhs.data[i]);
533  }
534 
535  return out;
536  }
537 
542  template<typename T, std::size_t N>
543  inline
545  Vector<T, N> out;
546 
547  for (std::size_t i = 0; i < N; ++i) {
548  out.data[i] = (cond.data[i] ? lhs.data[i] : rhs.data[i]);
549  }
550 
551  return out;
552  }
553 
561  template<typename T, std::size_t N>
562  inline
564  Vector<T, N> out;
565 
566  for (std::size_t i = 0; i < N; ++i) {
567  out.data[i] = clamp(val.data[i], lo.data[i], hi.data[i]);
568  }
569 
570  return out;
571  }
572 
579  template<typename T, std::size_t N>
580  inline
582  Vector<T, N> out;
583 
584  for (std::size_t i = 0; i < N; ++i) {
585  out.data[i] = clamp(val.data[i], lo, hi);
586  }
587 
588  return out;
589  }
590 
595  template<typename T, typename U, std::size_t N>
596  inline
598  Vector<T, N> out;
599 
600  for (std::size_t i = 0; i < N; ++i) {
601  out.data[i] = lerp(lhs.data[i], rhs.data[i], t);
602  }
603 
604  return out;
605  // return (1 - t) * lhs + t * rhs;
606  }
607 
624  template<typename T, std::size_t N>
625  inline
627  T out{0};
628 
629  for (std::size_t i = 0; i < N; ++i) {
630  out += std::abs(vec.data[i]);
631  }
632 
633  return out;
634  }
635 
650  template<typename T, std::size_t N>
651  inline
653  T out{0};
654 
655  for (std::size_t i = 0; i < N; ++i) {
656  out += square(vec.data[i]);
657  }
658 
659  return out;
660  }
661 
678  template<typename T, std::size_t N>
679  inline
681  return std::sqrt(squareLength(vec));
682  }
683 
684 #ifndef DOXYGEN_SHOULD_SKIP_THIS
685  // specializations of euclideanLength for Vector2f and Vector2d using std::hypot
686 
687  template<>
688  inline
689  float euclideanLength<float, 2>(Vector<float, 2> vec) {
690  return std::hypot(vec.x, vec.y);
691  }
692 
693  template<>
694  inline
695  double euclideanLength<double, 2>(Vector<double, 2> vec) {
696  return std::hypot(vec.x, vec.y);
697  }
698 #endif
699 
716  template<typename T, std::size_t N>
717  inline
719  T out = std::abs(vec.data[0]);
720 
721  for (std::size_t i = 1; i < N; ++i) {
722  out = std::max(out, std::abs(vec.data[i]));
723  }
724 
725  return out;
726  }
727 
745  template<typename T, std::size_t N>
746  inline
748  return manhattanLength(vec) + squareLength(vec);
749  }
750 
764  template<typename T, std::size_t N>
765  inline
767  return manhattanLength(lhs - rhs);
768  }
769 
783  template<typename T, std::size_t N>
784  inline
786  return squareLength(lhs - rhs);
787  }
788 
802  template<typename T, std::size_t N>
803  inline
805  return euclideanLength(lhs - rhs);
806  }
807 
821  template<typename T, std::size_t N>
822  inline
824  return chebyshevLength(lhs - rhs);
825  }
826 
840  template<typename T, std::size_t N>
841  inline
843  return naturalLength(lhs - rhs);
844  }
845 
861  template<typename T, std::size_t N>
862  inline
864  T length = euclideanLength(vec);
865  return vec / length;
866  }
867 
875  template<typename T>
876  inline
878  return { std::cos(angle), std::sin(angle) };
879  }
880 
888  template<typename T>
889  inline
890  float angle(Vector<T, 2> vec) {
891  return std::atan2(vec.y, vec.x);
892  }
893 
905  template<typename T>
906  constexpr
908  return { -vec.y, vec.x };
909  }
910 
924  template<typename T>
925  inline
927  return dot(a, c) * b - dot(a, b) * c;
928  }
929 
944  template<typename T>
945  inline
947  return - dot(c, b) * a + dot(c, a) * b;
948  }
949 
967  template<typename T>
968  constexpr
970  return lhs.x * rhs.y - lhs.y * rhs.x;
971  }
972 
973 
982  template<typename T>
983  constexpr
985  return {
986  lhs.y * rhs.z - lhs.z * rhs.y,
987  lhs.z * rhs.x - lhs.x * rhs.z,
988  lhs.x * rhs.y - lhs.y * rhs.x
989  };
990  }
991 
992 #ifndef DOXYGEN_SHOULD_SKIP_THIS
993 }
994 #endif
995 }
996 
997 #endif // GF_VECTOR_OPS_H
Vector< typename std::common_type< T, U >::type, N > operator/(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise division.
Definition: VectorOps.h:315
Vector< T, N > & operator+=(Vector< T, N > &lhs, U rhs)
Right scalar addition and assignment.
Definition: VectorOps.h:130
Vector< typename std::common_type< T, U >::type, N > operator+(Vector< T, N > lhs, U rhs)
Right scalar addition.
Definition: VectorOps.h:114
T euclideanLength(Vector< T, N > vec)
Euclidean length of a vector.
Definition: VectorOps.h:680
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:470
Vector< typename std::common_type< T, U >::type, N > operator*(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise multiplication.
Definition: VectorOps.h:239
Vector< typename std::common_type< T, U >::type, N > operator/(T lhs, Vector< U, N > rhs)
Left scalar division.
Definition: VectorOps.h:375
Vector< T, N > clamp(Vector< T, N > val, Vector< T, N > lo, Vector< T, N > hi)
Component-wise clamp function.
Definition: VectorOps.h:563
Vector< bool, N > greaterThan(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise comparison operator.
Definition: VectorOps.h:528
constexpr Vector< T, 3 > cross(Vector< T, 3 > lhs, Vector< T, 3 > rhs)
Cross product for 3D vectors.
Definition: VectorOps.h:984
Vector< T, 2 > vectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Regular vector triple product.
Definition: VectorOps.h:926
Vector< T, N > & operator/=(Vector< T, N > &lhs, U rhs)
Right scalar division and assignment.
Definition: VectorOps.h:361
Vector< typename std::common_type< T, U >::type, N > operator-(Vector< T, N > lhs, U rhs)
Right scalar substraction.
Definition: VectorOps.h:192
Vector< typename std::common_type< T, U >::type, N > operator+(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise addition.
Definition: VectorOps.h:84
T lerp(T lhs, T rhs, U t)
Linear interpolation function.
Definition: Math.h:242
Vector< bool, N > equals(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise equality operator.
Definition: VectorOps.h:496
Vector< T, N > normalize(Vector< T, N > vec)
Normalize a vector.
Definition: VectorOps.h:863
Vector< T, N > & operator+=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise addition and assignment.
Definition: VectorOps.h:100
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:471
T x
First coordinate in the (x,y,z) representation.
Definition: Vector.h:717
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:890
constexpr T clamp(T val, T lo, T hi)
Clamping function.
Definition: Math.h:260
T data[N]
The internal representation of the vector.
Definition: Vector.h:251
T squareDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Square Euclidean distance between two vectors.
Definition: VectorOps.h:785
Vector< bool, N > lessThan(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise comparison operator.
Definition: VectorOps.h:512
Vector< T, N > select(Vector< bool, N > cond, Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise selection operator.
Definition: VectorOps.h:544
Vector< T, N > min(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise minimum.
Definition: VectorOps.h:447
Vector< typename std::common_type< T, U >::type, N > operator*(Vector< T, N > lhs, U rhs)
Right scalar multiplication.
Definition: VectorOps.h:269
Vector< typename std::common_type< T, U >::type, N > operator+(T lhs, Vector< U, N > rhs)
Left scalar addition.
Definition: VectorOps.h:144
Vector< T, N > & operator-=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise substraction and assignment.
Definition: VectorOps.h:177
The namespace for gf classes.
Definition: Action.h:34
Vector< T, N > clamp(Vector< T, N > val, T lo, T hi)
Component-wise clamp function.
Definition: VectorOps.h:581
Vector< T, 2 > unit(T angle)
Unit vector in a specified direction.
Definition: VectorOps.h:877
float angle(Direction direction)
Get an angle from a direction.
bool operator==(Vector< T, N > lhs, Vector< T, N > rhs)
Equality operator between two vectors.
Definition: VectorOps.h:42
Vector< bool, N > operator||(Vector< bool, N > lhs, Vector< bool, N > rhs)
Component-wise logical or operator.
Definition: VectorOps.h:391
Vector< typename std::common_type< T, U >::type, N > operator*(T lhs, Vector< U, N > rhs)
Left scalar multiplication.
Definition: VectorOps.h:299
Vector< T, N > & operator-=(Vector< T, N > &lhs, U rhs)
Right scalar substraction and assignment.
Definition: VectorOps.h:208
Vector< T, N > operator-(Vector< T, N > val)
Component-wise unary minus.
Definition: VectorOps.h:68
T manhattanDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Manhattan distance between two vectors.
Definition: VectorOps.h:766
Vector< typename std::common_type< T, U >::type, N > operator/(Vector< T, N > lhs, U rhs)
Right scalar division.
Definition: VectorOps.h:345
A 2D vector.
Definition: Vector.h:298
T y
Second coordinate in the (x,y,z) representation.
Definition: Vector.h:718
T chebyshevLength(Vector< T, N > vec)
Chebyshev length of a vector.
Definition: VectorOps.h:718
T euclideanDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Euclidean distance between two vectors.
Definition: VectorOps.h:804
Vector< T, N > & operator*=(Vector< T, N > &lhs, U rhs)
Right scalar multiplication and assignment.
Definition: VectorOps.h:285
Vector< T, N > lerp(Vector< T, N > lhs, Vector< T, N > rhs, U t)
Component-wise lerp function.
Definition: VectorOps.h:597
T manhattanLength(Vector< T, N > vec)
Manhattan length of a vector.
Definition: VectorOps.h:626
Vector< T, N > max(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise maximum.
Definition: VectorOps.h:463
Vector< T, N > & operator/=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise division and assignment.
Definition: VectorOps.h:331
Vector< T, 2 > inverseVectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Inverse vector triple product.
Definition: VectorOps.h:946
Vector< typename std::common_type< T, U >::type, N > operator-(Vector< T, N > lhs, Vector< U, N > rhs)
Component-wise substraction.
Definition: VectorOps.h:161
Vector< T, N > abs(Vector< T, N > val)
Component-wise absolute value.
Definition: VectorOps.h:479
A 3D vector.
Definition: Vector.h:530
General purpose math vector.
Definition: Vector.h:60
T z
Third coordinate in the (x,y,z) representation.
Definition: Vector.h:719
Vector< typename std::common_type< T, U >::type, N > operator-(T lhs, Vector< U, N > rhs)
Left scalar substraction.
Definition: VectorOps.h:222
constexpr Vector< T, 2 > perp(Vector< T, 2 > vec)
Perpendicular vector.
Definition: VectorOps.h:907
Vector< T, N > & operator*=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise multiplication and assignment.
Definition: VectorOps.h:255
T naturalDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Natural distance between two vectors.
Definition: VectorOps.h:842
T naturalLength(Vector< T, N > vec)
Natural length of a vector.
Definition: VectorOps.h:747
T squareLength(Vector< T, N > vec)
Square Euclidean length of a vector.
Definition: VectorOps.h:652
T dot(Vector< T, N > lhs, Vector< T, N > rhs)
Scalar product.
Definition: VectorOps.h:431
bool operator!=(Vector< T, N > lhs, Vector< T, N > rhs)
Inequality operator between two vectors.
Definition: VectorOps.h:58
constexpr T cross(Vector< T, 2 > lhs, Vector< T, 2 > rhs)
Cross product for 2D vectors.
Definition: VectorOps.h:969
T chebyshevDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Chebyshev distance between two vectors.
Definition: VectorOps.h:823