Gamedev Framework (gf)  0.4.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 
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==(Vector<T, N> lhs, 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!=(Vector<T, N> lhs, 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-(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+(Vector<T, N> lhs, 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, 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+(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 Right scalar addition and assignment
127  */
128  template<typename T, typename U, std::size_t N>
129  inline
130  Vector<T, N>& operator+=(Vector<T, N>& lhs, U rhs) {
131  for (std::size_t i = 0; i < N; ++i) {
132  lhs.data[i] += rhs;
133  }
134 
135  return lhs;
136  }
137 
138  /**
139  * @relates Vector
140  * @brief Left scalar addition
141  */
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
144  Vector<typename std::common_type<T,U>::type, N> operator+(T lhs, Vector<U, N> rhs) {
145  Vector<typename std::common_type<T,U>::type, N> out;
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 
155  /**
156  * @relates Vector
157  * @brief Component-wise substraction
158  */
159  template<typename T, typename U, std::size_t N>
160  inline
161  Vector<typename std::common_type<T,U>::type, N> operator-(Vector<T, N> lhs, Vector<U, N> rhs) {
162  Vector<typename std::common_type<T,U>::type, N> out;
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 
171  /**
172  * @relates Vector
173  * @brief Component-wise substraction and assignment
174  */
175  template<typename T, typename U, std::size_t N>
176  inline
177  Vector<T, N>& operator-=(Vector<T, N>& lhs, Vector<U, N> rhs) {
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 
186  /**
187  * @relates Vector
188  * @brief Right scalar substraction
189  */
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
192  Vector<typename std::common_type<T,U>::type, N> operator-(Vector<T, N> lhs, U rhs) {
193  Vector<typename std::common_type<T,U>::type, N> out;
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 
202  /**
203  * @relates Vector
204  * @brief Right scalar substraction and assignment
205  */
206  template<typename T, typename U, std::size_t N>
207  inline
208  Vector<T, N>& operator-=(Vector<T, N>& lhs, U rhs) {
209  for (std::size_t i = 0; i < N; ++i) {
210  lhs.data[i] -= rhs;
211  }
212 
213  return lhs;
214  }
215 
216  /**
217  * @relates Vector
218  * @brief Left scalar substraction
219  */
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
222  Vector<typename std::common_type<T,U>::type, N> operator-(T lhs, Vector<U, N> rhs) {
223  Vector<typename std::common_type<T,U>::type, N> out;
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 
233  /**
234  * @relates Vector
235  * @brief Component-wise multiplication
236  */
237  template<typename T, typename U, std::size_t N>
238  inline
239  Vector<typename std::common_type<T,U>::type, N> operator*(Vector<T, N> lhs, Vector<U, N> rhs) {
240  Vector<typename std::common_type<T,U>::type, N> out;
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 
249  /**
250  * @relates Vector
251  * @brief Component-wise multiplication and assignment
252  */
253  template<typename T, typename U, std::size_t N>
254  inline
255  Vector<T, N>& operator*=(Vector<T, N>& lhs, Vector<U, N> rhs) {
256  for (std::size_t i = 0; i < N; ++i) {
257  lhs.data[i] *= rhs.data[i];
258  }
259 
260  return lhs;
261  }
262 
263  /**
264  * @relates Vector
265  * @brief Right scalar multiplication
266  */
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
269  Vector<typename std::common_type<T,U>::type, N> operator*(Vector<T, N> lhs, U rhs) {
270  Vector<typename std::common_type<T,U>::type, N> out;
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 
279  /**
280  * @relates Vector
281  * @brief Right scalar multiplication and assignment
282  */
283  template<typename T, typename U, std::size_t N>
284  inline
285  Vector<T, N>& operator*=(Vector<T, N>& lhs, U rhs) {
286  for (std::size_t i = 0; i < N; ++i) {
287  lhs.data[i] *= rhs;
288  }
289 
290  return lhs;
291  }
292 
293  /**
294  * @relates Vector
295  * @brief Left scalar multiplication
296  */
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
299  Vector<typename std::common_type<T,U>::type, N> operator*(T lhs, Vector<U, N> rhs) {
300  Vector<typename std::common_type<T,U>::type, N> out;
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 
309  /**
310  * @relates Vector
311  * @brief Component-wise division
312  */
313  template<typename T, typename U, std::size_t N>
314  inline
315  Vector<typename std::common_type<T,U>::type, N> operator/(Vector<T, N> lhs, Vector<U, N> rhs) {
316  Vector<typename std::common_type<T,U>::type, N> out;
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 
325  /**
326  * @relates Vector
327  * @brief Component-wise division and assignment
328  */
329  template<typename T, typename U, std::size_t N>
330  inline
331  Vector<T, N>& operator/=(Vector<T, N>& lhs, Vector<U, N> rhs) {
332  for (std::size_t i = 0; i < N; ++i) {
333  lhs.data[i] /= rhs.data[i];
334  }
335 
336  return lhs;
337  }
338 
339  /**
340  * @relates Vector
341  * @brief Right scalar division
342  */
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
345  Vector<typename std::common_type<T,U>::type, N> operator/(Vector<T, N> lhs, U rhs) {
346  Vector<typename std::common_type<T,U>::type, N> out;
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 
355  /**
356  * @relates Vector
357  * @brief Right scalar division and assignment
358  */
359  template<typename T, typename U, std::size_t N>
360  inline
361  Vector<T, N>& operator/=(Vector<T, N>& lhs, U rhs) {
362  for (std::size_t i = 0; i < N; ++i) {
363  lhs.data[i] /= rhs;
364  }
365 
366  return lhs;
367  }
368 
369  /**
370  * @relates Vector
371  * @brief Left scalar division
372  */
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
375  Vector<typename std::common_type<T,U>::type, N> operator/(T lhs, Vector<U, N> rhs) {
376  Vector<typename std::common_type<T,U>::type, N> out;
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 
385  /**
386  * @relates Vector
387  * @brief Component-wise logical or operator
388  */
389  template<std::size_t N>
390  inline
391  Vector<bool, N> operator||(Vector<bool, N> lhs, Vector<bool, N> rhs) {
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 
401  /**
402  * @relates Vector
403  * @brief Component-wise logical and operator
404  */
405  template<std::size_t N>
406  inline
407  Vector<bool, N> operator&&(Vector<bool, N> lhs, Vector<bool, N> rhs) {
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 
417  /**
418  * @relates Vector
419  * @brief Scalar product
420  *
421  * The [scalar product](https://en.wikipedia.org/wiki/Dot_product) or dot
422  * product of two vectors @f$ \mathbf{a} = (a_1, \ldots, a_N) @f$ and
423  * @f$ \mathbf{b} = (b_1, \ldots, b_N) @f$ is:
424  *
425  * @f[ \mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{N} a_i b_i
426  * = a_1 b_1 + \ldots + a_N b_N @f]
427  *
428  */
429  template<typename T, std::size_t N>
430  inline
431  T dot(Vector<T, N> lhs, Vector<T, N> rhs) {
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 
441  /**
442  * @relates Vector
443  * @brief Component-wise minimum
444  */
445  template<typename T, std::size_t N>
446  inline
447  Vector<T, N> min(Vector<T, N> lhs, Vector<T, N> rhs) {
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 
457  /**
458  * @relates Vector
459  * @brief Component-wise maximum
460  */
461  template<typename T, std::size_t N>
462  inline
463  Vector<T, N> max(Vector<T, N> lhs, Vector<T, N> rhs) {
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 
473  /**
474  * @relates Vector
475  * @brief Component-wise absolute value
476  */
477  template<typename T, std::size_t N>
478  inline
479  Vector<T, N> abs(Vector<T, N> val) {
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 
490  /**
491  * @relates Vector
492  * @brief Component-wise equality operator
493  */
494  template<typename T, std::size_t N>
495  inline
496  Vector<bool, N> equals(Vector<T, N> lhs, Vector<T, N> rhs) {
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 
506  /**
507  * @relates Vector
508  * @brief Component-wise comparison operator
509  */
510  template<typename T, std::size_t N>
511  inline
512  Vector<bool, N> lessThan(Vector<T, N> lhs, Vector<T, N> rhs) {
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 
522  /**
523  * @relates Vector
524  * @brief Component-wise comparison operator
525  */
526  template<typename T, std::size_t N>
527  inline
528  Vector<bool, N> greaterThan(Vector<T, N> lhs, Vector<T, N> rhs) {
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 
538  /**
539  * @relates Vector
540  * @brief Component-wise selection operator
541  */
542  template<typename T, std::size_t N>
543  inline
544  Vector<T, N> select(Vector<bool, N> cond, Vector<T, N> lhs, Vector<T, N> rhs) {
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 
554  /**
555  * @relates Vector
556  * @brief Component-wise clamp function
557  *
558  * Relative to two other vectors.
559  *
560  */
561  template<typename T, std::size_t N>
562  inline
563  Vector<T, N> clamp(Vector<T, N> val, Vector<T, N> lo, Vector<T, N> hi) {
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 
573  /**
574  * @relates Vector
575  * @brief Component-wise clamp function
576  *
577  * Relative to two values.
578  */
579  template<typename T, std::size_t N>
580  inline
581  Vector<T, N> clamp(Vector<T, N> val, T lo, T hi) {
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 
591  /**
592  * @relates Vector
593  * @brief Component-wise lerp function
594  */
595  template<typename T, typename U, std::size_t N>
596  inline
597  Vector<T, N> lerp(Vector<T, N> lhs, Vector<T, N> rhs, U t) {
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 
608  /**
609  * @relates Vector
610  * @brief Manhattan length of a vector
611  *
612  * The Manhattan length @f$ \|\mathbf{u}\|_1 @f$ of a vector
613  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
614  *
615  * @f[ \|\mathbf{u}\|_1 = \sum_{i = 1}^{N} |u_i| @f]
616  *
617  * The Manhattan length is also called the 1-norm.
618  *
619  * @param vec A vector.
620  * @returns The Manhattan length of the vector
621  *
622  * @sa manhattanDistance()
623  */
624  template<typename T, std::size_t N>
625  inline
626  T manhattanLength(Vector<T, N> vec) {
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 
636  /**
637  * @relates Vector
638  * @brief Square Euclidean length of a vector
639  *
640  * The square Euclidean length @f$ \|\mathbf{u}\|_2^2 @f$ of a vector
641  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
642  *
643  * @f[ \|\mathbf{u}\|_2^2 = \sum_{i = 1}^{N} u_i^2 @f]
644  *
645  * @param vec A vector.
646  * @returns The square Euclidean length of the vector
647  *
648  * @sa euclideanLength(), squareDistance()
649  */
650  template<typename T, std::size_t N>
651  inline
652  T squareLength(Vector<T, N> vec) {
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 
662  /**
663  * @relates Vector
664  * @brief Euclidean length of a vector
665  *
666  * The Euclidean length @f$ \|\mathbf{u}\|_2 @f$ of a vector
667  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
668  *
669  * @f[ \|\mathbf{u}\|_2 = \sqrt{\sum_{i = 1}^{N} u_i^2} @f]
670  *
671  * The Euclidean length is also called the 2-norm.
672  *
673  * @param vec A vector.
674  * @returns The Euclidean length of the vector
675  *
676  * @sa euclideanDistance()
677  */
678  template<typename T, std::size_t N>
679  inline
680  T euclideanLength(Vector<T, N> vec) {
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 
700  /**
701  * @relates Vector
702  * @brief Chebyshev length of a vector
703  *
704  * The Chebyshev length @f$ \|\mathbf{u}\|_{\infty} @f$ of a vector
705  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
706  *
707  * @f[ \|u\|_{\infty} = \max_{i = 1}^{N} |u_i| @f]
708  *
709  * The Chebyshev length is also called the infinity norm or maximum norm.
710  *
711  * @param vec A vector.
712  * @returns The Chebyshev length of the vector
713  *
714  * @sa chebyshevDistance()
715  */
716  template<typename T, std::size_t N>
717  inline
718  T chebyshevLength(Vector<T, N> vec) {
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 
728  /**
729  * @relates Vector
730  * @brief Natural length of a vector
731  *
732  * The natural length @f$ L @f$ of a vector:
733  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
734  *
735  * @f[ L = \|\mathbf{u}\|_1 + \|\mathbf{u}\|_2^2
736  * = \sum_{i = 1}^{N} |u_i| + \sum_{i = 1}^{N} u_i^2 @f]
737  *
738  * It's the sum of the Manhattan length and the square length.
739  *
740  * @param vec A vector.
741  * @returns The natural length of the vector
742  *
743  * @sa naturalDistance()
744  */
745  template<typename T, std::size_t N>
746  inline
747  T naturalLength(Vector<T, N> vec) {
748  return manhattanLength(vec) + squareLength(vec);
749  }
750 
751  /**
752  * @relates Vector
753  * @brief Manhattan distance between two vectors
754  *
755  * The Manhattan distance between two vectors is the Manhattan length of the
756  * difference of the two vectors.
757  *
758  * @param lhs A first vector
759  * @param rhs A second vector
760  * @returns The Manhattan distance between the two vectors
761  *
762  * @sa manhattanLength()
763  */
764  template<typename T, std::size_t N>
765  inline
766  T manhattanDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
767  return manhattanLength(lhs - rhs);
768  }
769 
770  /**
771  * @relates Vector
772  * @brief Square Euclidean distance between two vectors
773  *
774  * The square Euclidean distance between two vectors is the square Euclidean
775  * length of the difference of the two vectors.
776  *
777  * @param lhs A first vector
778  * @param rhs A second vector
779  * @returns The square Euclidean distance between the two vectors
780  *
781  * @sa squareLength(), euclideanDistance()
782  */
783  template<typename T, std::size_t N>
784  inline
785  T squareDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
786  return squareLength(lhs - rhs);
787  }
788 
789  /**
790  * @relates Vector
791  * @brief Euclidean distance between two vectors
792  *
793  * The Euclidean distance between two vectors is the Euclidean length of the
794  * difference of the two vectors.
795  *
796  * @param lhs A first vector
797  * @param rhs A second vector
798  * @returns The Euclidean distance between the two vectors
799  *
800  * @sa euclideanLength()
801  */
802  template<typename T, std::size_t N>
803  inline
804  T euclideanDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
805  return euclideanLength(lhs - rhs);
806  }
807 
808  /**
809  * @relates Vector
810  * @brief Chebyshev distance between two vectors
811  *
812  * The Chebyshev distance between two vectors is the Chebyshev length of the
813  * difference of the two vectors.
814  *
815  * @param lhs A first vector
816  * @param rhs A second vector
817  * @returns The Chebyshev distance between the two vectors
818  *
819  * @sa chebyshevLength()
820  */
821  template<typename T, std::size_t N>
822  inline
823  T chebyshevDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
824  return chebyshevLength(lhs - rhs);
825  }
826 
827  /**
828  * @relates Vector
829  * @brief Natural distance between two vectors
830  *
831  * The natural distance between two vectors is the natural length of the
832  * difference of the two vectors.
833  *
834  * @param lhs A first vector
835  * @param rhs A second vector
836  * @returns The natural distance between the two vectors
837  *
838  * @sa naturalLength()
839  */
840  template<typename T, std::size_t N>
841  inline
842  T naturalDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
843  return naturalLength(lhs - rhs);
844  }
845 
846  /**
847  * @relates Vector
848  * @brief Normalize a vector
849  *
850  * The normalized vector of @f$ \mathbf{u} @f$ is a vector in the same
851  * direction but with a (euclidean) length of 1:
852  *
853  * @f[ \frac{\mathbf{u}}{\|\mathbf{u}\|_2} @f]
854  *
855  * A normalized vector is also called a
856  * [unit vector](https://en.wikipedia.org/wiki/Unit_vector).
857  *
858  * @param vec A vector
859  * @returns A normalized vector
860  */
861  template<typename T, std::size_t N>
862  inline
863  Vector<T, N> normalize(Vector<T, N> vec) {
864  T length = euclideanLength(vec);
865  return vec / length;
866  }
867 
868  /**
869  * @relates Vector
870  * @brief Unit vector in a specified direction
871  *
872  * @param angle The angle of the direction
873  * @return A unit vector
874  */
875  template<typename T>
876  inline
877  Vector<T, 2> unit(T angle) {
878  return { std::cos(angle), std::sin(angle) };
879  }
880 
881  /**
882  * @relates Vector
883  * @brief Angle of a vector relative to the x-axis
884  *
885  * @param vec The vector
886  * @returns The angle of the vector
887  */
888  template<typename T>
889  inline
890  float angle(Vector<T, 2> vec) {
891  return std::atan2(vec.y, vec.x);
892  }
893 
894  /**
895  * @relates Vector
896  * @brief Perpendicular vector
897  *
898  * The perpendicular vector @f$ \mathbf{u}^{\perp} @f$ of vector @f$ \mathbf{u} = (x, y) @f$ is:
899  *
900  * @f[ \mathbf{u}^{\perp} = (-y, x) @f]
901  *
902  * @param vec A vector
903  * @returns A perpendicular vector
904  */
905  template<typename T>
906  constexpr
907  Vector<T, 2> perp(Vector<T, 2> vec) {
908  return { -vec.y, vec.x };
909  }
910 
911  /**
912  * @relates Vector
913  * @brief Regular vector triple product
914  *
915  * The regular [vector triple product](https://en.wikipedia.org/wiki/Triple_product#Vector_triple_product)
916  * of vectors @f$ \mathbf{a} @f$, @f$ \mathbf{b} @f$ and @f$ \mathbf{c} @f$
917  * is:
918  *
919  * @f[ \mathbf{a} \times (\mathbf{b} \times \mathbf{c})
920  * = (\mathbf{a} \cdot \mathbf{c}) \mathbf{b} - (\mathbf{a} \cdot \mathbf{b}) \mathbf{c} @f]
921  *
922  * @sa inverseVectorTripleProduct()
923  */
924  template<typename T>
925  inline
926  Vector<T, 2> vectorTripleProduct(Vector<T, 2> a, Vector<T, 2> b, Vector<T, 2> c) {
927  return dot(a, c) * b - dot(a, b) * c;
928  }
929 
930  /**
931  * @relates Vector
932  * @brief Inverse vector triple product
933  *
934  * The inverse [vector triple product](https://en.wikipedia.org/wiki/Triple_product#Vector_triple_product)
935  * of vectors @f$ \mathbf{a} @f$, @f$ \mathbf{b} @f$ and @f$ \mathbf{c} @f$
936  * is:
937  *
938  * @f[ (\mathbf{a} \times \mathbf{b}) \times \mathbf{c}
939  * = -\mathbf{c} \times (\mathbf{a} \times \mathbf{b})
940  * = -(\mathbf{c} \cdot \mathbf{b}) \mathbf{a} + (\mathbf{c} \cdot \mathbf{a}) \mathbf{b} @f]
941  *
942  * @sa vectorTripleProduct()
943  */
944  template<typename T>
945  inline
946  Vector<T, 2> inverseVectorTripleProduct(Vector<T, 2> a, Vector<T, 2> b, Vector<T, 2> c) {
947  return - dot(c, b) * a + dot(c, a) * b;
948  }
949 
950  /**
951  * @relates Vector
952  * @brief Cross product for 2D vectors
953  *
954  * The cross product of 2D vectors is not really a cross product, it is the
955  * magnitude of the vector resulting from a 3D cross product of 2D vectors
956  * with @f$ z = 0 @f$. The cross product @f$ \mathbf{a} \times \mathbf{b} @f$
957  * of the vectors @f$ \mathbf{a} @f$ and @f$ \mathbf{b} @f$ is:
958  *
959  * @f[ \mathbf{a} \times \mathbf{b} = \mathbf{a}^{\perp} \cdot \mathbf{b} @f]
960  *
961  * The 2D cross product is also known as the perp dot product or wedge product.
962  *
963  * @param lhs A first vector
964  * @param rhs A second vector
965  * @return The cross product of the two vectors
966  */
967  template<typename T>
968  constexpr
969  T cross(Vector<T, 2> lhs, Vector<T, 2> rhs) {
970  return lhs.x * rhs.y - lhs.y * rhs.x;
971  }
972 
973 
974  /**
975  * @relates Vector
976  * @brief Cross product for 3D vectors
977  *
978  * @param lhs A first vector
979  * @param rhs A second vector
980  * @return The cross product of the two vectors
981  */
982  template<typename T>
983  constexpr
984  Vector<T, 3> cross(Vector<T, 3> lhs, Vector<T, 3> rhs) {
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
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
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
float angle(Vector< T, 2 > vec)
Angle of a vector relative to the x-axis.
Definition: VectorOps.h:890
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
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
Vector< bool, N > operator&&(Vector< bool, N > lhs, Vector< bool, N > rhs)
Component-wise logical and operator.
Definition: VectorOps.h:407
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
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
General purpose math vector.
Definition: Vector.h:60
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