Hermes
vector.h
Go to the documentation of this file.
1 
32 #ifndef HERMES_GEOMETRY_VECTOR_H
33 #define HERMES_GEOMETRY_VECTOR_H
34 
35 #include <hermes/numeric/numeric.h>
36 #include <hermes/common/debug.h>
37 #include <hermes/common/index.h>
39 
40 #include <cstring>
41 #include <initializer_list>
42 #include <vector>
43 
44 namespace hermes {
45 
48 template<typename T> class Point2;
49 // *********************************************************************************************************************
50 // Vector2
51 // *********************************************************************************************************************
54 template<typename T> class Vector2 : public MathElement<T, 2u> {
55  static_assert(std::is_same<T, f32>::value || std::is_same<T, f64>::value ||
56  std::is_same<T, Interval<f32>>::value || std::is_same<T, Interval<f64>>::value,
57  "Vector2 must hold an float type!");
58 
59 public:
60  // *******************************************************************************************************************
61  // CONSTRUCTORS
62  // *******************************************************************************************************************
68  HERMES_DEVICE_CALLABLE Vector2(T _x, T _y) : x(_x), y(_y) {}
71  HERMES_DEVICE_CALLABLE explicit Vector2(const Point2<T> &p) : x(p.x), y(p.y) {}
74  HERMES_DEVICE_CALLABLE explicit Vector2(T f) { x = y = f; }
78  x = f[0];
79  y = f[1];
80  }
81  // *******************************************************************************************************************
82  // OPERATORS
83  // *******************************************************************************************************************
84  // access
89  HERMES_DEVICE_CALLABLE T operator[](size_t i) const { return (&x)[i]; }
94  HERMES_DEVICE_CALLABLE T &operator[](size_t i) { return (&x)[i]; }
95  // arithmetic
96 #define ARITHMETIC_OP(OP) \
97  HERMES_DEVICE_CALLABLE Vector2 &operator OP##= (const Vector2 &v) { \
98  x OP##= v.x; y OP##= v.y; return *this; } \
99  HERMES_DEVICE_CALLABLE Vector2 &operator OP##= (real_t f) { \
100  x OP##= f; y OP##= f; return *this; } \
101  HERMES_DEVICE_CALLABLE Vector2 operator OP (const Vector2<T> &b) const { \
102  return {x OP b.x, y OP b.y}; } \
103  HERMES_DEVICE_CALLABLE Vector2 operator OP (real_t f) const { \
104  return {x OP f, y OP f}; }
105  ARITHMETIC_OP(+)
106  ARITHMETIC_OP(-)
107  ARITHMETIC_OP(*)
108  ARITHMETIC_OP(/)
109 #undef ARITHMETIC_OP
110  HERMES_DEVICE_CALLABLE Vector2 operator-() const { return Vector2(-x, -y); }
111  // relational
112 #define RELATIONAL_OP(OP, CO) \
113  HERMES_DEVICE_CALLABLE bool operator OP (const Vector2 &b) const { \
114  return x OP b.x CO y OP b.y; }
115  RELATIONAL_OP(<, &&)
116  RELATIONAL_OP(>, &&)
117  RELATIONAL_OP(<=, &&)
118  RELATIONAL_OP(>=, &&)
119  RELATIONAL_OP(!=, ||)
120 #undef RELATIONAL_OP
121  HERMES_DEVICE_CALLABLE bool operator==(const Vector2<T> &b) const {
122  return Check::is_equal(x, b.x) && Check::is_equal(y, b.y);
123  }
124  // *******************************************************************************************************************
125  // METHODS
126  // *******************************************************************************************************************
129  HERMES_DEVICE_CALLABLE T length2() const { return x * x + y * y; }
132  HERMES_DEVICE_CALLABLE T length() const { return sqrtf(length2()); }
138  HERMES_DEVICE_CALLABLE Vector2 left() const { return Vector2(-y, x); }
139  // swizzle
142  Vector2 xy() const { return {x, y}; }
145  Vector2 yx() const { return {y, x}; }
148  Vector2 xx() const { return {x, x}; }
151  Vector2 yy() const { return {y, y}; }
152  // *******************************************************************************************************************
153  // PUBLIC FIELDS
154  // *******************************************************************************************************************
155  T x = T(0.0);
156  T y = T(0.0);
157 };
158 
159 template<typename T> class Point3;
160 
161 // *********************************************************************************************************************
162 // Vector3
163 // *********************************************************************************************************************
166 template<typename T> class Vector3 : public MathElement<T, 3u> {
167  static_assert(std::is_same<T, f32>::value || std::is_same<T, f64>::value ||
168  std::is_same<T, Interval<f32>>::value || std::is_same<T, Interval<f64>>::value,
169  "Vector3 must hold an float type!");
170 
171 public:
172  // *******************************************************************************************************************
173  // CONSTRUCTORS
174  // *******************************************************************************************************************
176  HERMES_DEVICE_CALLABLE Vector3() : x{0}, y{0}, z{0} {}
179  HERMES_DEVICE_CALLABLE explicit Vector3(T _f) : x(_f), y(_f), z(_f) {}
184  HERMES_DEVICE_CALLABLE Vector3(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {}
187  HERMES_DEVICE_CALLABLE explicit Vector3(const T *v) {
188  x = v[0];
189  y = v[1];
190  z = v[2];
191  }
192  // conversion
195  HERMES_DEVICE_CALLABLE explicit Vector3(const Point3<T> &p) : x(p.x), y(p.y), z(p.z) {}
200  template<typename S, typename C = T>
202  typename std::enable_if_t<
203  !std::is_same_v<C, Interval<f32>>
204  && !std::is_same_v<C, Interval<f64>>> * = nullptr) :
205  x(vi.x), y(vi.y), z(vi.z) {}
206  // *******************************************************************************************************************
207  // OPERATORS
208  // *******************************************************************************************************************
209  // assignment
214  x = y = z = v;
215  return *this;
216  }
217  // arithmetic
218 #define ARITHMETIC_OP(OP) \
219  HERMES_DEVICE_CALLABLE Vector3 &operator OP##= (const Vector3 &v) { \
220  x OP##= v.x; y OP##= v.y; z OP##= v.z; return *this; } \
221  HERMES_DEVICE_CALLABLE Vector3 &operator OP##= (real_t f) { \
222  x OP##= f; y OP##= f; z OP##= f; return *this; } \
223  HERMES_DEVICE_CALLABLE Vector3 operator OP (const Vector3<T> &b) const { \
224  return {x OP b.x, y OP b.y, z OP b.z}; } \
225  HERMES_DEVICE_CALLABLE Vector3 operator OP (T f) const { \
226  return {x OP f, y OP f, z OP f}; }
227  ARITHMETIC_OP(+)
228  ARITHMETIC_OP(-)
229  ARITHMETIC_OP(*)
230 #undef ARITHMETIC_OP
231  HERMES_DEVICE_CALLABLE Vector3<T> &operator/=(T f) {
233  T inv = 1.f / f;
234  x *= inv;
235  y *= inv;
236  z *= inv;
237  return *this;
238  }
239  HERMES_DEVICE_CALLABLE Vector3<T> &operator/=(const Vector3<T> &v) {
240  x /= v.x;
241  y /= v.y;
242  z /= v.z;
243  return *this;
244  }
245  HERMES_DEVICE_CALLABLE Vector3<T> operator/(const T &f) const {
246  T inv = 1.f / f;
247  return Vector3<T>(x * inv, y * inv, z * inv);
248  }
249  HERMES_DEVICE_CALLABLE Vector3<T> operator-() const { return Vector3(-x, -y, -z); }
250  // relational
251  HERMES_DEVICE_CALLABLE bool operator==(const Vector3<T> &b) const {
252  return Check::is_equal(x, b.x) && Check::is_equal(y, b.y) &&
253  Check::is_equal(z, b.z);
254  }
255  HERMES_DEVICE_CALLABLE bool operator<(const Vector3<T> &b) const {
256  if (x < b.x)
257  return true;
258  if (y < b.y)
259  return true;
260  return z < b.z;
261  }
262  HERMES_DEVICE_CALLABLE bool operator>(const Vector3<T> &b) const {
263  if (x > b.x)
264  return true;
265  if (y > b.y)
266  return true;
267  return z > b.z;
268  }
269  HERMES_DEVICE_CALLABLE bool operator>=(const Vector3<T> &b) const {
270  return x >= b.x && y >= b.y && z >= b.z;
271  }
272  HERMES_DEVICE_CALLABLE bool operator<=(const Vector3<T> &b) const {
273  return x <= b.x && y <= b.y && z <= b.z;
274  }
275  // *******************************************************************************************************************
276  // ACCESS
277  // *******************************************************************************************************************
282  HERMES_DEVICE_CALLABLE T operator[](int i) const { return (&x)[i]; }
287  HERMES_DEVICE_CALLABLE T &operator[](int i) { return (&x)[i]; }
292  HERMES_DEVICE_CALLABLE Vector2<T> xy(int i = 0, int j = 1) const {
293  return Vector2<T>((&x)[i], (&x)[j]);
294  }
295  // *******************************************************************************************************************
296  // METRICS
297  // *******************************************************************************************************************
302  HERMES_DEVICE_CALLABLE T mLength() const { return std::abs(x) + std::abs(y) + std::abs(z); }
307  template<typename C = T>
308  HERMES_DEVICE_CALLABLE T length(typename std::enable_if_t<!std::is_same_v<C, Interval<f32>>
309  && !std::is_same_v<C,
310  Interval<f64>>> * = nullptr) const {
311  return std::sqrt(length2());
312  }
316  template<typename C = T>
317  HERMES_DEVICE_CALLABLE T length(typename std::enable_if_t<std::is_same_v<C, Interval<f32>>
318  || std::is_same_v<C,
319  Interval<f64>>> * = nullptr) const {
320  return length2().sqrt();
321  }
326  HERMES_DEVICE_CALLABLE T length2() const { return x * x + y * y + z * z; }
332  if (std::abs(x) > std::abs(y) && std::abs(x) > std::abs(z))
333  return x;
334  if (std::abs(y) > std::abs(x) && std::abs(y) > std::abs(z))
335  return y;
336  return z;
337  }
342  if (x > y && x > z)
343  return x;
344  if (y > x && y > z)
345  return y;
346  return z;
347  }
351  [[nodiscard]] HERMES_DEVICE_CALLABLE int maxDimension() const {
352  if (x > y && x > z)
353  return 0;
354  if (y > x && y > z)
355  return 1;
356  return 2;
357  }
361  [[nodiscard]] HERMES_DEVICE_CALLABLE int maxAbsDimension() const {
362  if (std::abs(x) > std::abs(y) && std::abs(x) > std::abs(z))
363  return 0;
364  if (std::abs(y) > std::abs(x) && std::abs(y) > std::abs(z))
365  return 1;
366  return 2;
367  }
368  // *******************************************************************************************************************
369  // OPERATIONS
370  // *******************************************************************************************************************
375  auto l = length();
376  if (l != 0.f) {
377  x /= l;
378  y /= l;
379  z /= l;
380  }
381  }
387  auto l = length();
388  return (*this) / l;
389  }
395  return (dot(b, *this) / b.length2()) * b;
396  }
402  return *this - (dot(b, *this) / b.length2()) * b;
403  }
404  // *******************************************************************************************************************
405  // DEBUG
406  // *******************************************************************************************************************
409  HERMES_DEVICE_CALLABLE [[nodiscard]] bool hasNaNs() const {
410  return Check::is_nan(x) || Check::is_nan(y) || Check::is_nan(z);
411  }
412  // *******************************************************************************************************************
413  // PUBLIC FIELDS
414  // *******************************************************************************************************************
415  T x = T(0.0);
416  T y = T(0.0);
417  T z = T(0.0);
418 };
419 
420 // *********************************************************************************************************************
421 // Vector4
422 // *********************************************************************************************************************
425 template<typename T> class Vector4 : public MathElement<T, 4> {
426 public:
427  // *******************************************************************************************************************
428  // CONSTRUCTORS
429  // *******************************************************************************************************************
431  HERMES_DEVICE_CALLABLE Vector4() : x{0}, y{0}, z{0}, w{0} {}
437  HERMES_DEVICE_CALLABLE Vector4(T _x, T _y, T _z, T _w) : x(_x), y(_y), z(_z), w(_w) {}
438  // *******************************************************************************************************************
439  // OPERATORS
440  // *******************************************************************************************************************
441  // arithmetic
442  HERMES_DEVICE_CALLABLE Vector4<T> &operator+=(const Vector4<T> &v) {
443  x += v.x;
444  y += v.y;
445  z += v.z;
446  w += v.w;
447  return *this;
448  }
449  HERMES_DEVICE_CALLABLE Vector4<T> &operator-=(const Vector4<T> &v) {
450  x -= v.x;
451  y -= v.y;
452  z -= v.z;
453  w -= v.w;
454  return *this;
455  }
456  HERMES_DEVICE_CALLABLE Vector4<T> &operator*=(T f) {
457  x *= f;
458  y *= f;
459  z *= f;
460  w *= f;
461  return *this;
462  }
463  HERMES_DEVICE_CALLABLE Vector4<T> &operator/=(T f) {
464  T inv = 1.f / f;
465  x *= inv;
466  y *= inv;
467  z *= inv;
468  w *= inv;
469  return *this;
470  }
471  HERMES_DEVICE_CALLABLE Vector4<T> operator-() const { return Vector4(-x, -y, -z, -w); }
472  HERMES_DEVICE_CALLABLE Vector4<T> operator+(const Vector4<T> &b) {
473  return Vector4<T>(x + b.x, y + b.y, z + b.z, w + b.w);
474  }
475  HERMES_DEVICE_CALLABLE Vector4<T> operator-(const Vector4<T> &b) {
476  return Vector4<T>(x - b.x, y - b.y, z - b.z, w - b.w);
477  }
478  HERMES_DEVICE_CALLABLE Vector4<T> operator*(T f) {
479  return Vector4<T>(x * f, y * f, z * f, w * f);
480  }
481  HERMES_DEVICE_CALLABLE Vector4<T> operator/(T f) {
482  T inv = 1.f / f;
483  return Vector4<T>(x * inv, y * inv, z * inv, w * inv);
484  }
485  // *******************************************************************************************************************
486  // ACCESS
487  // *******************************************************************************************************************
492  HERMES_DEVICE_CALLABLE T operator[](int i) const { return (&x)[i]; }
497  HERMES_DEVICE_CALLABLE T &operator[](int i) { return (&x)[i]; }
504  // *******************************************************************************************************************
505  // METRICS
506  // *******************************************************************************************************************
509  HERMES_DEVICE_CALLABLE T length2() const { return x * x + y * y + z * z + w * w; }
512  HERMES_DEVICE_CALLABLE T length() const { return sqrtf(length2()); }
513  // *******************************************************************************************************************
514  // PUBLIC FIELDS
515  // *******************************************************************************************************************
516  T x = T(0.0);
517  T y = T(0.0);
518  T z = T(0.0);
519  T w = T(0.0);
520 };
521 
522 // *********************************************************************************************************************
523 // EXTERNAL FUNCTIONS
524 // *********************************************************************************************************************
525 // geometry
531 template<typename T>
533  return a.x * b.x + a.y * b.y;
534 }
540 template<typename T>
542  return a.x * b.x + a.y * b.y + a.z * b.z;
543 }
549 template<typename T>
551  return a.x * b.y - a.y * b.x;
552 }
558 template<typename T>
560  return Vector3<T>((a.y * b.z) - (a.z * b.y), (a.z * b.x) - (a.x * b.z),
561  (a.x * b.y) - (a.y * b.x));
562 }
569 template<typename T>
571  return dot(a, cross(b, c));
572 }
577 template<typename T>
579  return v / v.length();
580 }
585 template<typename T>
587  if (v.length2() == 0.f)
588  return v;
589  return v / v.length();
590 }
596 template<typename T>
598  Vector2<T> n = normalize(v);
599  if (first)
600  return Vector2<T>(-n.y, n.x);
601  return Vector2<T>(n.y, -n.x);
602 }
607 template<typename T>
609  return (dot(b, a) / b.length2()) * b;
610 }
617 template<typename T>
619  return (dot(b, a) / b.length2()) * b;
620 }
626 template<typename T>
628  return a - (dot(b, a) / b.length2()) * b;
629 }
634 template<typename T>
636  b = hermes::normalize(cross(a, ((std::abs(a.y) > 0.f || std::abs(a.z) > 0.f)
637  ? Vector3<T>(1, 0, 0)
638  : Vector3<T>(0, 1, 1))));
639  c = hermes::normalize(cross(a, b));
640 }
641 
642 
643 // arithmetic
644 #define DOP2(OP) f OP v.x, f OP v.y
645 #define DOP3(OP) f OP v.x, f OP v.y, f OP v.z
646 #define MATH_OP(D, OP) \
647 template<typename T> \
648 HERMES_DEVICE_CALLABLE Vector##D<T> operator OP(T f, const Vector##D<T> &v) { \
649  return Vector##D<T>(DOP##D(OP)); }
650 MATH_OP(2, *)
651 MATH_OP(2, /)
652 MATH_OP(3, *)
653 MATH_OP(3, /)
654 #undef MATH_OP
655 #undef DOP2
656 #undef DOP3
657 
658 #define DOP2(OP) OP(a.x, b.x), OP(a.y, b.y)
659 #define DOP3(OP) OP(a.x, b.x), OP(a.y, b.y), OP(a.z, b.z)
660 #define MATH_OP(D, NAME, OP) \
661 template<typename T> \
662 HERMES_DEVICE_CALLABLE Vector##D<T> NAME(const Vector##D<T> &a, const Vector##D<T> &b) { \
663  return Vector##D<T>(DOP##D(OP)); }
664 #ifdef HERMES_DEVICE_ENABLED
665 MATH_OP(2, min, min)
666 MATH_OP(2, max, max)
667 MATH_OP(3, min, min)
668 MATH_OP(3, max, max)
669 #else
670 MATH_OP(2, min, std::min)
671 MATH_OP(2, max, std::max)
672 MATH_OP(3, min, std::min)
673 MATH_OP(3, max, std::max)
674 #endif
675 #undef MATH_OP
676 #undef DOP2
677 #undef DOP3
678 
679 // numbers
680 #define DOP2(OP) OP(v.x), OP(v.y)
681 #define DOP3(OP) OP(v.x), OP(v.y), OP(v.z)
682 #define MATH_OP(NAME, OP, D) \
683  template<typename T> \
684  HERMES_DEVICE_CALLABLE Vector##D<T> NAME(const Vector##D<T>& v) { \
685  return Vector##D<T>(DOP##D(OP)); }
686 #ifdef HERMES_DEVICE_ENABLED
687 MATH_OP(floor, ::floor, 2)
688 MATH_OP(ceil, ::ceil, 2)
689 MATH_OP(abs, ::abs, 2)
690 MATH_OP(cos, ::cos, 2)
691 MATH_OP(floor, ::floor, 3)
692 MATH_OP(ceil, ::ceil, 3)
693 MATH_OP(abs, ::abs, 3)
694 MATH_OP(cos, ::cos, 3)
695 #else
696 MATH_OP(floor, std::floor, 2)
697 MATH_OP(ceil, std::ceil, 2)
698 MATH_OP(abs, std::abs, 2)
699 MATH_OP(cos, std::cos, 2)
700 MATH_OP(floor, std::floor, 3)
701 MATH_OP(ceil, std::ceil, 3)
702 MATH_OP(abs, std::abs, 3)
703 MATH_OP(cos, std::cos, 3)
704 #endif
705 #undef MATH_OP
706 #undef DOP2
707 #undef DOP3
708 // *********************************************************************************************************************
709 // IO
710 // *********************************************************************************************************************
711 template<typename T>
712 std::ostream &operator<<(std::ostream &os, const Vector2<T> &v) {
713  os << "Vector2 [" << v.x << " " << v.y << "]";
714  return os;
715 }
716 template<typename T>
717 std::ostream &operator<<(std::ostream &os, const Vector3<T> &v) {
718  os << "Vector3 [" << v.x << " " << v.y << " " << v.z << "]";
719  return os;
720 }
721 template<typename T>
722 std::ostream &operator<<(std::ostream &os, const Vector4<T> &v) {
723  os << "Vector4 [" << v.x << " " << v.y << " " << v.z << " " << v.w << "]";
724  return os;
725 }
726 
727 // *********************************************************************************************************************
728 // TYPEDEFS
729 // *********************************************************************************************************************
730 using vec2 = Vector2<real_t>;
731 using vec3 = Vector3<real_t>;
732 using vec4 = Vector4<real_t>;
733 using vec3d = Vector3<double>;
734 using vec3f = Vector3<float>;
735 using vec2f = Vector2<float>;
736 using vec2i = Vector2<Interval<real_t>>;
737 using vec3i = Vector3<Interval<real_t>>;
738 
739 } // namespace hermes
740 
741 // std hash support
742 namespace std {
743 
746 template<typename T> struct hash<hermes::Vector2<T>> {
750  size_t operator()(hermes::Vector2<T> const &v) const {
751  hash<T> hasher;
752  size_t s = 0;
753  // inject x component
754  size_t h = hasher(v.x);
755  h += 0x9e3779b9 + (s << 6) + (s >> 2);
756  s ^= h;
757  // inject y component
758  h = hasher(v.y);
759  h += 0x9e3779b9 + (s << 6) + (s >> 2);
760  s ^= h;
761  return s;
762  }
763 };
764 
767 template<typename T> struct hash<hermes::Vector3<T>> {
771  size_t operator()(hermes::Vector3<T> const &v) const {
772  hash<T> hasher;
773  size_t s = 0;
774  // inject x component
775  size_t h = hasher(v.x);
776  h += 0x9e3779b9 + (s << 6) + (s >> 2);
777  s ^= h;
778  // inject y component
779  h = hasher(v.y);
780  h += 0x9e3779b9 + (s << 6) + (s >> 2);
781  s ^= h;
782  // inject y component
783  h = hasher(v.z);
784  h += 0x9e3779b9 + (s << 6) + (s >> 2);
785  s ^= h;
786  return s;
787  }
788 };
789 
790 } // namespace std
791 
792 #endif
793 
Interface used by all basic geometric entities.
Definition: math_element.h:44
Geometric 2-dimensional point (x, y)
Definition: point.h:49
Geometric 3-dimensional vector (x, y, z)
Definition: point.h:148
Geometric 2-dimensional vector (x, y)
Definition: vector.h:54
HERMES_DEVICE_CALLABLE T length2() const
Computes squared magnitude.
Definition: vector.h:129
Vector2 xy() const
Gets swizzle form (x, y)
Definition: vector.h:142
HERMES_DEVICE_CALLABLE Vector2(T _x, T _y)
Constructs from component values.
Definition: vector.h:68
HERMES_DEVICE_CALLABLE T operator[](size_t i) const
Get i-th component.
Definition: vector.h:89
HERMES_DEVICE_CALLABLE Vector2 right() const
Gets orthogonal vector in right direction.
Definition: vector.h:135
Vector2 yx() const
Gets swizzle form (y, x)
Definition: vector.h:145
HERMES_DEVICE_CALLABLE T length() const
Computes magnitude.
Definition: vector.h:132
HERMES_DEVICE_CALLABLE Vector2 left() const
Gets orthogonal vector in left direction.
Definition: vector.h:138
HERMES_DEVICE_CALLABLE T & operator[](size_t i)
Get i-th component reference.
Definition: vector.h:94
T x
0-th component
Definition: vector.h:155
HERMES_DEVICE_CALLABLE Vector2()
Default constructor.
Definition: vector.h:64
Vector2 yy() const
Gets swizzle form (y, y)
Definition: vector.h:151
HERMES_DEVICE_CALLABLE Vector2(T f)
Constructs from single component value.
Definition: vector.h:74
HERMES_DEVICE_CALLABLE Vector2(const Point2< T > &p)
Constructs from geometric point.
Definition: vector.h:71
HERMES_DEVICE_CALLABLE Vector2(T *f)
Constructs from component array.
Definition: vector.h:77
T y
1-th component
Definition: vector.h:156
Vector2 xx() const
Gets swizzle form (x, x)
Definition: vector.h:148
Geometric 3-dimensional vector (x, y, z)
Definition: vector.h:166
HERMES_DEVICE_CALLABLE T length(typename std::enable_if_t< std::is_same_v< C, Interval< f32 >>||std::is_same_v< C, Interval< f64 >>> *=nullptr) const
Computes vector magnitude.
Definition: vector.h:317
HERMES_DEVICE_CALLABLE T operator[](int i) const
Get i-th component.
Definition: vector.h:282
HERMES_DEVICE_CALLABLE Vector3(const Vector3< Interval< S >> &vi, typename std::enable_if_t< !std::is_same_v< C, Interval< f32 >> &&!std::is_same_v< C, Interval< f64 >>> *=nullptr)
Constructs from interval.
Definition: vector.h:201
HERMES_DEVICE_CALLABLE T mLength() const
Computes Manhattan distance.
Definition: vector.h:302
HERMES_DEVICE_CALLABLE int maxAbsDimension() const
Gets index of component with maximum absolute value.
Definition: vector.h:361
HERMES_DEVICE_CALLABLE bool hasNaNs() const
Check for nans.
Definition: vector.h:409
HERMES_DEVICE_CALLABLE T maxAbs() const
Gets maximum absolute component value.
Definition: vector.h:331
HERMES_DEVICE_CALLABLE T length2() const
Computes vector squared magnitude.
Definition: vector.h:326
HERMES_DEVICE_CALLABLE Vector2< T > xy(int i=0, int j=1) const
Gets 2-dimensional swizzle form.
Definition: vector.h:292
HERMES_DEVICE_CALLABLE Vector3 rejectOn(const Vector3 b)
Rejects this vector on b.
Definition: vector.h:401
HERMES_DEVICE_CALLABLE Vector3 projectOnto(const Vector3 &b)
Projects this vector onto b.
Definition: vector.h:394
HERMES_DEVICE_CALLABLE Vector3(const T *v)
Constructs from component array.
Definition: vector.h:187
HERMES_DEVICE_CALLABLE T max() const
Gets maximum component value.
Definition: vector.h:341
HERMES_DEVICE_CALLABLE int maxDimension() const
Gets index of component with maximum value.
Definition: vector.h:351
HERMES_DEVICE_CALLABLE Vector3(T _f)
Constructs from single component value.
Definition: vector.h:179
HERMES_DEVICE_CALLABLE T & operator[](int i)
Get i-th component reference.
Definition: vector.h:287
T x
0-th component
Definition: vector.h:415
HERMES_DEVICE_CALLABLE T length(typename std::enable_if_t<!std::is_same_v< C, Interval< f32 >> &&!std::is_same_v< C, Interval< f64 >>> *=nullptr) const
Computes vector magnitude.
Definition: vector.h:308
HERMES_DEVICE_CALLABLE Vector3(T _x, T _y, T _z)
Constructs from component values.
Definition: vector.h:184
HERMES_DEVICE_CALLABLE void normalize()
Normalizes this vector.
Definition: vector.h:374
HERMES_DEVICE_CALLABLE Vector3()
Default constructor.
Definition: vector.h:176
T z
2-th component
Definition: vector.h:417
HERMES_DEVICE_CALLABLE Vector3(const Point3< T > &p)
Casts from geometric point.
Definition: vector.h:195
T y
1-th component
Definition: vector.h:416
HERMES_DEVICE_CALLABLE Vector3 normalized() const
Gets a normalized copy of this vector.
Definition: vector.h:386
HERMES_DEVICE_CALLABLE Vector3 & operator=(const T &v)
Copy assign.
Definition: vector.h:213
Geometric 4-dimensional point (x, y, z, w)
Definition: vector.h:425
HERMES_DEVICE_CALLABLE Vector3< T > xyz()
Gets first 3 components.
Definition: vector.h:503
T y
1-th component
Definition: vector.h:517
T z
2-th component
Definition: vector.h:518
T x
0-th component
Definition: vector.h:516
HERMES_DEVICE_CALLABLE T & operator[](int i)
Get i-th component reference.
Definition: vector.h:497
HERMES_DEVICE_CALLABLE T operator[](int i) const
Get i-th component.
Definition: vector.h:492
HERMES_DEVICE_CALLABLE Vector4()
Default constructor.
Definition: vector.h:431
HERMES_DEVICE_CALLABLE T length2() const
Computes vector squared magnitude.
Definition: vector.h:509
HERMES_DEVICE_CALLABLE T length() const
Computes vector magnitude.
Definition: vector.h:512
HERMES_DEVICE_CALLABLE Vector2< T > xy()
Gets first 2 components.
Definition: vector.h:500
T w
3-th component
Definition: vector.h:519
HERMES_DEVICE_CALLABLE Vector4(T _x, T _y, T _z, T _w)
Construct from component values.
Definition: vector.h:437
std::ostream & operator<<(std::ostream &o, const LaunchInfo &info)
LaunchInfo support for std::ostream << operator.
Definition: cuda_utils.h:234
Debug, logging and assertion macros.
#define HERMES_DEVICE_CALLABLE
Specifies that the function can be called from both host and device sides.
Definition: defs.h:45
#define HERMES_CHECK_EXP(expr)
Warns if expression is false.
Definition: debug.h:95
Set of multi-dimensional integer iterators.
#define ARITHMETIC_OP(OP)
asd
Definition: index.h:408
Numeric interval.
HERMES_DEVICE_CALLABLE Normal3< T > normalize(const Normal3< T > &normal)
Computes normalized copy.
Definition: normal.h:201
HERMES_DEVICE_CALLABLE Vector2< T > project(const Vector2< T > &v, const Normal2< T > &n)
projects v on the surface with normal n
Definition: normal.h:193
HERMES_DEVICE_CALLABLE T dot(const Normal3< T > &n, const Vector3< T > &v)
Computes dot product with vector.
Definition: normal.h:237
Number functions.
static constexpr HERMES_DEVICE_CALLABLE bool is_zero(T a)
Checks if number is 0.
Definition: numeric.h:834
static HERMES_DEVICE_CALLABLE std::enable_if_t< std::is_floating_point< T >::value, bool > is_nan(T v)
Checks if number representation is nan
Definition: numeric.h:884
static constexpr HERMES_DEVICE_CALLABLE bool is_equal(T a, T b)
Checks if two numbers are at most 1e-8 apart.
Definition: numeric.h:847
size_t operator()(hermes::Vector2< T > const &v) const
Computes hash for a given vector.
Definition: vector.h:750
size_t operator()(hermes::Vector3< T > const &v) const
Computes hash for a given vector.
Definition: vector.h:771
HERMES_DEVICE_CALLABLE T triple(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
Computes the triple product between 3 vectors.
Definition: vector.h:570
HERMES_DEVICE_CALLABLE Vector3< T > reject(const Vector3< T > &a, const Vector3< T > &b)
Rejects one vector on another.
Definition: vector.h:627
HERMES_DEVICE_CALLABLE T cross(const Vector2< T > &a, const Vector2< T > &b)
Computes the cross product between two vectors.
Definition: vector.h:550
HERMES_DEVICE_CALLABLE void tangential(const Vector3< T > &a, Vector3< T > &b, Vector3< T > &c)
compute the two orthogonal-tangential vectors from a
Definition: vector.h:635
HERMES_DEVICE_CALLABLE Vector2< T > orthonormal(const Vector2< T > &v, bool first=true)
Computes vector orthonormal to given vector.
Definition: vector.h:597