32 #ifndef HERMES_GEOMETRY_VECTOR_H
33 #define HERMES_GEOMETRY_VECTOR_H
41 #include <initializer_list>
48 template<
typename T>
class Point2;
55 static_assert(std::is_same<T, f32>::value || std::is_same<T, f64>::value ||
57 "Vector2 must hold an float type!");
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}; }
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; }
117 RELATIONAL_OP(<=, &&)
118 RELATIONAL_OP(>=, &&)
119 RELATIONAL_OP(!=, ||)
159 template<
typename T>
class Point3;
167 static_assert(std::is_same<T, f32>::value || std::is_same<T, f64>::value ||
169 "Vector3 must hold an float type!");
200 template<
typename S,
typename C = T>
202 typename std::enable_if_t<
205 x(vi.
x),
y(vi.
y),
z(vi.
z) {}
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}; }
247 return Vector3<T>(
x * inv,
y * inv,
z * inv);
270 return x >= b.x &&
y >= b.y &&
z >= b.z;
273 return x <= b.x &&
y <= b.y &&
z <= b.z;
307 template<
typename C = T>
309 && !std::is_same_v<C,
316 template<
typename C = T>
332 if (std::abs(
x) > std::abs(
y) && std::abs(
x) > std::abs(
z))
334 if (std::abs(
y) > std::abs(
x) && std::abs(
y) > std::abs(
z))
362 if (std::abs(
x) > std::abs(
y) && std::abs(
x) > std::abs(
z))
364 if (std::abs(
y) > std::abs(
x) && std::abs(
y) > std::abs(
z))
402 return *
this - (
dot(b, *
this) / b.
length2()) * b;
473 return Vector4<T>(
x + b.x,
y + b.y,
z + b.z,
w + b.w);
476 return Vector4<T>(
x - b.x,
y - b.y,
z - b.z,
w - b.w);
479 return Vector4<T>(
x * f,
y * f,
z * f,
w * f);
483 return Vector4<T>(
x * inv,
y * inv,
z * inv,
w * inv);
533 return a.
x * b.
x + a.
y * b.
y;
542 return a.
x * b.
x + a.
y * b.
y + a.
z * b.
z;
551 return a.
x * b.
y - a.
y * b.
x;
561 (a.
x * b.
y) - (a.
y * b.
x));
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)); }
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
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)
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)
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)
712 std::ostream &operator<<(std::ostream &os,
const Vector2<T> &v) {
713 os <<
"Vector2 [" << v.x <<
" " << v.y <<
"]";
717 std::ostream &
operator<<(std::ostream &os,
const Vector3<T> &v) {
718 os <<
"Vector3 [" << v.x <<
" " << v.y <<
" " << v.z <<
"]";
722 std::ostream &
operator<<(std::ostream &os,
const Vector4<T> &v) {
723 os <<
"Vector4 [" << v.x <<
" " << v.y <<
" " << v.z <<
" " << v.w <<
"]";
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>>;
746 template<
typename T>
struct hash<hermes::Vector2<T>> {
754 size_t h = hasher(v.
x);
755 h += 0x9e3779b9 + (s << 6) + (s >> 2);
759 h += 0x9e3779b9 + (s << 6) + (s >> 2);
767 template<
typename T>
struct hash<hermes::Vector3<T>> {
775 size_t h = hasher(v.
x);
776 h += 0x9e3779b9 + (s << 6) + (s >> 2);
780 h += 0x9e3779b9 + (s << 6) + (s >> 2);
784 h += 0x9e3779b9 + (s << 6) + (s >> 2);
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
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
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