29 #ifndef INCLUDE_SVECTORS_SIMPLEVECTORS_HPP_
30 #define INCLUDE_SVECTORS_SIMPLEVECTORS_HPP_
37 #include <initializer_list>
39 #include <type_traits>
63 template <std::
size_t D,
typename T =
double>
class Vector {
66 static_assert(std::is_arithmetic<T>::value,
"Vector type must be numeric");
68 #ifdef SVECTOR_EXPERIMENTAL_COMPARE
69 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
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>
84 typedef typename std::array<T, D>::const_iterator
86 typedef typename std::array<T, D>::reverse_iterator
88 typedef typename std::array<T, D>::const_reverse_iterator
110 Vector(
const std::initializer_list<T> args) {
114 std::size_t counter = 0;
115 for (
const auto &num : args) {
131 for (std::size_t i = 0; i < D; i++) {
150 if (
this == &other) {
154 for (std::size_t i = 0; i < D; i++) {
183 std::string str =
"<";
184 for (std::size_t i = 0; i < D - 1; i++) {
195 #ifdef SVECTOR_USE_CLASS_OPERATORS
214 for (std::size_t i = 0; i < D; i++) {
237 Vector<D, T>
operator-(
const Vector<D, T> &other)
const {
239 for (std::size_t i = 0; i < D; i++) {
259 Vector<D, T>
operator*(
const T other)
const {
261 for (std::size_t i = 0; i < D; i++) {
281 Vector<D, T>
operator/(
const T other)
const {
283 for (std::size_t i = 0; i < D; i++) {
303 bool operator==(
const Vector<D, T> &other)
const {
304 for (std::size_t i = 0; i < D; i++) {
326 bool operator!=(
const Vector<D, T> &other)
const {
327 return !((*this) == other);
342 for (std::size_t i = 0; i < D; i++) {
359 for (std::size_t i = 0; i < D; i++) {
374 for (std::size_t i = 0; i < D; i++) {
389 for (std::size_t i = 0; i < D; i++) {
404 for (std::size_t i = 0; i < D; i++) {
419 for (std::size_t i = 0; i < D; i++) {
441 for (std::size_t i = 0; i < D; i++) {
456 T sum_of_squares = 0;
459 sum_of_squares += i * i;
462 return std::sqrt(sum_of_squares);
526 const T &
at(
const std::size_t index)
const {
661 #ifdef SVECTOR_EXPERIMENTAL_COMPARE
680 template <std::
size_t D2,
typename T2>
682 std::size_t min_dim = std::min(D, D2);
683 std::size_t counter = 0;
687 if constexpr (D != D2) {
692 return D < D2 ? -1 : 1;
696 for (std::size_t i = 0; i < min_dim; i++) {
697 if (this->m_components[i] == other[i]) {
699 }
else if (this->m_components[i] < other[i]) {
706 if (counter != D || counter != D2) {
732 this->m_components[0] =
x;
733 this->m_components[1] =
y;
740 this->m_components[0] = other[0];
741 this->m_components[1] = other[1];
751 double x()
const {
return this->m_components[0]; }
760 void x(
const double &newX) { this->m_components[0] = newX; }
769 double y()
const {
return this->m_components[1]; }
778 void y(
const double &newY) { this->m_components[1] = newY; }
789 double angle()
const {
return std::atan2(this->
y(), this->
x()); }
810 const double xPrime = this->
x() * std::cos(ang) - this->
y() * std::sin(ang);
811 const double yPrime = this->
x() * std::sin(ang) + this->
y() * std::cos(ang);
829 return T{this->
x(), this->
y()};
849 Vector3D(
const double x,
const double y,
const double z) {
850 this->m_components[0] =
x;
851 this->m_components[1] =
y;
852 this->m_components[2] =
z;
859 this->m_components[0] = other[0];
860 this->m_components[1] = other[1];
861 this->m_components[2] = other[2];
871 double x()
const {
return this->m_components[0]; }
880 void x(
const double &newX) { this->m_components[0] = newX; }
889 double y()
const {
return this->m_components[1]; }
898 void y(
const double &newY) { this->m_components[1] = newY; }
907 double z()
const {
return this->m_components[2]; }
916 void z(
const double &newZ) { this->m_components[2] = newZ; }
926 const double newx = this->
y() * other.
z() - this->
z() * other.
y();
927 const double newy = this->
z() * other.
x() - this->
x() * other.
z();
928 const double newz = this->
x() * other.
y() - this->
y() * other.
x();
946 return T{this->
x(), this->
y(), this->
z()};
962 return T{this->getAlpha(), this->getBeta(), this->getGamma()};
980 template <AngleDir D>
double angle()
const {
983 return this->getAlpha();
985 return this->getBeta();
987 return this->getGamma();
1027 double getAlpha()
const {
return std::acos(this->
x() / this->
magn()); }
1036 double getBeta()
const {
return std::acos(this->y() / this->
magn()); }
1045 double getGamma()
const {
return std::acos(this->
z() / this->
magn()); }
1059 const double xPrime = this->
x();
1060 const double yPrime = this->
y() * std::cos(ang) - this->
z() * std::sin(ang);
1061 const double zPrime = this->
y() * std::sin(ang) + this->
z() * std::cos(ang);
1063 return Vector3D{xPrime, yPrime, zPrime};
1069 Vector3D
rotateBeta(
const double &ang)
const {
1078 const double xPrime = this->
x() * std::cos(ang) + this->
z() * std::sin(ang);
1079 const double yPrime = this->
y();
1080 const double zPrime =
1081 -this->
x() * std::sin(ang) + this->
z() * std::cos(ang);
1083 return Vector3D{xPrime, yPrime, zPrime};
1098 const double xPrime = this->
x() * std::cos(ang) - this->
y() * std::sin(ang);
1099 const double yPrime = this->
x() * std::sin(ang) + this->
y() * std::cos(ang);
1100 const double zPrime = this->
z();
1102 return Vector3D{xPrime, yPrime, zPrime};
1113 template <std::
size_t D,
typename T>
1116 for (std::size_t i = 0; i < D; i++) {
1137 template <std::
size_t D,
typename T>
1140 for (std::size_t i = 0; i < std::min(D, vector.size()); i++) {
1162 template <std::
size_t D,
typename T>
1183 inline void x(
Vector2D &v,
const double xValue) { v[0] = xValue; }
1200 inline void x(
Vector3D &v,
const double xValue) { v[0] = xValue; }
1217 inline void y(
Vector2D &v,
const double yValue) { v[1] = yValue; }
1234 inline void y(
Vector3D &v,
const double yValue) { v[1] = yValue; }
1251 inline void z(
Vector3D &v,
const double zValue) { v[2] = zValue; }
1263 template <
typename T, std::
size_t D>
1267 for (std::size_t i = 0; i < D; i++) {
1268 result += lhs[i] * rhs[i];
1282 T sum_of_squares = 0;
1284 for (std::size_t i = 0; i < D; i++) {
1285 sum_of_squares += v[i] * v[i];
1288 return std::sqrt(sum_of_squares);
1303 template <
typename T, std::
size_t D>
1314 return magn(v) == 0;
1348 const double xPrime =
x(v) * std::cos(ang) -
y(v) * std::sin(ang);
1349 const double yPrime =
x(v) * std::sin(ang) +
y(v) * std::cos(ang);
1363 const double newx =
y(lhs) *
z(rhs) -
z(lhs) *
y(rhs);
1364 const double newy =
z(lhs) *
x(rhs) -
x(lhs) *
z(rhs);
1365 const double newz =
x(lhs) *
y(rhs) -
y(lhs) *
x(rhs);
1431 const double xPrime =
x(v);
1432 const double yPrime =
y(v) * std::cos(ang) -
z(v) * std::sin(ang);
1433 const double zPrime =
y(v) * std::sin(ang) +
z(v) * std::cos(ang);
1435 return Vector3D{xPrime, yPrime, zPrime};
1457 const double xPrime =
x(v) * std::cos(ang) +
z(v) * std::sin(ang);
1458 const double yPrime =
y(v);
1459 const double zPrime = -
x(v) * std::sin(ang) +
z(v) * std::cos(ang);
1461 return Vector3D{xPrime, yPrime, zPrime};
1483 const double xPrime =
x(v) * std::cos(ang) -
y(v) * std::sin(ang);
1484 const double yPrime =
x(v) * std::sin(ang) +
y(v) * std::cos(ang);
1485 const double zPrime =
z(v);
1487 return Vector3D{xPrime, yPrime, zPrime};
1490 #ifndef SVECTOR_USE_CLASS_OPERATORS
1507 template <
typename T, std::
size_t D>
1511 for (std::size_t i = 0; i < D; i++) {
1512 tmp[i] = lhs[i] + rhs[i];
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];
1559 template <
typename T,
typename T2, std::
size_t D>
1562 for (std::size_t i = 0; i < D; i++) {
1563 tmp[i] = lhs[i] * rhs;
1583 template <
typename T,
typename T2, std::
size_t D>
1586 for (std::size_t i = 0; i < D; i++) {
1587 tmp[i] = lhs[i] / rhs;
1606 template <
typename T, std::
size_t D>
1608 for (std::size_t i = 0; i < D; i++) {
1609 if (lhs[i] != rhs[i]) {
1630 template <
typename T, std::
size_t D>
1632 return !(lhs == rhs);
1636 #ifdef SVECTOR_EXPERIMENTAL_COMPARE
1637 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
1638 bool operator<(
const Vector<D1, T1> &lhs,
const Vector<D2, T2> &rhs) {
1639 return lhs.compare(rhs) < 0;
1642 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
1643 bool operator>(
const Vector<D1, T1> &lhs,
const Vector<D2, T2> &rhs) {
1644 return lhs.compare(rhs) > 0;
1647 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
1648 bool operator<=(
const Vector<D1, T1> &lhs,
const Vector<D2, T2> &rhs) {
1649 return lhs.compare(rhs) <= 0;
1652 template <std::
size_t D1, std::
size_t D2,
typename T1,
typename T2>
1653 bool operator>=(
const Vector<D1, T1> &lhs,
const Vector<D2, T2> &rhs) {
1654 return lhs.compare(rhs) >= 0;
bool operator==(const Vector< D, T > &lhs, const Vector< D, T > &rhs)
Compares equality of two vectors.
Definition: simplevectors.hpp:1607
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:1175
double alpha(const Vector3D &v)
Gets α angle.
Definition: simplevectors.hpp:1382
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Cross product of two vectors.
Definition: simplevectors.hpp:1362
double angle(const Vector2D &v)
Gets the angle of a 2D vector in radians.
Definition: simplevectors.hpp:1326
Vector3D rotateAlpha(const Vector3D &v, const double &ang)
Rotates around x-axis.
Definition: simplevectors.hpp:1422
Vector3D rotateGamma(const Vector3D &v, const double &ang)
Rotates around z-axis.
Definition: simplevectors.hpp:1474
Vector< D, T > operator*(const Vector< D, T > &lhs, const T2 rhs)
Scalar multiplication.
Definition: simplevectors.hpp:1560
Vector2D rotate(const Vector2D &v, const double ang)
Rotates a 2D vector by a certain angle.
Definition: simplevectors.hpp:1340
double beta(const Vector3D &v)
Gets β angle.
Definition: simplevectors.hpp:1396
double y(const Vector2D &v)
Gets the y-component of a 2D vector.
Definition: simplevectors.hpp:1209
Vector3D rotateBeta(const Vector3D &v, const double &ang)
Rotates around y-axis.
Definition: simplevectors.hpp:1448
double z(const Vector3D &v)
Gets the z-component of a 3D vector.
Definition: simplevectors.hpp:1243
Vector< D, T > makeVector(std::array< T, D > array)
Creates a vector from an std::array.
Definition: simplevectors.hpp:1114
Vector< D, T > operator/(const Vector< D, T > &lhs, const T2 rhs)
Scalar division.
Definition: simplevectors.hpp:1584
bool operator!=(const Vector< D, T > &lhs, const Vector< D, T > &rhs)
Compares inequality of two vectors.
Definition: simplevectors.hpp:1631
double gamma(const Vector3D &v)
Gets γ angle.
Definition: simplevectors.hpp:1410
A base vector representation.
Definition: simplevectors.hpp:63
std::array< T, D >::const_reverse_iterator const_reverse_iterator
An std::array::const_reverse_iterator.
Definition: simplevectors.hpp:89
const T & at(const std::size_t index) const
Value of a certain component of a vector.
Definition: simplevectors.hpp:526
Vector()
No-argument constructor.
Definition: simplevectors.hpp:96
std::array< T, D >::const_iterator const_iterator
An std::array::const_iterator.
Definition: simplevectors.hpp:85
Vector< D, T > operator+() const
Positive of a vector.
Definition: simplevectors.hpp:357
reverse_iterator rend() noexcept
Reverse iterator to first element - 1.
Definition: simplevectors.hpp:637
Vector(Vector< D, T > &&) noexcept=default
Move constructor.
reverse_iterator rbegin() noexcept
Reverse iterator to last element.
Definition: simplevectors.hpp:606
T magn() const
Magnitude.
Definition: simplevectors.hpp:455
Vector< D, T > & operator+=(const Vector< D, T > &other)
In-place addition.
Definition: simplevectors.hpp:373
const_reverse_iterator rbegin() const noexcept
Const reverse iterator to last element.
Definition: simplevectors.hpp:619
iterator begin() noexcept
Iterator of first element.
Definition: simplevectors.hpp:551
std::array< T, D >::iterator iterator
An std::array::iterator.
Definition: simplevectors.hpp:66
const_iterator end() const noexcept
Const interator of last element + 1.
Definition: simplevectors.hpp:591
Vector< D, T > normalize() const
Normalizes a vector.
Definition: simplevectors.hpp:475
Vector< D, T > & operator-=(const Vector< D, T > &other)
In-place subtraction.
Definition: simplevectors.hpp:388
const_reverse_iterator rend() const noexcept
Const reverse iterator to first element - 1.
Definition: simplevectors.hpp:654
virtual std::string toString() const
Returns string form of vector.
Definition: simplevectors.hpp:182
Vector< D, T > operator-() const
Negative of a vector.
Definition: simplevectors.hpp:340
Vector(const std::initializer_list< T > args)
Initializes a vector given initializer list.
Definition: simplevectors.hpp:110
Vector< D, T > & operator=(Vector< D, T > &&) noexcept=default
Move assignment operator.
iterator end() noexcept
Interator of last element + 1.
Definition: simplevectors.hpp:578
Vector(const Vector< D, T > &other)
Copy constructor.
Definition: simplevectors.hpp:130
std::array< T, D > m_components
An array of components for the vector.
Definition: simplevectors.hpp:659
T dot(const Vector< D, T > &other) const
Dot product.
Definition: simplevectors.hpp:438
Vector< D, T > & operator/=(const T other)
In-place scalar division.
Definition: simplevectors.hpp:418
Vector< D, T > & operator*=(const T other)
In-place scalar multiplication.
Definition: simplevectors.hpp:403
std::array< T, D >::reverse_iterator reverse_iterator
An std::array::reverse_iterator.
Definition: simplevectors.hpp:87
T & operator[](const std::size_t index)
Sets value of a certain component.
Definition: simplevectors.hpp:512
bool isZero() const
Determines whether the current vector is a zero vector.
Definition: simplevectors.hpp:489
const_iterator begin() const noexcept
Const interator of first element.
Definition: simplevectors.hpp:561
T & at(const std::size_t index)
Sets value of a certain component.
Definition: simplevectors.hpp:539
constexpr std::size_t numDimensions() const
Gets the number of dimensions.
Definition: simplevectors.hpp:482
const T & operator[](const std::size_t index) const
Value of a certain component of a vector.
Definition: simplevectors.hpp:501
A simple 2D vector representation.
Definition: simplevectors.hpp:721
double angle() const
Angle of vector.
Definition: simplevectors.hpp:789
T componentsAs() const
Converts vector to another object.
Definition: simplevectors.hpp:828
double x() const
Gets x-component.
Definition: simplevectors.hpp:751
Vector2D rotate(const double ang) const
Rotates vector by a certain angle.
Definition: simplevectors.hpp:802
Vector2D(const Vec2_ &other)
Copy constructor for base class.
Definition: simplevectors.hpp:739
void y(const double &newY)
Sets y-component.
Definition: simplevectors.hpp:778
Vector2D(const double x, const double y)
Initializes a vector given xy components.
Definition: simplevectors.hpp:731
void x(const double &newX)
Sets x-component.
Definition: simplevectors.hpp:760
double y() const
Gets y-component.
Definition: simplevectors.hpp:769
A simple 3D vector representation.
Definition: simplevectors.hpp:838
T anglesAs() const
Converts angles to another object.
Definition: simplevectors.hpp:961
Vector3D(const double x, const double y, const double z)
Initializes a vector given xyz components.
Definition: simplevectors.hpp:849
Vector3D rotate(const double &ang) const
Rotates vector around a certain axis by a certain angle.
Definition: simplevectors.hpp:1008
Vector3D(const Vec3_ &other)
Copy constructor for the base class.
Definition: simplevectors.hpp:858
void z(const double &newZ)
Sets z-component.
Definition: simplevectors.hpp:916
Vector3D cross(const Vector3D &other) const
Cross product of two vectors.
Definition: simplevectors.hpp:925
T componentsAs() const
Converts vector to another object.
Definition: simplevectors.hpp:945
double z() const
Gets z-component.
Definition: simplevectors.hpp:907
void y(const double &newY)
Sets y-component.
Definition: simplevectors.hpp:898
double angle() const
Gets a specific angle of the vector.
Definition: simplevectors.hpp:980
void x(const double &newX)
Sets x-component.
Definition: simplevectors.hpp:880
double x() const
Gets x-component.
Definition: simplevectors.hpp:871
double y() const
Gets y-component.
Definition: simplevectors.hpp:889