NumCpp  2.12.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
Vec3.hpp
Go to the documentation of this file.
1
28#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"
42
43//====================================================================================
44
45namespace 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) &&
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:4524
self_type transpose() const
Definition: NdArrayCore.hpp:4882
Holds a 2D vector.
Definition: Vec2.hpp:49
Holds a 3D vector.
Definition: Vec3.hpp:51
double z
Definition: Vec3.hpp:56
std::string toString() const
Definition: Vec3.hpp:324
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
Vec3(const NdArray< double > &ndArray)
Definition: Vec3.hpp:115
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
Vec3 & operator-=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:431
static constexpr Vec3 left() noexcept
Definition: Vec3.hpp:246
double x
Definition: Vec3.hpp:54
Vec3 & operator/=(double scalar) noexcept
Definition: Vec3.hpp:461
Vec3 & operator-=(double scalar) noexcept
Definition: Vec3.hpp:416
double y
Definition: Vec3.hpp:55
Vec3 & operator*=(double scalar) noexcept
Definition: Vec3.hpp:446
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 & operator+=(const Vec3 &rhs) noexcept
Definition: Vec3.hpp:401
NdArray< double > toNdArray() const
Definition: Vec3.hpp:337
Vec3 & operator+=(double scalar) noexcept
Definition: Vec3.hpp:386
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:49
Definition: Cartesian.hpp:40
NdArray< dtype > min(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: min.hpp:44
Duration operator-(const DateTime &lhs, const DateTime &rhs) noexcept
Subtraction operator.
Definition: DateTime/DateTime.hpp:551
NdArray< dtype > operator/(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:819
double hypot(dtype inValue1, dtype inValue2) noexcept
Definition: hypot.hpp:56
auto cos(dtype inValue) noexcept
Definition: cos.hpp:49
std::ostream & operator<<(std::ostream &os, Duration duration)
Output stream operator for the Duration type.
Definition: Clock.hpp:30
NdArrayConstIterator< dtype, PointerType, DifferenceType > operator+(typename NdArrayConstIterator< dtype, PointerType, DifferenceType >::difference_type offset, NdArrayConstIterator< dtype, PointerType, DifferenceType > next) noexcept
Definition: NdArrayIterators.hpp:302
NdArray< dtype > operator*(const NdArray< dtype > &lhs, const NdArray< dtype > &rhs)
Definition: NdArrayOperators.hpp:604
NdArray< dtype > max(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: max.hpp:44