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