NumCpp  1.0
A C++ implementation of the Python Numpy library
Vec2.hpp
Go to the documentation of this file.
1 #pragma once
30 
32 #include "NumCpp/NdArray.hpp"
34 #include "NumCpp/Utils/interp.hpp"
35 
36 #include <cmath>
37 #include <initializer_list>
38 #include <iostream>
39 #include <sstream>
40 #include <string>
41 
42 //====================================================================================
43 
44 namespace nc
45 {
46  //================================================================================
47  // Class Description:
49  class Vec2
50  {
51  public:
52  //====================================Attributes==============================
53  double x{ 0.0 };
54  double y{ 0.0 };
55 
56  //============================================================================
57  // Method Description:
60  constexpr Vec2() = default;
61 
62  //============================================================================
63  // Method Description:
69  constexpr Vec2(double inX, double inY) noexcept :
70  x(inX),
71  y(inY)
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  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.0), -1.0);
123 
124  return std::acos(dotProduct);
125  }
126 
127  //============================================================================
128  // Method Description:
135  Vec2 clampMagnitude(double maxLength) const noexcept
136  {
137  const double magnitude = norm();
138  if (magnitude <= maxLength)
139  {
140  return *this;
141  }
142  else
143  {
144  Vec2 returnVec = Vec2(*this).normalize();
145  returnVec *= maxLength;
146  return returnVec;
147  }
148  }
149 
150  //============================================================================
151  // Method Description:
157  double distance(const Vec2& otherVec) const noexcept
158  {
159  return (Vec2(*this) -= otherVec).norm();
160  }
161 
162  //============================================================================
163  // Method Description:
169  double dot(const Vec2& otherVec) const noexcept
170  {
171  return x * otherVec.x + y * otherVec.y;
172  }
173 
174  //============================================================================
175  // Method Description:
180  static constexpr Vec2 down() noexcept
181  {
182  return Vec2(0.0, -1.0);
183  }
184 
185  //============================================================================
186  // Method Description:
191  static constexpr Vec2 left() noexcept
192  {
193  return Vec2(-1.0, 0.0);
194  }
195 
196  //============================================================================
197  // Method Description:
204  Vec2 lerp(const Vec2& otherVec, double t) const noexcept
205  {
206  t = std::max(std::min(t, 1.0), 0.0);
207 
208  Vec2 trajectory = otherVec;
209  trajectory -= *this;
210  const double xInterp = utils::interp(0.0, trajectory.x, t);
211  const double yInterp = utils::interp(0.0, trajectory.y, t);
212 
213  return Vec2(*this) += Vec2(xInterp, yInterp);
214  }
215 
216  //============================================================================
217  // Method Description:
222  double norm() const noexcept
223  {
224  return std::hypot(x, y);
225  }
226 
227  //============================================================================
228  // Method Description:
233  Vec2 normalize() const noexcept
234  {
235  return Vec2(*this) /= norm();
236  }
237 
238  //============================================================================
239  // Method Description:
245  Vec2 project(const Vec2& otherVec) const noexcept
246  {
247  const double projectedMagnitude = norm() * std::cos(angle(otherVec));
248  return otherVec.normalize() *= projectedMagnitude;
249  }
250 
251  //============================================================================
252  // Method Description:
257  static constexpr Vec2 right() noexcept
258  {
259  return Vec2(1.0, 0.0);
260  }
261 
262  //============================================================================
263  // Method Description:
268  std::string toString() const
269  {
270  std::stringstream stream;
271  stream << "Vec2[" << x << ", " << y << "]";
272  return stream.str();
273  }
274 
275  //============================================================================
276  // Method Description:
282  {
283  NdArray<double> returnArray = { x, y };
284  return returnArray.transpose();
285  }
286 
287  //============================================================================
288  // Method Description:
293  static constexpr Vec2 up() noexcept
294  {
295  return Vec2(0.0, 1.0);
296  }
297 
298  //============================================================================
299  // Method Description:
305  bool operator==(const Vec2& rhs) const noexcept
306  {
307  return utils::essentiallyEqual(x, rhs.x) && utils::essentiallyEqual(y, rhs.y);
308  }
309 
310  //============================================================================
311  // Method Description:
317  bool operator!=(const Vec2& rhs) const noexcept
318  {
319  return !(*this == rhs);
320  }
321 
322  //============================================================================
323  // Method Description:
329  Vec2& operator+=(double scaler) noexcept
330  {
331  x += scaler;
332  y += scaler;
333  return *this;
334  }
335 
336  //============================================================================
337  // Method Description:
343  Vec2& operator+=(const Vec2& rhs) noexcept
344  {
345  x += rhs.x;
346  y += rhs.y;
347  return *this;
348  }
349 
350  //============================================================================
351  // Method Description:
357  Vec2& operator-=(double scaler) noexcept
358  {
359  x -= scaler;
360  y -= scaler;
361  return *this;
362  }
363 
364  //============================================================================
365  // Method Description:
371  Vec2& operator-=(const Vec2& rhs) noexcept
372  {
373  x -= rhs.x;
374  y -= rhs.y;
375  return *this;
376  }
377 
378  //============================================================================
379  // Method Description:
385  Vec2& operator*=(double scaler) noexcept
386  {
387  x *= scaler;
388  y *= scaler;
389  return *this;
390  }
391 
392  //============================================================================
393  // Method Description:
399  Vec2& operator/=(double scaler) noexcept
400  {
401  x /= scaler;
402  y /= scaler;
403  return *this;
404  }
405  };
406 
407  //============================================================================
408  // Method Description:
415  inline Vec2 operator+(const Vec2& lhs, double rhs) noexcept
416  {
417  return Vec2(lhs) += rhs;
418  }
419 
420  //============================================================================
421  // Method Description:
428  inline Vec2 operator+(double lhs, const Vec2& rhs) noexcept
429  {
430  return Vec2(rhs) += lhs;
431  }
432 
433  //============================================================================
434  // Method Description:
441  inline Vec2 operator+(const Vec2& lhs, const Vec2& rhs) noexcept
442  {
443  return Vec2(lhs) += rhs;
444  }
445 
446  //============================================================================
447  // Method Description:
452  inline Vec2 operator-(const Vec2& vec) noexcept
453  {
454  return Vec2(-vec.x, -vec.y);
455  }
456 
457  //============================================================================
458  // Method Description:
465  inline Vec2 operator-(const Vec2& lhs, double rhs) noexcept
466  {
467  return Vec2(lhs) -= rhs;
468  }
469 
470  //============================================================================
471  // Method Description:
478  inline Vec2 operator-(double lhs, const Vec2& rhs) noexcept
479  {
480  return -Vec2(rhs) += lhs;
481  }
482 
483  //============================================================================
484  // Method Description:
491  inline Vec2 operator-(const Vec2& lhs, const Vec2& rhs) noexcept
492  {
493  return Vec2(lhs) -= rhs;
494  }
495 
496  //============================================================================
497  // Method Description:
504  inline Vec2 operator*(const Vec2& lhs, double rhs) noexcept
505  {
506  return Vec2(lhs) *= rhs;
507  }
508 
509  //============================================================================
510  // Method Description:
517  inline Vec2 operator*(double lhs, const Vec2& rhs) noexcept
518  {
519  return Vec2(rhs) *= lhs;
520  }
521 
522  //============================================================================
523  // Method Description:
531  inline double operator*(const Vec2& lhs, const Vec2& rhs) noexcept
532  {
533  return lhs.dot(rhs);
534  }
535 
536  //============================================================================
537  // Method Description:
544  inline Vec2 operator/(const Vec2& lhs, double rhs) noexcept
545  {
546  return Vec2(lhs) /= rhs;
547  }
548 
549  //============================================================================
550  // Method Description:
557  inline std::ostream& operator<<(std::ostream& stream, const Vec2& vec)
558  {
559  stream << vec.toString() << std::endl;
560  return stream;
561  }
562 }
nc::Vec2::dot
double dot(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:169
nc::Vec2::y
double y
Definition: Vec2.hpp:54
nc::Vec2
Holds a 2D vector.
Definition: Vec2.hpp:49
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:305
nc::NdArray::dot
NdArray< dtype > dot(const NdArray< dtype > &inOtherArray) const
Definition: NdArrayCore.hpp:2635
nc::Vec2::operator-=
Vec2 & operator-=(const Vec2 &rhs) noexcept
Definition: Vec2.hpp:371
nc::utils::interp
constexpr double interp(double inValue1, double inValue2, double inPercent) noexcept
Definition: Utils/interp.hpp:44
nc::Vec2::x
double x
Definition: Vec2.hpp:53
nc::operator/
NdArray< dtype > operator/(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1091
nc::Vec2::project
Vec2 project(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:245
nc::Vec2::right
static constexpr Vec2 right() noexcept
Definition: Vec2.hpp:257
nc::utils::essentiallyEqual
bool essentiallyEqual(dtype inValue1, dtype inValue2) noexcept
Definition: essentiallyEqual.hpp:53
nc::Vec2::operator+=
Vec2 & operator+=(const Vec2 &rhs) noexcept
Definition: Vec2.hpp:343
nc::Vec2::toString
std::string toString() const
Definition: Vec2.hpp:268
nc::Vec2::Vec2
Vec2(const NdArray< double > &ndArray)
Definition: Vec2.hpp:97
nc::NdArray::transpose
NdArray< dtype > transpose() const
Definition: NdArrayCore.hpp:4591
nc::NdArray< double >
interp.hpp
nc::Vec2::up
static constexpr Vec2 up() noexcept
Definition: Vec2.hpp:293
nc::cos
auto cos(dtype inValue) noexcept
Definition: cos.hpp:52
nc::Vec2::lerp
Vec2 lerp(const Vec2 &otherVec, double t) const noexcept
Definition: Vec2.hpp:204
NdArray.hpp
nc::Vec2::operator==
bool operator==(const Vec2 &rhs) const noexcept
Definition: Vec2.hpp:305
nc::NdArray::size
size_type size() const noexcept
Definition: NdArrayCore.hpp:4310
nc::Vec2::angle
double angle(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:115
nc::hypot
double hypot(dtype inValue1, dtype inValue2) noexcept
Definition: hypot.hpp:58
nc::Vec2::Vec2
constexpr Vec2(double inX, double inY) noexcept
Definition: Vec2.hpp:69
nc::operator-
NdArray< dtype > operator-(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:444
nc::Vec2::Vec2
constexpr Vec2()=default
nc
Definition: Coordinate.hpp:45
nc::Vec2::Vec2
Vec2(const std::initializer_list< double > &inList)
Definition: Vec2.hpp:80
nc::Vec2::norm
double norm() const noexcept
Definition: Vec2.hpp:222
essentiallyEqual.hpp
THROW_INVALID_ARGUMENT_ERROR
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
nc::Vec2::clampMagnitude
Vec2 clampMagnitude(double maxLength) const noexcept
Definition: Vec2.hpp:135
nc::operator<<
NdArray< dtype > operator<<(const NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:2414
nc::Vec2::operator*=
Vec2 & operator*=(double scaler) noexcept
Definition: Vec2.hpp:385
nc::max
NdArray< dtype > max(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: max.hpp:46
nc::Vec2::distance
double distance(const Vec2 &otherVec) const noexcept
Definition: Vec2.hpp:157
nc::Vec2::normalize
Vec2 normalize() const noexcept
Definition: Vec2.hpp:233
nc::Vec2::operator-=
Vec2 & operator-=(double scaler) noexcept
Definition: Vec2.hpp:357
nc::Vec2::down
static constexpr Vec2 down() noexcept
Definition: Vec2.hpp:180
nc::Vec2::operator/=
Vec2 & operator/=(double scaler) noexcept
Definition: Vec2.hpp:399
nc::Vec2::operator!=
bool operator!=(const Vec2 &rhs) const noexcept
Definition: Vec2.hpp:317
nc::operator*
NdArray< dtype > operator*(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:802
nc::Vec2::operator+=
Vec2 & operator+=(double scaler) noexcept
Definition: Vec2.hpp:329
nc::Vec2::left
static constexpr Vec2 left() noexcept
Definition: Vec2.hpp:191
nc::min
NdArray< dtype > min(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: min.hpp:46
nc::Vec2::toNdArray
NdArray< double > toNdArray() const
Definition: Vec2.hpp:281