Ocean
Vector2.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_MATH_VECTOR2_H
9 #define META_OCEAN_MATH_VECTOR2_H
10 
11 #include "ocean/math/Math.h"
12 #include "ocean/math/Numeric.h"
13 
14 #include <type_traits>
15 #include <vector>
16 
17 namespace Ocean
18 {
19 
20 // Forward declaration.
21 template <typename T> class VectorT2;
22 
23 /**
24  * Definition of a 2D vector.
25  * @see VectorT2
26  * @ingroup math
27  */
29 
30 /**
31  * Definition of a 2D vector with double values.
32  * @see VectorT2
33  * @ingroup math
34  */
36 
37 /**
38  * Definition of a 2D vector with float values.
39  * @see VectorT2
40  * @ingroup math
41  */
43 
44 /**
45  * Definition of a 2D vector with integer values.
46  * @see VectorT2
47  * @ingroup math
48  */
50 
51 /**
52  * Definition of a typename alias for vectors with VectorT2 objects.
53  * @see VectorT2
54  * @ingroup math
55  */
56 template <typename T>
57 using VectorsT2 = std::vector<VectorT2<T>>;
58 
59 /**
60  * Definition of a vector holding Vector2 objects.
61  * @see Vector2
62  * @ingroup math
63  */
64 typedef std::vector<Vector2> Vectors2;
65 
66 /**
67  * Definition of a vector holding VectorD2 objects.
68  * @see VectorD2
69  * @ingroup math
70  */
71 typedef std::vector<VectorD2> VectorsD2;
72 
73 /**
74  * Definition of a vector holding VectorF2 objects.
75  * @see VectorF2
76  * @ingroup math
77  */
78 typedef std::vector<VectorF2> VectorsF2;
79 
80 /**
81  * Definition of a vector holding VectorI2 objects.
82  * @see VectorI2
83  * @ingroup math
84  */
85 typedef std::vector<VectorI2> VectorsI2;
86 
87 /**
88  * This class implements a vector with two elements.
89  * The element order is: (x, y).
90  * @tparam T Data type of the vector elements.
91  * @see Vector2, VectorF2, VectorF3.
92  * @ingroup math
93  */
94 template <typename T>
95 class VectorT2
96 {
97  public:
98 
99  /**
100  * Definition of the used data type.
101  */
102  typedef T Type;
103 
104  public:
105 
106  /**
107  * Creates a new 2D vector with undefined elements.
108  * Beware: The elements are neither zero nor a specific value!
109  * This is useful in situations where VectorT2 objects are created (e.g, by a large array or vector)
110  * and their values are assigned in a function afterwards.
111  */
112  inline VectorT2() noexcept;
113 
114  /**
115  * Creates a new 2D vector.
116  * @param setToHomogeneous Determines whether a homogeneous vector (0, 1) will be created, otherwise the vector is initialized with zeros
117  */
118  inline explicit VectorT2(const bool setToHomogeneous) noexcept;
119 
120  /**
121  * Creates a new 2D vector with specified coordinates.
122  * @param x X value
123  * @param y Y value
124  */
125  inline VectorT2(const T x, const T y) noexcept;
126 
127  /**
128  * Creates a new 2D vector with a given array of elements.
129  * @param valueArray Array with at least two elements
130  */
131  inline explicit VectorT2(const T* valueArray) noexcept;
132 
133  /**
134  * Copies a vector.
135  * @param vector 2D vector that is copied
136  */
137  inline VectorT2(const VectorT2<T>& vector) noexcept;
138 
139  /**
140  * Copies a vector with different element data type than T.
141  * @param vector The 2D vector to copy
142  * @tparam U The element data type of the second vector
143  */
144  template <typename U>
145  inline explicit VectorT2(const VectorT2<U>& vector) noexcept;
146 
147  /**
148  * Returns the cross product of two 2D vectors.
149  * The cross product is the resulting z-component of a cross product between two 3D vectors having 0 as z-component.
150  * @param vector Right vector
151  * @return Cross product
152  * @see perpendicular().
153  */
154  inline T cross(const VectorT2<T>& vector) const;
155 
156  /**
157  * Returns a vector perpendicular to this vectors.
158  * The cross product between this vector and the resulting perpendicular vector will have a positive value.<br>
159  * @return Perpendicular vector with identical length as this vector
160  * @see cross().
161  */
162  inline VectorT2<T> perpendicular() const;
163 
164  /**
165  * Returns the normalized vector.
166  * Beware: This function does not throw an exception if this vector cannot be normalized.<br>
167  * Thus, ensure that this vector is not zero before calling this function.<br>
168  * Or even better, use different normalization functions like: normalizedOrZero(), normalizedOrValue(), or normalize().<br>
169  * In case, the vector cannot be normalized, an uninitialized vector will be returned (due to performance reasons).
170  * @return This vector as unit vector (vector with length 1)
171  * @see normalizedOrZero(), normalizedOrValue(), normalize().
172  */
173  inline VectorT2<T> normalized() const;
174 
175  /**
176  * Returns the normalized vector.
177  * If this vector cannot be normalized the zero vector is returned.
178  * @return Vector with length 1
179  */
180  inline VectorT2<T> normalizedOrZero() const;
181 
182  /**
183  * Returns the normalized vector.
184  * If this vector cannot be normalized the given vector is returned.
185  * @param value Vector that will be returned if the vector cannot be normalized
186  * @return Vector with length 1
187  */
188  inline VectorT2<T> normalizedOrValue(const VectorT2<T>& value) const;
189 
190  /**
191  * Normalizes this vector
192  * @return True, if the vector could be normalized
193  */
194  inline bool normalize();
195 
196  /**
197  * Returns the length of the vector.
198  * @return Vector length
199  */
200  inline T length() const;
201 
202  /**
203  * Returns the square of the vector length.
204  * @return Square of vector length
205  */
206  inline T sqr() const;
207 
208  /**
209  * Returns the distance between this 2D position and a second 2D position.
210  * @param right Second 2D position
211  * @return Distance between the two points
212  */
213  inline T distance(const VectorT2<T>& right) const;
214 
215  /**
216  * Returns the square distance between this 2D position and a second 2D position.
217  * @param right Second 2D position
218  * @return Square distance between the two points
219  */
220  inline T sqrDistance(const VectorT2<T>& right) const;
221 
222  /**
223  * Returns the angle between this vector and a second vectors.
224  * Beware: This vector must not be zero.<br>
225  * Beware: This function does not throw an exception if one or both vectors are zero.<br>
226  * In case, the angle cannot be determined -1 will be returned.
227  * @param right Second vector, must not be zero
228  * @return Angle between both vectors in radian, with range [0, PI], -1 in case of an error
229  * @see isNull().
230  */
231  T angle(const VectorT2<T>& right) const;
232 
233  /**
234  * Returns whether two vectors are parallel.
235  * A zero vector is be parallel.
236  * @param right The right vector
237  * @param epsilon The epsilon to be used, with range [0, infinity)
238  * @return True, if so
239  */
240  bool isParallel(const VectorT2<T>& right, const T epsilon = NumericT<T>::eps()) const;
241 
242  /**
243  * Returns whether two vectors are orthogonal.
244  * A zero vector is not orthogonal.
245  * @param right The right vector
246  * @param epsilon The epsilon to be used, with range [0, infinity)
247  * @return True, if so
248  */
249  bool isOrthogonal(const VectorT2<T>& right, const T epsilon = NumericT<T>::eps()) const;
250 
251  /**
252  * Returns the x value.
253  * @return X value
254  */
255  inline const T& x() const noexcept;
256 
257  /**
258  * Returns the x value.
259  * @return X value
260  */
261  inline T& x() noexcept;
262 
263  /**
264  * Returns the y value.
265  * @return Y value
266  */
267  inline const T& y() const noexcept;
268 
269  /**
270  * Returns the y value.
271  * @return Y value
272  */
273  inline T& y() noexcept;
274 
275  /**
276  * Returns an pointer to the vector elements.
277  * @return Pointer to elements
278  */
279  inline const T* data() const noexcept;
280 
281  /**
282  * Returns an pointer to the vector elements.
283  * @return Pointer to elements
284  */
285  inline T* data() noexcept;
286 
287  /**
288  * Returns whether this vector is a null vector up to a small epsilon.
289  * @return True, if so
290  */
291  inline bool isNull() const;
292 
293  /**
294  * Returns whether this vector is a unit vector (whether the vector has the length 1).
295  * @param eps Epsilon to be used, with range [0, infinity)
296  * @return True, if so
297  */
298  inline bool isUnit(const T eps = NumericT<T>::eps()) const;
299 
300  /**
301  * Returns whether two vectors are equal up to a specified epsilon.
302  * @param vector Second vector
303  * @param eps Epsilon to be used
304  * @return True, if so
305  */
306  inline bool isEqual(const VectorT2<T>& vector, const T eps) const;
307 
308  /**
309  * Copy assigns a vector
310  * @param vector 2D vector that is copied
311  */
312  inline VectorT2<T>& operator=(const VectorT2<T>& vector);
313 
314  /**
315  * Returns whether two vectors are identical up to a small epsilon.
316  * @param vector Right vector
317  * @return True, if so
318  */
319  inline bool operator==(const VectorT2<T>& vector) const;
320 
321  /**
322  * Returns whether two vectors are not identical up to a small epsilon.
323  * @param vector Right vector
324  * @return True, if so
325  */
326  inline bool operator!=(const VectorT2<T>& vector) const;
327 
328  /**
329  * Adds two vectors.
330  * @param vector Right vector
331  * @return Sum vector
332  */
333  inline VectorT2<T> operator+(const VectorT2<T>& vector) const;
334 
335  /**
336  * Adds and assigns two vectors.
337  * @param vector Right vector
338  * @return Reference to this vector
339  */
340  inline VectorT2<T>& operator+=(const VectorT2<T>& vector);
341 
342  /**
343  * Subtracts two vectors.
344  * @param vector Right vector
345  * @return Difference vector
346  */
347  inline VectorT2<T> operator-(const VectorT2<T>& vector) const;
348 
349  /**
350  * Subtracts and assigns two vectors.
351  * @param vector Right vector
352  * @return Reference to this vector
353  */
354  inline VectorT2<T>& operator-=(const VectorT2<T>& vector);
355 
356  /**
357  * Returns the negated vector.
358  * @return Negated vector
359  */
360  inline VectorT2<T> operator-() const;
361 
362  /**
363  * Returns the dot product of two vectors.
364  * @param vector Right vector
365  * @return Dot product
366  */
367  inline T operator*(const VectorT2<T>& vector) const;
368 
369  /**
370  * Multiplies this vector with a scalar.
371  * @param value Scalar value
372  * @return Resulting vector
373  */
374  inline VectorT2<T> operator*(const T& value) const;
375 
376  /**
377  * Multiplies and assigns this vector with a scalar.
378  * @param value Scalar value
379  * @return Reference to this vector
380  */
381  inline VectorT2<T>& operator*=(const T& value);
382 
383  /**
384  * Divides this vector by a scalar.
385  * Beware: This function does not throw an exception if the given value is zero.<br>
386  * Thus, ensure that given value is not zero before calling this function.<br>
387  * In case, the given value is zero, the result is undefined.
388  * @param value Scalar value to be used as denominator, must not be zero
389  * @return Resulting vector
390  */
391  inline VectorT2<T> operator/(const T& value) const;
392 
393  /**
394  * Divides and assigns this vector by a scalar.
395  * Beware: This function does not throw an exception if the given value is zero.<br>
396  * Thus, ensure that given value is not zero before calling this function.<br>
397  * In case, the given value is zero, the result is undefined.
398  * @param value Scalar value to be used as denominator, must not be zero
399  * @return Reference to this vector
400  */
401  inline VectorT2<T>& operator/=(const T& value);
402 
403  /**
404  * Compares two vector objects and returns whether the left vector represents a smaller value than the right vector.
405  * First the first component of both vectors are compared, if these values are equal then the next components are compares and so on.<br>
406  * @param vector The second vector to compare
407  * @return True, if so
408  */
409  inline bool operator<(const VectorT2<T>& vector) const;
410 
411  /**
412  * Element access operator.
413  * @param index Index of the element to access, with range [0, 1]
414  * @return Element of the vector
415  */
416  inline const T& operator[](const unsigned int index) const noexcept;
417 
418  /**
419  * Element access operator.
420  * @param index Index of the element to access, with range [0, 1]
421  * @return Element of the vector
422  */
423  inline T& operator[](const unsigned int index) noexcept;
424 
425  /**
426  * Element access operator.
427  * @param index Index of the element to access, with range [0, 1]
428  * @return Element of the vector
429  */
430  inline const T& operator()(const unsigned int index) const noexcept;
431 
432  /**
433  * Element access operator.
434  * @param index Index of the element to access, with range [0, 1]
435  * @return Element of the vector
436  */
437  inline T& operator()(const unsigned int index) noexcept;
438 
439  /**
440  * Access operator.
441  * @return Pointer to the elements
442  */
443  inline const T* operator()() const noexcept;
444 
445  /**
446  * Access operator.
447  * @return Pointer to the elements
448  */
449  inline T* operator()() noexcept;
450 
451  /**
452  * Hash function.
453  * @param vector The vector for which the hash value will be determined
454  * @return The resulting hash value
455  */
456  inline size_t operator()(const VectorT2<T>& vector) const;
457 
458  /**
459  * Converts vectors with specific data type to vectors with different data type.
460  * @param vectors The vectors to convert
461  * @return The converted vectors
462  * @tparam U The element data type of the vectors to convert
463  */
464  template <typename U>
465  static inline std::vector<VectorT2<T>> vectors2vectors(std::vector<VectorT2<U>>&& vectors);
466 
467  /**
468  * Converts vectors with specific data type to vectors with different data type.
469  * @param vectors The vectors to convert
470  * @return The converted vectors
471  * @tparam U The element data type of the vectors to convert
472  */
473  template <typename U>
474  static inline std::vector<VectorT2<T>> vectors2vectors(const std::vector<VectorT2<U>>& vectors);
475 
476  /**
477  * Converts vectors with specific data type to vectors with different data type.
478  * @param vectors The vectors to convert
479  * @param size The number of vector to convert
480  * @return The converted vectors
481  * @tparam U The element data type of the vectors to convert
482  */
483  template <typename U>
484  static inline std::vector<VectorT2<T>> vectors2vectors(const VectorT2<U>* vectors, const size_t size);
485 
486  protected:
487 
488  /// The two values of the vector, with element order x, y.
489  T values_[2];
490 };
491 
492 template <typename T>
493 inline VectorT2<T>::VectorT2() noexcept
494 {
495  static_assert(std::is_arithmetic<T>::value, "VectorT2 only supports arithmetic types");
496  // nothing to do here
497 }
498 
499 template <typename T>
500 inline VectorT2<T>::VectorT2(const bool setToHomogeneous) noexcept
501 {
502  if (setToHomogeneous)
503  {
504  values_[0] = T(0.0);
505  values_[1] = T(1.0);
506  }
507  else
508  {
509  values_[0] = T(0.0);
510  values_[1] = T(0.0);
511  }
512 }
513 
514 template <typename T>
515 inline VectorT2<T>::VectorT2(const T x, const T y) noexcept
516 {
517  values_[0] = x;
518  values_[1] = y;
519 }
520 
521 template <typename T>
522 inline VectorT2<T>::VectorT2(const T* valueArray) noexcept
523 {
524  values_[0] = valueArray[0];
525  values_[1] = valueArray[1];
526 }
527 
528 template <typename T>
529 inline VectorT2<T>::VectorT2(const VectorT2<T>& vector) noexcept
530 {
531  values_[0] = vector.values_[0];
532  values_[1] = vector.values_[1];
533 }
534 
535 template <typename T>
536 template <typename U>
537 inline VectorT2<T>::VectorT2(const VectorT2<U>& vector) noexcept
538 {
539  values_[0] = T(vector[0]);
540  values_[1] = T(vector[1]);
541 }
542 
543 template <typename T>
544 inline T VectorT2<T>::cross(const VectorT2<T>& vector) const
545 {
546  return values_[0] * vector.values_[1] - vector.values_[0] * values_[1];
547 }
548 
549 template <typename T>
551 {
552  ocean_assert((values_[0] == 0 && values_[1] == 0) || cross(VectorT2<T>(-values_[1], values_[0])) > 0);
553 
554  return VectorT2<T>(-values_[1], values_[0]);
555 }
556 
557 template <typename T>
559 {
560  T len = length();
561  if (NumericT<T>::isEqualEps(len))
562  {
563  ocean_assert(false && "Devision by zero!");
564  return VectorT2<T>();
565  }
566 
567  const T factor = T(1) / len;
568  return VectorT2<T>(values_[0] * factor, values_[1] * factor);
569 }
570 
571 template <typename T>
573 {
574  const T len = length();
575 
576  if (NumericT<T>::isEqualEps(len))
577  {
578  return *this;
579  }
580 
581  const T factor = T(1) / len;
582  return VectorT2<T>(values_[0] * factor, values_[1] * factor);
583 }
584 
585 template <typename T>
587 {
588  const T len = length();
589 
590  if (NumericT<T>::isEqualEps(len))
591  {
592  return value;
593  }
594 
595  const T factor = T(1) / len;
596  return VectorT2<T>(values_[0] * factor, values_[1] * factor);
597 }
598 
599 template <typename T>
601 {
602  const T len = length();
603  if (NumericT<T>::isEqualEps(len))
604  {
605  return false;
606  }
607 
608  const T factor = T(1) / len;
609  values_[0] *= factor;
610  values_[1] *= factor;
611  return true;
612 }
613 
614 template <typename T>
615 inline T VectorT2<T>::length() const
616 {
617  return NumericT<T>::sqrt(values_[0] * values_[0] + values_[1] * values_[1]);
618 }
619 
620 template <typename T>
621 inline T VectorT2<T>::sqr() const
622 {
623  return values_[0] * values_[0] + values_[1] * values_[1];
624 }
625 
626 template <typename T>
627 inline T VectorT2<T>::distance(const VectorT2<T>& right) const
628 {
629  return NumericT<T>::sqrt(sqrDistance(right));
630 }
631 
632 template <typename T>
633 inline T VectorT2<T>::sqrDistance(const VectorT2<T>& right) const
634 {
635 #ifdef OCEAN_DEBUG
636  if (!std::is_same<T, typename SignedTyper<T>::Type>::value)
637  {
638  typedef typename SignedTyper<T>::Type SignedT;
639 
640  // -15 == 46 - 61
641  // 225 == -15 * -15
642 
643  // 4294967281u == 46u - 61u
644  // 225u == 4294967281u * 4294967281u
645 
646  const SignedT debugSqr = NumericT<SignedT>::sqr(SignedT(values_[0]) - SignedT(right.values_[0])) + NumericT<SignedT>::sqr(SignedT(values_[1]) - SignedT(right.values_[1]));
647 
648  ocean_assert(T(debugSqr) == NumericT<T>::sqr(values_[0] - right.values_[0]) + NumericT<T>::sqr(values_[1] - right.values_[1]));
649  }
650 #endif
651 
652  return NumericT<T>::sqr(values_[0] - right.values_[0]) + NumericT<T>::sqr(values_[1] - right.values_[1]);
653 }
654 
655 template <typename T>
656 T VectorT2<T>::angle(const VectorT2<T>& right) const
657 {
658  // a * b = cos * |a| * |b|
659  // cos = (a * b) / (|a| * |b|)
660  // we separate the sqrt determinations to receive a higher accuracy
661 
662  const T thisLength = length();
663  const T rightLength = right.length();
664 
665  if (NumericT<T>::isEqualEps(thisLength) || NumericT<T>::isEqualEps(rightLength))
666  {
667  ocean_assert(false && "Invalid vector!");
668  return T(-1);
669  }
670 
671  const T dot = values_[0] * right.values_[0] + values_[1] * right.values_[1];
672 
673  return NumericT<T>::acos((dot / thisLength) / rightLength);
674 }
675 
676 template <typename T>
677 bool VectorT2<T>::isParallel(const VectorT2<T>& right, const T epsilon) const
678 {
679  ocean_assert(epsilon >= T(0));
680 
681  const VectorT2<T> normalizedThis(normalizedOrZero());
682  const VectorT2<T> normalizedRight(right.normalizedOrZero());
683 
684  const T dotProduct = normalizedThis * normalizedRight;
685 
686  return NumericT<T>::isEqual(dotProduct, T(1), epsilon) || NumericT<T>::isEqual(dotProduct, T(-1), epsilon);
687 }
688 
689 template <typename T>
690 bool VectorT2<T>::isOrthogonal(const VectorT2<T>& right, const T epsilon) const
691 {
692  ocean_assert(epsilon >= T(0));
693 
694  return NumericT<T>::isEqual(values_[0] * right.values_[0] + values_[1] * right.values_[1], T(0), epsilon);
695 }
696 
697 template <typename T>
698 inline const T& VectorT2<T>::x() const noexcept
699 {
700  return values_[0];
701 }
702 
703 template <typename T>
704 inline T& VectorT2<T>::x() noexcept
705 {
706  return values_[0];
707 }
708 
709 template <typename T>
710 inline const T& VectorT2<T>::y() const noexcept
711 {
712  return values_[1];
713 }
714 
715 template <typename T>
716 inline T& VectorT2<T>::y() noexcept
717 {
718  return values_[1];
719 }
720 
721 template <typename T>
722 inline const T* VectorT2<T>::data() const noexcept
723 {
724  return values_;
725 }
726 
727 template <typename T>
728 inline T* VectorT2<T>::data() noexcept
729 {
730  return values_;
731 }
732 
733 template <typename T>
734 inline bool VectorT2<T>::isNull() const
735 {
737 }
738 
739 template <typename T>
740 inline bool VectorT2<T>::isUnit(const T eps) const
741 {
742  return NumericT<T>::isEqual(length(), T(1), eps);
743 }
744 
745 template <typename T>
746 inline bool VectorT2<T>::isEqual(const VectorT2<T>& vector, const T eps) const
747 {
748  return NumericT<T>::isEqual(values_[0], vector.values_[0], eps)
749  && NumericT<T>::isEqual(values_[1], vector.values_[1], eps);
750 }
751 
752 template <typename T>
754 {
755  if (this == &vector)
756  {
757  return *this;
758  }
759 
760  values_[0] = vector.values_[0];
761  values_[1] = vector.values_[1];
762 
763  return *this;
764 }
765 
766 template <typename T>
767 inline bool VectorT2<T>::operator==(const VectorT2<T>& vector) const
768 {
769  return NumericT<T>::isEqual(values_[0], vector.values_[0])
770  && NumericT<T>::isEqual(values_[1], vector.values_[1]);
771 }
772 
773 template <typename T>
774 inline bool VectorT2<T>::operator!=(const VectorT2<T>& vector) const
775 {
776  return NumericT<T>::isNotEqual(values_[0], vector.values_[0])
777  || NumericT<T>::isNotEqual(values_[1], vector.values_[1]);
778 }
779 
780 template <typename T>
781 inline VectorT2<T> VectorT2<T>::operator+(const VectorT2<T>& vector) const
782 {
783  return VectorT2<T>(values_[0] + vector.values_[0], values_[1] + vector.values_[1]);
784 }
785 
786 template <typename T>
788 {
789  values_[0] += vector.values_[0];
790  values_[1] += vector.values_[1];
791 
792  return *this;
793 }
794 
795 template <typename T>
796 inline VectorT2<T> VectorT2<T>::operator-(const VectorT2<T>& vector) const
797 {
798  return VectorT2<T>(values_[0] - vector.values_[0], values_[1] - vector.values_[1]);
799 }
800 
801 template <typename T>
803 {
804  values_[0] -= vector.values_[0];
805  values_[1] -= vector.values_[1];
806 
807  return *this;
808 }
809 
810 template <typename T>
812 {
813  return VectorT2<T>(-values_[0], -values_[1]);
814 }
815 
816 template <typename T>
817 inline T VectorT2<T>::operator*(const VectorT2<T>& vector) const
818 {
819  return values_[0] * vector.values_[0] + values_[1] * vector.values_[1];
820 }
821 
822 template <typename T>
823 inline VectorT2<T> VectorT2<T>::operator*(const T& value) const
824 {
825  return VectorT2<T>(values_[0] * value, values_[1] * value);
826 }
827 
828 template <typename T>
829 inline VectorT2<T>& VectorT2<T>::operator*=(const T& value)
830 {
831  values_[0] *= value;
832  values_[1] *= value;
833 
834  return *this;
835 }
836 
837 template <typename T>
838 inline VectorT2<T> VectorT2<T>::operator/(const T& value) const
839 {
840  ocean_assert(NumericT<T>::isNotEqualEps(value));
841  const T factor = T(1) / value;
842 
843  return VectorT2<T>(values_[0] * factor, values_[1] * factor);
844 }
845 
846 template <typename T>
847 inline VectorT2<T>& VectorT2<T>::operator/=(const T& value)
848 {
849  ocean_assert(NumericT<T>::isNotEqualEps(value));
850  const T factor = T(1) / value;
851 
852  values_[0] *= factor;
853  values_[1] *= factor;
854 
855  return *this;
856 }
857 
858 template <typename T>
859 inline bool VectorT2<T>::operator<(const VectorT2<T>& vector) const
860 {
861  return values_[0] < vector.values_[0] || (values_[0] == vector.values_[0] && values_[1] < vector.values_[1]);
862 }
863 
864 template <typename T>
865 inline const T& VectorT2<T>::operator[](const unsigned int index) const noexcept
866 {
867  ocean_assert(index < 2u);
868  return values_[index];
869 }
870 
871 template <typename T>
872 inline T& VectorT2<T>::operator[](const unsigned int index) noexcept
873 {
874  ocean_assert(index < 2u);
875  return values_[index];
876 }
877 
878 template <typename T>
879 inline const T& VectorT2<T>::operator()(const unsigned int index) const noexcept
880 {
881  ocean_assert(index < 2u);
882  return values_[index];
883 }
884 
885 template <typename T>
886 inline T& VectorT2<T>::operator()(const unsigned int index) noexcept
887 {
888  ocean_assert(index < 2u);
889  return values_[index];
890 }
891 
892 template <typename T>
893 inline const T* VectorT2<T>::operator()() const noexcept
894 {
895  return values_;
896 }
897 
898 template <typename T>
899 inline T* VectorT2<T>::operator()() noexcept
900 {
901  return values_;
902 }
903 
904 template <typename T>
905 inline size_t VectorT2<T>::operator()(const VectorT2<T>& vector) const
906 {
907  size_t seed = std::hash<T>{}(vector.x());
908  seed ^= std::hash<T>{}(vector.y()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
909 
910  return seed;
911 }
912 
913 template <>
914 template <>
915 inline std::vector<VectorT2<float>> VectorT2<float>::vectors2vectors(std::vector<VectorT2<float>>&& vectors)
916 {
917  return std::move(vectors);
918 }
919 
920 template <>
921 template <>
922 inline std::vector<VectorT2<double>> VectorT2<double>::vectors2vectors(std::vector<VectorT2<double>>&& vectors)
923 {
924  return std::move(vectors);
925 }
926 
927 template <typename T>
928 template <typename U>
929 inline std::vector<VectorT2<T>> VectorT2<T>::vectors2vectors(std::vector<VectorT2<U>>&& vectors)
930 {
931  std::vector<VectorT2<T>> result;
932  result.reserve(vectors.size());
933 
934  for (typename std::vector<VectorT2<U>>::const_iterator i = vectors.cbegin(); i != vectors.cend(); ++i)
935  {
936  result.emplace_back(*i);
937  }
938 
939  return result;
940 }
941 
942 template <>
943 template <>
944 inline std::vector<VectorT2<float>> VectorT2<float>::vectors2vectors(const std::vector<VectorT2<float>>& vectors)
945 {
946  return vectors;
947 }
948 
949 template <>
950 template <>
951 inline std::vector<VectorT2<double>> VectorT2<double>::vectors2vectors(const std::vector<VectorT2<double>>& vectors)
952 {
953  return vectors;
954 }
955 
956 template <typename T>
957 template <typename U>
958 inline std::vector<VectorT2<T>> VectorT2<T>::vectors2vectors(const std::vector<VectorT2<U>>& vectors)
959 {
960  std::vector<VectorT2<T>> result;
961  result.reserve(vectors.size());
962 
963  for (typename std::vector<VectorT2<U>>::const_iterator i = vectors.cbegin(); i != vectors.cend(); ++i)
964  {
965  result.emplace_back(*i);
966  }
967 
968  return result;
969 }
970 
971 template <typename T>
972 template <typename U>
973 inline std::vector<VectorT2<T>> VectorT2<T>::vectors2vectors(const VectorT2<U>* vectors, const size_t size)
974 {
975  std::vector<VectorT2<T>> result;
976  result.reserve(size);
977 
978  for (size_t n = 0; n < size; ++n)
979  {
980  result.emplace_back(vectors[n]);
981  }
982 
983  return result;
984 }
985 
986 template <typename T>
987 std::ostream& operator<<(std::ostream& stream, const VectorT2<T>& vector)
988 {
989  stream << "[" << vector.x() << ", " << vector.y() << "]";
990 
991  return stream;
992 }
993 
994 template <bool tActive, typename T>
995 MessageObject<tActive>& operator<<(MessageObject<tActive>& messageObject, const VectorT2<T>& vector)
996 {
997  return messageObject << "[" << vector.x() << ", " << vector.y() << "]";
998 }
999 
1000 template <bool tActive, typename T>
1001 MessageObject<tActive>& operator<<(MessageObject<tActive>&& messageObject, const VectorT2<T>& vector)
1002 {
1003  return messageObject << "[" << vector.x() << ", " << vector.y() << "]";
1004 }
1005 
1006 }
1007 
1008 #endif // META_OCEAN_MATH_VECTOR2_H
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static T sqrt(const T value)
Returns the square root of a given value.
Definition: Numeric.h:1533
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition: Numeric.h:2386
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition: Numeric.h:1495
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition: Numeric.h:2087
static T acos(const T value)
Returns the arccosine of a given value.
Definition: Numeric.h:2907
static bool isNotEqual(const T first, const T second)
Returns whether two values are not equal up to a small epsilon.
Definition: Numeric.h:2613
T Type
Definition of the signed data type, if existing.
Definition: DataType.h:294
const T & x() const noexcept
Returns the x value.
Definition: Vector2.h:698
VectorT2< T > & operator*=(const T &value)
Multiplies and assigns this vector with a scalar.
Definition: Vector2.h:829
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
VectorT2< T > operator+(const VectorT2< T > &vector) const
Adds two vectors.
Definition: Vector2.h:781
VectorT2< T > & operator+=(const VectorT2< T > &vector)
Adds and assigns two vectors.
Definition: Vector2.h:787
VectorT2< T > & operator-=(const VectorT2< T > &vector)
Subtracts and assigns two vectors.
Definition: Vector2.h:802
const T * operator()() const noexcept
Access operator.
Definition: Vector2.h:893
bool isOrthogonal(const VectorT2< T > &right, const T epsilon=NumericT< T >::eps()) const
Returns whether two vectors are orthogonal.
Definition: Vector2.h:690
VectorT2< T > & operator/=(const T &value)
Divides and assigns this vector by a scalar.
Definition: Vector2.h:847
T operator*(const VectorT2< T > &vector) const
Returns the dot product of two vectors.
Definition: Vector2.h:817
const T & operator[](const unsigned int index) const noexcept
Element access operator.
Definition: Vector2.h:865
bool isUnit(const T eps=NumericT< T >::eps()) const
Returns whether this vector is a unit vector (whether the vector has the length 1).
Definition: Vector2.h:740
VectorT2< T > operator-() const
Returns the negated vector.
Definition: Vector2.h:811
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition: Vector2.h:722
bool operator==(const VectorT2< T > &vector) const
Returns whether two vectors are identical up to a small epsilon.
Definition: Vector2.h:767
T Type
Definition of the used data type.
Definition: Vector2.h:102
VectorT2< T > normalized() const
Returns the normalized vector.
Definition: Vector2.h:558
bool isEqual(const VectorT2< T > &vector, const T eps) const
Returns whether two vectors are equal up to a specified epsilon.
Definition: Vector2.h:746
T distance(const VectorT2< T > &right) const
Returns the distance between this 2D position and a second 2D position.
Definition: Vector2.h:627
VectorT2< T > normalizedOrZero() const
Returns the normalized vector.
Definition: Vector2.h:572
T angle(const VectorT2< T > &right) const
Returns the angle between this vector and a second vectors.
Definition: Vector2.h:656
T sqr() const
Returns the square of the vector length.
Definition: Vector2.h:621
static std::vector< VectorT2< T > > vectors2vectors(std::vector< VectorT2< U >> &&vectors)
Converts vectors with specific data type to vectors with different data type.
Definition: Vector2.h:929
VectorT2() noexcept
Creates a new 2D vector with undefined elements.
Definition: Vector2.h:493
VectorT2< T > normalizedOrValue(const VectorT2< T > &value) const
Returns the normalized vector.
Definition: Vector2.h:586
bool operator!=(const VectorT2< T > &vector) const
Returns whether two vectors are not identical up to a small epsilon.
Definition: Vector2.h:774
T values_[2]
The two values of the vector, with element order x, y.
Definition: Vector2.h:489
bool isNull() const
Returns whether this vector is a null vector up to a small epsilon.
Definition: Vector2.h:734
T sqrDistance(const VectorT2< T > &right) const
Returns the square distance between this 2D position and a second 2D position.
Definition: Vector2.h:633
VectorT2< T > & operator=(const VectorT2< T > &vector)
Copy assigns a vector.
Definition: Vector2.h:753
T length() const
Returns the length of the vector.
Definition: Vector2.h:615
bool normalize()
Normalizes this vector.
Definition: Vector2.h:600
bool operator<(const VectorT2< T > &vector) const
Compares two vector objects and returns whether the left vector represents a smaller value than the r...
Definition: Vector2.h:859
T cross(const VectorT2< T > &vector) const
Returns the cross product of two 2D vectors.
Definition: Vector2.h:544
bool isParallel(const VectorT2< T > &right, const T epsilon=NumericT< T >::eps()) const
Returns whether two vectors are parallel.
Definition: Vector2.h:677
VectorT2< T > operator/(const T &value) const
Divides this vector by a scalar.
Definition: Vector2.h:838
VectorT2< T > perpendicular() const
Returns a vector perpendicular to this vectors.
Definition: Vector2.h:550
VectorT2< int > VectorI2
Definition of a 2D vector with integer values.
Definition: Vector2.h:49
VectorT2< double > VectorD2
Definition of a 2D vector with double values.
Definition: Vector2.h:35
std::vector< VectorI2 > VectorsI2
Definition of a vector holding VectorI2 objects.
Definition: Vector2.h:85
std::vector< VectorD2 > VectorsD2
Definition of a vector holding VectorD2 objects.
Definition: Vector2.h:71
std::vector< VectorT2< T > > VectorsT2
Definition of a typename alias for vectors with VectorT2 objects.
Definition: Vector2.h:57
std::vector< VectorF2 > VectorsF2
Definition of a vector holding VectorF2 objects.
Definition: Vector2.h:78
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition: Vector2.h:64
VectorT2< float > VectorF2
Definition of a 2D vector with float values.
Definition: Vector2.h:42
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15
std::ostream & operator<<(std::ostream &stream, const HighPerformanceStatistic &highPerformanceStatistic)
Definition: HighPerformanceTimer.h:963