NumCpp  2.7.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
Vec3.hpp
Go to the documentation of this file.
1 #pragma once
29 
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 Vec3
50  {
51  public:
52  //====================================Attributes==============================
53  double x{ 0.0 };
54  double y{ 0.0 };
55  double z{ 0.0 };
56 
57  //============================================================================
58  // Method Description:
61  constexpr Vec3() = default;
62 
63  //============================================================================
64  // Method Description:
71  constexpr Vec3(double inX, double inY, double inZ) noexcept :
72  x(inX),
73  y(inY),
74  z(inZ)
75  {}
76 
77  //============================================================================
78  // Method Description:
83  Vec3(const std::initializer_list<double>& inList)
84  {
85  if (inList.size() != 3)
86  {
87  THROW_INVALID_ARGUMENT_ERROR("input initializer list must have a size = 3");
88  }
89 
90  x = *inList.begin();
91  y = *(inList.begin() + 1);
92  z = *(inList.begin() + 2);
93  }
94 
95  //============================================================================
96  // Method Description:
101  Vec3(const NdArray<double>& ndArray)
102  {
103  if (ndArray.size() != 3)
104  {
105  THROW_INVALID_ARGUMENT_ERROR("input NdArray must have a size = 3");
106  }
107 
108  x = ndArray[0];
109  y = ndArray[1];
110  z = ndArray[2];
111  }
112 
113  //============================================================================
114  // Method Description:
120  double angle(const Vec3& otherVec) const noexcept
121  {
122  double dotProduct = dot(otherVec);
123  dotProduct /= norm();
124  dotProduct /= otherVec.norm();
125 
126  // clamp the value to the acos range just to be safe
127  dotProduct = std::max(std::min(dotProduct, 1.0), -1.0);
128 
129  return std::acos(dotProduct);
130  }
131 
132  //============================================================================
133  // Method Description:
138  static constexpr Vec3 back() noexcept
139  {
140  return Vec3(0.0, 0.0, -1.0);
141  }
142 
143  //============================================================================
144  // Method Description:
151  Vec3 clampMagnitude(double maxLength) const noexcept
152  {
153  const double magnitude = norm();
154  if (magnitude <= maxLength)
155  {
156  return *this;
157  }
158 
159  Vec3 returnVec = Vec3(*this).normalize();
160  returnVec *= maxLength;
161  return returnVec;
162  }
163 
164  //============================================================================
165  // Method Description:
171  Vec3 cross(const Vec3& otherVec) const noexcept
172  {
173  const double crossX = y * otherVec.z - z * otherVec.y;
174  const double crossY = -(x * otherVec.z - z * otherVec.x);
175  const double crossZ = x * otherVec.y - y * otherVec.x;
176 
177  return {crossX, crossY, crossZ};
178  }
179 
180  //============================================================================
181  // Method Description:
187  double distance(const Vec3& otherVec) const noexcept
188  {
189  return (Vec3(*this) -= otherVec).norm();
190  }
191 
192  //============================================================================
193  // Method Description:
199  double dot(const Vec3& otherVec) const noexcept
200  {
201  return x * otherVec.x + y * otherVec.y + z * otherVec.z;
202  }
203 
204  //============================================================================
205  // Method Description:
210  static constexpr Vec3 down() noexcept
211  {
212  return Vec3(0.0, -1.0, 0.0);
213  }
214 
215  //============================================================================
216  // Method Description:
221  static constexpr Vec3 forward() noexcept
222  {
223  return Vec3(0.0, 0.0, 1.0);
224  }
225 
226  //============================================================================
227  // Method Description:
232  static constexpr Vec3 left() noexcept
233  {
234  return Vec3(-1.0, 0.0, 0.0);
235  }
236 
237  //============================================================================
238  // Method Description:
245  Vec3 lerp(const Vec3& otherVec, double t) const noexcept
246  {
247  t = std::max(std::min(t, 1.0), 0.0);
248 
249  Vec3 trajectory = otherVec;
250  trajectory -= *this;
251  const double xInterp = utils::interp(0.0, trajectory.x, t);
252  const double yInterp = utils::interp(0.0, trajectory.y, t);
253  const double zInterp = utils::interp(0.0, trajectory.z, t);
254 
255  return Vec3(*this) += Vec3(xInterp, yInterp, zInterp);
256  }
257 
258  //============================================================================
259  // Method Description:
264  double norm() const noexcept
265  {
266  return hypot(x, y, z);
267  }
268 
269  //============================================================================
270  // Method Description:
275  Vec3 normalize() const noexcept
276  {
277  return Vec3(*this) /= norm();
278  }
279 
280  //============================================================================
281  // Method Description:
287  Vec3 project(const Vec3& otherVec) const noexcept
288  {
289  const double projectedMagnitude = norm() * std::cos(angle(otherVec));
290  return otherVec.normalize() *= projectedMagnitude;
291  }
292 
293  //============================================================================
294  // Method Description:
299  static constexpr Vec3 right() noexcept
300  {
301  return Vec3(1.0, 0.0, 0.0);
302  }
303 
304  //============================================================================
305  // Method Description:
310  std::string toString() const
311  {
312  std::stringstream stream;
313  stream << "Vec3[" << x << ", " << y << ", " << z << "]";
314  return stream.str();
315  }
316 
317  //============================================================================
318  // Method Description:
324  {
325  NdArray<double> returnArray = { x, y, z };
326  return returnArray.transpose();
327  }
328 
329  //============================================================================
330  // Method Description:
335  static constexpr Vec3 up() noexcept
336  {
337  return Vec3(0.0, 1.0, 0.0);
338  }
339 
340  //============================================================================
341  // Method Description:
347  bool operator==(const Vec3& rhs) const noexcept
348  {
349  return utils::essentiallyEqual(x, rhs.x) &&
350  utils::essentiallyEqual(y, rhs.y) &&
351  utils::essentiallyEqual(z, rhs.z);
352  }
353 
354  //============================================================================
355  // Method Description:
361  bool operator!=(const Vec3& rhs) const noexcept
362  {
363  return !(*this == rhs);
364  }
365 
366  //============================================================================
367  // Method Description:
373  Vec3& operator+=(double scaler) noexcept
374  {
375  x += scaler;
376  y += scaler;
377  z += scaler;
378  return *this;
379  }
380 
381  //============================================================================
382  // Method Description:
388  Vec3& operator+=(const Vec3& rhs) noexcept
389  {
390  x += rhs.x;
391  y += rhs.y;
392  z += rhs.z;
393  return *this;
394  }
395 
396  //============================================================================
397  // Method Description:
403  Vec3& operator-=(double scaler) noexcept
404  {
405  x -= scaler;
406  y -= scaler;
407  z -= scaler;
408  return *this;
409  }
410 
411  //============================================================================
412  // Method Description:
418  Vec3& operator-=(const Vec3& rhs) noexcept
419  {
420  x -= rhs.x;
421  y -= rhs.y;
422  z -= rhs.z;
423  return *this;
424  }
425 
426  //============================================================================
427  // Method Description:
433  Vec3& operator*=(double scaler) noexcept
434  {
435  x *= scaler;
436  y *= scaler;
437  z *= scaler;
438  return *this;
439  }
440 
441  //============================================================================
442  // Method Description:
448  Vec3& operator/=(double scaler) noexcept
449  {
450  x /= scaler;
451  y /= scaler;
452  z /= scaler;
453  return *this;
454  }
455  };
456 
457  //============================================================================
458  // Method Description:
465  inline Vec3 operator+(const Vec3& lhs, double rhs) noexcept
466  {
467  return Vec3(lhs) += rhs;
468  }
469 
470  //============================================================================
471  // Method Description:
478  inline Vec3 operator+(double lhs, const Vec3& rhs) noexcept
479  {
480  return Vec3(rhs) += lhs;
481  }
482 
483  //============================================================================
484  // Method Description:
491  inline Vec3 operator+(const Vec3& lhs, const Vec3& rhs) noexcept
492  {
493  return Vec3(lhs) += rhs;
494  }
495 
496  //============================================================================
497  // Method Description:
502  inline Vec3 operator-(const Vec3& vec) noexcept
503  {
504  return {-vec.x, -vec.y, -vec.z};
505  }
506 
507  //============================================================================
508  // Method Description:
515  inline Vec3 operator-(const Vec3& lhs, double rhs) noexcept
516  {
517  return Vec3(lhs) -= rhs;
518  }
519 
520  //============================================================================
521  // Method Description:
528  inline Vec3 operator-(double lhs, const Vec3& rhs) noexcept
529  {
530  return -Vec3(rhs) += lhs;
531  }
532 
533  //============================================================================
534  // Method Description:
541  inline Vec3 operator-(const Vec3& lhs, const Vec3& rhs) noexcept
542  {
543  return Vec3(lhs) -= rhs;
544  }
545 
546  //============================================================================
547  // Method Description:
554  inline Vec3 operator*(const Vec3& lhs, double rhs) noexcept
555  {
556  return Vec3(lhs) *= rhs;
557  }
558 
559  //============================================================================
560  // Method Description:
567  inline Vec3 operator*(double lhs, const Vec3& rhs) noexcept
568  {
569  return Vec3(rhs) *= lhs;
570  }
571 
572  //============================================================================
573  // Method Description:
581  inline double operator*(const Vec3& lhs, const Vec3& rhs) noexcept
582  {
583  return lhs.dot(rhs);
584  }
585 
586  //============================================================================
587  // Method Description:
594  inline Vec3 operator/(const Vec3& lhs, double rhs) noexcept
595  {
596  return Vec3(lhs) /= rhs;
597  }
598 
599  //============================================================================
600  // Method Description:
607  inline std::ostream& operator<<(std::ostream& stream, const Vec3& vec)
608  {
609  stream << vec.toString() << std::endl;
610  return stream;
611  }
612 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
size_type size() const noexcept
Definition: NdArrayCore.hpp:4296
NdArray< dtype > transpose() const
Definition: NdArrayCore.hpp:4629
Holds a 3D vector.
Definition: Vec3.hpp:50
Vec3 & operator*=(double scaler) noexcept
Definition: Vec3.hpp:433
double z
Definition: Vec3.hpp:55
Vec3 & operator-=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:418
std::string toString() const
Definition: Vec3.hpp:310
Vec3 & operator+=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:388
bool operator==(const Vec3 &rhs) const noexcept
Definition: Vec3.hpp:347
double distance(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:187
Vec3(const std::initializer_list< double > &inList)
Definition: Vec3.hpp:83
Vec3 & operator/=(double scaler) noexcept
Definition: Vec3.hpp:448
static constexpr Vec3 back() noexcept
Definition: Vec3.hpp:138
NdArray< double > toNdArray() const
Definition: Vec3.hpp:323
Vec3(const NdArray< double > &ndArray)
Definition: Vec3.hpp:101
static constexpr Vec3 down() noexcept
Definition: Vec3.hpp:210
Vec3 clampMagnitude(double maxLength) const noexcept
Definition: Vec3.hpp:151
double angle(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:120
Vec3 normalize() const noexcept
Definition: Vec3.hpp:275
constexpr Vec3(double inX, double inY, double inZ) noexcept
Definition: Vec3.hpp:71
double norm() const noexcept
Definition: Vec3.hpp:264
Vec3 & operator-=(double scaler) noexcept
Definition: Vec3.hpp:403
static constexpr Vec3 left() noexcept
Definition: Vec3.hpp:232
double x
Definition: Vec3.hpp:53
double y
Definition: Vec3.hpp:54
Vec3 project(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:287
bool operator!=(const Vec3 &rhs) const noexcept
Definition: Vec3.hpp:361
static constexpr Vec3 up() noexcept
Definition: Vec3.hpp:335
Vec3 lerp(const Vec3 &otherVec, double t) const noexcept
Definition: Vec3.hpp:245
static constexpr Vec3 forward() noexcept
Definition: Vec3.hpp:221
double dot(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:199
constexpr Vec3()=default
Vec3 cross(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:171
static constexpr Vec3 right() noexcept
Definition: Vec3.hpp:299
Vec3 & operator+=(double scaler) noexcept
Definition: Vec3.hpp:373
constexpr double interp(double inValue1, double inValue2, double inPercent) noexcept
Definition: Utils/interp.hpp:43
bool essentiallyEqual(dtype inValue1, dtype inValue2) noexcept
Definition: essentiallyEqual.hpp:52
Definition: Coordinate.hpp:45
NdArray< dtype > operator<<(const NdArray< dtype > &lhs, uint8 inNumBits)
Definition: NdArrayOperators.hpp:2470
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:310
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:797
NdArray< dtype > operator-(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:441
NdArray< dtype > operator/(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:1084