criptic v1
Cosmic Ray Interstellar Propagation Tool using Itô Calculus
Loading...
Searching...
No Matches
Vec3.H
Go to the documentation of this file.
1
10#ifndef _VEC3_H_
11#define _VEC3_H_
12
13#include <cassert>
14#include <cmath>
15#include <istream>
16#include <ostream>
17#include <type_traits>
18#include <vector>
19#include "Types.H"
20
21namespace criptic {
22
32 template<class T> class Vec3 {
33
34 public:
35
37 // Storage
39
40 T v[3];
43 // Constructors
45
49 Vec3() {
50 v[0] = v[1] = v[2] = 0;
51 }
52
59 template<class U, class V, class W>
60 Vec3(const U& v0,
61 const V& v1,
62 const W& v2) {
63 v[0] = v0;
64 v[1] = v1;
65 v[2] = v2;
66 }
67
72 template<class U>
73 Vec3(const U& v0) {
74 v[0] = v[1] = v[2] = v0;
75 }
76
81 template<class U>
82 Vec3(const Vec3<U>& a) {
83 v[0] = a[0];
84 v[1] = a[1];
85 v[2] = a[2];
86 }
87
89 // Data access
91
98 T& operator [] (int i) {
99 assert(i >= 0 && i < 3);
100 return v[i];
101 }
108 const T& operator [] (int i) const {
109 assert(i >= 0 && i < 3);
110 return v[i];
111 }
118 T& operator () (int i) {
119 assert(i >= 0 && i < 3);
120 return v[i];
121 }
128 const T& operator () (int i) const {
129 assert(i >= 0 && i < 3);
130 return v[i];
131 }
136 T *data() {
137 return v;
138 }
143 const T *data() const {
144 return v;
145 }
146
148 // Unary operators
150
157 Vec3<T> rv;
158 for (int i=0; i<3; i++) rv[i] = -v[i];
159 return rv;
160 }
161
163 // Unary operators with scalars
165
172 template<class U,
173 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
174 Vec3<T>& operator+=(const U& a) {
175 for (int i=0; i<3; i++) v[i] += a;
176 return *this;
177 }
184 template<class U,
185 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
186 Vec3<T>& operator-=(const U& a) {
187 for (int i=0; i<3; i++) v[i] -= a;
188 return *this;
189 }
196 template<class U,
197 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
198 Vec3<T>& operator*=(const U& a) {
199 for (int i=0; i<3; i++) v[i] *= a;
200 return *this;
201 }
208 template<class U,
209 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
210 Vec3<T>& operator/=(const U& a) {
211 for (int i=0; i<3; i++) v[i] /= a;
212 return *this;
213 }
214
216 // Unary operators with vectors
218
225 template<class U,
226 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
228 for (int i=0; i<3; i++) v[i] += a[i];
229 return *this;
230 }
237 template<class U,
238 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
240 for (int i=0; i<3; i++) v[i] -= a[i];
241 return *this;
242 }
249 template<class U,
250 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
252 for (int i=0; i<3; i++) v[i] *= a[i];
253 return *this;
254 }
261 template<class U,
262 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
264 for (int i=0; i<3; i++) v[i] /= a[i];
265 return *this;
266 }
267
269 // Binary operations with scalars
271
278 Vec3<T>& operator=(const T& a) {
279 for (int i=0; i<3; i++) v[i] = a;
280 return *this;
281 }
288 template<class U,
289 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
290 auto operator+(const U& a) const -> Vec3<decltype(this->v[0]+a)> {
291 Vec3<decltype(a+v[0])> rv;
292 for (int i=0; i<3; i++) rv[i] = v[i] + a;
293 return rv;
294 }
301 template<class U,
302 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
303 auto operator-(const U& a) const -> Vec3<decltype(this->v[0]-a)> {
304 Vec3<decltype(a-v[0])> rv;
305 for (int i=0; i<3; i++) rv[i] = v[i] - a;
306 return rv;
307 }
314 template<class U,
315 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
316 auto operator*(const U& a) const -> Vec3<decltype(this->v[0]*a)> {
317 Vec3<decltype(a*v[0])> rv;
318 for (int i=0; i<3; i++) rv[i] = v[i] * a;
319 return rv;
320 }
327 template<class U,
328 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
329 auto operator/(const U& a) const -> Vec3<decltype(this->v[0]/a)> {
330 Vec3<decltype(v[0]/a)> rv;
331 for (int i=0; i<3; i++) rv[i] = v[i] / a;
332 return rv;
333 }
340 template<class U,
341 std::enable_if_t<std::is_arithmetic<U>::value ||
342 std::is_enum<T>::value, bool> = true >
343 Vec3<bool> operator==(const U& a) const {
344 Vec3<bool> rv;
345 for (int i=0; i<3; i++) rv[i] = (v[i] == a);
346 return rv;
347 }
354 template<class U,
355 std::enable_if_t<std::is_arithmetic<U>::value ||
356 std::is_enum<T>::value, bool> = true >
357 Vec3<bool> operator!=(const U& a) const {
358 Vec3<bool> rv;
359 for (int i=0; i<3; i++) rv[i] = (v[i] != a);
360 return rv;
361 }
362
364 // Binary operations with vectors
366
373 template<class U,
374 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
375 auto operator+(const Vec3<U>& a) const
376 -> Vec3<decltype(this->v[0]+a[0])> {
377 Vec3<decltype(v[0]+a[0])> rv;
378 for (int i=0; i<3; i++) rv[i] = v[i] + a[i];
379 return rv;
380 }
387 template<class U,
388 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
389 auto operator-(const Vec3<U>& a) const
390 -> Vec3<decltype(this->v[0]-a[0])> {
391 Vec3<decltype(v[0]+a[0])> rv;
392 for (int i=0; i<3; i++) rv[i] = v[i] - a[i];
393 return rv;
394 }
401 template<class U,
402 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
403 auto operator*(const Vec3<U>& a) const
404 -> Vec3<decltype(this->v[0]*a[0])> {
405 Vec3<decltype(v[0]*a[0])> rv;
406 for (int i=0; i<3; i++) rv[i] = v[i] * a[i];
407 return rv;
408 }
415 template<class U,
416 std::enable_if_t<std::is_arithmetic<U>::value, bool> = true >
417 auto operator/(const Vec3<U>& a) const
418 -> Vec3<decltype(this->v[0]/a[0])> {
419 Vec3<decltype(v[0]/a[0])> rv;
420 for (int i=0; i<3; i++) rv[i] = v[i] / a[i];
421 return rv;
422 }
430 template<class U,
431 std::enable_if_t<std::is_arithmetic<U>::value ||
432 std::is_enum<T>::value, bool> = true >
433 Vec3<bool> operator==(const Vec3<U>& a) const {
434 Vec3<bool> rv;
435 for (int i=0; i<3; i++) rv[i] = (v[i] == a[i]);
436 return rv;
437 }
445 template<class U,
446 std::enable_if_t<std::is_arithmetic<U>::value ||
447 std::is_enum<T>::value, bool> = true >
448 Vec3<bool> operator!=(const Vec3<U>& a) const {
449 Vec3<bool> rv;
450 for (int i=0; i<3; i++) rv[i] = (v[i] != a[i]);
451 return rv;
452 }
453
455 // Unary operations
457
462 constexpr T mag2() const {
463 return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
464 }
465
470 Real mag() const {
471 return std::sqrt(mag2());
472 }
473
478 Vec3<Real> unit() const {
479 Real m = mag();
480 if (m > 0)
481 return (*this) / m;
482 else
483 return (*this) * 0.0;
484 }
485
491 void normalize() {
492 Real m = mag();
493 if (m > 0)
494 (*this) /= m;
495 else
496 (*this) = 0.0;
497 }
498
503 T max() const {
504 T m = v[0];
505 if (v[1] > m) m = v[1];
506 if (v[2] > m) m = v[2];
507 return m;
508 }
509
514 int argmax() const {
515 T m = v[0];
516 int j = 0;
517 if (v[1] > m) {
518 m = v[1];
519 j = 1;
520 }
521 if (v[2] > m) {
522 m = v[2];
523 j = 2;
524 }
525 return j;
526 }
527
532 T min() const {
533 T m = v[0];
534 if (v[1] < m) m = v[1];
535 if (v[2] < m) m = v[2];
536 return m;
537 }
538
543 int argmin() const {
544 T m = v[0];
545 int j = 0;
546 if (v[1] < m) {
547 m = v[1];
548 j = 1;
549 }
550 if (v[2] < m) {
551 m = v[2];
552 j = 2;
553 }
554 return j;
555 }
556
561 T sum() const {
562 return v[0] + v[1] + v[2];
563 }
564
566 // Binary vector operations
568
574 template<class U>
575 auto dot(const Vec3<U>& a) const {
576 return a[0]*v[0] + a[1]*v[1] + a[2]*v[2];
577 }
578
584 template<class U>
585 auto cross(const Vec3<U> &a) const -> Vec3<decltype(this->v[0]+a[0])> {
586 Vec3<decltype(v[0]*a[0])> rv;
587 rv[0] = v[1]*a[2] - v[2]*a[1];
588 rv[1] = v[2]*a[0] - v[0]*a[2];
589 rv[2] = v[0]*a[1] - v[1]*a[0];
590 return rv;
591 }
592
594 // Other operations
596
604 template<class U>
605 Vec3<T>& operator=(const std::vector<U>& a) {
606 assert(a.size() >= 3);
607 for (int i=0; i<3; i++) v[i] = a[i];
608 return *this;
609 }
610
611
612 };
613
614 // Convenient typedefs
620 // Define various named Vec3 objects
621 static const RealVec zeroVec(0,0,0);
622 static const RealVec identityVec(1,1,1);
623 static const RealVec xHat(1,0,0);
624 static const RealVec yHat(0,1,0);
625 static const RealVec zHat(0,0,1);
626 static const IdxVec zeroIdxVec(0,0,0);
627 static const SIdxVec zeroSIdxVec(0,0,0);
628 static const BoolVec trueVec(1,1,1);
629 static const BoolVec falseVec(1,1,1);
631 // Overload some basic arithmetic operators and functions for Vec3's
638 template<class T, class U,
639 std::enable_if_t<std::is_arithmetic<T>::value, bool> = true >
640 inline auto operator+(const T& a,
641 const Vec3<U>& v) -> Vec3<decltype(a+v[0])>{
642 Vec3<decltype(a+v[0])> rv;
643 for (int i=0; i<3; i++) rv[i] = a + v[i];
644 return rv;
645 }
652 template<class T, class U,
653 std::enable_if_t<std::is_arithmetic<T>::value, bool> = true >
654 inline auto operator-(const T& a,
655 const Vec3<U>& v) -> Vec3<decltype(a-v[0])> {
656 Vec3<decltype(a-v[0])> rv;
657 for (int i=0; i<3; i++) rv[i] = a - v[i];
658 return rv;
659 }
666 template<class T, class U,
667 std::enable_if_t<std::is_arithmetic<T>::value, bool> = true >
668 inline auto operator*(const T& a,
669 const Vec3<U>& v) -> Vec3<decltype(a*v[0])> {
670 Vec3<decltype(a*v[0])> rv;
671 for (int i=0; i<3; i++) rv[i] = a * v[i];
672 return rv;
673 }
680 template<class T, class U,
681 std::enable_if_t<std::is_arithmetic<T>::value, bool> = true >
682 inline auto operator/(const T& a,
683 const Vec3<U>& v) -> Vec3<decltype(a/v[0])> {
684 Vec3<decltype(a/v[0])> rv;
685 for (int i=0; i<3; i++) rv[i] = a / v[i];
686 return rv;
687 }
694 template<class T, class U,
695 std::enable_if_t<std::is_arithmetic<T>::value ||
696 std::is_enum<T>::value, bool> = true >
697 inline Vec3<bool> operator==(const T& a,
698 const Vec3<U>& v) {
699 Vec3<bool> rv;
700 for (int i=0; i<3; i++) rv[i] = (a == v[i]);
701 return rv;
702 }
709 template<class T, class U,
710 std::enable_if_t<std::is_arithmetic<T>::value ||
711 std::is_enum<T>::value, bool> = true >
712 inline Vec3<bool> operator!=(const T& a,
713 const Vec3<U>& v) {
714 Vec3<bool> rv;
715 for (int i=0; i<3; i++) rv[i] = (a != v[i]);
716 return rv;
717 }
718
719 // Define functions to return the elementwise min and max of a pair
720 // of Vec3's
727 template<class T, class U>
728 inline auto min(const criptic::Vec3<T>& v1,
729 const criptic::Vec3<U>& v2) -> Vec3<decltype(v1[0]+v2[0])> {
730 Vec3<decltype(v1[0]+v2[0])> rv;
731 for (int i=0; i<3; i++) rv[i] = std::min(v1[i], v2[i]);
732 return rv;
733 }
734
741 template<class T, class U>
742 inline auto max(const criptic::Vec3<T>& v1,
743 const criptic::Vec3<U>& v2) -> Vec3<decltype(v1[0]+v2[0])> {
744 Vec3<decltype(v1[0]+v2[0])> rv;
745 for (int i=0; i<3; i++) rv[i] = std::max(v1[i], v2[i]);
746 return rv;
747 }
748
754 template<class T>
755 inline Vec3<T> floor(const criptic::Vec3<T>& v) {
756 Vec3<T> rv;
757 for (int i=0; i<3; i++) rv[i] = std::floor(v[i]);
758 return rv;
759 }
760}
761
762// Overload the >> and << operators for convenience
770template<class T>
771std::istream& operator>>(std::istream& is,
773
781template<class T>
782std::ostream& operator<<(std::ostream& os,
783 const criptic::Vec3<T>& v);
784
785
786#endif
787// _VEC3_H_
Basic integer and real types.
std::ostream & operator<<(std::ostream &os, const criptic::Vec3< T > &v)
ASCII-formatted output of Vec3 to stream.
Definition Vec3.cpp:14
std::istream & operator>>(std::istream &is, criptic::Vec3< T > &v)
ASCII-formatted read of Vec3 from stream.
Definition Vec3.cpp:7
Class that represents a mathematical vector.
Definition Vec3.H:32
T min() const
Return the value of the smallest element.
Definition Vec3.H:532
Vec3(const Vec3< U > &a)
Conversion constructor.
Definition Vec3.H:82
Vec3< T > & operator+=(const Vec3< U > &a)
Add another Vec3 to the Vec3 elementwise.
Definition Vec3.H:227
T * data()
Return pointer to data.
Definition Vec3.H:136
int argmax() const
Return the index of the largest element.
Definition Vec3.H:514
T max() const
Return the value of the largest element.
Definition Vec3.H:503
Real mag() const
Computes the magnitude of the vector.
Definition Vec3.H:470
int argmin() const
Return the index of the smallest element.
Definition Vec3.H:543
Vec3< bool > operator!=(const U &a) const
Evaluate inequality of vector elementwise.
Definition Vec3.H:357
constexpr T mag2() const
Computes the squared magnitude of the vector.
Definition Vec3.H:462
Vec3 & operator/=(const Vec3< U > &a)
Divide this Vec3 by another Vec3 elementwise.
Definition Vec3.H:263
Vec3< bool > operator!=(const Vec3< U > &a) const
Evaluate inequality of two Vec3's elementwise.
Definition Vec3.H:448
auto operator/(const Vec3< U > &a) const -> Vec3< decltype(this->v[0]/a[0])>
Divide two Vec3s elementwise.
Definition Vec3.H:417
auto operator*(const U &a) const -> Vec3< decltype(this->v[0] *a)>
Multiply a scalar by a Vec3 elementwise.
Definition Vec3.H:316
Vec3< T > & operator+=(const U &a)
Add a scalar to the Vec3 elementwise.
Definition Vec3.H:174
auto operator-(const U &a) const -> Vec3< decltype(this->v[0]-a)>
Subtract a scalar from a Vec3 elementwise.
Definition Vec3.H:303
auto dot(const Vec3< U > &a) const
Returns the dot product of this vector with another vector.
Definition Vec3.H:575
Vec3(const U &v0, const V &v1, const W &v2)
Construct a vector from 3 scalars.
Definition Vec3.H:60
T sum() const
Return the sum of the elements.
Definition Vec3.H:561
auto operator/(const U &a) const -> Vec3< decltype(this->v[0]/a)>
Divide a Vec3 by a scalar elementwise.
Definition Vec3.H:329
Vec3< T > & operator/=(const U &a)
Divide the Vec3 by a scalar elementwise.
Definition Vec3.H:210
Vec3(const U &v0)
Construct a vector with every element equal to given value.
Definition Vec3.H:73
auto operator*(const Vec3< U > &a) const -> Vec3< decltype(this->v[0] *a[0])>
Multiply two Vec3s elementwise.
Definition Vec3.H:403
Vec3 & operator*=(const Vec3< U > &a)
Multiply another Vec3 by the Vec3 elementwise.
Definition Vec3.H:251
Vec3< T > & operator=(const T &a)
Assign a scalar value to every element of a Vec3.
Definition Vec3.H:278
auto operator-(const Vec3< U > &a) const -> Vec3< decltype(this->v[0]-a[0])>
Subtract two Vec3s elementwise.
Definition Vec3.H:389
Vec3()
Construct a vector of all zeros.
Definition Vec3.H:49
Vec3< T > & operator*=(const U &a)
Multiply a scalar by the Vec3 elementwise.
Definition Vec3.H:198
Vec3< T > operator-()
Return the negative of a vector.
Definition Vec3.H:156
auto cross(const Vec3< U > &a) const -> Vec3< decltype(this->v[0]+a[0])>
Returns the cross product of this vector with another vector.
Definition Vec3.H:585
T v[3]
Definition Vec3.H:40
Vec3< Real > unit() const
Returns a unit vector parallel to the vector.
Definition Vec3.H:478
Vec3< bool > operator==(const Vec3< U > &a) const
Evaluate equality of two Vec3's elementwise.
Definition Vec3.H:433
Vec3< T > & operator=(const std::vector< U > &a)
Assign a Vec3 from a std::vector.
Definition Vec3.H:605
T & operator()(int i)
Return an element of the vector.
Definition Vec3.H:118
T & operator[](int i)
Return an element of the vector.
Definition Vec3.H:98
const T * data() const
Return const pointer to data.
Definition Vec3.H:143
auto operator+(const U &a) const -> Vec3< decltype(this->v[0]+a)>
Add a scalar and a Vec3 elementwise.
Definition Vec3.H:290
Vec3< bool > operator==(const U &a) const
Evaluate equality of vector elementwise.
Definition Vec3.H:343
auto operator+(const Vec3< U > &a) const -> Vec3< decltype(this->v[0]+a[0])>
Add two Vec3s elementwise.
Definition Vec3.H:375
void normalize()
Normalizes this vector to have unit length.
Definition Vec3.H:491
Vec3< T > & operator-=(const U &a)
Subtract a scalar from the Vec3 elementwise.
Definition Vec3.H:186
Vec3< T > & operator-=(const Vec3< U > &a)
Subtract another Vec3 from the Vec3 elementwise.
Definition Vec3.H:239
The primary namespace for criptic objects.
Definition AdvancePacket.H:25
Vec3< bool > operator!=(const T &a, const Vec3< U > &v)
Evaluate inequality of a Vec3 with a scalar elementwise.
Definition Vec3.H:712
static const RealVec yHat(0, 1, 0)
criptic::RealTensor2 operator-(const criptic::Real a, const criptic::RealTensor2 &t)
Subtract a scalar from a RealTensor2 elementwise.
Definition RealTensor2.H:847
Vec3< bool > operator==(const T &a, const Vec3< U > &v)
Evaluate equality of a Vec3 with a scalar elementwise.
Definition Vec3.H:697
static const SIdxVec zeroSIdxVec(0, 0, 0)
static const RealVec xHat(1, 0, 0)
Vec3< T > floor(const criptic::Vec3< T > &v)
Return the elementwise floor of a Vec3.
Definition Vec3.H:755
criptic::RealTensor2 operator+(const criptic::Real a, const criptic::RealTensor2 &t)
Add a scalar and a RealTensor2 elementwise.
Definition RealTensor2.H:834
Vec3< bool > BoolVec
Definition Vec3.H:618
criptic::RealTensor2 operator/(const criptic::Real a, const criptic::RealTensor2 &t)
Divide a RealTensor2 by a scalar elementwise.
Definition RealTensor2.H:873
Vec3< Real > RealVec
Definition Vec3.H:615
static const RealVec identityVec(1, 1, 1)
criptic::FieldQty max(const criptic::FieldQty &q1, const criptic::FieldQty &q2)
Take elementwise maximum of two FieldQty objects.
Definition FieldQty.H:277
double Real
Definition Types.H:38
static const RealVec zHat(0, 0, 1)
Vec3< SignedIdxType > SIdxVec
Definition Vec3.H:617
static const BoolVec trueVec(1, 1, 1)
static const BoolVec falseVec(1, 1, 1)
static const IdxVec zeroIdxVec(0, 0, 0)
Vec3< IdxType > IdxVec
Definition Vec3.H:616
static const RealVec zeroVec(0, 0, 0)
criptic::FieldQty min(const criptic::FieldQty &q1, const criptic::FieldQty &q2)
Take elementwise minimum of two FieldQty objects.
Definition FieldQty.H:263
criptic::FieldQty operator*(const criptic::Real a, const criptic::FieldQty &fq)
Multiply a scalar by a FieldQty elementwise.
Definition FieldQty.H:250