ACF $AcfVersion:0$
TVector.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ACF-Commercial
2#pragma once
3
4
5// Qt includes
6#include <QtCore/QtGlobal>
7#if QT_VERSION >= 0x050000
8#include <QtCore/QtMath>
9#else
10#include <QtCore/qmath.h>
11#endif
12
13// STL includes
14#include <initializer_list>
15
16// ACF includes
17#include <iser/IArchive.h>
18#include <imath/imath.h>
19
20
21namespace imath
22{
23
24
93template <int Size, class Element = double>
95{
96public:
97 typedef Element ElementType;
98 typedef Element Elements[Size];
99
114
122
141 TVector(std::initializer_list<Element> values);
142
155 const Element& GetElement(int i) const;
156
174 Element& GetElementRef(int i);
175
184 void SetElement(int i, const Element& value);
185
198 void SetAllElements(const Element& value);
199
208 void Reset();
209
217 void Clear();
218
227
244
254
264
282 void ScaledCumulate(const TVector<Size, Element>& vector, Element scale);
283
300 bool IsNull(Element tolerance = I_BIG_EPSILON) const;
301
322 Element GetDotProduct(const TVector<Size, Element>& vector) const;
323
334 Element GetLength2() const;
335
350 Element GetLength() const;
351
363 Element GetDistance2(const TVector<Size, Element>& vector) const;
364
379 Element GetDistance(const TVector<Size, Element>& vector) const;
380
391 Element GetElementsSum() const;
392
417 bool Normalize(Element length = 1.0);
418
440 bool GetNormalized(TVector<Size, Element>& result, Element length = 1.0) const;
441
445 void GetMinimal(const TVector<Size, Element>& vector, TVector<Size, Element>& result) const;
449 void GetMaximal(const TVector<Size, Element>& vector, TVector<Size, Element>& result) const;
450
454 bool Serialize(iser::IArchive& archive);
455
456 bool operator==(const TVector<Size, Element>& vector) const;
457 bool operator!=(const TVector<Size, Element>& vector) const;
458 bool operator<(const TVector<Size, Element>& vector) const;
459 bool operator>(const TVector<Size, Element>& vector) const;
460 bool operator<=(const TVector<Size, Element>& vector) const;
461 bool operator>=(const TVector<Size, Element>& vector) const;
462
464
466
469 TVector<Size, Element> operator*(Element scalar) const;
470 TVector<Size, Element> operator/(Element scalar) const;
471
476
477 const Element& operator[](int i) const;
478 Element& operator[](int i);
479
480 // static methods
481
485 static int GetElementsCount();
486
493 static bool SetElementsCount(int count);
494
499
500protected:
502
503private:
504 explicit TVector(Element vector);
505
506 static TVector<Size, Element> s_zero;
507};
508
509
510// inline constructors
511
512template <int Size, class Element>
516
517
518template <int Size, class Element>
520{
521 for (int i = 0; i < Size; ++i){
522 m_elements[i] = vector.m_elements[i];
523 }
524}
525
526
527template <int Size, class Element>
528inline TVector<Size, Element>::TVector(std::initializer_list<Element> values)
529{
530 int count = static_cast<int>(values.size());
531 Q_ASSERT(count <= Size);
532
533 for (int i = 0; i < count; ++i){
534 m_elements[i] = *(values.begin() + i);
535 }
536
537 for (int i = count; i < Size; ++i){
538 m_elements[i] = 0;
539 }
540}
541
542
543// inline methods
544
545template <int Size, class Element>
546inline const Element& TVector<Size, Element>::GetElement(int i) const
547{
548 return operator[](i);
549}
550
551
552template <int Size, class Element>
554{
555 return operator[](i);
556}
557
558
559template <int Size, class Element>
560inline void TVector<Size, Element>::SetElement(int i, const Element& value)
561{
562 operator[](i) = value;
563}
564
565
566template <int Size, class Element>
567inline void TVector<Size, Element>::SetAllElements(const Element& value)
568{
569 for (int i = 0; i < Size; ++i){
570 m_elements[i] = value;
571 }
572}
573
574
575template <int Size, class Element>
577{
578 for (int i = 0; i < Size; ++i){
579 m_elements[i] = 0;
580 }
581}
582
583
584template <int Size, class Element>
586{
587 for (int i = 0; i < Size; ++i){
588 m_elements[i] = 0;
589 }
590}
591
592
593template <int Size, class Element>
595{
596 return m_elements;
597}
598
599
600template <int Size, class Element>
602{
603 return m_elements;
604}
605
606
607template <int Size, class Element>
609{
610 for (int i = 0; i < Size; ++i){
611 m_elements[i] += vector.m_elements[i];
612 }
613}
614
615
616template <int Size, class Element>
621
622
623template <int Size, class Element>
625{
626 result = *this + vector;
627}
628
629
630template <int Size, class Element>
631inline void TVector<Size, Element>::ScaledCumulate(const TVector<Size, Element>& vector, Element scale)
632{
633 for (int i = 0; i < Size; ++i){
634 m_elements[i] += vector.m_elements[i] * scale;
635 }
636}
637
638
639template <int Size, class Element>
640inline bool TVector<Size, Element>::IsNull(Element tolerance) const
641{
642 return GetLength2() <= tolerance * tolerance;
643}
644
645
646template <int Size, class Element>
648{
649 Element retVal = 0.0;
650
651 for (int i = 0; i < Size; ++i){
652 retVal += m_elements[i] * vector.m_elements[i];
653 }
654
655 return retVal;
656}
657
658
659template <int Size, class Element>
661{
662 return GetDotProduct(*this);
663}
664
665
666template <int Size, class Element>
668{
669 return qSqrt(GetLength2());
670}
671
672
673template <int Size, class Element>
675{
676 return (*this - vector).GetLength2();
677}
678
679
680template <int Size, class Element>
682{
683 return qSqrt(GetDistance2(vector));
684}
685
686
687// operators
688
689template <int Size, class Element>
691{
692 for (int i = 0; i < Size; ++i){
693 if (m_elements[i] != vector.m_elements[i]){
694 return false;
695 }
696 }
697 return true;
698}
699
700
701template <int Size, class Element>
703{
704 return !operator==(vector);
705}
706
707
708template <int Size, class Element>
710{
711 for (int i = 0; i < Size; ++i){
712 if (m_elements[i] > vector.m_elements[i]){
713 return false;
714 }
715 else if (m_elements[i] < vector.m_elements[i]){
716 return true;
717 }
718 }
719
720 return false;
721}
722
723
724template <int Size, class Element>
726{
727 for (int i = 0; i < Size; ++i){
728 if (m_elements[i] > vector.m_elements[i]){
729 return true;
730 }
731 else if (m_elements[i] < vector.m_elements[i]){
732 return false;
733 }
734 }
735
736 return false;
737}
738
739
740template <int Size, class Element>
742{
743 for (int i = 0; i < Size; ++i){
744 if (m_elements[i] > vector.m_elements[i]){
745 return false;
746 }
747 else if (m_elements[i] < vector.m_elements[i]){
748 return true;
749 }
750 }
751
752 return true;
753}
754
755
756template <int Size, class Element>
758{
759 for (int i = 0; i < Size; ++i){
760 if (m_elements[i] > vector.m_elements[i]){
761 return true;
762 }
763 else if (m_elements[i] < vector.m_elements[i]){
764 return false;
765 }
766 }
767
768 return true;
769}
770
771
772template <int Size, class Element>
774{
775 for (int i = 0; i < Size; ++i){
776 m_elements[i] += vector.m_elements[i];
777 }
778
779 return *this;
780}
781
782
783template <int Size, class Element>
785{
786 for (int i = 0; i < Size; ++i){
787 m_elements[i] -= vector.m_elements[i];
788 }
789
790 return *this;
791}
792
793
794template <int Size, class Element>
796{
797 for (int i = 0; i < Size; ++i){
798 m_elements[i] *= scalar;
799 }
800
801 return *this;
802}
803
804
805template <int Size, class Element>
807{
808 for (int i = 0; i < Size; ++i){
809 m_elements[i] /= scalar;
810 }
811
812 return *this;
813}
814
815
816template <int Size, class Element>
818{
820
821 for (int i = 0; i < Size; ++i){
822 retVal.m_elements[i] = -m_elements[i];
823 }
824
825 return retVal;
826}
827
828
829template <int Size, class Element>
831{
833
834 for (int i = 0; i < Size; ++i){
835 retVal.m_elements[i] = m_elements[i] + vector.m_elements[i];
836 }
837
838 return retVal;
839}
840
841
842template <int Size, class Element>
844{
846
847 for (int i = 0; i < Size; ++i){
848 retVal.m_elements[i] = m_elements[i] - vector.m_elements[i];
849 }
850
851 return retVal;
852}
853
854
855template <int Size, class Element>
857{
859
860 for (int i = 0; i < Size; ++i){
861 retVal.m_elements[i] = m_elements[i] * scalar;
862 }
863
864 return retVal;
865}
866
867
868template <int Size, class Element>
870{
872
873 for (int i = 0; i < Size; ++i){
874 retVal.m_elements[i] = m_elements[i] / scalar;
875 }
876
877 return retVal;
878}
879
880
881template <int Size, class Element>
882const Element& TVector<Size, Element>::operator[](int i) const
883{
884 Q_ASSERT(i >= 0);
885 Q_ASSERT(i < Size);
886
887 return m_elements[i];
888}
889
890
891template <int Size, class Element>
893{
894 Q_ASSERT(i >= 0);
895 Q_ASSERT(i < Size);
896
897 return m_elements[i];
898}
899
900
901// static inline methods
902
903template <int Size, class Element>
905{
906 return Size;
907}
908
909
910template <int Size, class Element>
912{
913 return count == Size;
914}
915
916
917template <int Size, class Element>
919{
920 return s_zero;
921}
922
923
924// public methods
925
926template <int Size, class Element>
928{
929 Element retVal = 0;
930
931 for (int i = 0; i < Size; ++i){
932 retVal += m_elements[i];
933 }
934
935 return retVal;
936}
937
938
939template <int Size, class Element>
941{
942 Element isLength = GetLength();
943
944 Element proportion = isLength / length;
945
946 if (qAbs(proportion) > I_BIG_EPSILON){
947 for (int i = 0; i < Size; ++i){
948 m_elements[i] = m_elements[i] / proportion;
949 }
950
951 return true;
952 }
953 else{
954 return false;
955 }
956}
957
958
959template <int Size, class Element>
961{
962 Element isLength = GetLength();
963
964 Element proportion = isLength / length;
965
966 if (qAbs(proportion) > I_BIG_EPSILON){
967 for (int i = 0; i < Size; ++i){
968 result.m_elements[i] = m_elements[i] / proportion;
969 }
970
971 return true;
972 }
973 else{
974 return false;
975 }
976}
977
978
979template <int Size, class Element>
981{
982 for (int i = 0; i < Size; ++i){
983 result.SetElement(i, qMin(GetElement(i), vector.GetElement(i)));
984 }
985}
986
987
988template <int Size, class Element>
990{
991 for (int i = 0; i < Size; ++i){
992 result.SetElement(i, qMax(GetElement(i), vector.GetElement(i)));
993 }
994}
995
996
997template <int Size, class Element>
999{
1000 bool retVal = true;
1001
1002 for (int i = 0; i < Size; ++i){
1003 retVal = retVal && archive.Process(m_elements[i]);
1004 }
1005
1006 return retVal;
1007}
1008
1009
1010// private methods
1011
1012template <int Size, class Element>
1013TVector<Size, Element>::TVector(Element element)
1014{
1015 for (int i = 0; i < Size; ++i){
1016 m_elements[i] = element;
1017 }
1018}
1019
1020
1021template <int Size, class Element>
1022TVector<Size, Element> TVector<Size, Element>::s_zero(Element(0));
1023
1024
1025} // namespace imath
1026
1027
Implementation of fixed-size mathematical vector with specified type of elements.
Definition TVector.h:95
Element GetLength() const
Calculates the Euclidean length (magnitude) of the vector.
Definition TVector.h:667
TVector()
Creates an uninitialized vector.
Definition TVector.h:513
TVector< Size, Element > operator*(Element scalar) const
Definition TVector.h:856
Element & operator[](int i)
Definition TVector.h:892
TVector(const TVector< Size, Element > &vector)
Creates a copy of another vector.
Definition TVector.h:519
const Element & operator[](int i) const
Definition TVector.h:882
Element GetDistance2(const TVector< Size, Element > &vector) const
Calculates the squared distance to another vector.
Definition TVector.h:674
bool operator<=(const TVector< Size, Element > &vector) const
Definition TVector.h:741
Element GetDotProduct(const TVector< Size, Element > &vector) const
Calculates the dot product with another vector.
Definition TVector.h:647
TVector< Size, Element > & operator+=(const TVector< Size, Element > &vector)
Definition TVector.h:773
Element GetElementsSum() const
Calculates the sum of all vector elements.
Definition TVector.h:927
void Translate(const TVector< Size, Element > &vector)
Translates (adds) another vector to this vector.
Definition TVector.h:608
void GetTranslated(const TVector< Size, Element > &vector, TVector< Size, Element > &result)
Computes the translated vector and stores it in the result parameter.
Definition TVector.h:624
TVector< Size, Element >::Elements & GetElementsRef()
Get access to internal element container.
Definition TVector.h:601
static bool SetElementsCount(int count)
Set number of elements.
Definition TVector.h:911
TVector< Size, Element > operator+(const TVector< Size, Element > &vector) const
Definition TVector.h:830
bool operator>=(const TVector< Size, Element > &vector) const
Definition TVector.h:757
static int GetElementsCount()
Get number of elements.
Definition TVector.h:904
TVector< Size, Element > & operator/=(Element scalar)
Definition TVector.h:806
TVector< Size, Element > & operator-=(const TVector< Size, Element > &vector)
Definition TVector.h:784
Element GetLength2() const
Calculates the squared Euclidean length of the vector.
Definition TVector.h:660
TVector< Size, Element > & operator*=(Element scalar)
Definition TVector.h:795
TVector< Size, Element > & operator=(const TVector< Size, Element > &vector)=default
Element Elements[Size]
Definition TVector.h:98
bool Normalize(Element length=1.0)
Normalizes the vector to a specified length.
Definition TVector.h:940
TVector(std::initializer_list< Element > values)
Creates a vector from an initializer list.
Definition TVector.h:528
bool operator<(const TVector< Size, Element > &vector) const
Definition TVector.h:709
TVector< Size, Element > GetTranslated(const TVector< Size, Element > &vector)
Returns a new vector that is the translation of this vector.
Definition TVector.h:617
TVector< Size, Element > operator-() const
Definition TVector.h:817
TVector< Size, Element > operator/(Element scalar) const
Definition TVector.h:869
static const TVector< Size, Element > & GetZero()
Get vector with all coordinates set to 0.
Definition TVector.h:918
void ScaledCumulate(const TVector< Size, Element > &vector, Element scale)
Adds a scaled vector to this vector.
Definition TVector.h:631
bool operator!=(const TVector< Size, Element > &vector) const
Definition TVector.h:702
bool Serialize(iser::IArchive &archive)
Serialize this vector to specified archive.
Definition TVector.h:998
const TVector< Size, Element >::Elements & GetElements() const
Get read-only access to internal element container.
Definition TVector.h:594
void GetMaximal(const TVector< Size, Element > &vector, TVector< Size, Element > &result) const
Get vector with maximal elements values.
Definition TVector.h:989
void Clear()
Sets all coordinates to zero.
Definition TVector.h:585
bool operator==(const TVector< Size, Element > &vector) const
Definition TVector.h:690
Element & GetElementRef(int i)
Gets a reference to the element at the specified index (read-write).
Definition TVector.h:553
Element ElementType
Definition TVector.h:97
void GetMinimal(const TVector< Size, Element > &vector, TVector< Size, Element > &result) const
Get vector with minimal elements values.
Definition TVector.h:980
bool IsNull(Element tolerance=I_BIG_EPSILON) const
Checks if this vector is null (all elements approximately zero).
Definition TVector.h:640
TVector< Size, Element > operator-(const TVector< Size, Element > &vector) const
Definition TVector.h:843
bool operator>(const TVector< Size, Element > &vector) const
Definition TVector.h:725
void SetAllElements(const Element &value)
Sets all elements to the same value.
Definition TVector.h:567
Element GetDistance(const TVector< Size, Element > &vector) const
Calculates the Euclidean distance to another vector.
Definition TVector.h:681
void SetElement(int i, const Element &value)
Sets the element at the specified index.
Definition TVector.h:560
bool GetNormalized(TVector< Size, Element > &result, Element length=1.0) const
Returns a normalized copy of this vector with specified length.
Definition TVector.h:960
const Element & GetElement(int i) const
Gets the element at the specified index (read-only).
Definition TVector.h:546
void Reset()
Sets all coordinates to zero.
Definition TVector.h:576
Elements m_elements
Definition TVector.h:501
Represents an input/output persistence archive for object serialization.
Definition IArchive.h:164
virtual bool Process(bool &value)=0
Processes (reads or writes) a boolean value.
static const double I_BIG_EPSILON
Definition istd.h:26
Package with mathematical functions and algebraical primitives.