Gamedev Framework (gf) 0.21.0
A C++17 framework for 2D games
VectorOps.h
1/*
2 * Gamedev Framework (gf)
3 * Copyright (C) 2016-2021 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
32namespace gf {
33#ifndef DOXYGEN_SHOULD_SKIP_THIS
34inline 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
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
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
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
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
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
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
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
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
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
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
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
597 Vector<T, N> clamp(Vector<T, N> val, T lo, T hi) {
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 constexpr
894 return { vec.x, T(0) };
895 }
896
904 template<typename T>
905 constexpr
907 return { T(0), vec.y };
908 }
909
917 template<typename T>
918 constexpr
919 Vector<T, 2> dirx(T length) {
920 return { length, T(0) };
921 }
922
930 template<typename T>
931 constexpr
932 Vector<T, 2> diry(T length) {
933 return { T(0), length };
934 }
935
943 template<typename T>
944 inline
946 return { std::cos(angle), std::sin(angle) };
947 }
948
956 template<typename T>
957 inline
958 float angle(Vector<T, 2> vec) {
959 return std::atan2(vec.y, vec.x);
960 }
961
973 template<typename T>
974 constexpr
976 return { -vec.y, vec.x };
977 }
978
992 template<typename T>
993 constexpr
995 return dot(a, c) * b - dot(a, b) * c;
996 }
997
1012 template<typename T>
1013 constexpr
1015 return - dot(c, b) * a + dot(c, a) * b;
1016 }
1017
1035 template<typename T>
1036 constexpr
1038 return lhs.x * rhs.y - lhs.y * rhs.x;
1039 }
1040
1041
1050 template<typename T>
1051 constexpr
1053 return {
1054 lhs.y * rhs.z - lhs.z * rhs.y,
1055 lhs.z * rhs.x - lhs.x * rhs.z,
1056 lhs.x * rhs.y - lhs.y * rhs.x
1057 };
1058 }
1059
1060
1069 template<typename Archive, typename T, std::size_t N>
1070 inline
1071 Archive& operator|(Archive& ar, Vector<T,N>& vec) {
1072 for (std::size_t i = 0; i < N; ++i) {
1073 ar | vec[i];
1074 }
1075
1076 return ar;
1077 }
1078
1079#ifndef DOXYGEN_SHOULD_SKIP_THIS
1080}
1081#endif
1082}
1083
1084#endif // GF_VECTOR_OPS_H
GF_CORE_API float angle(Direction direction)
Get an angle from a direction.
constexpr T square(T val)
Square function.
Definition: Math.h:299
constexpr int sign(T val)
Sign function.
Definition: Math.h:334
constexpr T clamp(T val, T lo, T hi)
Clamping function.
Definition: Math.h:284
constexpr T lerp(T lhs, T rhs, U t)
Linear interpolation function.
Definition: Math.h:266
The namespace for gf classes.
Definition: Action.h:35
template struct GF_CORE_API Vector< double, 2 >
A 2D vector.
Definition: Vector.h:316
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:525
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:514
A 3D vector.
Definition: Vector.h:570
T x
First coordinate in the (x,y,z) representation.
Definition: Vector.h:794
T z
Third coordinate in the (x,y,z) representation.
Definition: Vector.h:810
T y
Second coordinate in the (x,y,z) representation.
Definition: Vector.h:802
General purpose math vector.
Definition: Vector.h:61
constexpr Vector< T, 2 > projx(Vector< T, 2 > vec)
Project the vector on the x axis.
Definition: VectorOps.h:893
Archive & operator|(Archive &ar, Vector< T, N > &vec)
Serialize and deserialize a vector.
Definition: VectorOps.h:1071
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 Vector< T, N > max(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise maximum.
Definition: VectorOps.h:464
constexpr Vector< T, N > & operator+=(Vector< T, N > &lhs, U rhs)
Right scalar addition and assignment.
Definition: VectorOps.h:131
T manhattanLength(Vector< T, N > vec)
Manhattan length of a vector.
Definition: VectorOps.h:642
float angle(Vector< T, 2 > vec)
Angle of a vector relative to the x-axis.
Definition: VectorOps.h:958
T squareLength(Vector< T, N > vec)
Square Euclidean length of a vector.
Definition: VectorOps.h:668
constexpr Vector< T, 2 > perp(Vector< T, 2 > vec)
Perpendicular vector.
Definition: VectorOps.h:975
Vector< T, 2 > unit(T angle)
Unit vector in a specified direction.
Definition: VectorOps.h:945
T euclideanDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Euclidean distance between two vectors.
Definition: VectorOps.h:820
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 > select(Vector< bool, N > cond, Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise selection operator.
Definition: VectorOps.h:560
constexpr bool operator!=(Vector< T, N > lhs, Vector< T, N > rhs)
Inequality operator between two vectors.
Definition: VectorOps.h:59
constexpr bool operator==(Vector< T, N > lhs, Vector< T, N > rhs)
Equality operator between two vectors.
Definition: VectorOps.h:43
constexpr Vector< T, N > & operator-=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise substraction and assignment.
Definition: VectorOps.h:178
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 > min(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise minimum.
Definition: VectorOps.h:448
constexpr Vector< T, N > operator-(Vector< T, N > val)
Component-wise unary minus.
Definition: VectorOps.h:69
constexpr Vector< T, N > clamp(Vector< T, N > val, T lo, T hi)
Component-wise clamp function.
Definition: VectorOps.h:597
constexpr Vector< std::common_type_t< T, U >, N > operator*(T lhs, Vector< U, N > rhs)
Left scalar multiplication.
Definition: VectorOps.h:300
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< std::common_type_t< T, U >, N > operator/(T lhs, Vector< U, N > rhs)
Left scalar division.
Definition: VectorOps.h:376
constexpr Vector< T, N > & operator*=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise multiplication and assignment.
Definition: VectorOps.h:256
Vector< T, N > normalize(Vector< T, N > vec)
Normalize a vector.
Definition: VectorOps.h:879
constexpr Vector< T, N > & operator-=(Vector< T, N > &lhs, U rhs)
Right scalar substraction and assignment.
Definition: VectorOps.h:209
constexpr Vector< T, 2 > projy(Vector< T, 2 > vec)
Project the vector on the y axis.
Definition: VectorOps.h:906
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
T euclideanLength(Vector< T, N > vec)
Euclidean length of a vector.
Definition: VectorOps.h:696
constexpr Vector< bool, N > equals(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise equality operator.
Definition: VectorOps.h:512
constexpr Vector< T, 2 > diry(T length)
Create a vector in the y direction.
Definition: VectorOps.h:932
Vector< T, N > abs(Vector< T, N > val)
Component-wise absolute value.
Definition: VectorOps.h:480
constexpr T dot(Vector< T, N > lhs, Vector< T, N > rhs)
Scalar product.
Definition: VectorOps.h:432
constexpr Vector< std::common_type_t< T, U >, N > operator-(T lhs, Vector< U, N > rhs)
Left scalar substraction.
Definition: VectorOps.h:223
T squareDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Square Euclidean distance between two vectors.
Definition: VectorOps.h:801
constexpr Vector< T, N > & operator*=(Vector< T, N > &lhs, U rhs)
Right scalar multiplication and assignment.
Definition: VectorOps.h:286
constexpr Vector< T, N > & operator+=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise addition and assignment.
Definition: VectorOps.h:101
T chebyshevDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Chebyshev distance between two vectors.
Definition: VectorOps.h:839
constexpr Vector< bool, N > operator||(Vector< bool, N > lhs, Vector< bool, N > rhs)
Component-wise logical or operator.
Definition: VectorOps.h:392
constexpr Vector< bool, N > lessThan(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise comparison operator.
Definition: VectorOps.h:528
constexpr Vector< T, 2 > vectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Regular vector triple product.
Definition: VectorOps.h:994
T naturalLength(Vector< T, N > vec)
Natural length of a vector.
Definition: VectorOps.h:763
T naturalDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Natural distance between two vectors.
Definition: VectorOps.h:858
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 > clamp(Vector< T, N > val, Vector< T, N > lo, Vector< T, N > hi)
Component-wise clamp function.
Definition: VectorOps.h:579
T chebyshevLength(Vector< T, N > vec)
Chebyshev length of a vector.
Definition: VectorOps.h:734
constexpr Vector< int, N > sign(Vector< T, N > val)
Component-wise sign value.
Definition: VectorOps.h:496
T manhattanDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Manhattan distance between two vectors.
Definition: VectorOps.h:782
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< T, N > & operator/=(Vector< T, N > &lhs, U rhs)
Right scalar division and assignment.
Definition: VectorOps.h:362
constexpr Vector< bool, N > operator&&(Vector< bool, N > lhs, Vector< bool, N > rhs)
Component-wise logical and operator.
Definition: VectorOps.h:408
constexpr Vector< T, 2 > dirx(T length)
Create a vector in the x direction.
Definition: VectorOps.h:919
constexpr Vector< std::common_type_t< T, U >, N > operator-(Vector< T, N > lhs, U rhs)
Right scalar substraction.
Definition: VectorOps.h:193
constexpr Vector< bool, N > greaterThan(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise comparison operator.
Definition: VectorOps.h:544
constexpr T cross(Vector< T, 2 > lhs, Vector< T, 2 > rhs)
Cross product for 2D vectors.
Definition: VectorOps.h:1037
constexpr Vector< T, 3 > cross(Vector< T, 3 > lhs, Vector< T, 3 > rhs)
Cross product for 3D vectors.
Definition: VectorOps.h:1052
constexpr Vector< T, N > & operator/=(Vector< T, N > &lhs, Vector< U, N > rhs)
Component-wise division and assignment.
Definition: VectorOps.h:332
constexpr Vector< T, 2 > inverseVectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Inverse vector triple product.
Definition: VectorOps.h:1014
constexpr Vector< std::common_type_t< T, U >, N > operator+(T lhs, Vector< U, N > rhs)
Left scalar addition.
Definition: VectorOps.h:145
constexpr Vector< std::common_type_t< T, U >, N > operator+(Vector< T, N > lhs, U rhs)
Right scalar addition.
Definition: VectorOps.h:115