Tatooine
axis_aligned_bounding_box.h
Go to the documentation of this file.
1#ifndef TATOOINE_AXIS_ALIGNED_BOUNDING_BOX_H
2#define TATOOINE_AXIS_ALIGNED_BOUNDING_BOX_H
3//==============================================================================
4#include <tatooine/concepts.h>
7#include <tatooine/tensor.h>
10
11#include <limits>
12#include <ostream>
13//==============================================================================
14namespace tatooine {
15//==============================================================================
16namespace detail {
17// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
18// template <typename AABB, typename Real, std::size_t NumDimensions>
19// struct aabb_ray_intersectable_parent {};
20template <typename AABB, typename Real, std::size_t NumDimensions>
21struct aabb_ray_intersectable_parent : ray_intersectable<Real, NumDimensions> {
25 using typename parent_type::ray_type;
26 //============================================================================
27 auto as_aabb() const -> auto const& {
28 return *dynamic_cast<AABB const*>(this);
29 }
30 //============================================================================
31 // ray_intersectable overrides
32 //============================================================================
33 auto check_intersection(ray_type const& r, Real const = 0) const
34 -> optional_intersection_type override {
35 auto const& aabb = as_aabb();
36 enum Quadrant { right, left, middle };
37 auto coord = vec<Real, NumDimensions>{};
38 auto inside = true;
39 auto quadrant = make_array<Quadrant, NumDimensions>();
40 auto which_plane = std::size_t(0);
41 auto max_t = make_array<Real, NumDimensions>();
42 auto candidate_plane = make_array<Real, NumDimensions>();
43
44 // Find candidate planes; this loop can be avoided if rays cast all from the
45 // eye(assume perpsective view)
46 for (std::size_t i = 0; i < NumDimensions; i++)
47 if (r.origin(i) < aabb.min(i)) {
48 quadrant[i] = left;
49 candidate_plane[i] = aabb.min(i);
50 inside = false;
51 } else if (r.origin(i) > aabb.max(i)) {
52 quadrant[i] = right;
53 candidate_plane[i] = aabb.max(i);
54 inside = false;
55 } else {
56 quadrant[i] = middle;
57 }
58
59 // Ray origin inside bounding box
60 if (inside) {
61 return intersection_type{this, r, Real(0), r.origin(),
63 }
64
65 // Calculate T distances to candidate planes
66 for (std::size_t i = 0; i < NumDimensions; i++)
67 if (quadrant[i] != middle && r.direction(i) != 0) {
68 max_t[i] = (candidate_plane[i] - r.origin(i)) / r.direction(i);
69 } else {
70 max_t[i] = -1;
71 }
72
73 // Get largest of the max_t's for final choice of intersection
74 which_plane = 0;
75 for (std::size_t i = 1; i < NumDimensions; i++)
76 if (max_t[which_plane] < max_t[i]) {
77 which_plane = i;
78 }
79
80 // Check final candidate actually inside box
81 if (max_t[which_plane] < 0) {
82 return {};
83 }
84 for (std::size_t i = 0; i < NumDimensions; i++)
85 if (which_plane != i) {
86 coord(i) = r.origin(i) + max_t[which_plane] * r.direction(i);
87 if (coord(i) < aabb.min(i) || coord(i) > aabb.max(i)) {
88 return {};
89 }
90 } else {
91 coord(i) = candidate_plane[i];
92 }
93 return intersection_type{this, r, max_t[which_plane], coord,
95 }
96};
97// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
98} // namespace detail
99// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
100template <typename Real, std::size_t NumDimensions>
103 axis_aligned_bounding_box<Real, NumDimensions>, Real, NumDimensions> {
104 static_assert(is_arithmetic<Real>);
105 //============================================================================
106 using real_type = Real;
110
111 static constexpr auto num_dimensions() -> std::size_t { return NumDimensions; }
112 static constexpr auto infinite() {
113 return this_type{pos_type::ones() * -std::numeric_limits<real_type>::max(),
114 pos_type::ones() * std::numeric_limits<real_type>::max()};
115 };
116 //============================================================================
117 private:
120 //============================================================================
121 public:
123 : m_min{pos_type::ones() * std::numeric_limits<real_type>::max()},
124 m_max{pos_type::ones() * -std::numeric_limits<real_type>::max()} {}
126 default;
128 axis_aligned_bounding_box&& other) noexcept = default;
129 constexpr auto operator=(axis_aligned_bounding_box const& other)
130 -> axis_aligned_bounding_box& = default;
131 constexpr auto operator=(axis_aligned_bounding_box&& other) noexcept
132 -> axis_aligned_bounding_box& = default;
134 //----------------------------------------------------------------------------
135 template <typename Real0, typename Real1>
138 : m_min{std::move(min)}, m_max{std::move(max)} {}
139 //----------------------------------------------------------------------------
140 template <typename Real0, typename Real1>
143 : m_min{min}, m_max{max} {}
144 //----------------------------------------------------------------------------
145 template <typename Tensor0, typename Tensor1, typename Real0, typename Real1>
149 : m_min{min}, m_max{max} {}
150 //============================================================================
151 auto constexpr min() const -> auto const& { return m_min; }
152 auto constexpr min() -> auto& { return m_min; }
153 auto constexpr min(std::size_t i) const -> auto const& { return m_min(i); }
154 auto constexpr min(std::size_t i) -> auto& { return m_min(i); }
155 //----------------------------------------------------------------------------
156 auto constexpr max() const -> auto const& { return m_max; }
157 auto constexpr max() -> auto& { return m_max; }
158 auto constexpr max(std::size_t i) const -> auto const& { return m_max(i); }
159 auto constexpr max(std::size_t i) -> auto& { return m_max(i); }
160 //----------------------------------------------------------------------------
161 auto constexpr extents() const { return m_max - m_min; }
162 auto constexpr extent(std::size_t i) const { return m_max(i) - m_min(i); }
163 //----------------------------------------------------------------------------
164 private:
165 template <std::size_t... Is>
166 auto constexpr area(std::index_sequence<Is...> /*seq*/) const {
167 auto const ext = extents();
168 return (ext(Is) * ...);
169 }
170 public:
171 auto constexpr area() const {
172 return area(std::make_index_sequence<NumDimensions>{});
173 }
174 //----------------------------------------------------------------------------
175 private:
176 template <std::size_t... Is>
177 auto constexpr volume(std::index_sequence<Is...> /*seq*/) const {
178 return (extent(Is) * ...);
179 }
180
181 public:
182 auto constexpr volume() const {
183 return volume(std::make_index_sequence<num_dimensions()>{});
184 }
185 //----------------------------------------------------------------------------
186 auto constexpr center() const { return (m_max + m_min) * Real(0.5); }
187 auto constexpr center(std::size_t const i) const {
188 return (m_max(i) + m_min(i)) * Real(0.5);
189 }
190 //----------------------------------------------------------------------------
191 auto constexpr is_inside(pos_type const& p) const {
192 for (std::size_t i = 0; i < NumDimensions; ++i) {
193 if (p(i) < m_min(i) || m_max(i) < p(i)) {
194 return false;
195 }
196 }
197 return true;
198 }
199 //----------------------------------------------------------------------------
205 vec<Real, 2> x2, vec<Real, 2> x3) const
206 requires(NumDimensions == 2) {
207 auto const c = center();
208 auto const e = extents() / 2;
209 x0 -= c;
210 x1 -= c;
211 x2 -= c;
212 x3 -= c;
213
214 // edges of rectangle
215 auto const f0 = x1 - x0; // normal of f1
216 auto const f1 = x3 - x0; // normal of f0
217
218 // normals of aabb
219 vec_type constexpr u0{1, 0};
220 vec_type constexpr u1{0, 1};
221
222 auto is_separating_axis = [&](auto const& axis) {
223 // Project all 4 vertices of the rectangle onto the seperating axis
224 auto const p0 = dot(x0, axis);
225 auto const p1 = dot(x1, axis);
226 auto const p2 = dot(x2, axis);
227 auto const p3 = dot(x3, axis);
228 // Project the AABB onto the seperating axis.
229 // We don't care about the end points of the projection just the length of
230 // the half-size of the aabb. That is, we're only casting the extents onto
231 // the seperating axis, not the aabb center. We don't need to cast the
232 // center, because we know that the aabb is at origin compared to the
233 // triangle!
234 auto r =
235 e.x() * std::abs(dot(u0, axis)) + e.y() * std::abs(dot(u1, axis));
236 return tatooine::max(-tatooine::max(p0, p1, p2, p3),
237 tatooine::min(p0, p1, p2, p3)) > r;
238 };
239 if (is_separating_axis(u0)) {
240 return false;
241 }
242 if (is_separating_axis(u1)) {
243 return false;
244 }
245 if (is_separating_axis(f0)) {
246 return false;
247 }
248 if (is_separating_axis(f1)) {
249 return false;
250 }
251 return true;
252 }
253 //----------------------------------------------------------------------------
254 constexpr auto is_simplex_inside(vec<Real, 2> const& x0,
255 vec<Real, 2> const& x1,
256 vec<Real, 2> const& x2) const
257 requires(NumDimensions == 2) {
258 auto const c = center();
259 auto const e = extents();
260 auto const x0_centered = x0 - c;
261 auto const x1_centered = x1 - c;
262 auto const x2_centered = x2 - c;
263 constexpr auto u0 = vec_type {1, 0};
264 constexpr auto u1 = vec_type {0, 1};
265 auto is_separating_axis = [&](auto const& axis) {
266 // Project all 4 vertices of the rectangle onto the seperating axis
267 auto const p0 = dot(x0_centered, axis);
268 auto const p1 = dot(x1_centered, axis);
269 auto const p2 = dot(x2_centered, axis);
270 // Project the AABB onto the seperating axis.
271 // We don't care about the end points of the projection just the length of
272 // the half-size of the aabb. That is, we're only casting the extents onto
273 // the seperating axis, not the aabb center. We don't need to cast the
274 // center, because we know that the aabb is at origin compared to the
275 // triangle!
276 auto const r =
277 e.x() * std::abs(dot(u0, axis)) + e.y() * std::abs(dot(u1, axis));
278 auto const m =
279 tatooine::max(-tatooine::max(p0, p1, p2), tatooine::min(p0, p1, p2));
280 return m > r;
281 };
282 if (is_separating_axis(u0)) {
283 return false;
284 }
285 if (is_separating_axis(u1)) {
286 return false;
287 }
288 if (is_separating_axis(vec_type{x0_centered(1) - x1_centered(1), x1_centered(0) - x0_centered(0)})) {
289 return false;
290 }
291 if (is_separating_axis(vec_type{x1_centered(1) - x2_centered(1), x2_centered(0) - x1_centered(0)})) {
292 return false;
293 }
294 if (is_separating_axis(vec_type{x2_centered(1) - x0_centered(1), x0_centered(0) - x2_centered(0)})) {
295 return false;
296 }
297 return true;
298 }
299 //----------------------------------------------------------------------------
303 vec<Real, 3> x2) const
304 requires(NumDimensions == 3) {
305 auto const c = center();
306 auto const e = extents() / 2;
307
308 x0 -= c;
309 x1 -= c;
310 x2 -= c;
311
312 auto const f0 = x1 - x0;
313 auto const f1 = x2 - x1;
314 auto const f2 = x0 - x2;
315
316 vec_type constexpr u0{1, 0, 0};
317 vec_type constexpr u1{0, 1, 0};
318 vec_type constexpr u2{0, 0, 1};
319
320 auto is_separating_axis = [&](auto const& axis) {
321 auto const p0 = dot(x0, axis);
322 auto const p1 = dot(x1, axis);
323 auto const p2 = dot(x2, axis);
324 auto r = e.x() * std::abs(dot(u0, axis)) +
325 e.y() * std::abs(dot(u1, axis)) +
326 e.z() * std::abs(dot(u2, axis));
327 return tatooine::max(-tatooine::max(p0, p1, p2),
328 tatooine::min(p0, p1, p2)) > r;
329 };
330
331 if (is_separating_axis(cross(u0, f0))) {
332 return false;
333 }
334 if (is_separating_axis(cross(u0, f1))) {
335 return false;
336 }
337 if (is_separating_axis(cross(u0, f2))) {
338 return false;
339 }
340 if (is_separating_axis(cross(u1, f0))) {
341 return false;
342 }
343 if (is_separating_axis(cross(u1, f1))) {
344 return false;
345 }
346 if (is_separating_axis(cross(u1, f2))) {
347 return false;
348 }
349 if (is_separating_axis(cross(u2, f0))) {
350 return false;
351 }
352 if (is_separating_axis(cross(u2, f1))) {
353 return false;
354 }
355 if (is_separating_axis(cross(u2, f2))) {
356 return false;
357 }
358 if (is_separating_axis(u0)) {
359 return false;
360 }
361 if (is_separating_axis(u1)) {
362 return false;
363 }
364 if (is_separating_axis(u2)) {
365 return false;
366 }
367 if (is_separating_axis(cross(f0, f1))) {
368 return false;
369 }
370 return true;
371 }
372 //----------------------------------------------------------------------------
374 vec<Real, 3> x2, vec<Real, 3> x3) const
375 requires(NumDimensions == 3) {
376 auto const c = center();
377 auto const e = extents() / 2;
378
379 x0 -= c;
380 x1 -= c;
381 x2 -= c;
382 x3 -= c;
383
384 auto const f0 = x1 - x0;
385 auto const f1 = x2 - x1;
386 auto const f2 = x0 - x2;
387 auto const f3 = x3 - x1;
388 auto const f4 = x2 - x3;
389 auto const f5 = x3 - x0;
390
391 vec_type constexpr u0{1, 0, 0};
392 vec_type constexpr u1{0, 1, 0};
393 vec_type constexpr u2{0, 0, 1};
394
395 auto is_separating_axis = [&](auto const axis) {
396 auto const p0 = dot(x0, axis);
397 auto const p1 = dot(x1, axis);
398 auto const p2 = dot(x2, axis);
399 auto const p3 = dot(x3, axis);
400 auto r = e.x() * std::abs(dot(u0, axis)) +
401 e.y() * std::abs(dot(u1, axis)) +
402 e.z() * std::abs(dot(u2, axis));
403 return tatooine::max(-tatooine::max(p0, p1, p2, p3),
404 tatooine::min(p0, p1, p2, p3)) > r;
405 };
406
407 if (is_separating_axis(cross(u0, f0))) {
408 return false;
409 }
410 if (is_separating_axis(cross(u0, f1))) {
411 return false;
412 }
413 if (is_separating_axis(cross(u0, f2))) {
414 return false;
415 }
416 if (is_separating_axis(cross(u0, f3))) {
417 return false;
418 }
419 if (is_separating_axis(cross(u0, f4))) {
420 return false;
421 }
422 if (is_separating_axis(cross(u0, f5))) {
423 return false;
424 }
425 if (is_separating_axis(cross(u1, f0))) {
426 return false;
427 }
428 if (is_separating_axis(cross(u1, f1))) {
429 return false;
430 }
431 if (is_separating_axis(cross(u1, f2))) {
432 return false;
433 }
434 if (is_separating_axis(cross(u1, f3))) {
435 return false;
436 }
437 if (is_separating_axis(cross(u1, f4))) {
438 return false;
439 }
440 if (is_separating_axis(cross(u1, f5))) {
441 return false;
442 }
443 if (is_separating_axis(cross(u2, f0))) {
444 return false;
445 }
446 if (is_separating_axis(cross(u2, f1))) {
447 return false;
448 }
449 if (is_separating_axis(cross(u2, f2))) {
450 return false;
451 }
452 if (is_separating_axis(cross(u2, f3))) {
453 return false;
454 }
455 if (is_separating_axis(cross(u2, f4))) {
456 return false;
457 }
458 if (is_separating_axis(cross(u2, f5))) {
459 return false;
460 }
461 if (is_separating_axis(u0)) {
462 return false;
463 }
464 if (is_separating_axis(u1)) {
465 return false;
466 }
467 if (is_separating_axis(u2)) {
468 return false;
469 }
470 if (is_separating_axis(cross(f0, f1))) {
471 return false;
472 }
473 if (is_separating_axis(cross(f3, f4))) {
474 return false;
475 }
476 if (is_separating_axis(cross(-f0, f5))) {
477 return false;
478 }
479 if (is_separating_axis(cross(f5, -f2))) {
480 return false;
481 }
482 return true;
483 }
484 //----------------------------------------------------------------------------
485 constexpr auto operator+=(pos_type const& point) {
486 for (std::size_t i = 0; i < point.num_components(); ++i) {
487 m_min(i) = std::min(m_min(i), point(i));
488 m_max(i) = std::max(m_max(i), point(i));
489 }
490 }
491 //----------------------------------------------------------------------------
492 constexpr auto reset() {
493 for (std::size_t i = 0; i < NumDimensions; ++i) {
494 m_min(i) = std::numeric_limits<Real>::max();
495 m_max(i) = -std::numeric_limits<Real>::max();
496 }
497 }
498 //----------------------------------------------------------------------------
499 [[nodiscard]] constexpr auto add_dimension(Real const min,
500 Real const max) const {
502 for (std::size_t i = 0; i < NumDimensions; ++i) {
503 addeddim.m_min(i) = m_min(i);
504 addeddim.m_max(i) = m_max(i);
505 }
506 addeddim.m_min(NumDimensions) = min;
507 addeddim.m_max(NumDimensions) = max;
508 return addeddim;
509 }
510 //----------------------------------------------------------------------------
511 template <typename RandomEngine = std::mt19937_64>
512 auto random_point(RandomEngine&& random_engine = RandomEngine{
513 std::random_device{}()}) const {
514 pos_type p;
515 for (std::size_t i = 0; i < NumDimensions; ++i) {
516 std::uniform_real_distribution<Real> distribution{m_min(i), m_max(i)};
517 p(i) = distribution(random_engine);
518 }
519 return p;
520 }
521 //----------------------------------------------------------------------------
522 auto write_vtk(filesystem::path const& path) {
524 f.write_header();
525 std::vector<vec<real_type, 3>> positions;
526 std::vector<std::vector<std::size_t>> indices;
527
528 positions.push_back(vec{min(0), min(1), min(2)});
529 positions.push_back(vec{max(0), min(1), min(2)});
530 positions.push_back(vec{max(0), max(1), min(2)});
531 positions.push_back(vec{min(0), max(1), min(2)});
532 positions.push_back(vec{min(0), min(1), max(2)});
533 positions.push_back(vec{max(0), min(1), max(2)});
534 positions.push_back(vec{max(0), max(1), max(2)});
535 positions.push_back(vec{min(0), max(1), max(2)});
536 indices.push_back({0, 1, 2, 3, 0});
537 indices.push_back({4, 5, 6, 7, 4});
538 indices.push_back({0, 4});
539 indices.push_back({1, 5});
540 indices.push_back({2, 6});
541 indices.push_back({3, 7});
542 f.write_points(positions);
543 f.write_lines(indices);
544 }
545};
546template <std::size_t NumDimensions>
548template <typename Real>
550template <typename Real>
552template <typename Real, std::size_t NumDimensions>
554
558
562//==============================================================================
563// deduction guides
564//==============================================================================
565template <typename Real0, typename Real1, std::size_t NumDimensions>
569//------------------------------------------------------------------------------
570template <typename Real0, typename Real1, std::size_t NumDimensions>
574//------------------------------------------------------------------------------
575template <typename Tensor0, typename Tensor1, typename Real0, typename Real1,
576 std::size_t NumDimensions>
580
581//==============================================================================
582// ostream output
583//==============================================================================
584template <typename Real, std::size_t NumDimensions>
585auto operator<<(std::ostream& out,
587 -> std::ostream& {
588 out << std::scientific;
589 for (std::size_t i = 0; i < NumDimensions; ++i) {
590 out << "[ ";
591 if (bb.min(i) >= 0) {
592 out << ' ';
593 }
594 out << bb.min(i) << " .. ";
595 if (bb.max(i) >= 0) {
596 out << ' ';
597 }
598 out << bb.max(i) << " ]\n";
599 }
600 out << std::defaultfloat;
601 return out;
602}
603//==============================================================================
604} // namespace tatooine
605//==============================================================================
606#endif
Definition: vtk_legacy.h:448
Definition: vtp_writer.h:3
Definition: algorithm.h:6
auto operator<<(std::ostream &out, linspace< Real > const &l) -> auto &
Definition: linspace.h:165
auto is_separating_axis(vec< Real, 2 > const &n, std::vector< vec< Real, 2 > > const &polygon0, std::vector< vec< Real, 2 > > const &polygon1)
Return true if n is a separating axis of polygon0 and polygon1.
Definition: separating_axis_theorem.h:12
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
constexpr auto dot(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: tensor_operations.h:120
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
constexpr auto cross(base_tensor< Tensor0, T0, 3 > const &lhs, base_tensor< Tensor1, T1, 3 > const &rhs)
Definition: cross.h:9
Definition: axis_aligned_bounding_box.h:103
auto constexpr min(std::size_t i) const -> auto const &
Definition: axis_aligned_bounding_box.h:153
vec< Real, NumDimensions > vec_type
Definition: axis_aligned_bounding_box.h:108
auto constexpr is_inside(pos_type const &p) const
Definition: axis_aligned_bounding_box.h:191
auto constexpr max() -> auto &
Definition: axis_aligned_bounding_box.h:157
constexpr axis_aligned_bounding_box()
Definition: axis_aligned_bounding_box.h:122
pos_type m_min
Definition: axis_aligned_bounding_box.h:118
auto constexpr max() const -> auto const &
Definition: axis_aligned_bounding_box.h:156
constexpr auto operator=(axis_aligned_bounding_box const &other) -> axis_aligned_bounding_box &=default
auto constexpr volume() const
Definition: axis_aligned_bounding_box.h:182
auto constexpr center() const
Definition: axis_aligned_bounding_box.h:186
auto constexpr area(std::index_sequence< Is... >) const
Definition: axis_aligned_bounding_box.h:166
auto constexpr center(std::size_t const i) const
Definition: axis_aligned_bounding_box.h:187
constexpr auto is_simplex_inside(vec< Real, 3 > x0, vec< Real, 3 > x1, vec< Real, 3 > x2, vec< Real, 3 > x3) const
Definition: axis_aligned_bounding_box.h:373
constexpr axis_aligned_bounding_box(vec< Real0, NumDimensions > &&min, vec< Real1, NumDimensions > &&max) noexcept
Definition: axis_aligned_bounding_box.h:136
auto constexpr max(std::size_t i) const -> auto const &
Definition: axis_aligned_bounding_box.h:158
auto constexpr min() const -> auto const &
Definition: axis_aligned_bounding_box.h:151
constexpr auto reset()
Definition: axis_aligned_bounding_box.h:492
constexpr auto add_dimension(Real const min, Real const max) const
Definition: axis_aligned_bounding_box.h:499
pos_type m_max
Definition: axis_aligned_bounding_box.h:119
constexpr axis_aligned_bounding_box(vec< Real0, NumDimensions > const &min, vec< Real1, NumDimensions > const &max)
Definition: axis_aligned_bounding_box.h:141
constexpr axis_aligned_bounding_box(axis_aligned_bounding_box &&other) noexcept=default
auto write_vtk(filesystem::path const &path)
Definition: axis_aligned_bounding_box.h:522
static constexpr auto num_dimensions() -> std::size_t
Definition: axis_aligned_bounding_box.h:111
constexpr axis_aligned_bounding_box(axis_aligned_bounding_box const &other)=default
auto constexpr volume(std::index_sequence< Is... >) const
Definition: axis_aligned_bounding_box.h:177
vec_type pos_type
Definition: axis_aligned_bounding_box.h:109
auto constexpr min(std::size_t i) -> auto &
Definition: axis_aligned_bounding_box.h:154
constexpr auto is_rectangle_inside(vec< Real, 2 > x0, vec< Real, 2 > x1, vec< Real, 2 > x2, vec< Real, 2 > x3) const
Definition: axis_aligned_bounding_box.h:204
constexpr auto operator+=(pos_type const &point)
Definition: axis_aligned_bounding_box.h:485
auto constexpr extent(std::size_t i) const
Definition: axis_aligned_bounding_box.h:162
static constexpr auto infinite()
Definition: axis_aligned_bounding_box.h:112
constexpr auto is_simplex_inside(vec< Real, 2 > const &x0, vec< Real, 2 > const &x1, vec< Real, 2 > const &x2) const
Definition: axis_aligned_bounding_box.h:254
auto constexpr min() -> auto &
Definition: axis_aligned_bounding_box.h:152
auto random_point(RandomEngine &&random_engine=RandomEngine{ std::random_device{}()}) const
Definition: axis_aligned_bounding_box.h:512
constexpr axis_aligned_bounding_box(base_tensor< Tensor0, Real0, NumDimensions > const &min, base_tensor< Tensor1, Real1, NumDimensions > const &max)
Definition: axis_aligned_bounding_box.h:146
auto constexpr max(std::size_t i) -> auto &
Definition: axis_aligned_bounding_box.h:159
constexpr auto is_simplex_inside(vec< Real, 3 > x0, vec< Real, 3 > x1, vec< Real, 3 > x2) const
Definition: axis_aligned_bounding_box.h:302
auto constexpr area() const
Definition: axis_aligned_bounding_box.h:171
auto constexpr extents() const
Definition: axis_aligned_bounding_box.h:161
constexpr auto operator=(axis_aligned_bounding_box &&other) noexcept -> axis_aligned_bounding_box &=default
Real real_type
Definition: axis_aligned_bounding_box.h:106
Definition: base_tensor.h:23
Definition: axis_aligned_bounding_box.h:21
auto check_intersection(ray_type const &r, Real const =0) const -> optional_intersection_type override
Definition: axis_aligned_bounding_box.h:33
auto as_aabb() const -> auto const &
Definition: axis_aligned_bounding_box.h:27
std::optional< intersection_type > optional_intersection_type
Definition: ray_intersectable.h:14
Definition: intersection.h:13
Definition: ray_intersectable.h:10
ray< real_type, NumDimensions > ray_type
Definition: ray_intersectable.h:15
std::optional< intersection_type > optional_intersection_type
Definition: ray_intersectable.h:14
intersection< real_type, NumDimensions > intersection_type
Definition: ray_intersectable.h:13
Definition: ray.h:10
auto direction() -> auto &
Definition: ray.h:54
auto origin() -> auto &
Definition: ray.h:41
static auto constexpr num_components()
Definition: base_tensor.h:43
Definition: vec.h:12
static auto constexpr ones()
Definition: vec.h:28
static auto constexpr zeros()
Definition: vec.h:26