Ocean
Loading...
Searching...
No Matches
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
18namespace Ocean
19{
20
21// Forward declaration.
22template <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 */
57template <typename T>
58using VectorsT4 = std::vector<VectorT4<T>>;
59
60/**
61 * Definition of a vector holding Vector4 objects.
62 * @see Vector4
63 * @ingroup math
64 */
65typedef std::vector<Vector4> Vectors4;
66
67/**
68 * Definition of a vector holding VectorD4 objects.
69 * @see VectorD4
70 * @ingroup math
71 */
72typedef std::vector<VectorD4> VectorsD4;
73
74/**
75 * Definition of a vector holding VectorF4 objects.
76 * @see VectorF4
77 * @ingroup math
78 */
79typedef std::vector<VectorF4> VectorsF4;
80
81/**
82 * Definition of a vector holding VectorI4 objects.
83 * @see VectorI4
84 * @ingroup math
85 */
86typedef 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 */
95template <typename T>
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 * Returns a 4D vector with all elements set to NumericT::minValue().
470 * @return The resulting 4D vector
471 */
472 static inline VectorT4<T> minValue();
473
474 /**
475 * Returns a 4D vector with all elements set to NumericT::maxValue().
476 * @return The resulting 4D vector
477 */
478 static inline VectorT4<T> maxValue();
479
480 /**
481 * Converts vectors with specific data type to vectors with different data type.
482 * @param vectors The vectors to convert
483 * @return The converted vectors
484 * @tparam U The element data type of the vectors to convert
485 */
486 template <typename U>
487 static inline std::vector<VectorT4<T>> vectors2vectors(std::vector<VectorT4<U>>&& vectors);
488
489 /**
490 * Converts vectors with specific data type to vectors with different data type.
491 * @param vectors The vectors to convert
492 * @return The converted vectors
493 * @tparam U The element data type of the vectors to convert
494 */
495 template <typename U>
496 static inline std::vector<VectorT4<T>> vectors2vectors(const std::vector<VectorT4<U>>& vectors);
497
498 /**
499 * Converts vectors with specific data type to vectors with different data type.
500 * @param vectors The vectors to convert
501 * @param size The number of vector to convert
502 * @return The converted vectors
503 * @tparam U The element data type of the vectors to convert
504 */
505 template <typename U>
506 static inline std::vector<VectorT4<T>> vectors2vectors(const VectorT4<U>* vectors, const size_t size);
507
508 protected:
509
510 /// The four values of the vector, with element order x, y, z, w.
511 T values_[4] = {T(0), T(0), T(0), T(0)};
512};
513
514template <typename T>
515inline VectorT4<T>::VectorT4(const T& x, const T& y, const T& z, const T& w) noexcept
516{
517 values_[0] = x;
518 values_[1] = y;
519 values_[2] = z;
520 values_[3] = w;
521}
522
523template <typename T>
524inline VectorT4<T>::VectorT4(const VectorT3<T>& vector) noexcept
525{
526 memcpy(values_, vector(), sizeof(T) * 3);
527 values_[3] = T(1);
528}
529
530template <typename T>
531inline VectorT4<T>::VectorT4(const VectorT3<T>& vector, const T& w) noexcept
532{
533 memcpy(values_, vector(), sizeof(T) * 3);
534 values_[3] = w;
535}
536
537template <typename T>
538inline VectorT4<T>::VectorT4(const T* valueArray) noexcept
539{
540 memcpy(values_, valueArray, sizeof(T) * 4);
541}
542
543template <typename T>
544inline VectorT4<T>::VectorT4(const VectorT4<T>& vector) noexcept
545{
546 values_[0] = vector.values_[0];
547 values_[1] = vector.values_[1];
548 values_[2] = vector.values_[2];
549 values_[3] = vector.values_[3];
550}
551
552template <typename T>
553template <typename U>
554inline VectorT4<T>::VectorT4(const VectorT4<U>& vector) noexcept
555{
556 values_[0] = T(vector[0]);
557 values_[1] = T(vector[1]);
558 values_[2] = T(vector[2]);
559 values_[3] = T(vector[3]);
560}
561
562template <typename T>
564{
565 T len = length();
567 {
568 ocean_assert(false && "Division by zero!");
569 return VectorT4<T>();
570 }
571
572 T factor = T(1) / len;
573 return VectorT4<T>(values_[0] * factor, values_[1] * factor, values_[2] * factor, values_[3] * factor);
574}
575
576template <typename T>
578{
579 const T len = length();
580
582 {
583 return *this;
584 }
585
586 const T factor = T(1) / len;
587 return VectorT4<T>(values_[0] * factor, values_[1] * factor, values_[2] * factor, values_[3] * factor);
588}
589
590template <typename T>
592{
593 const T len = length();
594
596 {
597 return value;
598 }
599
600 const T factor = T(1) / len;
601 return VectorT4<T>(values_[0] * factor, values_[1] * factor, values_[2] * factor, values_[3] * factor);
602}
603
604template <typename T>
606{
607 const T len = length();
609 {
610 return false;
611 }
612
613 const T factor = T(1) / len;
614 values_[0] *= factor;
615 values_[1] *= factor;
616 values_[2] *= factor;
617 values_[3] *= factor;
618 return true;
619}
620
621template <typename T>
622inline T VectorT4<T>::length() const
623{
624 return NumericT<T>::sqrt(values_[0] * values_[0] + values_[1] * values_[1] + values_[2] * values_[2] + values_[3] * values_[3]);
625}
626
627template <typename T>
628inline T VectorT4<T>::sqr() const
629{
630 return values_[0] * values_[0] + values_[1] * values_[1] + values_[2] * values_[2] + values_[3] * values_[3];
631}
632
633template <typename T>
634T VectorT4<T>::angle(const VectorT4<T>& right) const
635{
636 // a * b = cos * |a| * |b|
637 // cos = (a * b) / (|a| * |b|)
638 // we separate the sqrt determinations to receive a higher accuracy
639
640 const T thisLength = length();
641 const T rightLength = right.length();
642
643 if (NumericT<T>::isEqualEps(thisLength) || NumericT<T>::isEqualEps(rightLength))
644 {
645 ocean_assert(false && "Invalid vector!");
646 return T(-1);
647 }
648
649 const T dot = values_[0] * right.values_[0] + values_[1] * right.values_[1] + values_[2] * right.values_[2] + values_[3] * right.values_[3];
650
651 return NumericT<T>::acos((dot / thisLength) / rightLength);
652}
653
654template <typename T>
655bool VectorT4<T>::isParallel(const VectorT4<T>& right) const
656{
657 const VectorT4<T> normalizedThis(normalizedOrZero());
658 const VectorT4<T> normalizedRight(right.normalizedOrZero());
659
660 const T dotProduct = normalizedThis * normalizedRight;
661
662 return NumericT<T>::isEqual(dotProduct, 1) || NumericT<T>::isEqual(dotProduct, -1);
663}
664
665template <typename T>
667{
668 return NumericT<T>::isEqualEps(values_[0] * right.values_[0] + values_[1] * right.values_[1] + values_[2] * right.values_[2] + values_[3] * right.values_[3]);
669}
670
671template <typename T>
672inline const T& VectorT4<T>::x() const noexcept
673{
674 return values_[0];
675}
676
677template <typename T>
678inline T& VectorT4<T>::x() noexcept
679{
680 return values_[0];
681}
682
683template <typename T>
684inline const T& VectorT4<T>::y() const noexcept
685{
686 return values_[1];
687}
688
689template <typename T>
690inline T& VectorT4<T>::y() noexcept
691{
692 return values_[1];
693}
694
695template <typename T>
696inline const T& VectorT4<T>::z() const noexcept
697{
698 return values_[2];
699}
700
701template <typename T>
702inline T& VectorT4<T>::z() noexcept
703{
704 return values_[2];
705}
706
707template <typename T>
708inline const T& VectorT4<T>::w() const noexcept
709{
710 return values_[3];
711}
712
713template <typename T>
714inline T& VectorT4<T>::w() noexcept
715{
716 return values_[3];
717}
718
719template <typename T>
720inline VectorT2<T> VectorT4<T>::xy() const noexcept
721{
722 return VectorT2<T>(values_[0], values_[1]);
723}
724
725template <typename T>
726inline VectorT3<T> VectorT4<T>::xyz() const noexcept
727{
728 return VectorT3<T>(values_[0], values_[1], values_[2]);
729}
730
731template <typename T>
732inline const T* VectorT4<T>::data() const noexcept
733{
734 return values_;
735}
736
737template <typename T>
738inline T* VectorT4<T>::data() noexcept
739{
740 return values_;
741}
742
743template <typename T>
744inline bool VectorT4<T>::isNull() const
745{
746 return NumericT<T>::isEqualEps(values_[0]) && NumericT<T>::isEqualEps(values_[1])
747 && NumericT<T>::isEqualEps(values_[2]) && NumericT<T>::isEqualEps(values_[3]);
748}
749
750template <typename T>
751inline bool VectorT4<T>::isUnit(const T eps) const
752{
753 return NumericT<T>::isEqual(length(), T(1), eps);
754}
755
756template <typename T>
757inline bool VectorT4<T>::isEqual(const VectorT4<T>& vector, const T eps) const
758{
759 return NumericT<T>::isEqual(values_[0], vector.values_[0], eps)
760 && NumericT<T>::isEqual(values_[1], vector.values_[1], eps)
761 && NumericT<T>::isEqual(values_[2], vector.values_[2], eps)
762 && NumericT<T>::isEqual(values_[3], vector.values_[3], eps);
763}
764
765template <typename T>
767{
768 if (this == &vector)
769 {
770 return *this;
771 }
772
773 values_[0] = vector.values_[0];
774 values_[1] = vector.values_[1];
775 values_[2] = vector.values_[2];
776 values_[3] = vector.values_[3];
777
778 return *this;
779}
780
781template <typename T>
782inline bool VectorT4<T>::operator==(const VectorT4<T>& vector) const
783{
784 return NumericT<T>::isEqual(values_[0], vector.values_[0])
785 && NumericT<T>::isEqual(values_[1], vector.values_[1])
786 && NumericT<T>::isEqual(values_[2], vector.values_[2])
787 && NumericT<T>::isEqual(values_[3], vector.values_[3]);
788}
789
790template <typename T>
791inline bool VectorT4<T>::operator!=(const VectorT4<T>& vector) const
792{
793 return NumericT<T>::isNotEqual(values_[0], vector.values_[0])
794 || NumericT<T>::isNotEqual(values_[1], vector.values_[1])
795 || NumericT<T>::isNotEqual(values_[2], vector.values_[2])
796 || NumericT<T>::isNotEqual(values_[3], vector.values_[3]);
797}
798
799template <typename T>
801{
802 return VectorT4<T>(values_[0] + vector.values_[0], values_[1] + vector.values_[1], values_[2] + vector.values_[2], values_[3] + vector.values_[3]);
803}
804
805template <typename T>
807{
808 values_[0] += vector.values_[0];
809 values_[1] += vector.values_[1];
810 values_[2] += vector.values_[2];
811 values_[3] += vector.values_[3];
812
813 return *this;
814}
815
816template <typename T>
818{
819 return VectorT4<T>(values_[0] - vector.values_[0], values_[1] - vector.values_[1], values_[2] - vector.values_[2], values_[3] - vector.values_[3]);
820}
821
822template <typename T>
824{
825 values_[0] -= vector.values_[0];
826 values_[1] -= vector.values_[1];
827 values_[2] -= vector.values_[2];
828 values_[3] -= vector.values_[3];
829
830 return *this;
831}
832
833template <typename T>
835{
836 return VectorT4<T>(-values_[0], -values_[1], -values_[2], -values_[3]);
837}
838
839template <typename T>
840inline T VectorT4<T>::operator*(const VectorT4<T>& vector) const
841{
842 return values_[0] * vector.values_[0] + values_[1] * vector.values_[1] + values_[2] * vector.values_[2] + values_[3] * vector.values_[3];
843}
844
845template <typename T>
846inline VectorT4<T> VectorT4<T>::operator*(const T& value) const
847{
848 return VectorT4<T>(values_[0] * value, values_[1] * value, values_[2] * value, values_[3] * value);
849}
850
851template <typename T>
853{
854 values_[0] *= value;
855 values_[1] *= value;
856 values_[2] *= value;
857 values_[3] *= value;
858
859 return *this;
860}
861
862template <typename T>
863inline VectorT4<T> VectorT4<T>::operator/(const T& value) const
864{
865 ocean_assert(NumericT<T>::isNotEqualEps(value));
866 const T factor = T(1) / value;
867
868 return VectorT4<T>(values_[0] * factor, values_[1] * factor, values_[2] * factor, values_[3] * factor);
869}
870
871template <typename T>
873{
874 ocean_assert(NumericT<T>::isNotEqualEps(value));
875
876 const T factor = T(1) / value;
877
878 values_[0] *= factor;
879 values_[1] *= factor;
880 values_[2] *= factor;
881 values_[3] *= factor;
882
883 return *this;
884}
885
886template <typename T>
887inline bool VectorT4<T>::operator<(const VectorT4<T>& right) const
888{
889 return values_[0] < right.values_[0]
890 || (values_[0] == right.values_[0] && (values_[1] < right.values_[1]
891 || (values_[1] == right.values_[1] && (values_[2] < right.values_[2]
892 || (values_[2] == right.values_[2] && values_[3] < right.values_[3])))));
893}
894
895template <typename T>
896inline const T& VectorT4<T>::operator[](const unsigned int index) const noexcept
897{
898 ocean_assert(index < 4u);
899 return values_[index];
900}
901
902template <typename T>
903inline T& VectorT4<T>::operator[](const unsigned int index) noexcept
904{
905 ocean_assert(index < 4u);
906 return values_[index];
907}
908
909template <typename T>
910inline const T& VectorT4<T>::operator()(const unsigned int index) const noexcept
911{
912 ocean_assert(index < 4u);
913 return values_[index];
914}
915
916template <typename T>
917inline T& VectorT4<T>::operator()(const unsigned int index) noexcept
918{
919 ocean_assert(index < 4u);
920 return values_[index];
921}
922
923template <typename T>
924inline const T* VectorT4<T>::operator()() const noexcept
925{
926 return values_;
927}
928
929template <typename T>
930inline T* VectorT4<T>::operator()() noexcept
931{
932 return values_;
933}
934
935template <typename T>
936inline size_t VectorT4<T>::operator()(const VectorT4<T>& vector) const
937{
938 size_t seed = std::hash<T>{}(vector.x());
939 seed ^= std::hash<T>{}(vector.y()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
940 seed ^= std::hash<T>{}(vector.z()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
941 seed ^= std::hash<T>{}(vector.w()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
942
943 return seed;
944}
945
946template <typename T>
951
952template <typename T>
957
958template <>
959template <>
960inline std::vector<VectorT4<float>> VectorT4<float>::vectors2vectors(std::vector<VectorT4<float>>&& vectors)
961{
962 return std::move(vectors);
963}
964
965template <>
966template <>
967inline std::vector<VectorT4<double>> VectorT4<double>::vectors2vectors(std::vector<VectorT4<double>>&& vectors)
968{
969 return std::move(vectors);
970}
971
972template <typename T>
973template <typename U>
974inline std::vector<VectorT4<T>> VectorT4<T>::vectors2vectors(std::vector<VectorT4<U>>&& vectors)
975{
976 std::vector<VectorT4<T>> result;
977 result.reserve(vectors.size());
978
979 for (typename std::vector<VectorT4<U>>::const_iterator i = vectors.cbegin(); i != vectors.cend(); ++i)
980 {
981 result.emplace_back(*i);
982 }
983
984 return result;
985}
986
987template <>
988template <>
989inline std::vector<VectorT4<float>> VectorT4<float>::vectors2vectors(const std::vector<VectorT4<float>>& vectors)
990{
991 return vectors;
992}
993
994template <>
995template <>
996inline std::vector<VectorT4<double>> VectorT4<double>::vectors2vectors(const std::vector<VectorT4<double>>& vectors)
997{
998 return vectors;
999}
1000
1001template <typename T>
1002template <typename U>
1003inline std::vector<VectorT4<T>> VectorT4<T>::vectors2vectors(const std::vector<VectorT4<U>>& vectors)
1004{
1005 std::vector<VectorT4<T>> result;
1006 result.reserve(vectors.size());
1007
1008 for (typename std::vector<VectorT4<U>>::const_iterator i = vectors.begin(); i != vectors.end(); ++i)
1009 {
1010 result.emplace_back(*i);
1011 }
1012
1013 return result;
1014}
1015
1016template <typename T>
1017template <typename U>
1018inline std::vector<VectorT4<T>> VectorT4<T>::vectors2vectors(const VectorT4<U>* vectors, const size_t size)
1019{
1020 std::vector<VectorT4<T>> result;
1021 result.reserve(size);
1022
1023 for (size_t n = 0; n < size; ++n)
1024 {
1025 result.emplace_back(vectors[n]);
1026 }
1027
1028 return result;
1029}
1030
1031template <typename T>
1032std::ostream& operator<<(std::ostream& stream, const VectorT4<T>& vector)
1033{
1034 stream << "[" << vector.x() << ", " << vector.y() << ", " << vector.z() << ", " << vector.w() << "]";
1035
1036 return stream;
1037}
1038
1039template <bool tActive, typename T>
1040MessageObject<tActive>& operator<<(MessageObject<tActive>& messageObject, const VectorT4<T>& vector)
1041{
1042 return messageObject << "[" << vector.x() << ", " << vector.y() << ", " << vector.z() << ", " << vector.w() << "]";
1043}
1044
1045template <bool tActive, typename T>
1046MessageObject<tActive>& operator<<(MessageObject<tActive>&& messageObject, const VectorT4<T>& vector)
1047{
1048 return messageObject << "[" << vector.x() << ", " << vector.y() << ", " << vector.z() << ", " << vector.w() << "]";
1049}
1050
1051}
1052
1053#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:863
VectorT3< T > xyz() const noexcept
Returns the x, y and z component of the vector as new 3D vector.
Definition Vector4.h:726
bool isOrthogonal(const VectorT4< T > &right) const
Returns whether two vectors are orthogonal.
Definition Vector4.h:666
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:974
const T * operator()() const noexcept
Access operator.
Definition Vector4.h:924
T Type
Definition of the used data type.
Definition Vector4.h:103
VectorT4< T > normalizedOrZero() const
Returns the normalized vector.
Definition Vector4.h:577
bool operator==(const VectorT4< T > &vector) const
Returns whether two vectors are identical up to a small epsilon.
Definition Vector4.h:782
T length() const
Returns the length of the vector.
Definition Vector4.h:622
const T & y() const noexcept
Returns the y value.
Definition Vector4.h:684
const T & x() const noexcept
Returns the x value.
Definition Vector4.h:672
bool operator!=(const VectorT4< T > &vector) const
Returns whether two vectors are not identical up to a small epsilon.
Definition Vector4.h:791
VectorT4< T > & operator+=(const VectorT4< T > &vector)
Adds and assigns two vectors.
Definition Vector4.h:806
bool isEqual(const VectorT4< T > &vector, const T eps) const
Returns whether two vectors are equal up to a specified epsilon.
Definition Vector4.h:757
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition Vector4.h:732
const T & z() const noexcept
Returns the z value.
Definition Vector4.h:696
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:744
VectorT4< T > normalized() const
Returns the normalized vector.
Definition Vector4.h:563
VectorT4< T > & operator/=(const T &value)
Divides and assigns this vector by a scalar.
Definition Vector4.h:872
VectorT4< T > & operator*=(const T &value)
Multiplies and assigns this vector with a scalar.
Definition Vector4.h:852
static VectorT4< T > maxValue()
Returns a 4D vector with all elements set to NumericT::maxValue().
Definition Vector4.h:953
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:751
VectorT4< T > normalizedOrValue(const VectorT4< T > &value) const
Returns the normalized vector.
Definition Vector4.h:591
T values_[4]
The four values of the vector, with element order x, y, z, w.
Definition Vector4.h:511
const T & operator[](const unsigned int index) const noexcept
Element access operator.
Definition Vector4.h:896
T operator*(const VectorT4< T > &vector) const
Returns the dot product of two vectors.
Definition Vector4.h:840
static VectorT4< T > minValue()
Returns a 4D vector with all elements set to NumericT::minValue().
Definition Vector4.h:947
VectorT4< T > operator+(const VectorT4< T > &vector) const
Adds two vectors.
Definition Vector4.h:800
T sqr() const
Returns the square of the vector length.
Definition Vector4.h:628
VectorT4< T > & operator=(const VectorT4< T > &vector)
Copy assigns a vector.
Definition Vector4.h:766
const T & w() const noexcept
Returns the w value.
Definition Vector4.h:708
bool normalize()
Normalizes this vector.
Definition Vector4.h:605
VectorT4< T > & operator-=(const VectorT4< T > &vector)
Subtracts and assigns two vectors.
Definition Vector4.h:823
VectorT2< T > xy() const noexcept
Returns the x and y component of the vector as new 2D vector.
Definition Vector4.h:720
VectorT4< T > operator-() const
Returns the negated vector.
Definition Vector4.h:834
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:887
T angle(const VectorT4< T > &right) const
Returns the angle between this vector and a second vectors.
Definition Vector4.h:634
bool isParallel(const VectorT4< T > &right) const
Returns whether two vectors are parallel.
Definition Vector4.h:655
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:29
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