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 */
65typedef std::vector<Vector3> Vectors3;
66
67/**
68 * Definition of a vector holding VectorD3 objects.
69 * @see VectorD3
70 * @ingroup math
71 */
72typedef std::vector<VectorD3> VectorsD3;
73
74/**
75 * Definition of a vector holding VectorF3 objects.
76 * @see VectorF3
77 * @ingroup math
78 */
79typedef std::vector<VectorF3> VectorsF3;
80
81/**
82 * Definition of a vector holding VectorI3 objects.
83 * @see VectorI3
84 * @ingroup math
85 */
86typedef std::vector<VectorI3> VectorsI3;
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 typedef T Type;
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 inline VectorT3(const VectorT3<T>& vector) noexcept;
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 inline VectorT3& operator=(const VectorT3<T>& vector);
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>
592inline VectorT3<T>::VectorT3(const VectorT3<T>& vector) noexcept
593{
594 values_[0] = vector.values_[0];
595 values_[1] = vector.values_[1];
596 values_[2] = vector.values_[2];
597}
598
599template <typename T>
600template <typename U>
601inline VectorT3<T>::VectorT3(const VectorT3<U>& vector) noexcept
602{
603 values_[0] = T(vector[0]);
604 values_[1] = T(vector[1]);
605 values_[2] = T(vector[2]);
606}
607
608template <typename T>
609inline VectorT3<T> VectorT3<T>::cross(const VectorT3<T>& vector) const
610{
611 return VectorT3<T>(values_[1] * vector.values_[2] - values_[2] * vector.values_[1],
612 values_[2] * vector.values_[0] - values_[0] * vector.values_[2],
613 values_[0] * vector.values_[1] - values_[1] * vector.values_[0]);
614}
615
616template <typename T>
618{
619 const T len = length();
621 {
622 ocean_assert(false && "Division by zero!");
623 return VectorT3<T>();
624 }
625
626 const T factor = T(1) / len;
627 return VectorT3<T>(values_[0] * factor, values_[1] * factor, values_[2] * factor);
628}
629
630template <typename T>
632{
633 const T len = length();
634
636 {
637 return *this;
638 }
639
640 const T factor = T(1) / len;
641 return VectorT3<T>(values_[0] * factor, values_[1] * factor, values_[2] * factor);
642}
643
644template <typename T>
646{
647 const T len = length();
648
650 {
651 return value;
652 }
653
654 const T factor = T(1) / len;
655 return VectorT3<T>(values_[0] * factor, values_[1] * factor, values_[2] * factor);
656}
657
658template <typename T>
660{
661 const T len = length();
663 {
664 return false;
665 }
666
667 const T factor = T(1) / len;
668 values_[0] *= factor;
669 values_[1] *= factor;
670 values_[2] *= factor;
671
672 return true;
673}
674
675template <typename T>
676inline T VectorT3<T>::length() const
677{
678 return NumericT<T>::sqrt(values_[0] * values_[0] + values_[1] * values_[1] + values_[2] * values_[2]);
679}
680
681template <typename T>
682inline T VectorT3<T>::sqr() const
683{
684 return values_[0] * values_[0] + values_[1] * values_[1] + values_[2] * values_[2];
685}
686
687template <typename T>
688inline T VectorT3<T>::distance(const VectorT3<T>& right) const
689{
690 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]));
691}
692
693template <typename T>
694inline T VectorT3<T>::sqrDistance(const VectorT3<T>& right) const
695{
696 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]);
697}
698
699template <typename T>
700T VectorT3<T>::angle(const VectorT3<T>& right) const
701{
702 // a * b = cos * |a| * |b|
703 // cos = (a * b) / (|a| * |b|)
704 // we separate the sqrt determinations to receive a higher accuracy
705
706 const T thisLength = length();
707 const T rightLength = right.length();
708
709 if (NumericT<T>::isEqualEps(thisLength) || NumericT<T>::isEqualEps(rightLength))
710 {
711 ocean_assert(false && "Invalid vector!");
712 return T(-1);
713 }
714
715 const T dot = values_[0] * right.values_[0] + values_[1] * right.values_[1] + values_[2] * right.values_[2];
716
717 return NumericT<T>::acos((dot / thisLength) / rightLength);
718}
719
720template <typename T>
722{
723 ocean_assert(NumericT<T>::isNotEqualEps(normal.length()));
724 ocean_assert(*this * normal >= 0);
725
726#ifdef OCEAN_DEBUG
727 const VectorT3<T> result(normal * ((normal * *this) * 2) - *this);
728 ocean_assert(int(angle(normal) * 100) == int(result.angle(normal) * 100));
729 ocean_assert(result * normal >= 0);
730 ocean_assert(NumericT<T>::isWeakEqual(length(), result.length()));
731#endif // OCEAN_DEBUG
732
733 return normal * ((normal * *this) * 2) - *this;
734}
735
736template <typename T>
737VectorT3<T> VectorT3<T>::refract(const VectorT3<T>& normal, const T index) const
738{
739 ocean_assert(NumericT<T>::isNotEqualEps(normal.length()));
740 ocean_assert(*this * normal >= 0);
741 ocean_assert(index > T(0));
742
743 const T dot = normal * *this;
744
745 const T sqrtValue = T(1) - (index * index) * (T(1) - dot * dot);
746
747 // check whether a total internal reflection occurs
748 if (sqrtValue < T(0))
749 {
750 return reflect(normal);
751 }
752
753#ifdef OCEAN_DEBUG
754 const VectorT3<T> result(normal * (index * dot - NumericT<T>::sqrt(sqrtValue)) - *this * index);
755 const T angle0 = angle(normal);
756 const T angle1 = result.angle(-normal);
757 const T sin0 = NumericT<T>::sin(angle0);
758 const T sin1 = NumericT<T>::sin(angle1);
759 ocean_assert(NumericT<T>::isNotEqualEps(sin1));
760 ocean_assert(NumericT<T>::isWeakEqual(index, sin0 / sin1));
761 ocean_assert(NumericT<T>::isWeakEqual(length(), result.length()));
762#endif // OCEAN_DEBUG
763
764 return normal * (index * dot - NumericT<T>::sqrt(T(1) - (index * index) * (T(1) - dot * dot))) - *this * index;
765}
766
767template <typename T>
769{
771 {
772 return cross(VectorT3<T>(0, 1, 0));
773 }
774
776 {
777 return cross(VectorT3<T>(1, 0, 0));
778 }
779
780 ocean_assert(isNull());
781 return VectorT3<T>(1, 0, 0);
782}
783
784template <typename T>
785bool VectorT3<T>::isParallel(const VectorT3<T>& right) const
786{
787#ifdef OCEAN_DEBUG
788 if (std::is_same<double, Scalar>::value)
789 {
790 const VectorT3<T> normalizedThis(normalizedOrZero());
791 const VectorT3<T> normalizedRight(right.normalizedOrZero());
792
793 const T dotProduct = normalizedThis * normalizedRight;
794
795 const bool debugResult = NumericT<T>::isEqual(dotProduct, 1) || NumericT<T>::isEqual(dotProduct, -1);
796 const VectorT3<T> crossVector = cross(right);
797
798 ocean_assert_accuracy(debugResult == (!isNull() && !right.isNull() && crossVector.isNull()));
799 }
800#endif
801
802 return !isNull() && !right.isNull() && cross(right).isNull();
803}
804
805template <typename T>
806inline bool VectorT3<T>::isOrthogonal(const VectorT3<T>& right) const
807{
808 return NumericT<T>::isEqualEps(values_[0] * right.values_[0] + values_[1] * right.values_[1] + values_[2] * right.values_[2]);
809}
810
811template <typename T>
812inline const T& VectorT3<T>::x() const noexcept
813{
814 return values_[0];
815}
816
817template <typename T>
818inline T& VectorT3<T>::x() noexcept
819{
820 return values_[0];
821}
822
823template <typename T>
824inline const T& VectorT3<T>::y() const noexcept
825{
826 return values_[1];
827}
828
829template <typename T>
830inline T& VectorT3<T>::y() noexcept
831{
832 return values_[1];
833}
834
835template <typename T>
836inline const T& VectorT3<T>::z() const noexcept
837{
838 return values_[2];
839}
840
841template <typename T>
842inline T& VectorT3<T>::z() noexcept
843{
844 return values_[2];
845}
846
847template <typename T>
848inline VectorT2<T> VectorT3<T>::xy() const noexcept
849{
850 return VectorT2<T>(values_[0], values_[1]);
851}
852
853template <typename T>
854inline const T* VectorT3<T>::data() const noexcept
855{
856 return values_;
857}
858
859template <typename T>
860inline T* VectorT3<T>::data() noexcept
861{
862 return values_;
863}
864
865template <typename T>
871
872template <typename T>
873inline bool VectorT3<T>::isUnit(const T eps) const
874{
875 return NumericT<T>::isEqual(length(), T(1), eps);
876}
877
878template <typename T>
879inline bool VectorT3<T>::isEqual(const VectorT3<T>& vector, const T eps) const
880{
881 return NumericT<T>::isEqual(values_[0], vector.values_[0], eps)
882 && NumericT<T>::isEqual(values_[1], vector.values_[1], eps)
883 && NumericT<T>::isEqual(values_[2], vector.values_[2], eps);
884}
885
886template <typename T>
888{
889 if (this == &vector)
890 {
891 return *this;
892 }
893
894 values_[0] = vector.values_[0];
895 values_[1] = vector.values_[1];
896 values_[2] = vector.values_[2];
897
898 return *this;
899}
900
901template <typename T>
902inline bool VectorT3<T>::operator==(const VectorT3<T>& vector) const
903{
904 return NumericT<T>::isEqual(values_[0], vector.values_[0])
905 && NumericT<T>::isEqual(values_[1], vector.values_[1])
906 && NumericT<T>::isEqual(values_[2], vector.values_[2]);
907}
908
909template <typename T>
910inline bool VectorT3<T>::operator!=(const VectorT3<T>& vector) const
911{
912 return NumericT<T>::isNotEqual(values_[0], vector.values_[0])
913 || NumericT<T>::isNotEqual(values_[1], vector.values_[1])
914 || NumericT<T>::isNotEqual(values_[2], vector.values_[2]);
915}
916
917template <typename T>
919{
920 return VectorT3<T>(values_[0] + vector.values_[0], values_[1] + vector.values_[1], values_[2] + vector.values_[2]);
921}
922
923template <typename T>
925{
926 values_[0] += vector.values_[0];
927 values_[1] += vector.values_[1];
928 values_[2] += vector.values_[2];
929
930 return *this;
931}
932
933template <typename T>
935{
936 return VectorT3<T>(values_[0] - vector.values_[0], values_[1] - vector.values_[1], values_[2] - vector.values_[2]);
937}
938
939template <typename T>
941{
942 values_[0] -= vector.values_[0];
943 values_[1] -= vector.values_[1];
944 values_[2] -= vector.values_[2];
945
946 return *this;
947}
948
949template <typename T>
951{
952 return VectorT3<T>(-values_[0], -values_[1], -values_[2]);
953}
954
955template <typename T>
956inline T VectorT3<T>::operator*(const VectorT3<T>& vector) const
957{
958 return values_[0] * vector.values_[0] + values_[1] * vector.values_[1] + values_[2] * vector.values_[2];
959}
960
961template <typename T>
962inline VectorT3<T> VectorT3<T>::operator*(const T& value) const
963{
964 return VectorT3<T>(values_[0] * value, values_[1] * value, values_[2] * value);
965}
966
967template <typename T>
969{
970 values_[0] *= value;
971 values_[1] *= value;
972 values_[2] *= value;
973
974 return *this;
975}
976
977template <typename T>
978inline VectorT3<T> VectorT3<T>::operator/(const T& value) const
979{
980 ocean_assert(NumericT<T>::isNotEqualEps(value));
981 T factor = T(1) / value;
982
983 return VectorT3<T>(values_[0] * factor, values_[1] * factor, values_[2] * factor);
984}
985
986template <typename T>
988{
989 ocean_assert(NumericT<T>::isNotEqualEps(value));
990
991 T factor = T(1) / value;
992
993 values_[0] *= factor;
994 values_[1] *= factor;
995 values_[2] *= factor;
996
997 return *this;
998}
999
1000template <typename T>
1001inline bool VectorT3<T>::operator<(const VectorT3<T>& right) const
1002{
1003 return values_[0] < right.values_[0]
1004 || (values_[0] == right.values_[0] && (values_[1] < right.values_[1]
1005 || (values_[1] == right.values_[1] && values_[2] < right.values_[2])));
1006}
1007
1008template <typename T>
1009inline const T& VectorT3<T>::operator[](const unsigned int index) const noexcept
1010{
1011 ocean_assert(index < 3u);
1012 return values_[index];
1013}
1014
1015template <typename T>
1016inline T& VectorT3<T>::operator[](const unsigned int index) noexcept
1017{
1018 ocean_assert(index < 3u);
1019 return values_[index];
1020}
1021
1022template <typename T>
1023inline const T& VectorT3<T>::operator()(const unsigned int index) const noexcept
1024{
1025 ocean_assert(index < 3u);
1026 return values_[index];
1027}
1028
1029template <typename T>
1030inline T& VectorT3<T>::operator()(const unsigned int index) noexcept
1031{
1032 ocean_assert(index < 3u);
1033 return values_[index];
1034}
1035
1036template <typename T>
1037inline const T* VectorT3<T>::operator()() const noexcept
1038{
1039 return values_;
1040}
1041
1042template <typename T>
1043inline T* VectorT3<T>::operator()() noexcept
1044{
1045 return values_;
1046}
1047
1048template <typename T>
1049inline size_t VectorT3<T>::operator()(const VectorT3<T>& vector) const
1050{
1051 size_t seed = std::hash<T>{}(vector.x());
1052 seed ^= std::hash<T>{}(vector.y()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
1053 seed ^= std::hash<T>{}(vector.z()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
1054
1055 return seed;
1056}
1057
1058template <typename T>
1063
1064template <typename T>
1069
1070template <>
1071template <>
1072inline std::vector<VectorT3<float>> VectorT3<float>::vectors2vectors(std::vector<VectorT3<float>>&& vectors)
1073{
1074 return std::move(vectors);
1075}
1076
1077template <>
1078template <>
1079inline std::vector<VectorT3<double>> VectorT3<double>::vectors2vectors(std::vector<VectorT3<double>>&& vectors)
1080{
1081 return std::move(vectors);
1082}
1083
1084template <typename T>
1085template <typename U>
1086inline std::vector<VectorT3<T>> VectorT3<T>::vectors2vectors(std::vector<VectorT3<U>>&& vectors)
1087{
1088 std::vector<VectorT3<T>> result;
1089 result.reserve(vectors.size());
1090
1091 for (typename std::vector<VectorT3<U>>::const_iterator i = vectors.cbegin(); i != vectors.cend(); ++i)
1092 {
1093 result.emplace_back(*i);
1094 }
1095
1096 return result;
1097}
1098
1099template <>
1100template <>
1101inline std::vector<VectorT3<float>> VectorT3<float>::vectors2vectors(const std::vector<VectorT3<float>>& vectors)
1102{
1103 return vectors;
1104}
1105
1106template <>
1107template <>
1108inline std::vector<VectorT3<double>> VectorT3<double>::vectors2vectors(const std::vector<VectorT3<double>>& vectors)
1109{
1110 return vectors;
1111}
1112
1113template <typename T>
1114template <typename U>
1115inline std::vector<VectorT3<T>> VectorT3<T>::vectors2vectors(const std::vector<VectorT3<U>>& vectors)
1116{
1117 std::vector<VectorT3<T>> result;
1118 result.reserve(vectors.size());
1119
1120 for (typename std::vector<VectorT3<U>>::const_iterator i = vectors.cbegin(); i != vectors.cend(); ++i)
1121 {
1122 result.emplace_back(*i);
1123 }
1124
1125 return result;
1126}
1127
1128template <typename T>
1129template <typename U>
1130inline std::vector<VectorT3<T>> VectorT3<T>::vectors2vectors(const VectorT3<U>* vectors, const size_t size)
1131{
1132 std::vector< VectorT3<T>> result;
1133 result.reserve(size);
1134
1135 for (size_t n = 0; n < size; ++n)
1136 {
1137 result.emplace_back(vectors[n]);
1138 }
1139
1140 return result;
1141}
1142
1143template <typename T>
1144std::ostream& operator<<(std::ostream& stream, const VectorT3<T>& vector)
1145{
1146 stream << "[" << vector.x() << ", " << vector.y() << ", " << vector.z() << "]";
1147
1148 return stream;
1149}
1150
1151template <bool tActive, typename T>
1152MessageObject<tActive>& operator<<(MessageObject<tActive>& messageObject, const VectorT3<T>& vector)
1153{
1154 return messageObject << "[" << vector.x() << ", " << vector.y() << ", " << vector.z() << "]";
1155}
1156
1157template <bool tActive, typename T>
1158MessageObject<tActive>& operator<<(MessageObject<tActive>&& messageObject, const VectorT3<T>& vector)
1159{
1160 return messageObject << "[" << vector.x() << ", " << vector.y() << ", " << vector.z() << "]";
1161}
1162
1163}
1164
1165#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:1568
static T sqrt(const T value)
Returns the square root of a given value.
Definition Numeric.h:1533
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition Numeric.h:2386
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition Numeric.h:1495
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition Numeric.h:2087
static T acos(const T value)
Returns the arccosine of a given value.
Definition Numeric.h:2907
static bool isNotEqual(const T first, const T second)
Returns whether two values are not equal up to a small epsilon.
Definition Numeric.h:2613
This class implements a vector with two elements.
Definition Vector2.h:96
This class implements a vector with three elements.
Definition Vector3.h:97
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:873
VectorT3< T > normalizedOrValue(const VectorT3< T > &value) const
Returns the normalized vector.
Definition Vector3.h:645
const T * operator()() const noexcept
Access operator.
Definition Vector3.h:1037
VectorT3< T > perpendicular() const
Returns a vector that is perpendicular to this vector.
Definition Vector3.h:768
bool operator!=(const VectorT3< T > &vector) const
Returns whether two vectors are not identical up to a small epsilon.
Definition Vector3.h:910
VectorT3< T > & operator*=(const T &value)
Multiplies and assigns this vector with a scalar.
Definition Vector3.h:968
const T & y() const noexcept
Returns the y value.
Definition Vector3.h:824
VectorT3< T > & operator-=(const VectorT3< T > &vector)
Subtracts and assigns two vectors.
Definition Vector3.h:940
bool normalize()
Normalizes this vector.
Definition Vector3.h:659
T operator*(const VectorT3< T > &vector) const
Returns the dot product of two vectors.
Definition Vector3.h:956
VectorT3< T > cross(const VectorT3< T > &vector) const
Returns the cross product of two vectors.
Definition Vector3.h:609
bool isOrthogonal(const VectorT3< T > &right) const
Returns whether two vectors are orthogonal.
Definition Vector3.h:806
const T & operator[](const unsigned int index) const noexcept
Element access operator.
Definition Vector3.h:1009
const T & x() const noexcept
Returns the x value.
Definition Vector3.h:812
VectorT2< T > xy() const noexcept
Returns the x and y component of the vector as new 2D vector.
Definition Vector3.h:848
VectorT3< T > normalizedOrZero() const
Returns the normalized vector.
Definition Vector3.h:631
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:737
VectorT3< T > normalized() const
Returns the normalized vector.
Definition Vector3.h:617
static VectorT3< T > minValue()
Returns a 3D vector with all elements set to NumericT::minValue().
Definition Vector3.h:1059
const T & z() const noexcept
Returns the z value.
Definition Vector3.h:836
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:866
bool isEqual(const VectorT3< T > &vector, const T eps) const
Returns whether two vectors are equal up to a specified epsilon.
Definition Vector3.h:879
T values_[3]
The three values of the vector, with element order x, y, z.
Definition Vector3.h:542
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition Vector3.h:854
VectorT3< T > & operator/=(const T &value)
Divides and assigns this vector by a scalar.
Definition Vector3.h:987
T distance(const VectorT3< T > &right) const
Returns the distance between this 3D position and a second 3D position.
Definition Vector3.h:688
T sqrDistance(const VectorT3< T > &right) const
Returns the square distance between this 3D position and a second 3D position.
Definition Vector3.h:694
VectorT3< T > operator/(const T &value) const
Divides this vector by a scalar.
Definition Vector3.h:978
static VectorT3< T > maxValue()
Returns a 3D vector with all elements set to NumericT::maxValue().
Definition Vector3.h:1065
VectorT3< T > operator-() const
Returns the negated vector.
Definition Vector3.h:950
T length() const
Returns the length of the vector.
Definition Vector3.h:676
bool isParallel(const VectorT3< T > &right) const
Returns whether two vectors are parallel.
Definition Vector3.h:785
VectorT3< T > operator+(const VectorT3< T > &vector) const
Adds two vectors.
Definition Vector3.h:918
VectorT3< T > reflect(const VectorT3< T > &normal) const
Returns the reflected vector of this vector corresponding to a given normal vector.
Definition Vector3.h:721
VectorT3< T > & operator+=(const VectorT3< T > &vector)
Adds and assigns two vectors.
Definition Vector3.h:924
VectorT3 & operator=(const VectorT3< T > &vector)
Copy assigns a vector.
Definition Vector3.h:887
T Type
Definition of the used data type.
Definition Vector3.h:103
bool operator==(const VectorT3< T > &vector) const
Returns whether two vectors are identical up to a small epsilon.
Definition Vector3.h:902
T sqr() const
Returns the square of the vector length.
Definition Vector3.h:682
T angle(const VectorT3< T > &right) const
Returns the angle between this vector and a second vectors.
Definition Vector3.h:700
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:1086
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:1001
std::vector< VectorI3 > VectorsI3
Definition of a vector holding VectorI3 objects.
Definition Vector3.h:86
VectorT3< int > VectorI3
Definition of a 3D vector with integer values.
Definition Vector3.h:50
std::vector< VectorF3 > VectorsF3
Definition of a vector holding VectorF3 objects.
Definition Vector3.h:79
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition Vector3.h:29
std::vector< VectorD3 > VectorsD3
Definition of a vector holding VectorD3 objects.
Definition Vector3.h:72
VectorT3< float > VectorF3
Definition of a 3D vector with float values.
Definition Vector3.h:43
std::vector< VectorT3< T > > VectorsT3
Definition of a typename alias for vectors with VectorT3 objects.
Definition Vector3.h:58
VectorT3< double > VectorD3
Definition of a 3D vector with double values.
Definition Vector3.h:36
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition Vector3.h:65
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
std::ostream & operator<<(std::ostream &stream, const HighPerformanceStatistic &highPerformanceStatistic)
Definition HighPerformanceTimer.h:963