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