Gamedev Framework (gf)  0.6.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  * @relates Vector
491  * @brief Component-wise sign value
492  */
493  template<typename T, std::size_t N>
494  inline
495  Vector<int, N> sign(Vector<T, N> val) {
496  Vector<int, N> out;
497 
498  for (std::size_t i = 0; i < N; ++i) {
499  out.data[i] = gf::sign(val.data[i]);
500  }
501 
502  return out;
503  }
504 
505  /**
506  * @relates Vector
507  * @brief Component-wise equality operator
508  */
509  template<typename T, std::size_t N>
510  inline
511  Vector<bool, N> equals(Vector<T, N> lhs, Vector<T, N> rhs) {
512  Vector<bool, N> out;
513 
514  for (std::size_t i = 0; i < N; ++i) {
515  out.data[i] = (lhs.data[i] == rhs.data[i]);
516  }
517 
518  return out;
519  }
520 
521  /**
522  * @relates Vector
523  * @brief Component-wise comparison operator
524  */
525  template<typename T, std::size_t N>
526  inline
527  Vector<bool, N> lessThan(Vector<T, N> lhs, Vector<T, N> rhs) {
528  Vector<bool, N> out;
529 
530  for (std::size_t i = 0; i < N; ++i) {
531  out.data[i] = (lhs.data[i] < rhs.data[i]);
532  }
533 
534  return out;
535  }
536 
537  /**
538  * @relates Vector
539  * @brief Component-wise comparison operator
540  */
541  template<typename T, std::size_t N>
542  inline
543  Vector<bool, N> greaterThan(Vector<T, N> lhs, Vector<T, N> rhs) {
544  Vector<bool, N> out;
545 
546  for (std::size_t i = 0; i < N; ++i) {
547  out.data[i] = (lhs.data[i] > rhs.data[i]);
548  }
549 
550  return out;
551  }
552 
553  /**
554  * @relates Vector
555  * @brief Component-wise selection operator
556  */
557  template<typename T, std::size_t N>
558  inline
559  Vector<T, N> select(Vector<bool, N> cond, Vector<T, N> lhs, Vector<T, N> rhs) {
560  Vector<T, N> out;
561 
562  for (std::size_t i = 0; i < N; ++i) {
563  out.data[i] = (cond.data[i] ? lhs.data[i] : rhs.data[i]);
564  }
565 
566  return out;
567  }
568 
569  /**
570  * @relates Vector
571  * @brief Component-wise clamp function
572  *
573  * Relative to two other vectors.
574  *
575  */
576  template<typename T, std::size_t N>
577  inline
578  Vector<T, N> clamp(Vector<T, N> val, Vector<T, N> lo, Vector<T, N> hi) {
579  Vector<T, N> out;
580 
581  for (std::size_t i = 0; i < N; ++i) {
582  out.data[i] = clamp(val.data[i], lo.data[i], hi.data[i]);
583  }
584 
585  return out;
586  }
587 
588  /**
589  * @relates Vector
590  * @brief Component-wise clamp function
591  *
592  * Relative to two values.
593  */
594  template<typename T, std::size_t N>
595  inline
596  Vector<T, N> clamp(Vector<T, N> val, T lo, T hi) {
597  Vector<T, N> out;
598 
599  for (std::size_t i = 0; i < N; ++i) {
600  out.data[i] = clamp(val.data[i], lo, hi);
601  }
602 
603  return out;
604  }
605 
606  /**
607  * @relates Vector
608  * @brief Component-wise lerp function
609  */
610  template<typename T, typename U, std::size_t N>
611  inline
612  Vector<T, N> lerp(Vector<T, N> lhs, Vector<T, N> rhs, U t) {
613  Vector<T, N> out;
614 
615  for (std::size_t i = 0; i < N; ++i) {
616  out.data[i] = lerp(lhs.data[i], rhs.data[i], t);
617  }
618 
619  return out;
620  // return (1 - t) * lhs + t * rhs;
621  }
622 
623  /**
624  * @relates Vector
625  * @brief Manhattan length of a vector
626  *
627  * The Manhattan length @f$ \|\mathbf{u}\|_1 @f$ of a vector
628  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
629  *
630  * @f[ \|\mathbf{u}\|_1 = \sum_{i = 1}^{N} |u_i| @f]
631  *
632  * The Manhattan length is also called the 1-norm.
633  *
634  * @param vec A vector.
635  * @returns The Manhattan length of the vector
636  *
637  * @sa manhattanDistance()
638  */
639  template<typename T, std::size_t N>
640  inline
641  T manhattanLength(Vector<T, N> vec) {
642  T out{0};
643 
644  for (std::size_t i = 0; i < N; ++i) {
645  out += std::abs(vec.data[i]);
646  }
647 
648  return out;
649  }
650 
651  /**
652  * @relates Vector
653  * @brief Square Euclidean length of a vector
654  *
655  * The square Euclidean length @f$ \|\mathbf{u}\|_2^2 @f$ of a vector
656  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
657  *
658  * @f[ \|\mathbf{u}\|_2^2 = \sum_{i = 1}^{N} u_i^2 @f]
659  *
660  * @param vec A vector.
661  * @returns The square Euclidean length of the vector
662  *
663  * @sa euclideanLength(), squareDistance()
664  */
665  template<typename T, std::size_t N>
666  inline
667  T squareLength(Vector<T, N> vec) {
668  T out{0};
669 
670  for (std::size_t i = 0; i < N; ++i) {
671  out += square(vec.data[i]);
672  }
673 
674  return out;
675  }
676 
677  /**
678  * @relates Vector
679  * @brief Euclidean length of a vector
680  *
681  * The Euclidean length @f$ \|\mathbf{u}\|_2 @f$ of a vector
682  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
683  *
684  * @f[ \|\mathbf{u}\|_2 = \sqrt{\sum_{i = 1}^{N} u_i^2} @f]
685  *
686  * The Euclidean length is also called the 2-norm.
687  *
688  * @param vec A vector.
689  * @returns The Euclidean length of the vector
690  *
691  * @sa euclideanDistance()
692  */
693  template<typename T, std::size_t N>
694  inline
695  T euclideanLength(Vector<T, N> vec) {
696  return std::sqrt(squareLength(vec));
697  }
698 
699 #ifndef DOXYGEN_SHOULD_SKIP_THIS
700  // specializations of euclideanLength for Vector2f and Vector2d using std::hypot
701 
702  template<>
703  inline
704  float euclideanLength<float, 2>(Vector<float, 2> vec) {
705  return std::hypot(vec.x, vec.y);
706  }
707 
708  template<>
709  inline
710  double euclideanLength<double, 2>(Vector<double, 2> vec) {
711  return std::hypot(vec.x, vec.y);
712  }
713 #endif
714 
715  /**
716  * @relates Vector
717  * @brief Chebyshev length of a vector
718  *
719  * The Chebyshev length @f$ \|\mathbf{u}\|_{\infty} @f$ of a vector
720  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
721  *
722  * @f[ \|u\|_{\infty} = \max_{i = 1}^{N} |u_i| @f]
723  *
724  * The Chebyshev length is also called the infinity norm or maximum norm.
725  *
726  * @param vec A vector.
727  * @returns The Chebyshev length of the vector
728  *
729  * @sa chebyshevDistance()
730  */
731  template<typename T, std::size_t N>
732  inline
733  T chebyshevLength(Vector<T, N> vec) {
734  T out = std::abs(vec.data[0]);
735 
736  for (std::size_t i = 1; i < N; ++i) {
737  out = std::max(out, std::abs(vec.data[i]));
738  }
739 
740  return out;
741  }
742 
743  /**
744  * @relates Vector
745  * @brief Natural length of a vector
746  *
747  * The natural length @f$ L @f$ of a vector:
748  * @f$ \mathbf{u} = (u_1, \ldots, u_N) @f$ is:
749  *
750  * @f[ L = \|\mathbf{u}\|_1 + \|\mathbf{u}\|_2^2
751  * = \sum_{i = 1}^{N} |u_i| + \sum_{i = 1}^{N} u_i^2 @f]
752  *
753  * It's the sum of the Manhattan length and the square length.
754  *
755  * @param vec A vector.
756  * @returns The natural length of the vector
757  *
758  * @sa naturalDistance()
759  */
760  template<typename T, std::size_t N>
761  inline
762  T naturalLength(Vector<T, N> vec) {
763  return manhattanLength(vec) + squareLength(vec);
764  }
765 
766  /**
767  * @relates Vector
768  * @brief Manhattan distance between two vectors
769  *
770  * The Manhattan distance between two vectors is the Manhattan length of the
771  * difference of the two vectors.
772  *
773  * @param lhs A first vector
774  * @param rhs A second vector
775  * @returns The Manhattan distance between the two vectors
776  *
777  * @sa manhattanLength()
778  */
779  template<typename T, std::size_t N>
780  inline
781  T manhattanDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
782  return manhattanLength(lhs - rhs);
783  }
784 
785  /**
786  * @relates Vector
787  * @brief Square Euclidean distance between two vectors
788  *
789  * The square Euclidean distance between two vectors is the square Euclidean
790  * length of the difference of the two vectors.
791  *
792  * @param lhs A first vector
793  * @param rhs A second vector
794  * @returns The square Euclidean distance between the two vectors
795  *
796  * @sa squareLength(), euclideanDistance()
797  */
798  template<typename T, std::size_t N>
799  inline
800  T squareDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
801  return squareLength(lhs - rhs);
802  }
803 
804  /**
805  * @relates Vector
806  * @brief Euclidean distance between two vectors
807  *
808  * The Euclidean distance between two vectors is the Euclidean length of the
809  * difference of the two vectors.
810  *
811  * @param lhs A first vector
812  * @param rhs A second vector
813  * @returns The Euclidean distance between the two vectors
814  *
815  * @sa euclideanLength()
816  */
817  template<typename T, std::size_t N>
818  inline
819  T euclideanDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
820  return euclideanLength(lhs - rhs);
821  }
822 
823  /**
824  * @relates Vector
825  * @brief Chebyshev distance between two vectors
826  *
827  * The Chebyshev distance between two vectors is the Chebyshev length of the
828  * difference of the two vectors.
829  *
830  * @param lhs A first vector
831  * @param rhs A second vector
832  * @returns The Chebyshev distance between the two vectors
833  *
834  * @sa chebyshevLength()
835  */
836  template<typename T, std::size_t N>
837  inline
838  T chebyshevDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
839  return chebyshevLength(lhs - rhs);
840  }
841 
842  /**
843  * @relates Vector
844  * @brief Natural distance between two vectors
845  *
846  * The natural distance between two vectors is the natural length of the
847  * difference of the two vectors.
848  *
849  * @param lhs A first vector
850  * @param rhs A second vector
851  * @returns The natural distance between the two vectors
852  *
853  * @sa naturalLength()
854  */
855  template<typename T, std::size_t N>
856  inline
857  T naturalDistance(Vector<T, N> lhs, Vector<T, N> rhs) {
858  return naturalLength(lhs - rhs);
859  }
860 
861  /**
862  * @relates Vector
863  * @brief Normalize a vector
864  *
865  * The normalized vector of @f$ \mathbf{u} @f$ is a vector in the same
866  * direction but with a (euclidean) length of 1:
867  *
868  * @f[ \frac{\mathbf{u}}{\|\mathbf{u}\|_2} @f]
869  *
870  * A normalized vector is also called a
871  * [unit vector](https://en.wikipedia.org/wiki/Unit_vector).
872  *
873  * @param vec A vector
874  * @returns A normalized vector
875  */
876  template<typename T, std::size_t N>
877  inline
878  Vector<T, N> normalize(Vector<T, N> vec) {
879  T length = euclideanLength(vec);
880  return vec / length;
881  }
882 
883  /**
884  * @relates Vector
885  * @brief Unit vector in a specified direction
886  *
887  * @param angle The angle of the direction
888  * @return A unit vector
889  */
890  template<typename T>
891  inline
892  Vector<T, 2> unit(T angle) {
893  return { std::cos(angle), std::sin(angle) };
894  }
895 
896  /**
897  * @relates Vector
898  * @brief Angle of a vector relative to the x-axis
899  *
900  * @param vec The vector
901  * @returns The angle of the vector
902  */
903  template<typename T>
904  inline
905  float angle(Vector<T, 2> vec) {
906  return std::atan2(vec.y, vec.x);
907  }
908 
909  /**
910  * @relates Vector
911  * @brief Perpendicular vector
912  *
913  * The perpendicular vector @f$ \mathbf{u}^{\perp} @f$ of vector @f$ \mathbf{u} = (x, y) @f$ is:
914  *
915  * @f[ \mathbf{u}^{\perp} = (-y, x) @f]
916  *
917  * @param vec A vector
918  * @returns A perpendicular vector
919  */
920  template<typename T>
921  constexpr
922  Vector<T, 2> perp(Vector<T, 2> vec) {
923  return { -vec.y, vec.x };
924  }
925 
926  /**
927  * @relates Vector
928  * @brief Regular vector triple product
929  *
930  * The regular [vector triple product](https://en.wikipedia.org/wiki/Triple_product#Vector_triple_product)
931  * of vectors @f$ \mathbf{a} @f$, @f$ \mathbf{b} @f$ and @f$ \mathbf{c} @f$
932  * is:
933  *
934  * @f[ \mathbf{a} \times (\mathbf{b} \times \mathbf{c})
935  * = (\mathbf{a} \cdot \mathbf{c}) \mathbf{b} - (\mathbf{a} \cdot \mathbf{b}) \mathbf{c} @f]
936  *
937  * @sa inverseVectorTripleProduct()
938  */
939  template<typename T>
940  inline
941  Vector<T, 2> vectorTripleProduct(Vector<T, 2> a, Vector<T, 2> b, Vector<T, 2> c) {
942  return dot(a, c) * b - dot(a, b) * c;
943  }
944 
945  /**
946  * @relates Vector
947  * @brief Inverse vector triple product
948  *
949  * The inverse [vector triple product](https://en.wikipedia.org/wiki/Triple_product#Vector_triple_product)
950  * of vectors @f$ \mathbf{a} @f$, @f$ \mathbf{b} @f$ and @f$ \mathbf{c} @f$
951  * is:
952  *
953  * @f[ (\mathbf{a} \times \mathbf{b}) \times \mathbf{c}
954  * = -\mathbf{c} \times (\mathbf{a} \times \mathbf{b})
955  * = -(\mathbf{c} \cdot \mathbf{b}) \mathbf{a} + (\mathbf{c} \cdot \mathbf{a}) \mathbf{b} @f]
956  *
957  * @sa vectorTripleProduct()
958  */
959  template<typename T>
960  inline
961  Vector<T, 2> inverseVectorTripleProduct(Vector<T, 2> a, Vector<T, 2> b, Vector<T, 2> c) {
962  return - dot(c, b) * a + dot(c, a) * b;
963  }
964 
965  /**
966  * @relates Vector
967  * @brief Cross product for 2D vectors
968  *
969  * The cross product of 2D vectors is not really a cross product, it is the
970  * magnitude of the vector resulting from a 3D cross product of 2D vectors
971  * with @f$ z = 0 @f$. The cross product @f$ \mathbf{a} \times \mathbf{b} @f$
972  * of the vectors @f$ \mathbf{a} @f$ and @f$ \mathbf{b} @f$ is:
973  *
974  * @f[ \mathbf{a} \times \mathbf{b} = \mathbf{a}^{\perp} \cdot \mathbf{b} @f]
975  *
976  * The 2D cross product is also known as the perp dot product or wedge product.
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  T cross(Vector<T, 2> lhs, Vector<T, 2> rhs) {
985  return lhs.x * rhs.y - lhs.y * rhs.x;
986  }
987 
988 
989  /**
990  * @relates Vector
991  * @brief Cross product for 3D vectors
992  *
993  * @param lhs A first vector
994  * @param rhs A second vector
995  * @return The cross product of the two vectors
996  */
997  template<typename T>
998  constexpr
999  Vector<T, 3> cross(Vector<T, 3> lhs, Vector<T, 3> rhs) {
1000  return {
1001  lhs.y * rhs.z - lhs.z * rhs.y,
1002  lhs.z * rhs.x - lhs.x * rhs.z,
1003  lhs.x * rhs.y - lhs.y * rhs.x
1004  };
1005  }
1006 
1007 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1008 }
1009 #endif
1010 }
1011 
1012 #endif // GF_VECTOR_OPS_H
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:695
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:578
Vector< bool, N > greaterThan(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise comparison operator.
Definition: VectorOps.h:543
constexpr Vector< T, 3 > cross(Vector< T, 3 > lhs, Vector< T, 3 > rhs)
Cross product for 3D vectors.
Definition: VectorOps.h:999
Vector< T, 2 > vectorTripleProduct(Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c)
Regular vector triple product.
Definition: VectorOps.h:941
Vector< T, N > & 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:511
Vector< T, N > normalize(Vector< T, N > vec)
Normalize a vector.
Definition: VectorOps.h:878
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:905
Vector< bool, N > operator&&(Vector< bool, N > lhs, Vector< bool, N > rhs)
Component-wise logical and operator.
Definition: VectorOps.h:407
T squareDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Square Euclidean distance between two vectors.
Definition: VectorOps.h:800
Vector< bool, N > lessThan(Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise comparison operator.
Definition: VectorOps.h:527
Vector< T, N > select(Vector< bool, N > cond, Vector< T, N > lhs, Vector< T, N > rhs)
Component-wise selection operator.
Definition: VectorOps.h:559
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:596
Vector< T, 2 > unit(T angle)
Unit vector in a specified direction.
Definition: VectorOps.h:892
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:781
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:733
Vector< int, N > sign(Vector< T, N > val)
Component-wise sign value.
Definition: VectorOps.h:495
T euclideanDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Euclidean distance between two vectors.
Definition: VectorOps.h:819
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:612
T manhattanLength(Vector< T, N > vec)
Manhattan length of a vector.
Definition: VectorOps.h:641
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:961
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:922
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:857
T naturalLength(Vector< T, N > vec)
Natural length of a vector.
Definition: VectorOps.h:762
T squareLength(Vector< T, N > vec)
Square Euclidean length of a vector.
Definition: VectorOps.h:667
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:984
T chebyshevDistance(Vector< T, N > lhs, Vector< T, N > rhs)
Chebyshev distance between two vectors.
Definition: VectorOps.h:838