NumCpp  2.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 
160  Vec3 returnVec = Vec3(*this).normalize();
161  returnVec *= maxLength;
162  return returnVec;
163  }
164 
165  //============================================================================
166  // Method Description:
172  Vec3 cross(const Vec3& otherVec) const noexcept
173  {
174  const double crossX = y * otherVec.z - z * otherVec.y;
175  const double crossY = -(x * otherVec.z - z * otherVec.x);
176  const double crossZ = x * otherVec.y - y * otherVec.x;
177 
178  return {crossX, crossY, crossZ};
179  }
180 
181  //============================================================================
182  // Method Description:
188  double distance(const Vec3& otherVec) const noexcept
189  {
190  return (Vec3(*this) -= otherVec).norm();
191  }
192 
193  //============================================================================
194  // Method Description:
200  double dot(const Vec3& otherVec) const noexcept
201  {
202  return x * otherVec.x + y * otherVec.y + z * otherVec.z;
203  }
204 
205  //============================================================================
206  // Method Description:
211  static constexpr Vec3 down() noexcept
212  {
213  return Vec3(0.0, -1.0, 0.0);
214  }
215 
216  //============================================================================
217  // Method Description:
222  static constexpr Vec3 forward() noexcept
223  {
224  return Vec3(0.0, 0.0, 1.0);
225  }
226 
227  //============================================================================
228  // Method Description:
233  static constexpr Vec3 left() noexcept
234  {
235  return Vec3(-1.0, 0.0, 0.0);
236  }
237 
238  //============================================================================
239  // Method Description:
246  Vec3 lerp(const Vec3& otherVec, double t) const noexcept
247  {
248  t = std::max(std::min(t, 1.0), 0.0);
249 
250  Vec3 trajectory = otherVec;
251  trajectory -= *this;
252  const double xInterp = utils::interp(0.0, trajectory.x, t);
253  const double yInterp = utils::interp(0.0, trajectory.y, t);
254  const double zInterp = utils::interp(0.0, trajectory.z, t);
255 
256  return Vec3(*this) += Vec3(xInterp, yInterp, zInterp);
257  }
258 
259  //============================================================================
260  // Method Description:
265  double norm() const noexcept
266  {
267  return hypot(x, y, z);
268  }
269 
270  //============================================================================
271  // Method Description:
276  Vec3 normalize() const noexcept
277  {
278  return Vec3(*this) /= norm();
279  }
280 
281  //============================================================================
282  // Method Description:
288  Vec3 project(const Vec3& otherVec) const noexcept
289  {
290  const double projectedMagnitude = norm() * std::cos(angle(otherVec));
291  return otherVec.normalize() *= projectedMagnitude;
292  }
293 
294  //============================================================================
295  // Method Description:
300  static constexpr Vec3 right() noexcept
301  {
302  return Vec3(1.0, 0.0, 0.0);
303  }
304 
305  //============================================================================
306  // Method Description:
311  std::string toString() const
312  {
313  std::stringstream stream;
314  stream << "Vec3[" << x << ", " << y << ", " << z << "]";
315  return stream.str();
316  }
317 
318  //============================================================================
319  // Method Description:
325  {
326  NdArray<double> returnArray = { x, y, z };
327  return returnArray.transpose();
328  }
329 
330  //============================================================================
331  // Method Description:
336  static constexpr Vec3 up() noexcept
337  {
338  return Vec3(0.0, 1.0, 0.0);
339  }
340 
341  //============================================================================
342  // Method Description:
348  bool operator==(const Vec3& rhs) const noexcept
349  {
350  return utils::essentiallyEqual(x, rhs.x) &&
351  utils::essentiallyEqual(y, rhs.y) &&
352  utils::essentiallyEqual(z, rhs.z);
353  }
354 
355  //============================================================================
356  // Method Description:
362  bool operator!=(const Vec3& rhs) const noexcept
363  {
364  return !(*this == rhs);
365  }
366 
367  //============================================================================
368  // Method Description:
374  Vec3& operator+=(double scaler) noexcept
375  {
376  x += scaler;
377  y += scaler;
378  z += scaler;
379  return *this;
380  }
381 
382  //============================================================================
383  // Method Description:
389  Vec3& operator+=(const Vec3& rhs) noexcept
390  {
391  x += rhs.x;
392  y += rhs.y;
393  z += rhs.z;
394  return *this;
395  }
396 
397  //============================================================================
398  // Method Description:
404  Vec3& operator-=(double scaler) noexcept
405  {
406  x -= scaler;
407  y -= scaler;
408  z -= scaler;
409  return *this;
410  }
411 
412  //============================================================================
413  // Method Description:
419  Vec3& operator-=(const Vec3& rhs) noexcept
420  {
421  x -= rhs.x;
422  y -= rhs.y;
423  z -= rhs.z;
424  return *this;
425  }
426 
427  //============================================================================
428  // Method Description:
434  Vec3& operator*=(double scaler) noexcept
435  {
436  x *= scaler;
437  y *= scaler;
438  z *= scaler;
439  return *this;
440  }
441 
442  //============================================================================
443  // Method Description:
449  Vec3& operator/=(double scaler) noexcept
450  {
451  x /= scaler;
452  y /= scaler;
453  z /= scaler;
454  return *this;
455  }
456  };
457 
458  //============================================================================
459  // Method Description:
466  inline Vec3 operator+(const Vec3& lhs, double rhs) noexcept
467  {
468  return Vec3(lhs) += rhs;
469  }
470 
471  //============================================================================
472  // Method Description:
479  inline Vec3 operator+(double lhs, const Vec3& rhs) noexcept
480  {
481  return Vec3(rhs) += lhs;
482  }
483 
484  //============================================================================
485  // Method Description:
492  inline Vec3 operator+(const Vec3& lhs, const Vec3& rhs) noexcept
493  {
494  return Vec3(lhs) += rhs;
495  }
496 
497  //============================================================================
498  // Method Description:
503  inline Vec3 operator-(const Vec3& vec) noexcept
504  {
505  return {-vec.x, -vec.y, -vec.z};
506  }
507 
508  //============================================================================
509  // Method Description:
516  inline Vec3 operator-(const Vec3& lhs, double rhs) noexcept
517  {
518  return Vec3(lhs) -= rhs;
519  }
520 
521  //============================================================================
522  // Method Description:
529  inline Vec3 operator-(double lhs, const Vec3& rhs) noexcept
530  {
531  return -Vec3(rhs) += lhs;
532  }
533 
534  //============================================================================
535  // Method Description:
542  inline Vec3 operator-(const Vec3& lhs, const Vec3& rhs) noexcept
543  {
544  return Vec3(lhs) -= rhs;
545  }
546 
547  //============================================================================
548  // Method Description:
555  inline Vec3 operator*(const Vec3& lhs, double rhs) noexcept
556  {
557  return Vec3(lhs) *= rhs;
558  }
559 
560  //============================================================================
561  // Method Description:
568  inline Vec3 operator*(double lhs, const Vec3& rhs) noexcept
569  {
570  return Vec3(rhs) *= lhs;
571  }
572 
573  //============================================================================
574  // Method Description:
582  inline double operator*(const Vec3& lhs, const Vec3& rhs) noexcept
583  {
584  return lhs.dot(rhs);
585  }
586 
587  //============================================================================
588  // Method Description:
595  inline Vec3 operator/(const Vec3& lhs, double rhs) noexcept
596  {
597  return Vec3(lhs) /= rhs;
598  }
599 
600  //============================================================================
601  // Method Description:
608  inline std::ostream& operator<<(std::ostream& stream, const Vec3& vec)
609  {
610  stream << vec.toString() << std::endl;
611  return stream;
612  }
613 } // namespace nc
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:288
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:211
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:2644
nc::Vec3::operator-=
Vec3 & operator-=(double scaler) noexcept
Definition: Vec3.hpp:404
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:311
nc::Vec3::forward
static constexpr Vec3 forward() noexcept
Definition: Vec3.hpp:222
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:246
nc::Vec3::z
double z
Definition: Vec3.hpp:56
nc::Vec3::right
static constexpr Vec3 right() noexcept
Definition: Vec3.hpp:300
nc::NdArray::transpose
NdArray< dtype > transpose() const
Definition: NdArrayCore.hpp:4608
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:4326
nc::Vec3::norm
double norm() const noexcept
Definition: Vec3.hpp:265
nc::Vec3::operator-=
Vec3 & operator-=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:419
nc::hypot
double hypot(dtype inValue1, dtype inValue2) noexcept
Definition: hypot.hpp:58
nc::Vec3::left
static constexpr Vec3 left() noexcept
Definition: Vec3.hpp:233
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:434
nc::Vec3::operator/=
Vec3 & operator/=(double scaler) noexcept
Definition: Vec3.hpp:449
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:188
essentiallyEqual.hpp
nc::Vec3::toNdArray
NdArray< double > toNdArray() const
Definition: Vec3.hpp:324
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:348
nc::Vec3::operator+=
Vec3 & operator+=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:389
nc::Vec3::cross
Vec3 cross(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:172
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:276
nc::Vec3::operator!=
bool operator!=(const Vec3 &rhs) const noexcept
Definition: Vec3.hpp:362
nc::Vec3::up
static constexpr Vec3 up() noexcept
Definition: Vec3.hpp:336
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:200
nc::Vec3::operator+=
Vec3 & operator+=(double scaler) noexcept
Definition: Vec3.hpp:374