Gamedev Framework (gf)  0.3.0
A C++11 framework for 2D games
VectorOps.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_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 
36  /**
37  * @relates Vector
38  * @brief Equality operator between two vectors
39  */
40  template<typename T, std::size_t N>
41  inline
42  bool operator==(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
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 
52  /**
53  * @relates Vector
54  * @brief Inequality operator between two vectors
55  */
56  template<typename T, std::size_t N>
57  inline
58  bool operator!=(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
59  return !(lhs == rhs);
60  }
61 
62  /**
63  * @relates Vector
64  * @brief Component-wise unary minus
65  */
66  template<typename T, std::size_t N>
67  inline
68  Vector<T, N> operator-(const Vector<T, N>& val) {
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 
78  /**
79  * @relates Vector
80  * @brief Component-wise addition
81  */
82  template<typename T, typename U, std::size_t N>
83  inline
84  Vector<typename std::common_type<T,U>::type, N> operator+(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
85  Vector<typename std::common_type<T,U>::type, N> out;
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 
94  /**
95  * @relates Vector
96  * @brief Component-wise addition and assignment
97  */
98  template<typename T, typename U, std::size_t N>
99  inline
100  Vector<T, N>& operator+=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
101  for (std::size_t i = 0; i < N; ++i) {
102  lhs.data[i] += rhs.data[i];
103  }
104 
105  return lhs;
106  }
107 
108  /**
109  * @relates Vector
110  * @brief Right scalar addition
111  */
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
114  Vector<typename std::common_type<T,U>::type, N> operator+(const Vector<T, N>& lhs, U rhs) {
115  Vector<typename std::common_type<T,U>::type, N> out;
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 
124  /**
125  * @relates Vector
126  * @brief Left scalar addition
127  */
128  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
129  inline
130  Vector<typename std::common_type<T,U>::type, N> operator+(T lhs, const Vector<U, N>& rhs) {
131  Vector<typename std::common_type<T,U>::type, N> out;
132 
133  for (std::size_t i = 0; i < N; ++i) {
134  out.data[i] = lhs + rhs.data[i];
135  }
136 
137  return out;
138  }
139 
140 
141  /**
142  * @relates Vector
143  * @brief Component-wise substraction
144  */
145  template<typename T, typename U, std::size_t N>
146  inline
147  Vector<typename std::common_type<T,U>::type, N> operator-(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
148  Vector<typename std::common_type<T,U>::type, N> out;
149 
150  for (std::size_t i = 0; i < N; ++i) {
151  out.data[i] = lhs.data[i] - rhs.data[i];
152  }
153 
154  return out;
155  }
156 
157  /**
158  * @relates Vector
159  * @brief Component-wise substraction and assignment
160  */
161  template<typename T, typename U, std::size_t N>
162  inline
163  Vector<T, N>& operator-=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
164  for (std::size_t i = 0; i < N; ++i) {
165  lhs.data[i] -= rhs.data[i];
166  }
167 
168  return lhs;
169  }
170 
171 
172  /**
173  * @relates Vector
174  * @brief Right scalar substraction
175  */
176  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
177  inline
178  Vector<typename std::common_type<T,U>::type, N> operator-(const Vector<T, N>& lhs, U rhs) {
179  Vector<typename std::common_type<T,U>::type, N> out;
180 
181  for (std::size_t i = 0; i < N; ++i) {
182  out.data[i] = lhs.data[i] - rhs;
183  }
184 
185  return out;
186  }
187 
188  /**
189  * @relates Vector
190  * @brief Left scalar substraction
191  */
192  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
193  inline
194  Vector<typename std::common_type<T,U>::type, N> operator-(T lhs, const Vector<U, N>& rhs) {
195  Vector<typename std::common_type<T,U>::type, N> out;
196 
197  for (std::size_t i = 0; i < N; ++i) {
198  out.data[i] = lhs - rhs.data[i];
199  }
200 
201  return out;
202  }
203 
204 
205  /**
206  * @relates Vector
207  * @brief Component-wise multiplication
208  */
209  template<typename T, typename U, std::size_t N>
210  inline
211  Vector<typename std::common_type<T,U>::type, N> operator*(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
212  Vector<typename std::common_type<T,U>::type, N> out;
213 
214  for (std::size_t i = 0; i < N; ++i) {
215  out.data[i] = lhs.data[i] * rhs.data[i];
216  }
217 
218  return out;
219  }
220 
221  /**
222  * @relates Vector
223  * @brief Component-wise multiplication and assignment
224  */
225  template<typename T, typename U, std::size_t N>
226  inline
227  Vector<T, N>& operator*=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
228  for (std::size_t i = 0; i < N; ++i) {
229  lhs.data[i] *= rhs.data[i];
230  }
231 
232  return lhs;
233  }
234 
235  /**
236  * @relates Vector
237  * @brief Right scalar multiplication
238  */
239  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
240  inline
241  Vector<typename std::common_type<T,U>::type, N> operator*(const Vector<T, N>& lhs, U rhs) {
242  Vector<typename std::common_type<T,U>::type, N> out;
243 
244  for (std::size_t i = 0; i < N; ++i) {
245  out.data[i] = lhs.data[i] * rhs;
246  }
247 
248  return out;
249  }
250 
251  /**
252  * @relates Vector
253  * @brief Right scalar multiplication and assignment
254  */
255  template<typename T, typename U, std::size_t N>
256  inline
257  Vector<T, N>& operator*=(Vector<T, N>& lhs, U rhs) {
258  for (std::size_t i = 0; i < N; ++i) {
259  lhs.data[i] *= rhs;
260  }
261 
262  return lhs;
263  }
264 
265  /**
266  * @relates Vector
267  * @brief Left scalar multiplication
268  */
269  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
270  inline
271  Vector<typename std::common_type<T,U>::type, N> operator*(T lhs, const Vector<U, N>& rhs) {
272  Vector<typename std::common_type<T,U>::type, N> out;
273 
274  for (std::size_t i = 0; i < N; ++i) {
275  out.data[i] = lhs * rhs.data[i];
276  }
277 
278  return out;
279  }
280 
281  /**
282  * @relates Vector
283  * @brief Component-wise division
284  */
285  template<typename T, typename U, std::size_t N>
286  inline
287  Vector<typename std::common_type<T,U>::type, N> operator/(const Vector<T, N>& lhs, const Vector<U, N>& rhs) {
288  Vector<typename std::common_type<T,U>::type, N> out;
289 
290  for (std::size_t i = 0; i < N; ++i) {
291  out.data[i] = lhs.data[i] / rhs.data[i];
292  }
293 
294  return out;
295  }
296 
297  /**
298  * @relates Vector
299  * @brief Component-wise division and assignment
300  */
301  template<typename T, typename U, std::size_t N>
302  inline
303  Vector<T, N>& operator/=(Vector<T, N>& lhs, const Vector<U, N>& rhs) {
304  for (std::size_t i = 0; i < N; ++i) {
305  lhs.data[i] /= rhs.data[i];
306  }
307 
308  return lhs;
309  }
310 
311  /**
312  * @relates Vector
313  * @brief Right scalar division
314  */
315  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<U>::value, U>::type>
316  inline
317  Vector<typename std::common_type<T,U>::type, N> operator/(const Vector<T, N>& lhs, U rhs) {
318  Vector<typename std::common_type<T,U>::type, N> out;
319 
320  for (std::size_t i = 0; i < N; ++i) {
321  out.data[i] = lhs.data[i] / rhs;
322  }
323 
324  return out;
325  }
326 
327  /**
328  * @relates Vector
329  * @brief Right scalar division and assignment
330  */
331  template<typename T, typename U, std::size_t N>
332  inline
333  Vector<T, N>& operator/=(Vector<T, N>& lhs, U rhs) {
334  for (std::size_t i = 0; i < N; ++i) {
335  lhs.data[i] /= rhs;
336  }
337 
338  return lhs;
339  }
340 
341  /**
342  * @relates Vector
343  * @brief Left scalar division
344  */
345  template<typename T, typename U, std::size_t N, typename E = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
346  inline
347  Vector<typename std::common_type<T,U>::type, N> operator/(T lhs, const Vector<U, N>& rhs) {
348  Vector<typename std::common_type<T,U>::type, N> out;
349 
350  for (std::size_t i = 0; i < N; ++i) {
351  out.data[i] = lhs / rhs.data[i];
352  }
353 
354  return out;
355  }
356 
357  /**
358  * @relates Vector
359  * @brief Component-wise logical or operator
360  */
361  template<std::size_t N>
362  inline
363  Vector<bool, N> operator||(const Vector<bool, N>& lhs, const Vector<bool, N>& rhs) {
364  Vector<bool, N> out;
365 
366  for (std::size_t i = 0; i < N; ++i) {
367  out.data[i] = lhs.data[i] || rhs.data[i];
368  }
369 
370  return out;
371  }
372 
373  /**
374  * @relates Vector
375  * @brief Component-wise logical and operator
376  */
377  template<std::size_t N>
378  inline
379  Vector<bool, N> operator&&(const Vector<bool, N>& lhs, const Vector<bool, N>& rhs) {
380  Vector<bool, N> out;
381 
382  for (std::size_t i = 0; i < N; ++i) {
383  out.data[i] = lhs.data[i] && rhs.data[i];
384  }
385 
386  return out;
387  }
388 
389  /**
390  * @relates Vector
391  * @brief Scalar product
392  *
393  * The [scalar product](https://en.wikipedia.org/wiki/Dot_product) or dot
394  * product of two vectors @f$ \mathbf{a} = (a_1, \ldots, a_N) @f$ and
395  * @f$ \mathbf{b} = (b_1, \ldots, b_N) @f$ is:
396  *
397  * @f[ \mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{N} a_i b_i
398  * = a_1 b_1 + \ldots + a_N b_N @f]
399  *
400  */
401  template<typename T, std::size_t N>
402  inline
403  T dot(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
404  T out{0};
405 
406  for (std::size_t i = 0; i < N; ++i) {
407  out += lhs.data[i] * rhs.data[i];
408  }
409 
410  return out;
411  }
412 
413  /**
414  * @relates Vector
415  * @brief Component-wise minimum
416  */
417  template<typename T, std::size_t N>
418  inline
419  Vector<T, N> min(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
420  Vector<T, N> out;
421 
422  for (std::size_t i = 0; i < N; ++i) {
423  out.data[i] = std::min(lhs.data[i], rhs.data[i]);
424  }
425 
426  return out;
427  }
428 
429  /**
430  * @relates Vector
431  * @brief Component-wise maximum
432  */
433  template<typename T, std::size_t N>
434  inline
435  Vector<T, N> max(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
436  Vector<T, N> out;
437 
438  for (std::size_t i = 0; i < N; ++i) {
439  out.data[i] = std::max(lhs.data[i], rhs.data[i]);
440  }
441 
442  return out;
443  }
444 
445  /**
446  * @relates Vector
447  * @brief Component-wise absolute value
448  */
449  template<typename T, std::size_t N>
450  inline
451  Vector<T, N> abs(const Vector<T, N>& val) {
452  Vector<T, N> out;
453 
454  for (std::size_t i = 0; i < N; ++i) {
455  out.data[i] = std::abs(val.data[i]);
456  }
457 
458  return out;
459  }
460 
461 
462  /**
463  * @relates Vector
464  * @brief Component-wise equality operator
465  */
466  template<typename T, std::size_t N>
467  inline
468  Vector<bool, N> equals(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
469  Vector<bool, N> out;
470 
471  for (std::size_t i = 0; i < N; ++i) {
472  out.data[i] = (lhs.data[i] == rhs.data[i]);
473  }
474 
475  return out;
476  }
477 
478  /**
479  * @relates Vector
480  * @brief Component-wise comparison operator
481  */
482  template<typename T, std::size_t N>
483  inline
484  Vector<bool, N> lessThan(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
485  Vector<bool, N> out;
486 
487  for (std::size_t i = 0; i < N; ++i) {
488  out.data[i] = (lhs.data[i] < rhs.data[i]);
489  }
490 
491  return out;
492  }
493 
494  /**
495  * @relates Vector
496  * @brief Component-wise comparison operator
497  */
498  template<typename T, std::size_t N>
499  inline
500  Vector<bool, N> greaterThan(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
501  Vector<bool, N> out;
502 
503  for (std::size_t i = 0; i < N; ++i) {
504  out.data[i] = (lhs.data[i] > rhs.data[i]);
505  }
506 
507  return out;
508  }
509 
510  /**
511  * @relates Vector
512  * @brief Component-wise selection operator
513  */
514  template<typename T, std::size_t N>
515  inline
516  Vector<T, N> select(const Vector<bool, N>& cond, const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
517  Vector<T, N> out;
518 
519  for (std::size_t i = 0; i < N; ++i) {
520  out.data[i] = (cond.data[i] ? lhs.data[i] : rhs.data[i]);
521  }
522 
523  return out;
524  }
525 
526  /**
527  * @relates Vector
528  * @brief Component-wise clamp function
529  *
530  * Relative to two other vectors.
531  *
532  */
533  template<typename T, std::size_t N>
534  inline
535  Vector<T, N> clamp(const Vector<T, N>& val, const Vector<T, N>& lo, const Vector<T, N>& hi) {
536  Vector<T, N> out;
537 
538  for (std::size_t i = 0; i < N; ++i) {
539  out.data[i] = clamp(val.data[i], lo.data[i], hi.data[i]);
540  }
541 
542  return out;
543  }
544 
545  /**
546  * @relates Vector
547  * @brief Component-wise clamp function
548  *
549  * Relative to two values.
550  */
551  template<typename T, std::size_t N>
552  inline
553  Vector<T, N> clamp(const Vector<T, N>& val, T lo, T hi) {
554  Vector<T, N> out;
555 
556  for (std::size_t i = 0; i < N; ++i) {
557  out.data[i] = clamp(val.data[i], lo, hi);
558  }
559 
560  return out;
561  }
562 
563  /**
564  * @relates Vector
565  * @brief Component-wise lerp function
566  */
567  template<typename T, typename U, std::size_t N>
568  inline
569  Vector<typename std::common_type<T,U>::type, N> lerp(const Vector<T, N>& lhs, const Vector<T, N>& rhs, U t) {
570  return (1 - t) * lhs + t * rhs;
571  }
572 
573  /**
574  * @relates Vector
575  * @brief Manhattan length of a vector
576  *
577  * The Manhattan length @f$ \|\mathbf{u}\|_1 @f$ of a vector
578  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
579  *
580  * @f[ \|\mathbf{u}\|_1 = \sum_{i = 1}^{N} |u_i| @f]
581  *
582  * The Manhattan length is also called the 1-norm.
583  *
584  * @param vec A vector.
585  * @returns The Manhattan length of the vector
586  *
587  * @sa manhattanDistance()
588  */
589  template<typename T, std::size_t N>
590  inline
591  T manhattanLength(const Vector<T, N>& vec) {
592  T out{0};
593 
594  for (std::size_t i = 0; i < N; ++i) {
595  out += std::abs(vec.data[i]);
596  }
597 
598  return out;
599  }
600 
601  /**
602  * @relates Vector
603  * @brief Square Euclidean length of a vector
604  *
605  * The square Euclidean length @f$ \|\mathbf{u}\|_2^2 @f$ of a vector
606  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
607  *
608  * @f[ \|\mathbf{u}\|_2^2 = \sum_{i = 1}^{N} u_i^2 @f]
609  *
610  * @param vec A vector.
611  * @returns The square Euclidean length of the vector
612  *
613  * @sa euclideanLength(), squareDistance()
614  */
615  template<typename T, std::size_t N>
616  inline
617  T squareLength(const Vector<T, N>& vec) {
618  T out{0};
619 
620  for (std::size_t i = 0; i < N; ++i) {
621  out += square(vec.data[i]);
622  }
623 
624  return out;
625  }
626 
627  /**
628  * @relates Vector
629  * @brief Euclidean length of a vector
630  *
631  * The Euclidean length @f$ \|\mathbf{u}\|_2 @f$ of a vector
632  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
633  *
634  * @f[ \|\mathbf{u}\|_2 = \sqrt{\sum_{i = 1}^{N} u_i^2} @f]
635  *
636  * The Euclidean length is also called the 2-norm.
637  *
638  * @param vec A vector.
639  * @returns The Euclidean length of the vector
640  *
641  * @sa euclideanDistance()
642  */
643  template<typename T, std::size_t N>
644  inline
645  T euclideanLength(const Vector<T, N>& vec) {
646  return std::sqrt(squareLength(vec));
647  }
648 
649 #ifndef DOXYGEN_SHOULD_SKIP_THIS
650  // specializations of euclideanLength for Vector2f and Vector2d using std::hypot
651 
652  template<>
653  inline
654  float euclideanLength<float, 2>(const Vector<float, 2>& vec) {
655  return std::hypot(vec.x, vec.y);
656  }
657 
658  template<>
659  inline
660  double euclideanLength<double, 2>(const Vector<double, 2>& vec) {
661  return std::hypot(vec.x, vec.y);
662  }
663 #endif
664 
665  /**
666  * @relates Vector
667  * @brief Chebyshev length of a vector
668  *
669  * The Chebyshev length @f$ \|\mathbf{u}\|_{\infty} @f$ of a vector
670  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
671  *
672  * @f[ \|u\|_{\infty} = \max_{i = 1}^{N} |u_i| @f]
673  *
674  * The Chebyshev length is also called the infinity norm or maximum norm.
675  *
676  * @param vec A vector.
677  * @returns The Chebyshev length of the vector
678  *
679  * @sa chebyshevDistance()
680  */
681  template<typename T, std::size_t N>
682  inline
683  T chebyshevLength(const Vector<T, N>& vec) {
684  T out = std::abs(vec.data[0]);
685 
686  for (std::size_t i = 1; i < N; ++i) {
687  out = std::max(out, std::abs(vec.data[i]));
688  }
689 
690  return out;
691  }
692 
693  /**
694  * @relates Vector
695  * @brief Natural length of a vector
696  *
697  * The natural length @f$ L @f$ of a vector:
698  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
699  *
700  * @f[ L = \|\mathbf{u}\|_1 + \|\mathbf{u}\|_2^2
701  * = \sum_{i = 1}^{N} |u_i| + \sum_{i = 1}^{N} u_i^2 @f]
702  *
703  * It's the sum of the Manhattan length and the square length.
704  *
705  * @param vec A vector.
706  * @returns The natural length of the vector
707  *
708  * @sa naturalDistance()
709  */
710  template<typename T, std::size_t N>
711  inline
712  T naturalLength(const Vector<T, N>& vec) {
713  return manhattanLength(vec) + squareLength(vec);
714  }
715 
716  /**
717  * @relates Vector
718  * @brief Manhattan distance between two vectors
719  *
720  * The Manhattan distance between two vectors is the Manhattan length of the
721  * difference of the two vectors.
722  *
723  * @param lhs A first vector
724  * @param rhs A second vector
725  * @returns The Manhattan distance between the two vectors
726  *
727  * @sa manhattanLength()
728  */
729  template<typename T, std::size_t N>
730  inline
731  T manhattanDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
732  return manhattanLength(lhs - rhs);
733  }
734 
735  /**
736  * @relates Vector
737  * @brief Square Euclidean distance between two vectors
738  *
739  * The square Euclidean distance between two vectors is the square Euclidean
740  * length of the difference of the two vectors.
741  *
742  * @param lhs A first vector
743  * @param rhs A second vector
744  * @returns The square Euclidean distance between the two vectors
745  *
746  * @sa squareLength(), euclideanDistance()
747  */
748  template<typename T, std::size_t N>
749  inline
750  T squareDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
751  return squareLength(lhs - rhs);
752  }
753 
754  /**
755  * @relates Vector
756  * @brief Euclidean distance between two vectors
757  *
758  * The Euclidean distance between two vectors is the Euclidean length of the
759  * difference of the two vectors.
760  *
761  * @param lhs A first vector
762  * @param rhs A second vector
763  * @returns The Euclidean distance between the two vectors
764  *
765  * @sa euclideanLength()
766  */
767  template<typename T, std::size_t N>
768  inline
769  T euclideanDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
770  return euclideanLength(lhs - rhs);
771  }
772 
773  /**
774  * @relates Vector
775  * @brief Chebyshev distance between two vectors
776  *
777  * The Chebyshev distance between two vectors is the Chebyshev length of the
778  * difference of the two vectors.
779  *
780  * @param lhs A first vector
781  * @param rhs A second vector
782  * @returns The Chebyshev distance between the two vectors
783  *
784  * @sa chebyshevLength()
785  */
786  template<typename T, std::size_t N>
787  inline
788  T chebyshevDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
789  return chebyshevLength(lhs - rhs);
790  }
791 
792  /**
793  * @relates Vector
794  * @brief Natural distance between two vectors
795  *
796  * The natural distance between two vectors is the natural length of the
797  * difference of the two vectors.
798  *
799  * @param lhs A first vector
800  * @param rhs A second vector
801  * @returns The natural distance between the two vectors
802  *
803  * @sa naturalLength()
804  */
805  template<typename T, std::size_t N>
806  inline
807  T naturalDistance(const Vector<T, N>& lhs, const Vector<T, N>& rhs) {
808  return naturalLength(lhs - rhs);
809  }
810 
811  /**
812  * @relates Vector
813  * @brief Normalize a vector
814  *
815  * The normalized vector of @f$ \mathbf{u} @f$ is a vector in the same
816  * direction but with a (euclidean) length of 1:
817  *
818  * @f[ \frac{\mathbf{u}}{\|\mathbf{u}\|_2} @f]
819  *
820  * A normalized vector is also called a
821  * [unit vector](https://en.wikipedia.org/wiki/Unit_vector).
822  *
823  * @param vec A vector
824  * @returns A normalized vector
825  */
826  template<typename T, std::size_t N>
827  inline
828  Vector<T, N> normalize(const Vector<T, N>& vec) {
829  T length = euclideanLength(vec);
830  return vec / length;
831  }
832 
833  /**
834  * @relates Vector
835  * @brief Unit vector in a specified direction
836  *
837  * @param angle The angle of the direction
838  * @return A unit vector
839  */
840  template<typename T>
841  inline
842  Vector<T, 2> unit(T angle) {
843  return { std::cos(angle), std::sin(angle) };
844  }
845 
846  /**
847  * @relates Vector
848  * @brief Angle of a vector relative to the x-axis
849  *
850  * @param vec The vector
851  * @returns The angle of the vector
852  */
853  template<typename T>
854  inline
855  float angle(Vector<T, 2> vec) {
856  return std::atan2(vec.y, vec.x);
857  }
858 
859  /**
860  * @relates Vector
861  * @brief Perpendicular vector
862  *
863  * The perpendicular vector @f$ \mathbf{u}^{\perp} @f$ of vector @f$ \mathbf{u} = (x, y) @f$ is:
864  *
865  * @f[ \mathbf{u}^{\perp} = (-y, x) @f]
866  *
867  * @param vec A vector
868  * @returns A perpendicular vector
869  */
870  template<typename T>
871  constexpr
872  Vector<T, 2> perp(Vector<T, 2> vec) {
873  return { -vec.y, vec.x };
874  }
875 
876  /**
877  * @relates Vector
878  * @brief Regular vector triple product
879  *
880  * The regular [vector triple product](https://en.wikipedia.org/wiki/Triple_product#Vector_triple_product)
881  * of vectors @f$ \mathbf{a} @f$, @f$ \mathbf{b} @f$ and @f$ \mathbf{c} @f$
882  * is:
883  *
884  * @f[ \mathbf{a} \times (\mathbf{b} \times \mathbf{c})
885  * = (\mathbf{a} \cdot \mathbf{c}) \mathbf{b} - (\mathbf{a} \cdot \mathbf{b}) \mathbf{c} @f]
886  *
887  * @sa inverseVectorTripleProduct()
888  */
889  template<typename T>
890  inline
891  Vector<T, 2> vectorTripleProduct(Vector<T, 2> a, Vector<T, 2> b, Vector<T, 2> c) {
892  return dot(a, c) * b - dot(a, b) * c;
893  }
894 
895  /**
896  * @relates Vector
897  * @brief Inverse vector triple product
898  *
899  * The inverse [vector triple product](https://en.wikipedia.org/wiki/Triple_product#Vector_triple_product)
900  * of vectors @f$ \mathbf{a} @f$, @f$ \mathbf{b} @f$ and @f$ \mathbf{c} @f$
901  * is:
902  *
903  * @f[ (\mathbf{a} \times \mathbf{b}) \times \mathbf{c}
904  * = -\mathbf{c} \times (\mathbf{a} \times \mathbf{b})
905  * = -(\mathbf{c} \cdot \mathbf{b}) \mathbf{a} + (\mathbf{c} \cdot \mathbf{a}) \mathbf{b} @f]
906  *
907  * @sa vectorTripleProduct()
908  */
909  template<typename T>
910  inline
911  Vector<T, 2> inverseVectorTripleProduct(Vector<T, 2> a, Vector<T, 2> b, Vector<T, 2> c) {
912  return - dot(c, b) * a + dot(c, a) * b;
913  }
914 
915  /**
916  * @relates Vector
917  * @brief Cross product for 2D vectors
918  *
919  * The cross product of 2D vectors is not really a cross product, it is the
920  * magnitude of the vector resulting from a 3D cross product of 2D vectors
921  * with @f$ z = 0 @f$. The cross product @f$ \mathbf{a} \times \mathbf{b} @f$
922  * of the vectors @f$ \mathbf{a} @f$ and @f$ \mathbf{b} @f$ is:
923  *
924  * @f[ \mathbf{a} \times \mathbf{b} = \mathbf{a}^{\perp} \cdot \mathbf{b} @f]
925  *
926  * The 2D cross product is also known as the perp dot product.
927  *
928  * @param lhs A first vector
929  * @param rhs A second vector
930  * @return The cross product of the two vectors
931  */
932  template<typename T>
933  constexpr
934  T cross(Vector<T, 2> lhs, Vector<T, 2> rhs) {
935  return -lhs.y * rhs.x + lhs.x * rhs.y;
936  }
937 
938 
939  /**
940  * @relates Vector
941  * @brief Cross product for 3D vectors
942  *
943  * @param lhs A first vector
944  * @param rhs A second vector
945  * @return The cross product of the two vectors
946  */
947  template<typename T>
948  constexpr
949  Vector<T, 3> cross(const Vector<T, 3>& lhs, const Vector<T, 3>& rhs) {
950  return {
951  lhs.y * rhs.z - lhs.z * rhs.y,
952  lhs.z * rhs.x - lhs.x * rhs.z,
953  lhs.x * rhs.y - lhs.y * rhs.x
954  };
955  }
956 
957 #ifndef DOXYGEN_SHOULD_SKIP_THIS
958 }
959 #endif
960 }
961 
962 #endif // GF_VECTOR_OPS_H
T manhattanLength(const Vector< T, N > &vec)
Manhattan length of a vector.
Definition: VectorOps.h:591
T dot(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Scalar product.
Definition: VectorOps.h:403
Vector< T, N > abs(const Vector< T, N > &val)
Component-wise absolute value.
Definition: VectorOps.h:451
Vector< typename std::common_type< T, U >::type, N > operator/(T lhs, const Vector< U, N > &rhs)
Left scalar division.
Definition: VectorOps.h:347
Vector< T, N > select(const Vector< bool, N > &cond, const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise selection operator.
Definition: VectorOps.h:516
bool operator==(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Equality operator between two vectors.
Definition: VectorOps.h:42
Vector< typename std::common_type< T, U >::type, N > operator+(T lhs, const Vector< U, N > &rhs)
Left scalar addition.
Definition: VectorOps.h:130
T squareLength(const Vector< T, N > &vec)
Square Euclidean length of a vector.
Definition: VectorOps.h:617
Vector< T, N > & operator/=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise division and assignment.
Definition: VectorOps.h:303
Vector< T, 2 > vectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Regular vector triple product.
Definition: VectorOps.h:891
Vector< T, N > clamp(const Vector< T, N > &val, T lo, T hi)
Component-wise clamp function.
Definition: VectorOps.h:553
T euclideanLength(const Vector< T, N > &vec)
Euclidean length of a vector.
Definition: VectorOps.h:645
Vector< T, N > max(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise maximum.
Definition: VectorOps.h:435
Vector< bool, N > greaterThan(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise comparison operator.
Definition: VectorOps.h:500
Vector< T, N > & operator/=(Vector< T, N > &lhs, U rhs)
Right scalar division and assignment.
Definition: VectorOps.h:333
Vector< bool, N > equals(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise equality operator.
Definition: VectorOps.h:468
Vector< typename std::common_type< T, U >::type, N > operator+(const Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise addition.
Definition: VectorOps.h:84
Vector< typename std::common_type< T, U >::type, N > operator*(const Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise multiplication.
Definition: VectorOps.h:211
Vector< typename std::common_type< T, U >::type, N > operator/(const Vector< T, N > &lhs, U rhs)
Right scalar division.
Definition: VectorOps.h:317
Vector< T, N > & operator+=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise addition and assignment.
Definition: VectorOps.h:100
T chebyshevLength(const Vector< T, N > &vec)
Chebyshev length of a vector.
Definition: VectorOps.h:683
Vector< bool, N > operator&&(const Vector< bool, N > &lhs, const Vector< bool, N > &rhs)
Component-wise logical and operator.
Definition: VectorOps.h:379
Vector< bool, N > lessThan(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise comparison operator.
Definition: VectorOps.h:484
float angle(Vector< T, 2 > vec)
Angle of a vector relative to the x-axis.
Definition: VectorOps.h:855
Vector< T, N > operator-(const Vector< T, N > &val)
Component-wise unary minus.
Definition: VectorOps.h:68
Vector< typename std::common_type< T, U >::type, N > operator-(T lhs, const Vector< U, N > &rhs)
Left scalar substraction.
Definition: VectorOps.h:194
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: VectorOps.h:569
T naturalDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Natural distance between two vectors.
Definition: VectorOps.h:807
T chebyshevDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Chebyshev distance between two vectors.
Definition: VectorOps.h:788
Definition: Action.h:34
T naturalLength(const Vector< T, N > &vec)
Natural length of a vector.
Definition: VectorOps.h:712
T squareDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Square Euclidean distance between two vectors.
Definition: VectorOps.h:750
Vector< T, 2 > unit(T angle)
Unit vector in a specified direction.
Definition: VectorOps.h:842
Vector< typename std::common_type< T, U >::type, N > operator/(const Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise division.
Definition: VectorOps.h:287
Vector< T, N > clamp(const Vector< T, N > &val, const Vector< T, N > &lo, const Vector< T, N > &hi)
Component-wise clamp function.
Definition: VectorOps.h:535
Vector< typename std::common_type< T, U >::type, N > operator-(const Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise substraction.
Definition: VectorOps.h:147
T euclideanDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Euclidean distance between two vectors.
Definition: VectorOps.h:769
Vector< bool, N > operator||(const Vector< bool, N > &lhs, const Vector< bool, N > &rhs)
Component-wise logical or operator.
Definition: VectorOps.h:363
Vector< typename std::common_type< T, U >::type, N > operator-(const Vector< T, N > &lhs, U rhs)
Right scalar substraction.
Definition: VectorOps.h:178
bool operator!=(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Inequality operator between two vectors.
Definition: VectorOps.h:58
Vector< T, N > normalize(const Vector< T, N > &vec)
Normalize a vector.
Definition: VectorOps.h:828
Vector< T, N > min(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Component-wise minimum.
Definition: VectorOps.h:419
Vector< T, N > & operator*=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise multiplication and assignment.
Definition: VectorOps.h:227
Vector< typename std::common_type< T, U >::type, N > operator*(const Vector< T, N > &lhs, U rhs)
Right scalar multiplication.
Definition: VectorOps.h:241
Vector< T, N > & operator*=(Vector< T, N > &lhs, U rhs)
Right scalar multiplication and assignment.
Definition: VectorOps.h:257
T manhattanDistance(const Vector< T, N > &lhs, const Vector< T, N > &rhs)
Manhattan distance between two vectors.
Definition: VectorOps.h:731
Vector< T, 2 > inverseVectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Inverse vector triple product.
Definition: VectorOps.h:911
General purpose math vector.
Definition: Vector.h:60
constexpr Vector< T, 3 > cross(const Vector< T, 3 > &lhs, const Vector< T, 3 > &rhs)
Cross product for 3D vectors.
Definition: VectorOps.h:949
Vector< typename std::common_type< T, U >::type, N > operator+(const Vector< T, N > &lhs, U rhs)
Right scalar addition.
Definition: VectorOps.h:114
Vector< T, N > & operator-=(Vector< T, N > &lhs, const Vector< U, N > &rhs)
Component-wise substraction and assignment.
Definition: VectorOps.h:163
Vector< typename std::common_type< T, U >::type, N > operator*(T lhs, const Vector< U, N > &rhs)
Left scalar multiplication.
Definition: VectorOps.h:271
constexpr Vector< T, 2 > perp(Vector< T, 2 > vec)
Perpendicular vector.
Definition: VectorOps.h:872
constexpr T cross(Vector< T, 2 > lhs, Vector< T, 2 > rhs)
Cross product for 2D vectors.
Definition: VectorOps.h:934