NumCpp  2.4.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
Vec2.hpp
Go to the documentation of this file.
1 #pragma once
29 
31 #include "NumCpp/NdArray.hpp"
33 #include "NumCpp/Utils/interp.hpp"
34 
35 #include <cmath>
36 #include <initializer_list>
37 #include <iostream>
38 #include <sstream>
39 #include <string>
40 
41 //====================================================================================
42 
43 namespace nc
44 {
45  //================================================================================
46  // Class Description:
48  class Vec2
49  {
50  public:
51  //====================================Attributes==============================
52  double x{ 0.0 };
53  double y{ 0.0 };
54 
55  //============================================================================
56  // Method Description:
59  constexpr Vec2() = default;
60 
61  //============================================================================
62  // Method Description:
68  constexpr Vec2(double inX, double inY) noexcept :
69  x(inX),
70  y(inY)
71  {}
72 
73  //============================================================================
74  // Method Description:
79  Vec2(const std::initializer_list<double>& inList)
80  {
81  if (inList.size() != 2)
82  {
83  THROW_INVALID_ARGUMENT_ERROR("input initializer list must have a size = 2");
84  }
85 
86  x = *inList.begin();
87  y = *(inList.begin() + 1);
88  }
89 
90  //============================================================================
91  // Method Description:
96  Vec2(const NdArray<double>& ndArray)
97  {
98  if (ndArray.size() != 2)
99  {
100  THROW_INVALID_ARGUMENT_ERROR("input NdArray must have a size = 2");
101  }
102 
103  x = ndArray[0];
104  y = ndArray[1];
105  }
106 
107  //============================================================================
108  // Method Description:
114  double angle(const Vec2& otherVec) const noexcept
115  {
116  double dotProduct = dot(otherVec);
117  dotProduct /= norm();
118  dotProduct /= otherVec.norm();
119 
120  // clamp the value to the acos range just to be safe
121  dotProduct = std::max(std::min(dotProduct, 1.0), -1.0);
122 
123  return std::acos(dotProduct);
124  }
125 
126  //============================================================================
127  // Method Description:
134  Vec2 clampMagnitude(double maxLength) const noexcept
135  {
136  const double magnitude = norm();
137  if (magnitude <= maxLength)
138  {
139  return *this;
140  }
141 
142  Vec2 returnVec = Vec2(*this).normalize();
143  returnVec *= maxLength;
144  return returnVec;
145  }
146 
147  //============================================================================
148  // Method Description:
154  double distance(const Vec2& otherVec) const noexcept
155  {
156  return (Vec2(*this) -= otherVec).norm();
157  }
158 
159  //============================================================================
160  // Method Description:
166  double dot(const Vec2& otherVec) const noexcept
167  {
168  return x * otherVec.x + y * otherVec.y;
169  }
170 
171  //============================================================================
172  // Method Description:
177  static constexpr Vec2 down() noexcept
178  {
179  return Vec2(0.0, -1.0);
180  }
181 
182  //============================================================================
183  // Method Description:
188  static constexpr Vec2 left() noexcept
189  {
190  return Vec2(-1.0, 0.0);
191  }
192 
193  //============================================================================
194  // Method Description:
201  Vec2 lerp(const Vec2& otherVec, double t) const noexcept
202  {
203  t = std::max(std::min(t, 1.0), 0.0);
204 
205  Vec2 trajectory = otherVec;
206  trajectory -= *this;
207  const double xInterp = utils::interp(0.0, trajectory.x, t);
208  const double yInterp = utils::interp(0.0, trajectory.y, t);
209 
210  return Vec2(*this) += Vec2(xInterp, yInterp);
211  }
212 
213  //============================================================================
214  // Method Description:
219  double norm() const noexcept
220  {
221  return std::hypot(x, y);
222  }
223 
224  //============================================================================
225  // Method Description:
230  Vec2 normalize() const noexcept
231  {
232  return Vec2(*this) /= norm();
233  }
234 
235  //============================================================================
236  // Method Description:
242  Vec2 project(const Vec2& otherVec) const noexcept
243  {
244  const double projectedMagnitude = norm() * std::cos(angle(otherVec));
245  return otherVec.normalize() *= projectedMagnitude;
246  }
247 
248  //============================================================================
249  // Method Description:
254  static constexpr Vec2 right() noexcept
255  {
256  return Vec2(1.0, 0.0);
257  }
258 
259  //============================================================================
260  // Method Description:
265  std::string toString() const
266  {
267  std::stringstream stream;
268  stream << "Vec2[" << x << ", " << y << "]";
269  return stream.str();
270  }
271 
272  //============================================================================
273  // Method Description:
279  {
280  NdArray<double> returnArray = { x, y };
281  return returnArray.transpose();
282  }
283 
284  //============================================================================
285  // Method Description:
290  static constexpr Vec2 up() noexcept
291  {
292  return Vec2(0.0, 1.0);
293  }
294 
295  //============================================================================
296  // Method Description:
302  bool operator==(const Vec2& rhs) const noexcept
303  {
304  return utils::essentiallyEqual(x, rhs.x) && utils::essentiallyEqual(y, rhs.y);
305  }
306 
307  //============================================================================
308  // Method Description:
314  bool operator!=(const Vec2& rhs) const noexcept
315  {
316  return !(*this == rhs);
317  }
318 
319  //============================================================================
320  // Method Description:
326  Vec2& operator+=(double scaler) noexcept
327  {
328  x += scaler;
329  y += scaler;
330  return *this;
331  }
332 
333  //============================================================================
334  // Method Description:
340  Vec2& operator+=(const Vec2& rhs) noexcept
341  {
342  x += rhs.x;
343  y += rhs.y;
344  return *this;
345  }
346 
347  //============================================================================
348  // Method Description:
354  Vec2& operator-=(double scaler) noexcept
355  {
356  x -= scaler;
357  y -= scaler;
358  return *this;
359  }
360 
361  //============================================================================
362  // Method Description:
368  Vec2& operator-=(const Vec2& rhs) noexcept
369  {
370  x -= rhs.x;
371  y -= rhs.y;
372  return *this;
373  }
374 
375  //============================================================================
376  // Method Description:
382  Vec2& operator*=(double scaler) noexcept
383  {
384  x *= scaler;
385  y *= scaler;
386  return *this;
387  }
388 
389  //============================================================================
390  // Method Description:
396  Vec2& operator/=(double scaler) noexcept
397  {
398  x /= scaler;
399  y /= scaler;
400  return *this;
401  }
402  };
403 
404  //============================================================================
405  // Method Description:
412  inline Vec2 operator+(const Vec2& lhs, double rhs) noexcept
413  {
414  return Vec2(lhs) += rhs;
415  }
416 
417  //============================================================================
418  // Method Description:
425  inline Vec2 operator+(double lhs, const Vec2& rhs) noexcept
426  {
427  return Vec2(rhs) += lhs;
428  }
429 
430  //============================================================================
431  // Method Description:
438  inline Vec2 operator+(const Vec2& lhs, const Vec2& rhs) noexcept
439  {
440  return Vec2(lhs) += rhs;
441  }
442 
443  //============================================================================
444  // Method Description:
449  inline Vec2 operator-(const Vec2& vec) noexcept
450  {
451  return {-vec.x, -vec.y};
452  }
453 
454  //============================================================================
455  // Method Description:
462  inline Vec2 operator-(const Vec2& lhs, double rhs) noexcept
463  {
464  return Vec2(lhs) -= rhs;
465  }
466 
467  //============================================================================
468  // Method Description:
475  inline Vec2 operator-(double lhs, const Vec2& rhs) noexcept
476  {
477  return -Vec2(rhs) += lhs;
478  }
479 
480  //============================================================================
481  // Method Description:
488  inline Vec2 operator-(const Vec2& lhs, const Vec2& rhs) noexcept
489  {
490  return Vec2(lhs) -= rhs;
491  }
492 
493  //============================================================================
494  // Method Description:
501  inline Vec2 operator*(const Vec2& lhs, double rhs) noexcept
502  {
503  return Vec2(lhs) *= rhs;
504  }
505 
506  //============================================================================
507  // Method Description:
514  inline Vec2 operator*(double lhs, const Vec2& rhs) noexcept
515  {
516  return Vec2(rhs) *= lhs;
517  }
518 
519  //============================================================================
520  // Method Description:
528  inline double operator*(const Vec2& lhs, const Vec2& rhs) noexcept
529  {
530  return lhs.dot(rhs);
531  }
532 
533  //============================================================================
534  // Method Description:
541  inline Vec2 operator/(const Vec2& lhs, double rhs) noexcept
542  {
543  return Vec2(lhs) /= rhs;
544  }
545 
546  //============================================================================
547  // Method Description:
554  inline std::ostream& operator<<(std::ostream& stream, const Vec2& vec)
555  {
556  stream << vec.toString() << std::endl;
557  return stream;
558  }
559 } // namespace nc
nc::Vec2::dot
double dot(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:166
nc::Vec2::y
double y
Definition: Vec2.hpp:53
nc::Vec2
Holds a 2D vector.
Definition: Vec2.hpp:48
Error.hpp
nc::operator+
NdArrayConstIterator< dtype, PointerType, DifferenceType > operator+(typename NdArrayConstIterator< dtype, PointerType, DifferenceType >::difference_type offset, NdArrayConstIterator< dtype, PointerType, DifferenceType > next) noexcept
Definition: NdArrayIterators.hpp:304
nc::NdArray::dot
NdArray< dtype > dot(const NdArray< dtype > &inOtherArray) const
Definition: NdArrayCore.hpp:2661
nc::Vec2::operator-=
Vec2 & operator-=(const Vec2 &rhs) noexcept
Definition: Vec2.hpp:368
nc::utils::interp
constexpr double interp(double inValue1, double inValue2, double inPercent) noexcept
Definition: Utils/interp.hpp:43
nc::Vec2::x
double x
Definition: Vec2.hpp:52
nc::operator/
NdArray< dtype > operator/(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1090
nc::Vec2::project
Vec2 project(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:242
nc::Vec2::right
static constexpr Vec2 right() noexcept
Definition: Vec2.hpp:254
nc::utils::essentiallyEqual
bool essentiallyEqual(dtype inValue1, dtype inValue2) noexcept
Definition: essentiallyEqual.hpp:52
nc::Vec2::operator+=
Vec2 & operator+=(const Vec2 &rhs) noexcept
Definition: Vec2.hpp:340
nc::Vec2::toString
std::string toString() const
Definition: Vec2.hpp:265
nc::Vec2::Vec2
Vec2(const NdArray< double > &ndArray)
Definition: Vec2.hpp:96
nc::NdArray::transpose
NdArray< dtype > transpose() const
Definition: NdArrayCore.hpp:4652
nc::NdArray< double >
interp.hpp
nc::Vec2::up
static constexpr Vec2 up() noexcept
Definition: Vec2.hpp:290
nc::cos
auto cos(dtype inValue) noexcept
Definition: cos.hpp:51
nc::Vec2::lerp
Vec2 lerp(const Vec2 &otherVec, double t) const noexcept
Definition: Vec2.hpp:201
NdArray.hpp
nc::Vec2::operator==
bool operator==(const Vec2 &rhs) const noexcept
Definition: Vec2.hpp:302
nc::NdArray::size
size_type size() const noexcept
Definition: NdArrayCore.hpp:4370
nc::Vec2::angle
double angle(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:114
nc::hypot
double hypot(dtype inValue1, dtype inValue2) noexcept
Definition: hypot.hpp:57
nc::Vec2::Vec2
constexpr Vec2(double inX, double inY) noexcept
Definition: Vec2.hpp:68
nc::operator-
NdArray< dtype > operator-(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:443
nc::Vec2::Vec2
constexpr Vec2()=default
nc
Definition: Coordinate.hpp:44
nc::Vec2::Vec2
Vec2(const std::initializer_list< double > &inList)
Definition: Vec2.hpp:79
nc::Vec2::norm
double norm() const noexcept
Definition: Vec2.hpp:219
essentiallyEqual.hpp
THROW_INVALID_ARGUMENT_ERROR
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
nc::Vec2::clampMagnitude
Vec2 clampMagnitude(double maxLength) const noexcept
Definition: Vec2.hpp:134
nc::operator<<
NdArray< dtype > operator<<(const NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:2413
nc::Vec2::operator*=
Vec2 & operator*=(double scaler) noexcept
Definition: Vec2.hpp:382
nc::max
NdArray< dtype > max(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: max.hpp:45
nc::Vec2::distance
double distance(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:154
nc::Vec2::normalize
Vec2 normalize() const noexcept
Definition: Vec2.hpp:230
nc::Vec2::operator-=
Vec2 & operator-=(double scaler) noexcept
Definition: Vec2.hpp:354
nc::Vec2::down
static constexpr Vec2 down() noexcept
Definition: Vec2.hpp:177
nc::Vec2::operator/=
Vec2 & operator/=(double scaler) noexcept
Definition: Vec2.hpp:396
nc::Vec2::operator!=
bool operator!=(const Vec2 &rhs) const noexcept
Definition: Vec2.hpp:314
nc::operator*
NdArray< dtype > operator*(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:801
nc::Vec2::operator+=
Vec2 & operator+=(double scaler) noexcept
Definition: Vec2.hpp:326
nc::Vec2::left
static constexpr Vec2 left() noexcept
Definition: Vec2.hpp:188
nc::min
NdArray< dtype > min(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: min.hpp:45
nc::Vec2::toNdArray
NdArray< double > toNdArray() const
Definition: Vec2.hpp:278