Hermes
point.h
Go to the documentation of this file.
1 
32 #ifndef HERMES_GEOMETRY_POINT_H
33 #define HERMES_GEOMETRY_POINT_H
34 
35 #include <initializer_list>
36 
37 #include <hermes/geometry/vector.h>
38 #include <hermes/common/debug.h>
41 
42 namespace hermes {
43 
44 // *********************************************************************************************************************
45 // Point2
46 // *********************************************************************************************************************
49 template<typename T> class Point2 : public MathElement<T, 2u> {
50  static_assert(std::is_same<T, f32>::value || std::is_same<T, f64>::value ||
51  std::is_same<T, Interval<f32>>::value || std::is_same<T, Interval<f64>>::value,
52  "Point2 must hold a float type!");
53 public:
54  // *******************************************************************************************************************
55  // CONSTRUCTORS
56  // *******************************************************************************************************************
59  HERMES_DEVICE_CALLABLE explicit Point2(T f = T(0)) { x = y = f; }
62  HERMES_DEVICE_CALLABLE explicit Point2(const real_t *v) : x(v[0]), y(v[1]) {}
66  HERMES_DEVICE_CALLABLE Point2(real_t _x, real_t _y) : x(_x), y(_y) {}
70  template<typename U>
71  HERMES_DEVICE_CALLABLE Point2(const Index2<U> &index) : x{static_cast<T>(index.i)}, y{static_cast<T>(index.j)} {}
72  // *******************************************************************************************************************
73  // OPERATORS
74  // *******************************************************************************************************************
75  // casting
79  template<typename U>
80  HERMES_DEVICE_CALLABLE operator Index2<U>() const {
81  return Index2<U>(x, y);
82  }
83  // assignment
88  template<typename U>
90  x = index.i;
91  y = index.j;
92  return *this;
93  }
94  // access
99  HERMES_DEVICE_CALLABLE const T &operator[](int i) const { return (&x)[i]; }
104  HERMES_DEVICE_CALLABLE T &operator[](int i) { return (&x)[i]; }
105  // arithmetic
106 #define ARITHMETIC_OP(OP) \
107  HERMES_DEVICE_CALLABLE Point2 &operator OP##= (const Vector2 <T> &v) { \
108  x OP##= v.x; y OP##= v.y; return *this; } \
109  HERMES_DEVICE_CALLABLE Point2 &operator OP##= (real_t f) { \
110  x OP##= f; y OP##= f; return *this; } \
111  HERMES_DEVICE_CALLABLE Point2 operator OP (const Vector2 <T> &v) const { \
112  return {x OP v.x, y OP v.y}; } \
113  HERMES_DEVICE_CALLABLE Point2 operator OP (real_t f) const { \
114  return {x OP f, y OP f}; }
115  ARITHMETIC_OP(+)
116  ARITHMETIC_OP(-)
117  ARITHMETIC_OP(/)
118  ARITHMETIC_OP(*)
119 #undef ARITHMETIC_OP
120  HERMES_DEVICE_CALLABLE Vector2<T> operator-(const Point2<T> &b) const {
121  return Vector2<T>(x - b.x, y - b.y);
122  }
123  // relational
124 #define RELATIONAL_OP(OP, CO) \
125  HERMES_DEVICE_CALLABLE bool operator OP (const Point2<T> &b) const { \
126  return x OP b.x CO y OP b.y; }
127  RELATIONAL_OP(<, &&)
128  RELATIONAL_OP(>, &&)
129  RELATIONAL_OP(<=, &&)
130  RELATIONAL_OP(>=, &&)
131  RELATIONAL_OP(!=, ||)
132 #undef RELATIONAL_OP
133  HERMES_DEVICE_CALLABLE bool operator==(const Point2<T> &b) const {
134  return Check::is_equal(x, b.x) && Check::is_equal(y, b.y);
135  }
136  // *******************************************************************************************************************
137  // PUBLIC FIELDS
138  // *******************************************************************************************************************
139  T x = T(0.0);
140  T y = T(0.0);
141 };
142 
143 // *********************************************************************************************************************
144 // Point3
145 // *********************************************************************************************************************
148 template<typename T> class Point3 : public MathElement<T, 3u> {
149  static_assert(std::is_same<T, f32>::value || std::is_same<T, f64>::value ||
150  std::is_same<T, Interval<f32>>::value || std::is_same<T, Interval<f64>>::value,
151  "Size2 must hold an float type!");
152 public:
153  // *******************************************************************************************************************
154  // CONSTRUCTORS
155  // *******************************************************************************************************************
157  HERMES_DEVICE_CALLABLE Point3() : x{0}, y{0}, z{0} {}
160  HERMES_DEVICE_CALLABLE explicit Point3(T v) { x = y = z = v; }
165  HERMES_DEVICE_CALLABLE Point3(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {}
168  HERMES_DEVICE_CALLABLE explicit Point3(const Point2<T> &p, T _z = 0) : x(p.x), y(p.y), z(_z) {}
171  HERMES_DEVICE_CALLABLE explicit Point3(const real_t *v) : x(v[0]), y(v[1]), z(v[2]) {}
177  template<typename S, typename C = T>
178  HERMES_DEVICE_CALLABLE explicit Point3(const Point3<S> &c, const Vector3<S> &r,
179  typename std::enable_if_t<
180  std::is_same_v<C, Interval<f32>>
181  || std::is_same_v<C, Interval<f64>>> * = nullptr)
182  : x(Interval<S>::withRadius(c.x, r.x)),
183  y(Interval<S>::withRadius(c.y, r.y)), z(Interval<S>::withRadius(c.z, r.z)) {}
184  // conversion
187  HERMES_DEVICE_CALLABLE explicit Point3(const Vector3<T> &v) : x(v.x), y(v.y), z(v.z) {}
192  template<typename S, typename C = T>
194  typename std::enable_if_t<
195  !std::is_same_v<C, Interval<f32>>
196  && !std::is_same_v<C, Interval<f64>>> * = nullptr) :
197  x(vi.x), y(vi.y), z(vi.z) {}
201  template<typename U>
202  HERMES_DEVICE_CALLABLE Point3(const Index3<U> &index) : x{static_cast<T>(index.i)}, y{static_cast<T>(index.j)},
203  z{static_cast<T>(index.k)} {}
204  // *******************************************************************************************************************
205  // OPERATORS
206  // *******************************************************************************************************************
207  // casting
210  HERMES_DEVICE_CALLABLE explicit operator Vector3<T>() const { return Vector3<T>(x, y, z); }
211  // access
216  HERMES_DEVICE_CALLABLE T operator[](int i) const { return (&x)[i]; }
221  HERMES_DEVICE_CALLABLE T &operator[](int i) { return (&x)[i]; }
222  // arithmetic
223 #define ARITHMETIC_OP(OP) \
224  HERMES_DEVICE_CALLABLE Point3 &operator OP##= (const Vector3 <T> &v) { \
225  x OP##= v.x; y OP##= v.y; z OP##= v.z; return *this; } \
226  HERMES_DEVICE_CALLABLE Point3 &operator OP##= (real_t f) { \
227  x OP##= f; y OP##= f; z OP##= f; return *this; } \
228  HERMES_DEVICE_CALLABLE Point3 operator OP (const Vector3 <T> &v) const { \
229  return {x OP v.x, y OP v.y, z OP v.z}; } \
230  HERMES_DEVICE_CALLABLE Point3 operator OP (T f) const { \
231  return {x OP f, y OP f, z OP f}; }
232  ARITHMETIC_OP(+)
233  ARITHMETIC_OP(-)
234  ARITHMETIC_OP(/)
235  ARITHMETIC_OP(*)
236 #undef ARITHMETIC_OP
237  HERMES_DEVICE_CALLABLE Vector3<T> operator-(const Point3<T> &b) const {
238  return Vector3<T>(x - b.x, y - b.y, z - b.z);
239  }
240  // relational
241 #define RELATIONAL_OP(OP, CO) \
242  HERMES_DEVICE_CALLABLE bool operator OP (const Point3<T> &b) const { \
243  return x OP b.x CO y OP b.y CO z OP b.z; }
244  RELATIONAL_OP(<, &&)
245  RELATIONAL_OP(>, &&)
246  RELATIONAL_OP(<=, &&)
247  RELATIONAL_OP(>=, &&)
248  RELATIONAL_OP(!=, ||)
249 #undef RELATIONAL_OP
250  HERMES_DEVICE_CALLABLE bool operator==(const Point3<T> &b) const {
251  return Check::is_equal(x, b.x) && Check::is_equal(y, b.y) &&
252  Check::is_equal(z, b.z);
253  }
254  // *******************************************************************************************************************
255  // METHODS
256  // *******************************************************************************************************************
257  // access
267  // *******************************************************************************************************************
268  // PUBLIC FIELDS
269  // *******************************************************************************************************************
270  T x = T(0.0);
271  T y = T(0.0);
272  T z = T(0.0);
273 };
274 
275 // *********************************************************************************************************************
276 // EXTERNAL FUNCTIONS
277 // *********************************************************************************************************************
278 // arithmetic
284 template<typename T>
286  return Point2<T>(a.x * f, a.y * f);
287 }
288 // geometry
294 template<typename T>
296  return (a - b).length();
297 }
303 template<typename T>
305  return (a - b).length2();
306 }
312 template<typename T>
314  return (a - b).length();
315 }
321 template<typename T>
323  return (a - b).length2();
324 }
325 // numbers
326 #define MATH_OP(NAME, OP) \
327  template<typename T> \
328  HERMES_DEVICE_CALLABLE Point2<T> NAME(const Point2<T>& p) { \
329  return Point2<T>(OP(p.x), OP(p.y)); }
330 #ifdef HERMES_DEVICE_ENABLED
331 MATH_OP(floor, ::floor)
332 MATH_OP(ceil, ::ceil)
333 MATH_OP(abs, ::abs)
334 #else
335 MATH_OP(floor, std::floor)
336 MATH_OP(ceil, std::ceil)
337 MATH_OP(abs, std::abs)
338 #endif
339 #undef MATH_OP
340 
341 // *********************************************************************************************************************
342 // IO
343 // *********************************************************************************************************************
344 template<typename T>
345 std::ostream &operator<<(std::ostream &os, const Point2<T> &p) {
346  os << "Point2[" << p.x << " " << p.y << "]";
347  return os;
348 }
349 template<typename T>
350 std::ostream &operator<<(std::ostream &os, const Point3<T> &p) {
351  os << "Point3[" << p.x << " " << p.y << " " << p.z << "]";
352  return os;
353 }
354 
355 // *********************************************************************************************************************
356 // TYPEDEFS
357 // *********************************************************************************************************************
358 using point2 = Point2<real_t>;
359 using point2f = Point2<float>;
360 using point2d = Point2<double>;
361 using point3 = Point3<real_t>;
362 using point3f = Point3<float>;
363 using point3d = Point3<double>;
364 using point2i = Point2<Interval<real_t>>;
365 using point3i = Point3<Interval<real_t>>;
366 
367 } // namespace hermes
368 
369 // std hash support
370 namespace std {
371 
374 template<typename T> struct hash<hermes::Point2<T>> {
378  size_t operator()(hermes::Point2<T> const &v) const {
379  hash<T> hasher;
380  size_t s = 0;
381  // inject x component
382  size_t h = hasher(v.x);
383  h += 0x9e3779b9 + (s << 6) + (s >> 2);
384  s ^= h;
385  // inject y component
386  h = hasher(v.y);
387  h += 0x9e3779b9 + (s << 6) + (s >> 2);
388  s ^= h;
389  return s;
390  }
391 };
392 
395 template<typename T> struct hash<hermes::Point3<T>> {
399  size_t operator()(hermes::Point3<T> const &v) const {
400  hash<T> hasher;
401  size_t s = 0;
402  // inject x component
403  size_t h = hasher(v.x);
404  h += 0x9e3779b9 + (s << 6) + (s >> 2);
405  s ^= h;
406  // inject y component
407  h = hasher(v.y);
408  h += 0x9e3779b9 + (s << 6) + (s >> 2);
409  s ^= h;
410  // inject y component
411  h = hasher(v.z);
412  h += 0x9e3779b9 + (s << 6) + (s >> 2);
413  s ^= h;
414  return s;
415  }
416 };
417 
418 } // namespace std
419 
420 #endif
421 
Interface used by all basic geometric entities.
Definition: math_element.h:44
Geometric 2-dimensional point (x, y)
Definition: point.h:49
HERMES_DEVICE_CALLABLE Point2(T f=T(0))
Constructs from single component value.
Definition: point.h:59
HERMES_DEVICE_CALLABLE Point2(const real_t *v)
Constructs from component array.
Definition: point.h:62
T y
1-th component
Definition: point.h:140
HERMES_DEVICE_CALLABLE Point2 & operator=(const Index2< U > &index)
Copy assigns from index 2.
Definition: point.h:89
HERMES_DEVICE_CALLABLE Point2(real_t _x, real_t _y)
Constructs from component values.
Definition: point.h:66
HERMES_DEVICE_CALLABLE T & operator[](int i)
Get i-th component reference.
Definition: point.h:104
HERMES_DEVICE_CALLABLE const T & operator[](int i) const
Get i-th component.
Definition: point.h:99
HERMES_DEVICE_CALLABLE Point2(const Index2< U > &index)
Constructs from index2.
Definition: point.h:71
T x
0-th component
Definition: point.h:139
Geometric 3-dimensional vector (x, y, z)
Definition: point.h:148
HERMES_DEVICE_CALLABLE T operator[](int i) const
Get i-th component.
Definition: point.h:216
HERMES_DEVICE_CALLABLE Point3()
Default constructor.
Definition: point.h:157
T x
0-th component
Definition: point.h:270
HERMES_DEVICE_CALLABLE Point3(T v)
Constructs from single component value.
Definition: point.h:160
HERMES_DEVICE_CALLABLE Point2< T > xz() const
Gets 2-dimensional swizzle (x, z)
Definition: point.h:266
HERMES_DEVICE_CALLABLE T & operator[](int i)
Get i-th component reference.
Definition: point.h:221
HERMES_DEVICE_CALLABLE Point3(const Point3< S > &c, const Vector3< S > &r, typename std::enable_if_t< std::is_same_v< C, Interval< f32 >>||std::is_same_v< C, Interval< f64 >>> *=nullptr)
Constructs from interval center and radius.
Definition: point.h:178
HERMES_DEVICE_CALLABLE Point2< T > xy() const
Gets 2-dimensional swizzle (x, y)
Definition: point.h:260
HERMES_DEVICE_CALLABLE Point2< T > yz() const
Gets 2-dimensional swizzle (y, z)
Definition: point.h:263
T y
1-th component
Definition: point.h:271
HERMES_DEVICE_CALLABLE Point3(const Index3< U > &index)
Constructs from index3.
Definition: point.h:202
HERMES_DEVICE_CALLABLE Point3(const Point3< 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 point3.
Definition: point.h:193
HERMES_DEVICE_CALLABLE Point3(const real_t *v)
Constructs from component array.
Definition: point.h:171
HERMES_DEVICE_CALLABLE Point3(const Vector3< T > &v)
Constructs from vector.
Definition: point.h:187
HERMES_DEVICE_CALLABLE Point3(T _x, T _y, T _z)
Constructs from component values.
Definition: point.h:165
HERMES_DEVICE_CALLABLE Point3(const Point2< T > &p, T _z=0)
Constructs from point2.
Definition: point.h:168
T z
2-th component
Definition: point.h:272
Geometric 2-dimensional vector (x, y)
Definition: vector.h:54
Geometric 3-dimensional vector (x, y, z)
Definition: vector.h:166
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.
float real_t
default floating point type
Definition: defs.h:75
#define HERMES_DEVICE_CALLABLE
Specifies that the function can be called from both host and device sides.
Definition: defs.h:45
#define ARITHMETIC_OP(OP)
asd
Definition: index.h:408
Numeric interval.
HERMES_DEVICE_CALLABLE real_t distance2(const Point2< T > &a, const Point2< T > &b)
Computes the squared Euclidean distance between two points.
Definition: point.h:304
HERMES_DEVICE_CALLABLE real_t distance(const Point2< T > &a, const Point2< T > &b)
Computes the Euclidean distance between two points.
Definition: point.h:295
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
Holds 2-dimensional integer index coordinates.
Definition: index.h:50
T i
0-th coordinate value
Definition: index.h:199
T j
1-th coordinate value
Definition: index.h:201
Holds 3-dimensional index coordinates.
Definition: index.h:362
size_t operator()(hermes::Point2< T > const &v) const
Computes hash for a given vector.
Definition: point.h:378
size_t operator()(hermes::Point3< T > const &v) const
Computes hash for a given vector.
Definition: point.h:399
Geometric vector classes.