NumCpp  2.10.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
Vec2.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <cmath>
31 #include <initializer_list>
32 #include <iostream>
33 #include <sstream>
34 #include <string>
35 
37 #include "NumCpp/NdArray.hpp"
39 #include "NumCpp/Utils/interp.hpp"
40 
41 //====================================================================================
42 
43 namespace nc
44 {
45  //================================================================================
46  // Class Description:
48  class Vec2
49  {
50  public:
51  //====================================Attributes==============================
52  double x{ 0. };
53  double y{ 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  //============================================================================
75  // Method Description:
80  Vec2(const std::initializer_list<double>& inList)
81  {
82  if (inList.size() != 2)
83  {
84  THROW_INVALID_ARGUMENT_ERROR("input initializer list must have a size = 2");
85  }
86 
87  x = *inList.begin();
88  y = *(inList.begin() + 1);
89  }
90 
91  //============================================================================
92  // Method Description:
97  Vec2(const NdArray<double>& ndArray)
98  {
99  if (ndArray.size() != 2)
100  {
101  THROW_INVALID_ARGUMENT_ERROR("input NdArray must have a size = 2");
102  }
103 
104  x = ndArray[0];
105  y = ndArray[1];
106  }
107 
108  //============================================================================
109  // Method Description:
115  [[nodiscard]] double angle(const Vec2& otherVec) const noexcept
116  {
117  double dotProduct = dot(otherVec);
118  dotProduct /= norm();
119  dotProduct /= otherVec.norm();
120 
121  // clamp the value to the acos range just to be safe
122  dotProduct = std::max(std::min(dotProduct, 1.), -1.);
123 
124  return std::acos(dotProduct);
125  }
126 
127  //============================================================================
128  // Method Description:
135  [[nodiscard]] Vec2 clampMagnitude(double maxLength) const noexcept
136  {
137  const double magnitude = norm();
138  if (magnitude <= maxLength)
139  {
140  return *this;
141  }
142 
143  Vec2 returnVec = Vec2(*this).normalize();
144  returnVec *= maxLength;
145  return returnVec;
146  }
147 
148  //============================================================================
149  // Method Description:
155  [[nodiscard]] double distance(const Vec2& otherVec) const noexcept
156  {
157  return (Vec2(*this) -= otherVec).norm();
158  }
159 
160  //============================================================================
161  // Method Description:
167  [[nodiscard]] double dot(const Vec2& otherVec) const noexcept
168  {
169  return x * otherVec.x + y * otherVec.y;
170  }
171 
172  //============================================================================
173  // Method Description:
178  static constexpr Vec2 down() noexcept
179  {
180  return Vec2(0., -1.); // NOLINT(modernize-return-braced-init-list)
181  }
182 
183  //============================================================================
184  // Method Description:
189  static constexpr Vec2 left() noexcept
190  {
191  return Vec2(-1., 0.); // NOLINT(modernize-return-braced-init-list)
192  }
193 
194  //============================================================================
195  // Method Description:
202  [[nodiscard]] Vec2 lerp(const Vec2& otherVec, double t) const noexcept
203  {
204  t = std::max(std::min(t, 1.), 0.);
205 
206  Vec2 trajectory = otherVec;
207  trajectory -= *this;
208  const double xInterp = utils::interp(0., trajectory.x, t);
209  const double yInterp = utils::interp(0., trajectory.y, t);
210 
211  return Vec2(*this) += Vec2(xInterp, yInterp);
212  }
213 
214  //============================================================================
215  // Method Description:
220  [[nodiscard]] double norm() const noexcept
221  {
222  return std::hypot(x, y);
223  }
224 
225  //============================================================================
226  // Method Description:
231  [[nodiscard]] Vec2 normalize() const noexcept
232  {
233  return Vec2(*this) /= norm();
234  }
235 
236  //============================================================================
237  // Method Description:
243  [[nodiscard]] Vec2 project(const Vec2& otherVec) const noexcept
244  {
245  const double projectedMagnitude = norm() * std::cos(angle(otherVec));
246  return otherVec.normalize() *= projectedMagnitude;
247  }
248 
249  //============================================================================
250  // Method Description:
255  static constexpr Vec2 right() noexcept
256  {
257  return Vec2(1., 0.); // NOLINT(modernize-return-braced-init-list)
258  }
259 
260  //============================================================================
261  // Method Description:
266  [[nodiscard]] std::string toString() const
267  {
268  std::stringstream stream;
269  stream << "Vec2[" << x << ", " << y << "]";
270  return stream.str();
271  }
272 
273  //============================================================================
274  // Method Description:
279  [[nodiscard]] NdArray<double> toNdArray() const
280  {
281  NdArray<double> returnArray = { x, y };
282  return returnArray.transpose();
283  }
284 
285  //============================================================================
286  // Method Description:
291  static constexpr Vec2 up() noexcept
292  {
293  return Vec2(0., 1.); // NOLINT(modernize-return-braced-init-list)
294  }
295 
296  //============================================================================
297  // Method Description:
303  bool operator==(const Vec2& rhs) const noexcept
304  {
305  return utils::essentiallyEqual(x, rhs.x) && utils::essentiallyEqual(y, rhs.y);
306  }
307 
308  //============================================================================
309  // Method Description:
315  bool operator!=(const Vec2& rhs) const noexcept
316  {
317  return !(*this == rhs);
318  }
319 
320  //============================================================================
321  // Method Description:
327  Vec2& operator+=(double scalar) noexcept
328  {
329  x += scalar;
330  y += scalar;
331  return *this;
332  }
333 
334  //============================================================================
335  // Method Description:
341  Vec2& operator+=(const Vec2& rhs) noexcept
342  {
343  x += rhs.x;
344  y += rhs.y;
345  return *this;
346  }
347 
348  //============================================================================
349  // Method Description:
355  Vec2& operator-=(double scalar) noexcept
356  {
357  x -= scalar;
358  y -= scalar;
359  return *this;
360  }
361 
362  //============================================================================
363  // Method Description:
369  Vec2& operator-=(const Vec2& rhs) noexcept
370  {
371  x -= rhs.x;
372  y -= rhs.y;
373  return *this;
374  }
375 
376  //============================================================================
377  // Method Description:
383  Vec2& operator*=(double scalar) noexcept
384  {
385  x *= scalar;
386  y *= scalar;
387  return *this;
388  }
389 
390  //============================================================================
391  // Method Description:
397  Vec2& operator/=(double scalar) noexcept
398  {
399  x /= scalar;
400  y /= scalar;
401  return *this;
402  }
403  };
404 
405  //============================================================================
406  // Method Description:
413  inline Vec2 operator+(const Vec2& lhs, double rhs) noexcept
414  {
415  return Vec2(lhs) += rhs;
416  }
417 
418  //============================================================================
419  // Method Description:
426  inline Vec2 operator+(double lhs, const Vec2& rhs) noexcept
427  {
428  return Vec2(rhs) += lhs;
429  }
430 
431  //============================================================================
432  // Method Description:
439  inline Vec2 operator+(const Vec2& lhs, const Vec2& rhs) noexcept
440  {
441  return Vec2(lhs) += rhs;
442  }
443 
444  //============================================================================
445  // Method Description:
450  inline Vec2 operator-(const Vec2& vec) noexcept
451  {
452  return Vec2(-vec.x, -vec.y); // NOLINT(modernize-return-braced-init-list)
453  }
454 
455  //============================================================================
456  // Method Description:
463  inline Vec2 operator-(const Vec2& lhs, double rhs) noexcept
464  {
465  return Vec2(lhs) -= rhs;
466  }
467 
468  //============================================================================
469  // Method Description:
476  inline Vec2 operator-(double lhs, const Vec2& rhs) noexcept
477  {
478  return -Vec2(rhs) += lhs;
479  }
480 
481  //============================================================================
482  // Method Description:
489  inline Vec2 operator-(const Vec2& lhs, const Vec2& rhs) noexcept
490  {
491  return Vec2(lhs) -= rhs;
492  }
493 
494  //============================================================================
495  // Method Description:
502  inline Vec2 operator*(const Vec2& lhs, double rhs) noexcept
503  {
504  return Vec2(lhs) *= rhs;
505  }
506 
507  //============================================================================
508  // Method Description:
515  inline Vec2 operator*(double lhs, const Vec2& rhs) noexcept
516  {
517  return Vec2(rhs) *= lhs;
518  }
519 
520  //============================================================================
521  // Method Description:
529  inline double operator*(const Vec2& lhs, const Vec2& rhs) noexcept
530  {
531  return lhs.dot(rhs);
532  }
533 
534  //============================================================================
535  // Method Description:
542  inline Vec2 operator/(const Vec2& lhs, double rhs) noexcept
543  {
544  return Vec2(lhs) /= rhs;
545  }
546 
547  //============================================================================
548  // Method Description:
555  inline std::ostream& operator<<(std::ostream& stream, const Vec2& vec)
556  {
557  stream << vec.toString() << std::endl;
558  return stream;
559  }
560 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
size_type size() const noexcept
Definition: NdArrayCore.hpp:4415
self_type transpose() const
Definition: NdArrayCore.hpp:4775
Holds a 2D vector.
Definition: Vec2.hpp:49
Vec2 & operator-=(const Vec2 &rhs) noexcept
Definition: Vec2.hpp:369
Vec2 & operator*=(double scalar) noexcept
Definition: Vec2.hpp:383
Vec2 & operator+=(double scalar) noexcept
Definition: Vec2.hpp:327
double dot(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:167
static constexpr Vec2 down() noexcept
Definition: Vec2.hpp:178
double angle(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:115
double x
Definition: Vec2.hpp:52
double distance(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:155
static constexpr Vec2 up() noexcept
Definition: Vec2.hpp:291
Vec2 normalize() const noexcept
Definition: Vec2.hpp:231
Vec2 lerp(const Vec2 &otherVec, double t) const noexcept
Definition: Vec2.hpp:202
Vec2(const NdArray< double > &ndArray)
Definition: Vec2.hpp:97
Vec2 project(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:243
double norm() const noexcept
Definition: Vec2.hpp:220
static constexpr Vec2 right() noexcept
Definition: Vec2.hpp:255
Vec2 clampMagnitude(double maxLength) const noexcept
Definition: Vec2.hpp:135
Vec2(const std::initializer_list< double > &inList)
Definition: Vec2.hpp:80
bool operator!=(const Vec2 &rhs) const noexcept
Definition: Vec2.hpp:315
std::string toString() const
Definition: Vec2.hpp:266
Vec2 & operator-=(double scalar) noexcept
Definition: Vec2.hpp:355
NdArray< double > toNdArray() const
Definition: Vec2.hpp:279
double y
Definition: Vec2.hpp:53
static constexpr Vec2 left() noexcept
Definition: Vec2.hpp:189
Vec2 & operator/=(double scalar) noexcept
Definition: Vec2.hpp:397
constexpr Vec2()=default
constexpr Vec2(double inX, double inY) noexcept
Definition: Vec2.hpp:68
bool operator==(const Vec2 &rhs) const noexcept
Definition: Vec2.hpp:303
Vec2 & operator+=(const Vec2 &rhs) noexcept
Definition: Vec2.hpp:341
constexpr double interp(double inValue1, double inValue2, double inPercent) noexcept
Definition: Utils/interp.hpp:41
bool essentiallyEqual(dtype inValue1, dtype inValue2) noexcept
Definition: essentiallyEqual.hpp:48
Definition: Coordinate.hpp:45
Duration operator-(const DateTime &lhs, const DateTime &rhs) noexcept
Subtraction operator.
Definition: DateTime/DateTime.hpp:551
double hypot(dtype inValue1, dtype inValue2) noexcept
Definition: hypot.hpp:56
NdArray< dtype > max(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: max.hpp:44
NdArrayConstIterator< dtype, PointerType, DifferenceType > operator+(typename NdArrayConstIterator< dtype, PointerType, DifferenceType >::difference_type offset, NdArrayConstIterator< dtype, PointerType, DifferenceType > next) noexcept
Definition: NdArrayIterators.hpp:307
auto cos(dtype inValue) noexcept
Definition: cos.hpp:49
NdArray< dtype > min(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: min.hpp:44
NdArray< dtype > operator*(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:604
std::ostream & operator<<(std::ostream &os, Duration duration)
Output stream operator for the Duration type.
Definition: Clock.hpp:30
NdArray< dtype > operator/(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:819