29 #ifndef INCLUDE_SVECTORS_SIMPLEVECTORS_HPP_
30 #define INCLUDE_SVECTORS_SIMPLEVECTORS_HPP_
37 #include <initializer_list>
39 #include <type_traits>
66 template <std::
size_t D,
typename T =
double>
class Vector {
69 static_assert(std::is_arithmetic<T>::value,
"Vector type must be numeric");
71 #ifdef SVECTOR_EXPERIMENTAL_COMPARE
72 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
75 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
78 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
81 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
87 typedef typename std::array<T, D>::const_iterator
89 typedef typename std::array<T, D>::reverse_iterator
91 typedef typename std::array<T, D>::const_reverse_iterator
113 Vector(
const std::initializer_list<T> args) {
117 std::size_t counter = 0;
118 for (
const auto &num : args) {
134 for (std::size_t i = 0; i < D; i++) {
153 if (
this == &other) {
157 for (std::size_t i = 0; i < D; i++) {
186 std::string str =
"<";
187 for (std::size_t i = 0; i < D - 1; i++) {
198 #ifdef SVECTOR_USE_CLASS_OPERATORS
217 for (std::size_t i = 0; i < D; i++) {
240 Vector<D, T>
operator-(
const Vector<D, T> &other)
const {
242 for (std::size_t i = 0; i < D; i++) {
262 Vector<D, T>
operator*(
const T other)
const {
264 for (std::size_t i = 0; i < D; i++) {
284 Vector<D, T>
operator/(
const T other)
const {
286 for (std::size_t i = 0; i < D; i++) {
306 bool operator==(
const Vector<D, T> &other)
const {
307 for (std::size_t i = 0; i < D; i++) {
329 bool operator!=(
const Vector<D, T> &other)
const {
330 return !((*this) == other);
345 for (std::size_t i = 0; i < D; i++) {
362 for (std::size_t i = 0; i < D; i++) {
377 for (std::size_t i = 0; i < D; i++) {
392 for (std::size_t i = 0; i < D; i++) {
407 for (std::size_t i = 0; i < D; i++) {
422 for (std::size_t i = 0; i < D; i++) {
444 for (std::size_t i = 0; i < D; i++) {
459 T sum_of_squares = 0;
462 sum_of_squares += i * i;
465 return std::sqrt(sum_of_squares);
529 const T &
at(
const std::size_t index)
const {
664 #ifdef SVECTOR_EXPERIMENTAL_COMPARE
686 template <std::
size_t D2,
typename T2>
688 std::size_t min_dim = std::min(D, D2);
689 std::size_t counter = 0;
693 if constexpr (D != D2) {
698 return D < D2 ? -1 : 1;
702 for (std::size_t i = 0; i < min_dim; i++) {
703 if (this->m_components[i] == other[i]) {
705 }
else if (this->m_components[i] < other[i]) {
712 if (counter != D || counter != D2) {
738 this->m_components[0] =
x;
739 this->m_components[1] =
y;
746 this->m_components[0] = other[0];
747 this->m_components[1] = other[1];
757 double x()
const {
return this->m_components[0]; }
766 void x(
const double &newX) { this->m_components[0] = newX; }
775 double y()
const {
return this->m_components[1]; }
784 void y(
const double &newY) { this->m_components[1] = newY; }
795 double angle()
const {
return std::atan2(this->
y(), this->
x()); }
816 const double xPrime = this->
x() * std::cos(ang) - this->
y() * std::sin(ang);
817 const double yPrime = this->
x() * std::sin(ang) + this->
y() * std::cos(ang);
835 return T{this->
x(), this->
y()};
855 Vector3D(
const double x,
const double y,
const double z) {
856 this->m_components[0] =
x;
857 this->m_components[1] =
y;
858 this->m_components[2] =
z;
865 this->m_components[0] = other[0];
866 this->m_components[1] = other[1];
867 this->m_components[2] = other[2];
877 double x()
const {
return this->m_components[0]; }
886 void x(
const double &newX) { this->m_components[0] = newX; }
895 double y()
const {
return this->m_components[1]; }
904 void y(
const double &newY) { this->m_components[1] = newY; }
913 double z()
const {
return this->m_components[2]; }
922 void z(
const double &newZ) { this->m_components[2] = newZ; }
932 const double newx = this->
y() * other.
z() - this->
z() * other.
y();
933 const double newy = this->
z() * other.
x() - this->
x() * other.
z();
934 const double newz = this->
x() * other.
y() - this->
y() * other.
x();
952 return T{this->
x(), this->
y(), this->
z()};
968 return T{this->getAlpha(), this->getBeta(), this->getGamma()};
986 template <AngleDir D>
double angle()
const {
989 return this->getAlpha();
991 return this->getBeta();
993 return this->getGamma();
1033 double getAlpha()
const {
return std::acos(this->
x() / this->
magn()); }
1042 double getBeta()
const {
return std::acos(this->y() / this->
magn()); }
1051 double getGamma()
const {
return std::acos(this->
z() / this->
magn()); }
1065 const double xPrime = this->
x();
1066 const double yPrime = this->
y() * std::cos(ang) - this->
z() * std::sin(ang);
1067 const double zPrime = this->
y() * std::sin(ang) + this->
z() * std::cos(ang);
1069 return Vector3D{xPrime, yPrime, zPrime};
1075 Vector3D
rotateBeta(
const double &ang)
const {
1084 const double xPrime = this->
x() * std::cos(ang) + this->
z() * std::sin(ang);
1085 const double yPrime = this->
y();
1086 const double zPrime =
1087 -this->
x() * std::sin(ang) + this->
z() * std::cos(ang);
1089 return Vector3D{xPrime, yPrime, zPrime};
1104 const double xPrime = this->
x() * std::cos(ang) - this->
y() * std::sin(ang);
1105 const double yPrime = this->
x() * std::sin(ang) + this->
y() * std::cos(ang);
1106 const double zPrime = this->
z();
1108 return Vector3D{xPrime, yPrime, zPrime};
1121 template <std::
size_t D,
typename T>
1124 for (std::size_t i = 0; i < D; i++) {
1147 template <std::
size_t D,
typename T>
1150 for (std::size_t i = 0; i < std::min(D, vector.size()); i++) {
1174 template <std::
size_t D,
typename T>
1195 inline void x(
Vector2D &v,
const double xValue) { v[0] = xValue; }
1212 inline void x(
Vector3D &v,
const double xValue) { v[0] = xValue; }
1229 inline void y(
Vector2D &v,
const double yValue) { v[1] = yValue; }
1246 inline void y(
Vector3D &v,
const double yValue) { v[1] = yValue; }
1263 inline void z(
Vector3D &v,
const double zValue) { v[2] = zValue; }
1278 template <
typename T, std::
size_t D>
1282 for (std::size_t i = 0; i < D; i++) {
1283 result += lhs[i] * rhs[i];
1300 T sum_of_squares = 0;
1302 for (std::size_t i = 0; i < D; i++) {
1303 sum_of_squares += v[i] * v[i];
1306 return std::sqrt(sum_of_squares);
1324 template <
typename T, std::
size_t D>
1338 return magn(v) == 0;
1372 const double xPrime =
x(v) * std::cos(ang) -
y(v) * std::sin(ang);
1373 const double yPrime =
x(v) * std::sin(ang) +
y(v) * std::cos(ang);
1387 const double newx =
y(lhs) *
z(rhs) -
z(lhs) *
y(rhs);
1388 const double newy =
z(lhs) *
x(rhs) -
x(lhs) *
z(rhs);
1389 const double newz =
x(lhs) *
y(rhs) -
y(lhs) *
x(rhs);
1455 const double xPrime =
x(v);
1456 const double yPrime =
y(v) * std::cos(ang) -
z(v) * std::sin(ang);
1457 const double zPrime =
y(v) * std::sin(ang) +
z(v) * std::cos(ang);
1459 return Vector3D{xPrime, yPrime, zPrime};
1481 const double xPrime =
x(v) * std::cos(ang) +
z(v) * std::sin(ang);
1482 const double yPrime =
y(v);
1483 const double zPrime = -
x(v) * std::sin(ang) +
z(v) * std::cos(ang);
1485 return Vector3D{xPrime, yPrime, zPrime};
1507 const double xPrime =
x(v) * std::cos(ang) -
y(v) * std::sin(ang);
1508 const double yPrime =
x(v) * std::sin(ang) +
y(v) * std::cos(ang);
1509 const double zPrime =
z(v);
1511 return Vector3D{xPrime, yPrime, zPrime};
1514 #ifndef SVECTOR_USE_CLASS_OPERATORS
1534 template <
typename T, std::
size_t D>
1538 for (std::size_t i = 0; i < D; i++) {
1539 tmp[i] = lhs[i] + rhs[i];
1564 template <
typename T, std::
size_t D>
1568 for (std::size_t i = 0; i < D; i++) {
1569 tmp[i] = lhs[i] - rhs[i];
1593 template <
typename T,
typename T2, std::
size_t D>
1596 for (std::size_t i = 0; i < D; i++) {
1597 tmp[i] = lhs[i] * rhs;
1621 template <
typename T,
typename T2, std::
size_t D>
1624 for (std::size_t i = 0; i < D; i++) {
1625 tmp[i] = lhs[i] / rhs;
1647 template <
typename T, std::
size_t D>
1649 for (std::size_t i = 0; i < D; i++) {
1650 if (lhs[i] != rhs[i]) {
1674 template <
typename T, std::
size_t D>
1676 return !(lhs == rhs);
1680 #ifdef SVECTOR_EXPERIMENTAL_COMPARE
1681 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
1682 bool operator<(
const Vector<D1, T1> &lhs,
const Vector<D2, T2> &rhs) {
1683 return lhs.compare(rhs) < 0;
1686 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
1687 bool operator>(
const Vector<D1, T1> &lhs,
const Vector<D2, T2> &rhs) {
1688 return lhs.compare(rhs) > 0;
1691 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
1692 bool operator<=(
const Vector<D1, T1> &lhs,
const Vector<D2, T2> &rhs) {
1693 return lhs.compare(rhs) <= 0;
1696 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
1697 bool operator>=(
const Vector<D1, T1> &lhs,
const Vector<D2, T2> &rhs) {
1698 return lhs.compare(rhs) >= 0;
bool operator==(const Quaternion &lhs, const Quaternion &rhs)
Equality of two quaternions.
Definition: quaternion.hpp:212
bool operator!=(const Quaternion &lhs, const Quaternion &rhs)
Inequality of two quaternions.
Definition: quaternion.hpp:224
Quaternion operator*(const Quaternion &lhs, const Quaternion &rhs)
Product of two quaternions.
Definition: quaternion.hpp:187
AngleDir
Angle enumerator.
Definition: simplevectors.hpp:51
@ ALPHA
Angle between positive x-axis and vector.
Definition: simplevectors.hpp:52
@ GAMMA
Angle between positive z-axis and vector.
Definition: simplevectors.hpp:54
@ BETA
Angle between positive y-axis and vector.
Definition: simplevectors.hpp:53
double x(const Vector2D &v)
Gets the x-component of a 2D vector.
Definition: simplevectors.hpp:1187
double alpha(const Vector3D &v)
Gets α angle.
Definition: simplevectors.hpp:1406
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Cross product of two vectors.
Definition: simplevectors.hpp:1386
double angle(const Vector2D &v)
Gets the angle of a 2D vector in radians.
Definition: simplevectors.hpp:1350
Vector3D rotateAlpha(const Vector3D &v, const double &ang)
Rotates around x-axis.
Definition: simplevectors.hpp:1446
Vector3D rotateGamma(const Vector3D &v, const double &ang)
Rotates around z-axis.
Definition: simplevectors.hpp:1498
Vector2D rotate(const Vector2D &v, const double ang)
Rotates a 2D vector by a certain angle.
Definition: simplevectors.hpp:1364
double beta(const Vector3D &v)
Gets β angle.
Definition: simplevectors.hpp:1420
double y(const Vector2D &v)
Gets the y-component of a 2D vector.
Definition: simplevectors.hpp:1221
Vector3D rotateBeta(const Vector3D &v, const double &ang)
Rotates around y-axis.
Definition: simplevectors.hpp:1472
double z(const Vector3D &v)
Gets the z-component of a 3D vector.
Definition: simplevectors.hpp:1255
Vector< D, T > makeVector(std::array< T, D > array)
Creates a vector from an std::array.
Definition: simplevectors.hpp:1122
Vector< D, T > operator/(const Vector< D, T > &lhs, const T2 rhs)
Scalar division.
Definition: simplevectors.hpp:1622
double gamma(const Vector3D &v)
Gets γ angle.
Definition: simplevectors.hpp:1434
A base vector representation.
Definition: simplevectors.hpp:66
std::array< T, D >::const_reverse_iterator const_reverse_iterator
An std::array::const_reverse_iterator.
Definition: simplevectors.hpp:92
const T & at(const std::size_t index) const
Value of a certain component of a vector.
Definition: simplevectors.hpp:529
Vector()
No-argument constructor.
Definition: simplevectors.hpp:99
std::array< T, D >::const_iterator const_iterator
An std::array::const_iterator.
Definition: simplevectors.hpp:88
Vector< D, T > operator+() const
Positive of a vector.
Definition: simplevectors.hpp:360
reverse_iterator rend() noexcept
Reverse iterator to first element - 1.
Definition: simplevectors.hpp:640
Vector(Vector< D, T > &&) noexcept=default
Move constructor.
reverse_iterator rbegin() noexcept
Reverse iterator to last element.
Definition: simplevectors.hpp:609
T magn() const
Magnitude.
Definition: simplevectors.hpp:458
Vector< D, T > & operator+=(const Vector< D, T > &other)
In-place addition.
Definition: simplevectors.hpp:376
const_reverse_iterator rbegin() const noexcept
Const reverse iterator to last element.
Definition: simplevectors.hpp:622
iterator begin() noexcept
Iterator of first element.
Definition: simplevectors.hpp:554
std::array< T, D >::iterator iterator
An std::array::iterator.
Definition: simplevectors.hpp:69
const_iterator end() const noexcept
Const interator of last element + 1.
Definition: simplevectors.hpp:594
Vector< D, T > normalize() const
Normalizes a vector.
Definition: simplevectors.hpp:478
Vector< D, T > & operator-=(const Vector< D, T > &other)
In-place subtraction.
Definition: simplevectors.hpp:391
const_reverse_iterator rend() const noexcept
Const reverse iterator to first element - 1.
Definition: simplevectors.hpp:657
virtual std::string toString() const
Returns string form of vector.
Definition: simplevectors.hpp:185
Vector< D, T > operator-() const
Negative of a vector.
Definition: simplevectors.hpp:343
Vector(const std::initializer_list< T > args)
Initializes a vector given initializer list.
Definition: simplevectors.hpp:113
Vector< D, T > & operator=(Vector< D, T > &&) noexcept=default
Move assignment operator.
iterator end() noexcept
Interator of last element + 1.
Definition: simplevectors.hpp:581
Vector(const Vector< D, T > &other)
Copy constructor.
Definition: simplevectors.hpp:133
std::array< T, D > m_components
An array of components for the vector.
Definition: simplevectors.hpp:662
T dot(const Vector< D, T > &other) const
Dot product.
Definition: simplevectors.hpp:441
Vector< D, T > & operator/=(const T other)
In-place scalar division.
Definition: simplevectors.hpp:421
Vector< D, T > & operator*=(const T other)
In-place scalar multiplication.
Definition: simplevectors.hpp:406
std::array< T, D >::reverse_iterator reverse_iterator
An std::array::reverse_iterator.
Definition: simplevectors.hpp:90
T & operator[](const std::size_t index)
Sets value of a certain component.
Definition: simplevectors.hpp:515
bool isZero() const
Determines whether the current vector is a zero vector.
Definition: simplevectors.hpp:492
const_iterator begin() const noexcept
Const interator of first element.
Definition: simplevectors.hpp:564
T & at(const std::size_t index)
Sets value of a certain component.
Definition: simplevectors.hpp:542
constexpr std::size_t numDimensions() const
Gets the number of dimensions.
Definition: simplevectors.hpp:485
const T & operator[](const std::size_t index) const
Value of a certain component of a vector.
Definition: simplevectors.hpp:504
A simple 2D vector representation.
Definition: simplevectors.hpp:727
double angle() const
Angle of vector.
Definition: simplevectors.hpp:795
T componentsAs() const
Converts vector to another object.
Definition: simplevectors.hpp:834
double x() const
Gets x-component.
Definition: simplevectors.hpp:757
Vector2D rotate(const double ang) const
Rotates vector by a certain angle.
Definition: simplevectors.hpp:808
Vector2D(const Vec2_ &other)
Copy constructor for base class.
Definition: simplevectors.hpp:745
void y(const double &newY)
Sets y-component.
Definition: simplevectors.hpp:784
Vector2D(const double x, const double y)
Initializes a vector given xy components.
Definition: simplevectors.hpp:737
void x(const double &newX)
Sets x-component.
Definition: simplevectors.hpp:766
double y() const
Gets y-component.
Definition: simplevectors.hpp:775
A simple 3D vector representation.
Definition: simplevectors.hpp:844
T anglesAs() const
Converts angles to another object.
Definition: simplevectors.hpp:967
Vector3D(const double x, const double y, const double z)
Initializes a vector given xyz components.
Definition: simplevectors.hpp:855
Vector3D rotate(const double &ang) const
Rotates vector around a certain axis by a certain angle.
Definition: simplevectors.hpp:1014
Vector3D(const Vec3_ &other)
Copy constructor for the base class.
Definition: simplevectors.hpp:864
void z(const double &newZ)
Sets z-component.
Definition: simplevectors.hpp:922
Vector3D cross(const Vector3D &other) const
Cross product of two vectors.
Definition: simplevectors.hpp:931
T componentsAs() const
Converts vector to another object.
Definition: simplevectors.hpp:951
double z() const
Gets z-component.
Definition: simplevectors.hpp:913
void y(const double &newY)
Sets y-component.
Definition: simplevectors.hpp:904
double angle() const
Gets a specific angle of the vector.
Definition: simplevectors.hpp:986
void x(const double &newX)
Sets x-component.
Definition: simplevectors.hpp:886
double x() const
Gets x-component.
Definition: simplevectors.hpp:877
double y() const
Gets y-component.
Definition: simplevectors.hpp:895