NumCpp  2.11.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 
30 #include <cmath>
31 #include <initializer_list>
32 #include <iostream>
33 #include <sstream>
34 #include <string>
35 
38 #include "NumCpp/NdArray.hpp"
40 #include "NumCpp/Utils/interp.hpp"
41 #include "NumCpp/Vector/Vec2.hpp"
42 
43 //====================================================================================
44 
45 namespace nc
46 {
47  //================================================================================
48  // Class Description:
50  class Vec3
51  {
52  public:
53  //====================================Attributes==============================
54  double x{ 0. };
55  double y{ 0. };
56  double z{ 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  //============================================================================
80  // Method Description:
85  Vec3(const std::initializer_list<double>& inList)
86  {
87  if (inList.size() != 3)
88  {
89  THROW_INVALID_ARGUMENT_ERROR("input initializer list must have a size = 3");
90  }
91 
92  x = *inList.begin();
93  y = *(inList.begin() + 1);
94  z = *(inList.begin() + 2);
95  }
96 
97  //============================================================================
98  // Method Description:
103  constexpr Vec3(const Vec2& vec2) noexcept :
104  x(vec2.x),
105  y(vec2.y)
106  {
107  }
108 
109  //============================================================================
110  // Method Description:
115  Vec3(const NdArray<double>& ndArray)
116  {
117  if (ndArray.size() != 3)
118  {
119  THROW_INVALID_ARGUMENT_ERROR("input NdArray must have a size = 3");
120  }
121 
122  x = ndArray[0];
123  y = ndArray[1];
124  z = ndArray[2];
125  }
126 
127  //============================================================================
128  // Method Description:
134  [[nodiscard]] double angle(const Vec3& otherVec) const noexcept
135  {
136  double dotProduct = dot(otherVec);
137  dotProduct /= norm();
138  dotProduct /= otherVec.norm();
139 
140  // clamp the value to the acos range just to be safe
141  dotProduct = std::max(std::min(dotProduct, 1.), -1.);
142 
143  return std::acos(dotProduct);
144  }
145 
146  //============================================================================
147  // Method Description:
152  static constexpr Vec3 back() noexcept
153  {
154  return Vec3(0., 0., -1.); // NOLINT(modernize-return-braced-init-list)
155  }
156 
157  //============================================================================
158  // Method Description:
165  [[nodiscard]] Vec3 clampMagnitude(double maxLength) const noexcept
166  {
167  const double magnitude = norm();
168  if (magnitude <= maxLength)
169  {
170  return *this;
171  }
172 
173  Vec3 returnVec = Vec3(*this).normalize();
174  returnVec *= maxLength;
175  return returnVec;
176  }
177 
178  //============================================================================
179  // Method Description:
185  [[nodiscard]] Vec3 cross(const Vec3& otherVec) const noexcept
186  {
187  const double crossX = y * otherVec.z - z * otherVec.y;
188  const double crossY = -(x * otherVec.z - z * otherVec.x);
189  const double crossZ = x * otherVec.y - y * otherVec.x;
190 
191  return Vec3(crossX, crossY, crossZ); // NOLINT(modernize-return-braced-init-list)
192  }
193 
194  //============================================================================
195  // Method Description:
201  [[nodiscard]] double distance(const Vec3& otherVec) const noexcept
202  {
203  return (Vec3(*this) -= otherVec).norm();
204  }
205 
206  //============================================================================
207  // Method Description:
213  [[nodiscard]] double dot(const Vec3& otherVec) const noexcept
214  {
215  return x * otherVec.x + y * otherVec.y + z * otherVec.z;
216  }
217 
218  //============================================================================
219  // Method Description:
224  static constexpr Vec3 down() noexcept
225  {
226  return Vec3(0., -1., 0.); // NOLINT(modernize-return-braced-init-list)
227  }
228 
229  //============================================================================
230  // Method Description:
235  static constexpr Vec3 forward() noexcept
236  {
237  return Vec3(0., 0., 1.); // NOLINT(modernize-return-braced-init-list)
238  }
239 
240  //============================================================================
241  // Method Description:
246  static constexpr Vec3 left() noexcept
247  {
248  return Vec3(-1., 0., 0.); // NOLINT(modernize-return-braced-init-list)
249  }
250 
251  //============================================================================
252  // Method Description:
259  [[nodiscard]] Vec3 lerp(const Vec3& otherVec, double t) const noexcept
260  {
261  t = std::max(std::min(t, 1.), 0.);
262 
263  Vec3 trajectory = otherVec;
264  trajectory -= *this;
265  const double xInterp = utils::interp(0., trajectory.x, t);
266  const double yInterp = utils::interp(0., trajectory.y, t);
267  const double zInterp = utils::interp(0., trajectory.z, t);
268 
269  return Vec3(*this) += Vec3(xInterp, yInterp, zInterp);
270  }
271 
272  //============================================================================
273  // Method Description:
278  [[nodiscard]] double norm() const noexcept
279  {
280  return hypot(x, y, z);
281  }
282 
283  //============================================================================
284  // Method Description:
289  [[nodiscard]] Vec3 normalize() const noexcept
290  {
291  return Vec3(*this) /= norm();
292  }
293 
294  //============================================================================
295  // Method Description:
301  [[nodiscard]] Vec3 project(const Vec3& otherVec) const noexcept
302  {
303  const double projectedMagnitude = norm() * std::cos(angle(otherVec));
304  return otherVec.normalize() *= projectedMagnitude;
305  }
306 
307  //============================================================================
308  // Method Description:
313  static constexpr Vec3 right() noexcept
314  {
315  return Vec3(1., 0., 0.); // NOLINT(modernize-return-braced-init-list)
316  }
317 
318  //============================================================================
319  // Method Description:
324  [[nodiscard]] std::string toString() const
325  {
326  std::stringstream stream;
327  stream << "Vec3[" << x << ", " << y << ", " << z << "]";
328  return stream.str();
329  }
330 
331  //============================================================================
332  // Method Description:
337  [[nodiscard]] NdArray<double> toNdArray() const
338  {
339  NdArray<double> returnArray = { x, y, z };
340  return returnArray.transpose();
341  }
342 
343  //============================================================================
344  // Method Description:
349  static constexpr Vec3 up() noexcept
350  {
351  return Vec3(0., 1., 0.); // NOLINT(modernize-return-braced-init-list)
352  }
353 
354  //============================================================================
355  // Method Description:
361  bool operator==(const Vec3& rhs) const noexcept
362  {
363  return utils::essentiallyEqual(x, rhs.x) && utils::essentiallyEqual(y, rhs.y) &&
364  utils::essentiallyEqual(z, rhs.z);
365  }
366 
367  //============================================================================
368  // Method Description:
374  bool operator!=(const Vec3& rhs) const noexcept
375  {
376  return !(*this == rhs);
377  }
378 
379  //============================================================================
380  // Method Description:
386  Vec3& operator+=(double scalar) noexcept
387  {
388  x += scalar;
389  y += scalar;
390  z += scalar;
391  return *this;
392  }
393 
394  //============================================================================
395  // Method Description:
401  Vec3& operator+=(const Vec3& rhs) noexcept
402  {
403  x += rhs.x;
404  y += rhs.y;
405  z += rhs.z;
406  return *this;
407  }
408 
409  //============================================================================
410  // Method Description:
416  Vec3& operator-=(double scalar) noexcept
417  {
418  x -= scalar;
419  y -= scalar;
420  z -= scalar;
421  return *this;
422  }
423 
424  //============================================================================
425  // Method Description:
431  Vec3& operator-=(const Vec3& rhs) noexcept
432  {
433  x -= rhs.x;
434  y -= rhs.y;
435  z -= rhs.z;
436  return *this;
437  }
438 
439  //============================================================================
440  // Method Description:
446  Vec3& operator*=(double scalar) noexcept
447  {
448  x *= scalar;
449  y *= scalar;
450  z *= scalar;
451  return *this;
452  }
453 
454  //============================================================================
455  // Method Description:
461  Vec3& operator/=(double scalar) noexcept
462  {
463  x /= scalar;
464  y /= scalar;
465  z /= scalar;
466  return *this;
467  }
468  };
469 
470  //============================================================================
471  // Method Description:
478  inline Vec3 operator+(const Vec3& lhs, double rhs) noexcept
479  {
480  return Vec3(lhs) += rhs;
481  }
482 
483  //============================================================================
484  // Method Description:
491  inline Vec3 operator+(double lhs, const Vec3& rhs) noexcept
492  {
493  return Vec3(rhs) += lhs;
494  }
495 
496  //============================================================================
497  // Method Description:
504  inline Vec3 operator+(const Vec3& lhs, const Vec3& rhs) noexcept
505  {
506  return Vec3(lhs) += rhs;
507  }
508 
509  //============================================================================
510  // Method Description:
515  inline Vec3 operator-(const Vec3& vec) noexcept
516  {
517  return Vec3(-vec.x, -vec.y, -vec.z); // NOLINT(modernize-return-braced-init-list)
518  }
519 
520  //============================================================================
521  // Method Description:
528  inline Vec3 operator-(const Vec3& lhs, double rhs) noexcept
529  {
530  return Vec3(lhs) -= rhs;
531  }
532 
533  //============================================================================
534  // Method Description:
541  inline Vec3 operator-(double lhs, const Vec3& rhs) noexcept
542  {
543  return -Vec3(rhs) += lhs;
544  }
545 
546  //============================================================================
547  // Method Description:
554  inline Vec3 operator-(const Vec3& lhs, const Vec3& rhs) noexcept
555  {
556  return Vec3(lhs) -= rhs;
557  }
558 
559  //============================================================================
560  // Method Description:
567  inline Vec3 operator*(const Vec3& lhs, double rhs) noexcept
568  {
569  return Vec3(lhs) *= rhs;
570  }
571 
572  //============================================================================
573  // Method Description:
580  inline Vec3 operator*(double lhs, const Vec3& rhs) noexcept
581  {
582  return Vec3(rhs) *= lhs;
583  }
584 
585  //============================================================================
586  // Method Description:
594  inline double operator*(const Vec3& lhs, const Vec3& rhs) noexcept
595  {
596  return lhs.dot(rhs);
597  }
598 
599  //============================================================================
600  // Method Description:
607  inline Vec3 operator/(const Vec3& lhs, double rhs) noexcept
608  {
609  return Vec3(lhs) /= rhs;
610  }
611 
612  //============================================================================
613  // Method Description:
620  inline std::ostream& operator<<(std::ostream& stream, const Vec3& vec)
621  {
622  stream << vec.toString() << std::endl;
623  return stream;
624  }
625 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
size_type size() const noexcept
Definition: NdArrayCore.hpp:4477
self_type transpose() const
Definition: NdArrayCore.hpp:4837
Holds a 2D vector.
Definition: Vec2.hpp:49
Holds a 3D vector.
Definition: Vec3.hpp:51
double z
Definition: Vec3.hpp:56
Vec3 & operator*=(double scalar) noexcept
Definition: Vec3.hpp:446
Vec3 & operator-=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:431
std::string toString() const
Definition: Vec3.hpp:324
Vec3 & operator+=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:401
bool operator==(const Vec3 &rhs) const noexcept
Definition: Vec3.hpp:361
double distance(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:201
constexpr Vec3(const Vec2 &vec2) noexcept
Definition: Vec3.hpp:103
Vec3(const std::initializer_list< double > &inList)
Definition: Vec3.hpp:85
static constexpr Vec3 back() noexcept
Definition: Vec3.hpp:152
NdArray< double > toNdArray() const
Definition: Vec3.hpp:337
Vec3(const NdArray< double > &ndArray)
Definition: Vec3.hpp:115
Vec3 & operator+=(double scalar) noexcept
Definition: Vec3.hpp:386
Vec3 & operator-=(double scalar) noexcept
Definition: Vec3.hpp:416
Vec3 & operator/=(double scalar) noexcept
Definition: Vec3.hpp:461
static constexpr Vec3 down() noexcept
Definition: Vec3.hpp:224
Vec3 clampMagnitude(double maxLength) const noexcept
Definition: Vec3.hpp:165
double angle(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:134
Vec3 normalize() const noexcept
Definition: Vec3.hpp:289
constexpr Vec3(double inX, double inY, double inZ) noexcept
Definition: Vec3.hpp:72
double norm() const noexcept
Definition: Vec3.hpp:278
static constexpr Vec3 left() noexcept
Definition: Vec3.hpp:246
double x
Definition: Vec3.hpp:54
double y
Definition: Vec3.hpp:55
Vec3 project(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:301
bool operator!=(const Vec3 &rhs) const noexcept
Definition: Vec3.hpp:374
static constexpr Vec3 up() noexcept
Definition: Vec3.hpp:349
Vec3 lerp(const Vec3 &otherVec, double t) const noexcept
Definition: Vec3.hpp:259
static constexpr Vec3 forward() noexcept
Definition: Vec3.hpp:235
double dot(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:213
constexpr Vec3()=default
Vec3 cross(const Vec3 &otherVec) const noexcept
Definition: Vec3.hpp:185
static constexpr Vec3 right() noexcept
Definition: Vec3.hpp:313
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: Cartesian.hpp:40
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:302
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