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