NumCpp  1.0
A C++ implementation of the Python Numpy library
Vec3.hpp
Go to the documentation of this file.
1 #pragma once
30 
33 #include "NumCpp/NdArray.hpp"
35 #include "NumCpp/Utils/interp.hpp"
36 
37 #include <cmath>
38 #include <initializer_list>
39 #include <iostream>
40 #include <sstream>
41 #include <string>
42 
43 //====================================================================================
44 
45 namespace nc
46 {
47  //================================================================================
48  // Class Description:
50  class Vec3
51  {
52  public:
53  //====================================Attributes==============================
54  double x{ 0.0 };
55  double y{ 0.0 };
56  double z{ 0.0 };
57 
58  //============================================================================
59  // Method Description:
62  constexpr Vec3() = default;
63 
64  //============================================================================
65  // Method Description:
72  constexpr Vec3(double inX, double inY, double inZ) noexcept :
73  x(inX),
74  y(inY),
75  z(inZ)
76  {}
77 
78  //============================================================================
79  // Method Description:
84  Vec3(const std::initializer_list<double>& inList)
85  {
86  if (inList.size() != 3)
87  {
88  THROW_INVALID_ARGUMENT_ERROR("input initializer list must have a size = 3");
89  }
90 
91  x = *inList.begin();
92  y = *(inList.begin() + 1);
93  z = *(inList.begin() + 2);
94  }
95 
96  //============================================================================
97  // Method Description:
102  Vec3(const NdArray<double>& ndArray)
103  {
104  if (ndArray.size() != 3)
105  {
106  THROW_INVALID_ARGUMENT_ERROR("input NdArray must have a size = 3");
107  }
108 
109  x = ndArray[0];
110  y = ndArray[1];
111  z = ndArray[2];
112  }
113 
114  //============================================================================
115  // Method Description:
121  double angle(const Vec3& otherVec) const noexcept
122  {
123  double dotProduct = dot(otherVec);
124  dotProduct /= norm();
125  dotProduct /= otherVec.norm();
126 
127  // clamp the value to the acos range just to be safe
128  dotProduct = std::max(std::min(dotProduct, 1.0), -1.0);
129 
130  return std::acos(dotProduct);
131  }
132 
133  //============================================================================
134  // Method Description:
139  static constexpr Vec3 back() noexcept
140  {
141  return Vec3(0.0, 0.0, -1.0);
142  }
143 
144  //============================================================================
145  // Method Description:
152  Vec3 clampMagnitude(double maxLength) const noexcept
153  {
154  const double magnitude = norm();
155  if (magnitude <= maxLength)
156  {
157  return *this;
158  }
159  else
160  {
161  Vec3 returnVec = Vec3(*this).normalize();
162  returnVec *= maxLength;
163  return returnVec;
164  }
165  }
166 
167  //============================================================================
168  // Method Description:
174  Vec3 cross(const Vec3& otherVec) const noexcept
175  {
176  const double crossX = y * otherVec.z - z * otherVec.y;
177  const double crossY = -(x * otherVec.z - z * otherVec.x);
178  const double crossZ = x * otherVec.y - y * otherVec.x;
179 
180  return Vec3(crossX, crossY, crossZ);
181  }
182 
183  //============================================================================
184  // Method Description:
190  double distance(const Vec3& otherVec) const noexcept
191  {
192  return (Vec3(*this) -= otherVec).norm();
193  }
194 
195  //============================================================================
196  // Method Description:
202  double dot(const Vec3& otherVec) const noexcept
203  {
204  return x * otherVec.x + y * otherVec.y + z * otherVec.z;
205  }
206 
207  //============================================================================
208  // Method Description:
213  static constexpr Vec3 down() noexcept
214  {
215  return Vec3(0.0, -1.0, 0.0);
216  }
217 
218  //============================================================================
219  // Method Description:
224  static constexpr Vec3 forward() noexcept
225  {
226  return Vec3(0.0, 0.0, 1.0);
227  }
228 
229  //============================================================================
230  // Method Description:
235  static constexpr Vec3 left() noexcept
236  {
237  return Vec3(-1.0, 0.0, 0.0);
238  }
239 
240  //============================================================================
241  // Method Description:
248  Vec3 lerp(const Vec3& otherVec, double t) const noexcept
249  {
250  t = std::max(std::min(t, 1.0), 0.0);
251 
252  Vec3 trajectory = otherVec;
253  trajectory -= *this;
254  const double xInterp = utils::interp(0.0, trajectory.x, t);
255  const double yInterp = utils::interp(0.0, trajectory.y, t);
256  const double zInterp = utils::interp(0.0, trajectory.z, t);
257 
258  return Vec3(*this) += Vec3(xInterp, yInterp, zInterp);
259  }
260 
261  //============================================================================
262  // Method Description:
267  double norm() const noexcept
268  {
269  return hypot(x, y, z);
270  }
271 
272  //============================================================================
273  // Method Description:
278  Vec3 normalize() const noexcept
279  {
280  return Vec3(*this) /= norm();
281  }
282 
283  //============================================================================
284  // Method Description:
290  Vec3 project(const Vec3& otherVec) const noexcept
291  {
292  const double projectedMagnitude = norm() * std::cos(angle(otherVec));
293  return otherVec.normalize() *= projectedMagnitude;
294  }
295 
296  //============================================================================
297  // Method Description:
302  static constexpr Vec3 right() noexcept
303  {
304  return Vec3(1.0, 0.0, 0.0);
305  }
306 
307  //============================================================================
308  // Method Description:
313  std::string toString() const
314  {
315  std::stringstream stream;
316  stream << "Vec3[" << x << ", " << y << ", " << z << "]";
317  return stream.str();
318  }
319 
320  //============================================================================
321  // Method Description:
327  {
328  NdArray<double> returnArray = { x, y, z };
329  return returnArray.transpose();
330  }
331 
332  //============================================================================
333  // Method Description:
338  static constexpr Vec3 up() noexcept
339  {
340  return Vec3(0.0, 1.0, 0.0);
341  }
342 
343  //============================================================================
344  // Method Description:
350  bool operator==(const Vec3& rhs) const noexcept
351  {
352  return utils::essentiallyEqual(x, rhs.x) &&
353  utils::essentiallyEqual(y, rhs.y) &&
354  utils::essentiallyEqual(z, rhs.z);
355  }
356 
357  //============================================================================
358  // Method Description:
364  bool operator!=(const Vec3& rhs) const noexcept
365  {
366  return !(*this == rhs);
367  }
368 
369  //============================================================================
370  // Method Description:
376  Vec3& operator+=(double scaler) noexcept
377  {
378  x += scaler;
379  y += scaler;
380  z += scaler;
381  return *this;
382  }
383 
384  //============================================================================
385  // Method Description:
391  Vec3& operator+=(const Vec3& rhs) noexcept
392  {
393  x += rhs.x;
394  y += rhs.y;
395  z += rhs.z;
396  return *this;
397  }
398 
399  //============================================================================
400  // Method Description:
406  Vec3& operator-=(double scaler) noexcept
407  {
408  x -= scaler;
409  y -= scaler;
410  z -= scaler;
411  return *this;
412  }
413 
414  //============================================================================
415  // Method Description:
421  Vec3& operator-=(const Vec3& rhs) noexcept
422  {
423  x -= rhs.x;
424  y -= rhs.y;
425  z -= rhs.z;
426  return *this;
427  }
428 
429  //============================================================================
430  // Method Description:
436  Vec3& operator*=(double scaler) noexcept
437  {
438  x *= scaler;
439  y *= scaler;
440  z *= scaler;
441  return *this;
442  }
443 
444  //============================================================================
445  // Method Description:
451  Vec3& operator/=(double scaler) noexcept
452  {
453  x /= scaler;
454  y /= scaler;
455  z /= scaler;
456  return *this;
457  }
458  };
459 
460  //============================================================================
461  // Method Description:
468  inline Vec3 operator+(const Vec3& lhs, double rhs) noexcept
469  {
470  return Vec3(lhs) += rhs;
471  }
472 
473  //============================================================================
474  // Method Description:
481  inline Vec3 operator+(double lhs, const Vec3& rhs) noexcept
482  {
483  return Vec3(rhs) += lhs;
484  }
485 
486  //============================================================================
487  // Method Description:
494  inline Vec3 operator+(const Vec3& lhs, const Vec3& rhs) noexcept
495  {
496  return Vec3(lhs) += rhs;
497  }
498 
499  //============================================================================
500  // Method Description:
505  inline Vec3 operator-(const Vec3& vec) noexcept
506  {
507  return Vec3(-vec.x, -vec.y, -vec.z);
508  }
509 
510  //============================================================================
511  // Method Description:
518  inline Vec3 operator-(const Vec3& lhs, double rhs) noexcept
519  {
520  return Vec3(lhs) -= rhs;
521  }
522 
523  //============================================================================
524  // Method Description:
531  inline Vec3 operator-(double lhs, const Vec3& rhs) noexcept
532  {
533  return -Vec3(rhs) += lhs;
534  }
535 
536  //============================================================================
537  // Method Description:
544  inline Vec3 operator-(const Vec3& lhs, const Vec3& rhs) noexcept
545  {
546  return Vec3(lhs) -= rhs;
547  }
548 
549  //============================================================================
550  // Method Description:
557  inline Vec3 operator*(const Vec3& lhs, double rhs) noexcept
558  {
559  return Vec3(lhs) *= rhs;
560  }
561 
562  //============================================================================
563  // Method Description:
570  inline Vec3 operator*(double lhs, const Vec3& rhs) noexcept
571  {
572  return Vec3(rhs) *= lhs;
573  }
574 
575  //============================================================================
576  // Method Description:
584  inline double operator*(const Vec3& lhs, const Vec3& rhs) noexcept
585  {
586  return lhs.dot(rhs);
587  }
588 
589  //============================================================================
590  // Method Description:
597  inline Vec3 operator/(const Vec3& lhs, double rhs) noexcept
598  {
599  return Vec3(lhs) /= rhs;
600  }
601 
602  //============================================================================
603  // Method Description:
610  inline std::ostream& operator<<(std::ostream& stream, const Vec3& vec)
611  {
612  stream << vec.toString() << std::endl;
613  return stream;
614  }
615 }
nc::Vec3::back
static constexpr Vec3 back() noexcept
Definition: Vec3.hpp:139
nc::Vec3::project
Vec3 project(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:290
nc::Vec3::Vec3
Vec3(const NdArray< double > &ndArray)
Definition: Vec3.hpp:102
nc::Vec3::y
double y
Definition: Vec3.hpp:55
nc::Vec3::down
static constexpr Vec3 down() noexcept
Definition: Vec3.hpp:213
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::Vec3::operator-=
Vec3 & operator-=(double scaler) noexcept
Definition: Vec3.hpp:406
nc::utils::interp
constexpr double interp(double inValue1, double inValue2, double inPercent) noexcept
Definition: Utils/interp.hpp:44
nc::Vec3::toString
std::string toString() const
Definition: Vec3.hpp:313
nc::Vec3::forward
static constexpr Vec3 forward() noexcept
Definition: Vec3.hpp:224
nc::operator/
NdArray< dtype > operator/(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1091
nc::utils::essentiallyEqual
bool essentiallyEqual(dtype inValue1, dtype inValue2) noexcept
Definition: essentiallyEqual.hpp:53
nc::Vec3::lerp
Vec3 lerp(const Vec3 &otherVec, double t) const noexcept
Definition: Vec3.hpp:248
nc::Vec3::z
double z
Definition: Vec3.hpp:56
nc::Vec3::right
static constexpr Vec3 right() noexcept
Definition: Vec3.hpp:302
nc::NdArray::transpose
NdArray< dtype > transpose() const
Definition: NdArrayCore.hpp:4591
nc::NdArray< double >
interp.hpp
nc::cos
auto cos(dtype inValue) noexcept
Definition: cos.hpp:52
hypot.hpp
NdArray.hpp
nc::Vec3::Vec3
constexpr Vec3()=default
nc::NdArray::size
size_type size() const noexcept
Definition: NdArrayCore.hpp:4310
nc::Vec3::norm
double norm() const noexcept
Definition: Vec3.hpp:267
nc::Vec3::operator-=
Vec3 & operator-=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:421
nc::hypot
double hypot(dtype inValue1, dtype inValue2) noexcept
Definition: hypot.hpp:58
nc::Vec3::left
static constexpr Vec3 left() noexcept
Definition: Vec3.hpp:235
nc::operator-
NdArray< dtype > operator-(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:444
nc
Definition: Coordinate.hpp:45
nc::Vec3::operator*=
Vec3 & operator*=(double scaler) noexcept
Definition: Vec3.hpp:436
nc::Vec3::operator/=
Vec3 & operator/=(double scaler) noexcept
Definition: Vec3.hpp:451
nc::Vec3::angle
double angle(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:121
nc::Vec3::distance
double distance(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:190
essentiallyEqual.hpp
nc::Vec3::toNdArray
NdArray< double > toNdArray() const
Definition: Vec3.hpp:326
THROW_INVALID_ARGUMENT_ERROR
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
nc::Vec3::x
double x
Definition: Vec3.hpp:54
nc::operator<<
NdArray< dtype > operator<<(const NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:2414
nc::max
NdArray< dtype > max(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: max.hpp:46
nc::Vec3::Vec3
Vec3(const std::initializer_list< double > &inList)
Definition: Vec3.hpp:84
nc::Vec3::operator==
bool operator==(const Vec3 &rhs) const noexcept
Definition: Vec3.hpp:350
nc::Vec3::operator+=
Vec3 & operator+=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:391
nc::Vec3::cross
Vec3 cross(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:174
nc::operator*
NdArray< dtype > operator*(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:802
nc::Vec3::Vec3
constexpr Vec3(double inX, double inY, double inZ) noexcept
Definition: Vec3.hpp:72
nc::Vec3
Holds a 3D vector.
Definition: Vec3.hpp:50
nc::Vec3::normalize
Vec3 normalize() const noexcept
Definition: Vec3.hpp:278
nc::Vec3::operator!=
bool operator!=(const Vec3 &rhs) const noexcept
Definition: Vec3.hpp:364
nc::Vec3::up
static constexpr Vec3 up() noexcept
Definition: Vec3.hpp:338
nc::Vec3::clampMagnitude
Vec3 clampMagnitude(double maxLength) const noexcept
Definition: Vec3.hpp:152
nc::min
NdArray< dtype > min(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: min.hpp:46
nc::Vec3::dot
double dot(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:202
nc::Vec3::operator+=
Vec3 & operator+=(double scaler) noexcept
Definition: Vec3.hpp:376