Line data Source code
1 :
2 : #include "doctest/doctest.h"
3 :
4 : #include "SliceTraversal.h"
5 : #include "Intersection.h"
6 :
7 : #include <deque>
8 :
9 : using namespace elsa;
10 : using namespace doctest;
11 :
12 : #include "PrettyPrint/Eigen.h"
13 : #include "PrettyPrint/Stl.h"
14 :
15 : TEST_SUITE_BEGIN("projectors");
16 :
17 : Eigen::IOFormat vecfmt(10, 0, ", ", ", ", "", "", "[", "]");
18 : Eigen::IOFormat matfmt(10, 0, ", ", "\n", "\t\t[", "]");
19 :
20 : void checkTransformation(const RealRay_t& ray, const RealVector_t& centerOfRotation,
21 : RealVector_t expectedro, RealVector_t expectedrd,
22 : RealMatrix_t expectedRotation)
23 96 : {
24 96 : TransformToTraversal transformation(ray, centerOfRotation);
25 :
26 96 : const RealVector_t ro = ray.origin();
27 96 : const RealVector_t rd = ray.direction();
28 :
29 96 : THEN("The rotation matrix is the same as the linear part of the transformation")
30 96 : {
31 24 : CHECK_EQ(transformation.rotation(), transformation.linear());
32 24 : }
33 :
34 96 : THEN("The rotation part of the transformation matrix is correct")
35 96 : {
36 24 : const RealMatrix_t matrix = transformation.rotation();
37 :
38 24 : INFO("R :=\n", matrix.format(matfmt));
39 24 : INFO("Expected R :=\n", expectedRotation.format(matfmt));
40 :
41 24 : CHECK_UNARY(matrix.isApprox(expectedRotation));
42 24 : }
43 :
44 96 : THEN("The ray direction is transformed correctly")
45 96 : {
46 24 : const RealVector_t transformed = transformation * Vec(rd);
47 :
48 24 : INFO("R := \n", transformation.linear().format(matfmt));
49 24 : INFO("R * rd := ", transformed.format(vecfmt));
50 :
51 24 : INFO("Expected R * rd := ", expectedrd.format(vecfmt));
52 :
53 24 : CHECK_UNARY(transformed.isApprox(expectedrd));
54 24 : }
55 :
56 96 : THEN("The ray origin is transformed correctly")
57 96 : {
58 24 : const RealVector_t transformed = transformation * Point(ro);
59 :
60 24 : INFO("T :=\n", transformation.transformation().format(matfmt));
61 24 : INFO("T * ro := ", transformed.format(vecfmt));
62 :
63 24 : INFO("Expected T * ro := ", expectedro.format(vecfmt));
64 :
65 24 : CHECK_UNARY(transformed.isApprox(expectedro));
66 24 : }
67 96 : }
68 :
69 : void checkTransformationBasic(const RealRay_t& ray, const RealVector_t& centerOfRotation,
70 : RealMatrix_t rotation)
71 40 : {
72 40 : RealVector_t expectedro = RealVector_t::Zero(ray.dim());
73 40 : expectedro[0] = -4;
74 :
75 40 : RealVector_t expectedrd = RealVector_t::Zero(ray.dim());
76 40 : expectedrd[0] = 1;
77 :
78 40 : checkTransformation(ray, centerOfRotation, expectedro, expectedrd, rotation);
79 40 : }
80 :
81 : TEST_CASE("TraversalTransformation: Test transformation with ray going in +x")
82 4 : {
83 4 : auto rotation0 = Eigen::Rotation2D<real_t>(0).matrix();
84 4 : const RealVector_t centerOfRotation({{1.5, 1.5}});
85 :
86 4 : GIVEN("A ray with largest component in +x direction")
87 4 : {
88 4 : const RealVector_t ro({{-2.5, 1.5}});
89 4 : INFO("ro := ", ro.format(vecfmt));
90 :
91 4 : const RealVector_t rd({{1, 0}});
92 4 : INFO("rd := ", rd.format(vecfmt));
93 :
94 4 : const RealRay_t ray(ro, rd);
95 :
96 4 : checkTransformationBasic(ray, centerOfRotation, rotation0);
97 4 : }
98 4 : }
99 :
100 : TEST_CASE("TraversalTransformation: Test transformation with ray going in -x")
101 4 : {
102 4 : auto rotation180 = Eigen::Rotation2D<real_t>(pi_t).matrix();
103 4 : const RealVector_t centerOfRotation({{1.5, 1.5}});
104 :
105 4 : GIVEN("A ray with largest component in -x direction")
106 4 : {
107 4 : const RealVector_t ro({{5.5, 1.5}});
108 4 : INFO("ro := ", ro.format(vecfmt));
109 :
110 4 : const RealVector_t rd({{-1, 0}});
111 4 : INFO("rd := ", rd.format(vecfmt));
112 :
113 4 : const RealRay_t ray(ro, rd);
114 :
115 4 : checkTransformationBasic(ray, centerOfRotation, rotation180);
116 4 : }
117 4 : }
118 :
119 : TEST_CASE("TraversalTransformation: Test transformation with ray going in +y")
120 4 : {
121 4 : auto rotation270 = Eigen::Rotation2D<real_t>(3 * pi_t / 2).matrix();
122 4 : const RealVector_t centerOfRotation({{1.5, 1.5}});
123 :
124 4 : GIVEN("A ray with largest component in +y direction")
125 4 : {
126 4 : const RealVector_t ro({{1.5, -2.5}});
127 4 : INFO("ro := ", ro.format(vecfmt));
128 :
129 4 : const RealVector_t rd({{0, 1}});
130 4 : INFO("rd := ", rd.format(vecfmt));
131 :
132 4 : const RealRay_t ray(ro, rd);
133 :
134 4 : checkTransformationBasic(ray, centerOfRotation, rotation270);
135 4 : }
136 4 : }
137 :
138 : TEST_CASE("TraversalTransformation: Test transformation with ray going in -y")
139 4 : {
140 4 : auto rotation90 = Eigen::Rotation2D<real_t>(pi_t / 2).matrix();
141 4 : const RealVector_t centerOfRotation({{1.5, 1.5}});
142 :
143 4 : GIVEN("A ray with largest component in -y direction")
144 4 : {
145 4 : RealVector_t ro({{1.5, 5.5}});
146 4 : INFO("ro := ", ro.format(vecfmt));
147 :
148 4 : RealVector_t rd({{0, -1}});
149 4 : INFO("rd := ", rd.format(vecfmt));
150 :
151 4 : RealRay_t ray(ro, rd);
152 :
153 4 : checkTransformationBasic(ray, centerOfRotation, rotation90);
154 4 : }
155 4 : }
156 :
157 : TEST_CASE("TraversalTransformation: Test transformation with ray direction [1, 1]")
158 4 : {
159 4 : auto rotation0 = Eigen::Rotation2D<real_t>(0).matrix();
160 4 : const RealVector_t centerOfRotation({{1.5, 1.5}});
161 :
162 4 : GIVEN("A ray with equally large positive component")
163 4 : {
164 4 : RealVector_t ro({{-2.5, 1.5}});
165 4 : INFO("ro := ", ro.format(vecfmt));
166 :
167 4 : RealVector_t rd({{1, 1}});
168 4 : INFO("rd := ", rd.format(vecfmt));
169 :
170 4 : RealRay_t ray(ro, rd);
171 :
172 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 0}}), RealVector_t({{1, 1}}),
173 4 : rotation0);
174 4 : }
175 4 : }
176 :
177 : TEST_CASE("TraversalTransformation: Test transformation with ray direction [1, -1]")
178 4 : {
179 4 : auto rotation0 = Eigen::Rotation2D<real_t>(0).matrix();
180 4 : const RealVector_t centerOfRotation({{1.5, 1.5}});
181 :
182 4 : GIVEN("A ray with equally large component, where only x is positive")
183 4 : {
184 4 : RealVector_t ro({{-2.5, 1.5}});
185 4 : INFO("ro := ", ro.format(vecfmt));
186 :
187 4 : RealVector_t rd({{1, -1}});
188 4 : INFO("rd := ", rd.format(vecfmt));
189 :
190 4 : RealRay_t ray(ro, rd);
191 :
192 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 0}}), RealVector_t({{1, -1}}),
193 4 : rotation0);
194 4 : }
195 4 : }
196 :
197 : TEST_CASE("TraversalTransformation: Test transformation with ray direction [-1, 1]")
198 4 : {
199 4 : auto rotation180 = Eigen::Rotation2D<real_t>(pi_t).matrix();
200 4 : const RealVector_t centerOfRotation({{1.5, 1.5}});
201 :
202 4 : GIVEN("A ray with equally large component, where x is negative")
203 4 : {
204 4 : RealVector_t ro({{5.5, 1.5}});
205 4 : INFO("ro := ", ro.format(vecfmt));
206 :
207 4 : RealVector_t rd({{-1, 1}});
208 4 : INFO("rd := ", rd.format(vecfmt));
209 :
210 4 : RealRay_t ray(ro, rd);
211 :
212 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 0}}), RealVector_t({{1, -1}}),
213 4 : rotation180);
214 4 : }
215 4 : }
216 :
217 : TEST_CASE("TraversalTransformation: Test transformation with ray direction [-1, -1]")
218 4 : {
219 4 : auto rotation180 = Eigen::Rotation2D<real_t>(pi_t).matrix();
220 4 : const RealVector_t centerOfRotation({{1.5, 1.5}});
221 :
222 4 : GIVEN("A ray with equally large negative component")
223 4 : {
224 4 : RealVector_t ro({{5.5, 1.5}});
225 4 : INFO("ro := ", ro.format(vecfmt));
226 :
227 4 : RealVector_t rd({{-1, -1}});
228 4 : INFO("rd := ", rd.format(vecfmt));
229 :
230 4 : RealRay_t ray(ro, rd);
231 :
232 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 0}}), RealVector_t({{1, 1}}),
233 4 : rotation180);
234 4 : }
235 4 : }
236 :
237 : void checkBoundingBox(BoundingBox aabb, RealVector_t expectedMin, RealVector_t expectedMax)
238 14 : {
239 14 : CAPTURE(aabb);
240 :
241 14 : THEN("min() is as expected")
242 14 : {
243 7 : INFO("min() := ", aabb.min().format(vecfmt));
244 7 : INFO("expected min() := ", expectedMin.format(vecfmt));
245 7 : CHECK_UNARY(aabb.min().isApprox(expectedMin));
246 7 : }
247 :
248 14 : THEN("max() is as expected")
249 14 : {
250 7 : INFO("max() := ", aabb.max().format(vecfmt));
251 7 : INFO("expected max() := ", expectedMax.format(vecfmt));
252 7 : CHECK_UNARY(aabb.max().isApprox(expectedMax));
253 7 : }
254 14 : }
255 :
256 : TEST_CASE("TraversalTransformation: Transform square bounding box")
257 8 : {
258 8 : BoundingBox aabb(IndexVector_t{{5, 5}});
259 8 : CAPTURE(aabb);
260 :
261 8 : const RealVector_t expectedMin({{-2.5, -2.5}});
262 8 : const RealVector_t expectedMax({{2.5, 2.5}});
263 :
264 8 : GIVEN("A ray through the center of the bounding box point in +x direction")
265 8 : {
266 2 : const RealVector_t ro({{-1.5, 2.5}});
267 2 : const RealVector_t rd({{1, 0}});
268 :
269 2 : const RealRay_t ray(ro, rd);
270 :
271 2 : TransformToTraversal transformation(ray, aabb.center());
272 :
273 2 : WHEN("Transforming the bounding box")
274 2 : {
275 2 : auto rotatedAABB = transformation.toTraversalCoordinates(aabb);
276 2 : checkBoundingBox(rotatedAABB, expectedMin, expectedMax);
277 2 : }
278 2 : }
279 :
280 8 : GIVEN("A ray through the center of the bounding box point in -x direction")
281 8 : {
282 2 : const RealVector_t ro({{6.5, 2.5}});
283 2 : const RealVector_t rd({{-1, 0}});
284 :
285 2 : const RealRay_t ray(ro, rd);
286 :
287 2 : TransformToTraversal transformation(ray, aabb.center());
288 :
289 2 : WHEN("Transforming the bounding box")
290 2 : {
291 2 : auto rotatedAABB = transformation.toTraversalCoordinates(aabb);
292 2 : checkBoundingBox(rotatedAABB, expectedMin, expectedMax);
293 2 : }
294 2 : }
295 :
296 8 : GIVEN("A ray through the center of the bounding box point in +y direction")
297 8 : {
298 2 : const RealVector_t ro({{2.5, -1.5}});
299 2 : const RealVector_t rd({{0, 1}});
300 :
301 2 : const RealRay_t ray(ro, rd);
302 :
303 2 : TransformToTraversal transformation(ray, aabb.center());
304 :
305 2 : WHEN("Transforming the bounding box")
306 2 : {
307 2 : auto rotatedAABB = transformation.toTraversalCoordinates(aabb);
308 2 : checkBoundingBox(rotatedAABB, expectedMin, expectedMax);
309 2 : }
310 2 : }
311 :
312 8 : GIVEN("A ray through the center of the bounding box point in -y direction")
313 8 : {
314 2 : const RealVector_t ro({{2.5, 6.5}});
315 2 : const RealVector_t rd({{0, -1}});
316 :
317 2 : const RealRay_t ray(ro, rd);
318 :
319 2 : TransformToTraversal transformation(ray, aabb.center());
320 :
321 2 : WHEN("Transforming the bounding box")
322 2 : {
323 2 : auto rotatedAABB = transformation.toTraversalCoordinates(aabb);
324 2 : checkBoundingBox(rotatedAABB, expectedMin, expectedMax);
325 2 : }
326 2 : }
327 8 : }
328 :
329 : TEST_CASE("TraversalTransformation: Transform non-square bounding box")
330 6 : {
331 6 : Eigen::IOFormat fmt(4, 0, ", ", "\n", "\t\t[", "]");
332 :
333 6 : BoundingBox aabb(IndexVector_t{{8, 5}});
334 6 : CAPTURE(aabb);
335 :
336 6 : GIVEN("A ray through the center of the bounding box point in +x direction")
337 6 : {
338 2 : const RealVector_t expectedMin({{-4, -2.5}});
339 2 : const RealVector_t expectedMax({{4, 2.5}});
340 :
341 2 : const RealVector_t ro({{-1.5, 2.5}});
342 2 : const RealVector_t rd({{1, 0}});
343 :
344 2 : const RealRay_t ray(ro, rd);
345 :
346 2 : TransformToTraversal transformation(ray, aabb.center());
347 :
348 2 : WHEN("Transforming the bounding box")
349 2 : {
350 2 : auto rotatedAABB = transformation.toTraversalCoordinates(aabb);
351 2 : checkBoundingBox(rotatedAABB, expectedMin, expectedMax);
352 2 : }
353 2 : }
354 :
355 6 : const RealVector_t expectedMin({{-2.5, -4}});
356 6 : const RealVector_t expectedMax({{2.5, 4}});
357 :
358 6 : GIVEN("A ray through the center of the bounding box point in +y direction")
359 6 : {
360 :
361 2 : const RealVector_t ro({{4, -1.5}});
362 2 : const RealVector_t rd({{0, 1}});
363 :
364 2 : const RealRay_t ray(ro, rd);
365 :
366 2 : TransformToTraversal transformation(ray, aabb.center());
367 :
368 2 : WHEN("Transforming the bounding box")
369 2 : {
370 2 : auto rotatedAABB = transformation.toTraversalCoordinates(aabb);
371 2 : checkBoundingBox(rotatedAABB, expectedMin, expectedMax);
372 2 : }
373 2 : }
374 :
375 6 : GIVEN("A ray through the center of the bounding box point in -y direction")
376 6 : {
377 2 : const RealVector_t ro({{4, 6.5}});
378 2 : const RealVector_t rd({{0, -1}});
379 :
380 2 : const RealRay_t ray(ro, rd);
381 :
382 2 : TransformToTraversal transformation(ray, aabb.center());
383 :
384 2 : WHEN("Transforming the bounding box")
385 2 : {
386 2 : auto rotatedAABB = transformation.toTraversalCoordinates(aabb);
387 2 : checkBoundingBox(rotatedAABB, expectedMin, expectedMax);
388 2 : }
389 2 : }
390 6 : }
391 :
392 : index_t checkTraversal(BoundingBox aabb, RealRay_t ray, std::deque<RealVector_t> visitedVoxels)
393 43 : {
394 43 : Eigen::IOFormat fmt(10, 0, ", ", ", ", "", "", "[", "]");
395 :
396 43 : SliceTraversal traversal(aabb, ray);
397 :
398 43 : INFO("rd := ", ray.direction().format(vecfmt));
399 43 : INFO("ro := ", ray.origin().format(vecfmt));
400 :
401 43 : CAPTURE(traversal.startIndex());
402 43 : CAPTURE(traversal.endIndex());
403 43 : CHECK_EQ(traversal.endIndex(), visitedVoxels.size());
404 : // INFO("entryPoint := ", traversal.entryPoint_.format(fmt));
405 : // INFO("exitPoint := ", traversal.exitPoint_.format(fmt));
406 :
407 43 : index_t counter = 0;
408 43 : auto t = traversal.t();
409 43 : auto tdelta = traversal.tDelta();
410 145 : for (auto iter = traversal.begin(); iter != traversal.end(); ++iter) {
411 102 : auto value = *iter;
412 :
413 102 : CAPTURE(counter);
414 102 : REQUIRE_MESSAGE(!visitedVoxels.empty(), "Visiting more voxels than expected");
415 :
416 102 : RealVector_t expected = visitedVoxels.front();
417 102 : RealVector_t point = ray.pointAt(t);
418 :
419 102 : CAPTURE(t);
420 102 : INFO("RealRay_t hit: ", point.format(fmt));
421 102 : INFO("Should hit: ", expected.format(fmt));
422 :
423 102 : CHECK_UNARY(point.isApprox(expected));
424 :
425 : // Pop the first element, as we don't need it anymore
426 102 : visitedVoxels.pop_front();
427 :
428 : // increment counter
429 102 : ++counter;
430 102 : t += tdelta;
431 102 : }
432 :
433 43 : INFO("Voxels left in list: ", visitedVoxels.size());
434 :
435 43 : REQUIRE_MESSAGE(visitedVoxels.empty(), "Voxel list is not empty, so we've visited too few");
436 43 : CHECK_NE(counter, 0);
437 : // CHECK(false);
438 :
439 43 : return counter;
440 43 : }
441 :
442 : TEST_CASE("SliceTraversal: Traversing a 2D grid parallel to x-axis, dir [1, 0]")
443 2 : {
444 :
445 2 : IndexVector_t size({{3, 3}});
446 :
447 2 : BoundingBox aabb(size);
448 :
449 2 : const RealVector_t rd({{1, 0}});
450 2 : const real_t x = -1.5f;
451 :
452 8 : for (real_t i = 0; i < 3; ++i) {
453 6 : const real_t y = 0.5f + i;
454 6 : const RealVector_t ro({{x, y}});
455 6 : const RealRay_t ray(ro, rd);
456 :
457 : // list of points we expect to visit
458 6 : std::deque<RealVector_t> visitedVoxels;
459 6 : visitedVoxels.emplace_back(RealVector_t{{0.5, y}});
460 6 : visitedVoxels.emplace_back(RealVector_t{{1.5, y}});
461 6 : visitedVoxels.emplace_back(RealVector_t{{2.5, y}});
462 :
463 6 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
464 :
465 6 : THEN("Exactly 3 voxels are visited")
466 6 : {
467 1 : CHECK_EQ(counter, 3);
468 1 : }
469 6 : }
470 2 : }
471 :
472 : TEST_CASE("SliceTraversal: Traversing a 2D grid parallel to x-axis, dir [-1, 0]")
473 2 : {
474 2 : IndexVector_t size({{3, 3}});
475 :
476 2 : BoundingBox aabb(size);
477 :
478 2 : const RealVector_t rd({{-1, 0}});
479 2 : const real_t x = 5.5f;
480 :
481 6 : for (real_t i = 1; i < 3; ++i) {
482 4 : const real_t y = 0.5f + i;
483 4 : const RealVector_t ro({{x, y}});
484 4 : const RealRay_t ray(ro, rd);
485 :
486 : // list of points we expect to visit
487 4 : std::deque<RealVector_t> visitedVoxels;
488 4 : visitedVoxels.emplace_back(RealVector_t{{2.5, y}});
489 4 : visitedVoxels.emplace_back(RealVector_t{{1.5, y}});
490 4 : visitedVoxels.emplace_back(RealVector_t{{0.5, y}});
491 :
492 4 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
493 :
494 4 : THEN("Exactly 3 voxels are visited")
495 4 : {
496 1 : CHECK_EQ(counter, 3);
497 1 : }
498 4 : }
499 2 : }
500 :
501 : TEST_CASE("SliceTraversal: Traversing a 2D grid parallel to y-axis, dir [0, 1]")
502 2 : {
503 2 : IndexVector_t size({{3, 3}});
504 :
505 2 : BoundingBox aabb(size);
506 :
507 2 : const RealVector_t rd({{0, 1}});
508 2 : const real_t y = -1.5;
509 :
510 6 : for (real_t i = 1; i < 3; ++i) {
511 4 : const real_t x = 0.5f + i;
512 4 : const RealVector_t ro({{x, y}});
513 4 : const RealRay_t ray(ro, rd);
514 :
515 : // list of points we expect to visit
516 4 : std::deque<RealVector_t> visitedVoxels;
517 4 : visitedVoxels.emplace_back(RealVector_t{{x, 0.5}});
518 4 : visitedVoxels.emplace_back(RealVector_t{{x, 1.5}});
519 4 : visitedVoxels.emplace_back(RealVector_t{{x, 2.5}});
520 :
521 4 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
522 :
523 4 : THEN("Exactly 3 voxels are visited")
524 4 : {
525 1 : CHECK_EQ(counter, 3);
526 1 : }
527 4 : }
528 2 : }
529 :
530 : TEST_CASE("SliceTraversal: Traversing a 2D grid parallel to y-axis, dir [0, -1]")
531 2 : {
532 2 : IndexVector_t size({{3, 3}});
533 :
534 2 : BoundingBox aabb(size);
535 :
536 2 : const RealVector_t rd({{0, -1}});
537 2 : const real_t y = 5.5;
538 :
539 6 : for (real_t i = 1; i < 3; ++i) {
540 4 : const real_t x = 0.5f + i;
541 4 : const RealVector_t ro({{x, y}});
542 4 : const RealRay_t ray(ro, rd);
543 :
544 : // list of points we expect to visit
545 4 : std::deque<RealVector_t> visitedVoxels;
546 4 : visitedVoxels.emplace_back(RealVector_t{{x, 2.5}});
547 4 : visitedVoxels.emplace_back(RealVector_t{{x, 1.5}});
548 4 : visitedVoxels.emplace_back(RealVector_t{{x, 0.5}});
549 :
550 4 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
551 :
552 4 : THEN("Exactly 3 voxels are visited")
553 4 : {
554 1 : CHECK_EQ(counter, 3);
555 1 : }
556 4 : }
557 2 : }
558 :
559 : TEST_CASE("SliceTraversal: Traversing a 2D grid diagonally, dir [1, 1]")
560 5 : {
561 5 : IndexVector_t size({{3, 3}});
562 :
563 5 : BoundingBox aabb(size);
564 :
565 5 : RealVector_t rd({{1, 1}});
566 5 : rd.normalize();
567 :
568 5 : WHEN("Traversing the grid through the center")
569 5 : {
570 1 : const RealVector_t ro({{-1.5, -1.5}});
571 :
572 1 : const RealRay_t ray(ro, rd);
573 :
574 : // list of points we expect to visit
575 1 : std::deque<RealVector_t> visitedVoxels;
576 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 0.5}});
577 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 1.5}});
578 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 2.5}});
579 :
580 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
581 :
582 1 : THEN("Exactly two steps are taken")
583 1 : {
584 1 : CHECK_EQ(counter, 3);
585 1 : }
586 1 : }
587 :
588 5 : WHEN("Traversing the grid through the left middle and top middle voxel")
589 5 : {
590 1 : const RealVector_t ro({{-0.5, 0.5}});
591 :
592 1 : const RealRay_t ray(ro, rd);
593 :
594 : // list of points we expect to visit
595 1 : std::deque<RealVector_t> visitedVoxels;
596 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 1.5}});
597 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 2.5}});
598 :
599 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
600 :
601 1 : THEN("Exactly two steps are taken")
602 1 : {
603 1 : CHECK_EQ(counter, 2);
604 1 : }
605 1 : }
606 :
607 5 : WHEN("Traversing the grid through the right middle and bottom middle voxel")
608 5 : {
609 1 : Eigen::IOFormat fmtvec(10, 0, ", ", ", ", "", "", "[", "]");
610 :
611 1 : const RealVector_t ro({{0.5, -0.5}});
612 :
613 1 : const RealRay_t ray(ro, rd);
614 :
615 : // list of points we expect to visit
616 1 : std::deque<RealVector_t> visitedVoxels;
617 1 : visitedVoxels.push_back(RealVector_t{{1.5, 0.5}});
618 1 : visitedVoxels.push_back(RealVector_t{{2.5, 1.5}});
619 :
620 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
621 :
622 1 : THEN("Exactly two steps are taken")
623 1 : {
624 1 : CHECK_EQ(counter, 2);
625 1 : }
626 1 : }
627 :
628 5 : WHEN("Traversing the grid through the bottom right corner")
629 5 : {
630 1 : const RealVector_t ro({{2.5 - 1, 0.5 - 1}});
631 :
632 1 : const RealRay_t ray(ro, rd);
633 :
634 : // list of points we expect to visit
635 1 : std::deque<RealVector_t> visitedVoxels;
636 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 0.5}});
637 :
638 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
639 :
640 1 : THEN("Exactly two steps are taken")
641 1 : {
642 1 : CHECK_EQ(counter, 1);
643 1 : }
644 1 : }
645 :
646 5 : WHEN("Traversing the grid through the top left corner")
647 5 : {
648 1 : const RealVector_t ro({{-0.5, 1.5}});
649 :
650 1 : const RealRay_t ray(ro, rd);
651 :
652 : // list of points we expect to visit
653 1 : std::deque<RealVector_t> visitedVoxels;
654 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 2.5}});
655 :
656 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
657 :
658 1 : THEN("Exactly two steps are taken")
659 1 : {
660 1 : CHECK_EQ(counter, 1);
661 1 : }
662 1 : }
663 5 : }
664 :
665 : TEST_CASE("SliceTraversal: Traversing a 2D grid diagonally, dir [1, -1]")
666 5 : {
667 5 : IndexVector_t size({{3, 3}});
668 :
669 5 : BoundingBox aabb(size);
670 :
671 5 : RealVector_t rd({{1, -1}});
672 5 : rd.normalize();
673 :
674 5 : WHEN("Traversing the bottom left corner")
675 5 : {
676 1 : const RealVector_t ro({{-0.5, 1.5}});
677 :
678 1 : const RealRay_t ray(ro, rd);
679 :
680 : // list of points we expect to visit
681 1 : std::deque<RealVector_t> visitedVoxels;
682 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 0.5}});
683 :
684 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
685 :
686 1 : THEN("Exactly one step is taken")
687 1 : {
688 1 : CHECK_EQ(counter, 1);
689 1 : }
690 1 : }
691 :
692 5 : WHEN("Traversing the grid through the left middle and top middle voxel")
693 5 : {
694 1 : const RealVector_t ro({{-0.5, 2.5}});
695 :
696 1 : const RealRay_t ray(ro, rd);
697 :
698 : // list of points we expect to visit
699 1 : std::deque<RealVector_t> visitedVoxels;
700 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 1.5}});
701 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 0.5}});
702 :
703 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
704 :
705 1 : THEN("Exactly two steps are taken")
706 1 : {
707 1 : CHECK_EQ(counter, 2);
708 1 : }
709 1 : }
710 :
711 5 : WHEN("Traversing the grid through the center diagonally")
712 5 : {
713 1 : const RealVector_t ro({{-0.5, 3.5}});
714 :
715 1 : const RealRay_t ray(ro, rd);
716 :
717 : // list of points we expect to visit
718 1 : std::deque<RealVector_t> visitedVoxels;
719 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 2.5}});
720 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 1.5}});
721 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 0.5}});
722 :
723 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
724 :
725 1 : THEN("Exactly three steps are taken")
726 1 : {
727 1 : CHECK_EQ(counter, 3);
728 1 : }
729 1 : }
730 :
731 5 : WHEN("Traversing the grid through the top middle and right middle voxel")
732 5 : {
733 1 : const RealVector_t ro({{0.5, 3.5}});
734 :
735 1 : const RealRay_t ray(ro, rd);
736 :
737 : // list of points we expect to visit
738 1 : std::deque<RealVector_t> visitedVoxels;
739 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 2.5}});
740 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 1.5}});
741 :
742 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
743 :
744 1 : THEN("Exactly two steps are taken")
745 1 : {
746 1 : CHECK_EQ(counter, 2);
747 1 : }
748 1 : }
749 :
750 5 : WHEN("Traversing the grid through the top right voxel")
751 5 : {
752 1 : const RealVector_t ro({{1.5, 3.5}});
753 :
754 1 : const RealRay_t ray(ro, rd);
755 :
756 : // list of points we expect to visit
757 1 : std::deque<RealVector_t> visitedVoxels;
758 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 2.5}});
759 :
760 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
761 :
762 1 : THEN("Exactly two steps are taken")
763 1 : {
764 1 : CHECK_EQ(counter, 1);
765 1 : }
766 1 : }
767 5 : }
768 :
769 : TEST_CASE("SliceTraversal: Traversing a 2D grid diagonally, dir [-1, 1]")
770 5 : {
771 5 : IndexVector_t size({{3, 3}});
772 :
773 5 : BoundingBox aabb(size);
774 :
775 5 : RealVector_t rd({{-1, 1}});
776 5 : rd.normalize();
777 :
778 5 : WHEN("Traversing the top right corner")
779 5 : {
780 1 : const RealVector_t ro({{3.5, 1.5}});
781 :
782 1 : const RealRay_t ray(ro, rd);
783 :
784 : // list of points we expect to visit
785 1 : std::deque<RealVector_t> visitedVoxels;
786 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 2.5}});
787 :
788 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
789 :
790 1 : THEN("Exactly one step is taken")
791 1 : {
792 1 : CHECK_EQ(counter, 1);
793 1 : }
794 1 : }
795 :
796 5 : WHEN("Traversing the grid through the top center and right center voxel")
797 5 : {
798 1 : const RealVector_t ro({{3.5, 0.5}});
799 :
800 1 : const RealRay_t ray(ro, rd);
801 :
802 : // list of points we expect to visit
803 1 : std::deque<RealVector_t> visitedVoxels;
804 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 1.5}});
805 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 2.5}});
806 :
807 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
808 :
809 1 : THEN("Exactly two steps are taken")
810 1 : {
811 1 : CHECK_EQ(counter, 2);
812 1 : }
813 1 : }
814 :
815 5 : WHEN("Traversing the grid through the center diagonally")
816 5 : {
817 1 : const RealVector_t ro({{3.5, -0.5}});
818 :
819 1 : const RealRay_t ray(ro, rd);
820 :
821 : // list of points we expect to visit
822 1 : std::deque<RealVector_t> visitedVoxels;
823 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 0.5}});
824 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 1.5}});
825 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 2.5}});
826 :
827 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
828 :
829 1 : THEN("Exactly three steps are taken")
830 1 : {
831 1 : CHECK_EQ(counter, 3);
832 1 : }
833 1 : }
834 :
835 5 : WHEN("Traversing the grid through the left center and bottom center voxel")
836 5 : {
837 1 : const RealVector_t ro({{2.5, -0.5}});
838 :
839 1 : const RealRay_t ray(ro, rd);
840 :
841 : // list of points we expect to visit
842 1 : std::deque<RealVector_t> visitedVoxels;
843 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 0.5}});
844 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 1.5}});
845 :
846 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
847 :
848 1 : THEN("Exactly two steps are taken")
849 1 : {
850 1 : CHECK_EQ(counter, 2);
851 1 : }
852 1 : }
853 :
854 5 : WHEN("Traversing the grid through the bottom left voxel")
855 5 : {
856 1 : const RealVector_t ro({{1.5, -0.5}});
857 :
858 1 : const RealRay_t ray(ro, rd);
859 :
860 : // list of points we expect to visit
861 1 : std::deque<RealVector_t> visitedVoxels;
862 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 0.5}});
863 :
864 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
865 :
866 1 : THEN("Exactly two steps are taken")
867 1 : {
868 1 : CHECK_EQ(counter, 1);
869 1 : }
870 1 : }
871 5 : }
872 :
873 : TEST_CASE("SliceTraversal: Traversing a 2D grid diagonally, dir [-1, -1]")
874 9 : {
875 9 : IndexVector_t size({{3, 3}});
876 :
877 9 : BoundingBox aabb(size);
878 :
879 9 : RealVector_t rd({{-1, -1}});
880 9 : rd.normalize();
881 :
882 9 : CAPTURE(aabb);
883 :
884 9 : WHEN("Traversing the grid through the center of the top left corner")
885 9 : {
886 1 : const RealVector_t ro({{1.5, 3.5}});
887 :
888 1 : const RealRay_t ray(ro, rd);
889 :
890 : // list of points we expect to visit
891 1 : std::deque<RealVector_t> visitedVoxels;
892 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 2.5}});
893 :
894 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
895 :
896 1 : THEN("Exactly one step is taken")
897 1 : {
898 1 : CHECK_EQ(counter, 1);
899 1 : }
900 1 : }
901 :
902 9 : WHEN("Traversing the grid through the top left voxel, but not centered")
903 9 : {
904 1 : const RealVector_t ro({{1.75, 3.5}});
905 :
906 1 : const RealRay_t ray(ro, rd);
907 :
908 : // list of points we expect to visit
909 1 : std::deque<RealVector_t> visitedVoxels;
910 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 2.25}});
911 :
912 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
913 :
914 1 : THEN("Exactly two steps are taken")
915 1 : {
916 1 : CHECK_EQ(counter, 1);
917 1 : }
918 1 : }
919 :
920 9 : WHEN("Traversing the grid through the left and top center voxel")
921 9 : {
922 1 : const RealVector_t ro({{2.5, 3.5}});
923 :
924 1 : const RealRay_t ray(ro, rd);
925 :
926 : // list of points we expect to visit
927 1 : std::deque<RealVector_t> visitedVoxels;
928 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 2.5}});
929 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 1.5}});
930 :
931 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
932 :
933 1 : THEN("Exactly two steps are taken")
934 1 : {
935 1 : CHECK_EQ(counter, 2);
936 1 : }
937 1 : }
938 :
939 9 : WHEN("Traversing the grid through the left and top center voxel but not centered")
940 9 : {
941 1 : const RealVector_t ro({{2, 3.5}});
942 :
943 1 : const RealRay_t ray(ro, rd);
944 :
945 : // list of points we expect to visit
946 1 : std::deque<RealVector_t> visitedVoxels;
947 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 3}});
948 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 2}});
949 :
950 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
951 :
952 1 : THEN("Exactly two steps are taken")
953 1 : {
954 1 : CHECK_EQ(counter, 2);
955 1 : }
956 1 : }
957 :
958 9 : WHEN("Traversing the grid slightly above the volume center diagonally")
959 9 : {
960 1 : const RealVector_t ro({{3.25, 3.5}});
961 :
962 1 : const RealRay_t ray(ro, rd);
963 :
964 : // list of points we expect to visit
965 1 : std::deque<RealVector_t> visitedVoxels;
966 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 2.75}});
967 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 1.75}});
968 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 0.75}});
969 :
970 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
971 :
972 1 : THEN("Exactly three steps are taken")
973 1 : {
974 1 : CHECK_EQ(counter, 3);
975 1 : }
976 1 : }
977 :
978 9 : WHEN("Traversing the grid through the volume center diagonally")
979 9 : {
980 1 : const RealVector_t ro({{3.5, 3.5}});
981 :
982 1 : const RealRay_t ray(ro, rd);
983 :
984 : // list of points we expect to visit
985 1 : std::deque<RealVector_t> visitedVoxels;
986 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 2.5}});
987 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 1.5}});
988 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 0.5}});
989 :
990 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
991 :
992 1 : THEN("Exactly three steps are taken")
993 1 : {
994 1 : CHECK_EQ(counter, 3);
995 1 : }
996 1 : }
997 :
998 9 : WHEN("Traversing the grid slightly below the volume center diagonally")
999 9 : {
1000 1 : const RealVector_t ro({{3.75, 3.5}});
1001 :
1002 1 : const RealRay_t ray(ro, rd);
1003 :
1004 : // list of points we expect to visit
1005 1 : std::deque<RealVector_t> visitedVoxels;
1006 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 2.25}});
1007 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 1.25}});
1008 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 0.25}});
1009 :
1010 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
1011 :
1012 1 : THEN("Exactly three steps are taken")
1013 1 : {
1014 1 : CHECK_EQ(counter, 3);
1015 1 : }
1016 1 : }
1017 :
1018 9 : WHEN("Traversing the grid through the bottom and right center voxel")
1019 9 : {
1020 1 : const RealVector_t ro({{3.5, 2.5}});
1021 :
1022 1 : const RealRay_t ray(ro, rd);
1023 :
1024 : // list of points we expect to visit
1025 1 : std::deque<RealVector_t> visitedVoxels;
1026 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 1.5}});
1027 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 0.5}});
1028 :
1029 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
1030 :
1031 1 : THEN("Exactly two steps are taken")
1032 1 : {
1033 1 : CHECK_EQ(counter, 2);
1034 1 : }
1035 1 : }
1036 :
1037 9 : WHEN("Traversing the grid through the bottom left corner")
1038 9 : {
1039 1 : const RealVector_t ro({{3.5, 1.5}});
1040 :
1041 1 : const RealRay_t ray(ro, rd);
1042 :
1043 : // list of points we expect to visit
1044 1 : std::deque<RealVector_t> visitedVoxels;
1045 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 0.5}});
1046 :
1047 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
1048 :
1049 1 : THEN("Exactly two steps are taken")
1050 1 : {
1051 1 : CHECK_EQ(counter, 1);
1052 1 : }
1053 1 : }
1054 9 : }
1055 :
1056 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [1, 0, 0]")
1057 4 : {
1058 4 : auto expectedRotation = Eigen::AngleAxisf(0, Eigen::Vector3f::UnitX()).matrix();
1059 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1060 :
1061 4 : const RealVector_t ro({{-2.5, 1.5, 1.5}});
1062 4 : INFO("ro := ", ro.format(vecfmt));
1063 :
1064 4 : const RealVector_t rd({{1, 0, 0}});
1065 4 : INFO("rd := ", rd.format(vecfmt));
1066 :
1067 4 : const RealRay_t ray(ro, rd);
1068 :
1069 4 : checkTransformationBasic(ray, centerOfRotation, expectedRotation);
1070 4 : }
1071 :
1072 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [1, 1, 0]")
1073 4 : {
1074 4 : auto expectedRotation = Eigen::AngleAxisf(0, Eigen::Vector3f::UnitX()).matrix();
1075 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1076 :
1077 4 : const RealVector_t ro({{-2.5, -2.5, 1.5}});
1078 4 : INFO("ro := ", ro.format(vecfmt));
1079 :
1080 4 : const RealVector_t rd({{1, 1, 0}});
1081 4 : INFO("rd := ", rd.format(vecfmt));
1082 :
1083 4 : const RealRay_t ray(ro, rd);
1084 :
1085 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, -4, 0}}), rd, expectedRotation);
1086 4 : }
1087 :
1088 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [1, -1, 0]")
1089 4 : {
1090 4 : auto expectedRotation = Eigen::AngleAxisf(0, Eigen::Vector3f::UnitX()).matrix();
1091 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1092 :
1093 4 : const RealVector_t ro({{-2.5, 5.5, 1.5}});
1094 4 : INFO("ro := ", ro.format(vecfmt));
1095 :
1096 4 : const RealVector_t rd({{1, -1, 0}});
1097 4 : INFO("rd := ", rd.format(vecfmt));
1098 :
1099 4 : const RealRay_t ray(ro, rd);
1100 :
1101 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 4, 0}}), rd, expectedRotation);
1102 4 : }
1103 :
1104 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [1, 0, 1]")
1105 4 : {
1106 4 : auto expectedRotation = Eigen::AngleAxisf(0, Eigen::Vector3f::UnitX()).matrix();
1107 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1108 :
1109 4 : const RealVector_t ro({{-2.5, 1.5, -2.5}});
1110 4 : INFO("ro := ", ro.format(vecfmt));
1111 :
1112 4 : const RealVector_t rd({{1, 0, 1}});
1113 4 : INFO("rd := ", rd.format(vecfmt));
1114 :
1115 4 : const RealRay_t ray(ro, rd);
1116 :
1117 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 0, -4}}), rd, expectedRotation);
1118 4 : }
1119 :
1120 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [1, 0, -1]")
1121 4 : {
1122 4 : auto expectedRotation = Eigen::AngleAxisf(0, Eigen::Vector3f::UnitX()).matrix();
1123 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1124 :
1125 4 : const RealVector_t ro({{-2.5, 1.5, 5.5}});
1126 4 : INFO("ro := ", ro.format(vecfmt));
1127 :
1128 4 : const RealVector_t rd({{1, 0, -1}});
1129 4 : INFO("rd := ", rd.format(vecfmt));
1130 :
1131 4 : const RealRay_t ray(ro, rd);
1132 :
1133 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 0, 4}}), rd, expectedRotation);
1134 4 : }
1135 :
1136 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [1, 1, 1]")
1137 4 : {
1138 4 : auto expectedRotation = Eigen::AngleAxisf(0, Eigen::Vector3f::UnitX()).matrix();
1139 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1140 :
1141 4 : const RealVector_t ro({{-2.5, -2.5, -2.5}});
1142 4 : INFO("ro := ", ro.format(vecfmt));
1143 :
1144 4 : const RealVector_t rd({{1, 1, 1}});
1145 4 : INFO("rd := ", rd.format(vecfmt));
1146 :
1147 4 : const RealRay_t ray(ro, rd);
1148 :
1149 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, -4, -4}}), rd, expectedRotation);
1150 4 : }
1151 :
1152 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [1, 1, -1]")
1153 4 : {
1154 4 : auto expectedRotation = Eigen::AngleAxisf(0, Eigen::Vector3f::UnitX()).matrix();
1155 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1156 :
1157 4 : const RealVector_t ro({{-2.5, -2.5, 5.5}});
1158 4 : INFO("ro := ", ro.format(vecfmt));
1159 :
1160 4 : const RealVector_t rd({{1, 1, -1}});
1161 4 : INFO("rd := ", rd.format(vecfmt));
1162 :
1163 4 : const RealRay_t ray(ro, rd);
1164 :
1165 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, -4, 4}}), rd, expectedRotation);
1166 4 : }
1167 :
1168 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [-1, 0, 0]")
1169 4 : {
1170 4 : auto expectedRotation = Eigen::AngleAxisf(pi_t, Eigen::Vector3f::UnitY()).matrix();
1171 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1172 :
1173 4 : const RealVector_t ro({{5.5, 1.5, 1.5}});
1174 4 : INFO("ro := ", ro.format(vecfmt));
1175 :
1176 4 : const RealVector_t rd({{-1, 0, 0}});
1177 4 : INFO("rd := ", rd.format(vecfmt));
1178 :
1179 4 : const RealRay_t ray(ro, rd);
1180 :
1181 4 : checkTransformationBasic(ray, centerOfRotation, expectedRotation);
1182 4 : }
1183 :
1184 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [-1, 1, 0]")
1185 4 : {
1186 4 : auto expectedRotation = Eigen::AngleAxisf(pi_t, Eigen::Vector3f::UnitY()).matrix();
1187 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1188 :
1189 4 : const RealVector_t ro({{5.5, -2.5, 1.5}});
1190 4 : INFO("ro := ", ro.format(vecfmt));
1191 :
1192 4 : const RealVector_t rd({{-1, 1, 0}});
1193 4 : INFO("rd := ", rd.format(vecfmt));
1194 :
1195 4 : const RealRay_t ray(ro, rd);
1196 :
1197 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, -4, 0}}),
1198 4 : RealVector_t({{1, 1, 0}}), expectedRotation);
1199 4 : }
1200 :
1201 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [-1, -1, 0]")
1202 4 : {
1203 4 : auto expectedRotation = Eigen::AngleAxisf(pi_t, Eigen::Vector3f::UnitY()).matrix();
1204 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1205 :
1206 4 : const RealVector_t ro({{5.5, 5.5, 1.5}});
1207 4 : INFO("ro := ", ro.format(vecfmt));
1208 :
1209 4 : const RealVector_t rd({{-1, -1, 0}});
1210 4 : INFO("rd := ", rd.format(vecfmt));
1211 :
1212 4 : const RealRay_t ray(ro, rd);
1213 :
1214 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 4, 0}}),
1215 4 : RealVector_t({{1, -1, 0}}), expectedRotation);
1216 4 : }
1217 :
1218 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [-1, 0, 1]")
1219 4 : {
1220 4 : auto expectedRotation = Eigen::AngleAxisf(pi_t, Eigen::Vector3f::UnitY()).matrix();
1221 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1222 :
1223 4 : const RealVector_t ro({{5.5, 1.5, -2.5}});
1224 4 : INFO("ro := ", ro.format(vecfmt));
1225 :
1226 4 : const RealVector_t rd({{-1, 0, 1}});
1227 4 : INFO("rd := ", rd.format(vecfmt));
1228 :
1229 4 : const RealRay_t ray(ro, rd);
1230 :
1231 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 0, 4}}),
1232 4 : RealVector_t({{1, 0, -1}}), expectedRotation);
1233 4 : }
1234 :
1235 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [-1, 0, -1]")
1236 4 : {
1237 4 : auto expectedRotation = Eigen::AngleAxisf(pi_t, Eigen::Vector3f::UnitY()).matrix();
1238 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1239 :
1240 4 : const RealVector_t ro({{5.5, 1.5, 5.5}});
1241 4 : INFO("ro := ", ro.format(vecfmt));
1242 :
1243 4 : const RealVector_t rd({{-1, 0, -1}});
1244 4 : INFO("rd := ", rd.format(vecfmt));
1245 :
1246 4 : const RealRay_t ray(ro, rd);
1247 :
1248 4 : checkTransformation(ray, centerOfRotation, RealVector_t({{-4, 0, -4}}),
1249 4 : RealVector_t({{1, 0, 1}}), expectedRotation);
1250 4 : }
1251 :
1252 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [0, 1, 0]")
1253 4 : {
1254 4 : auto expectedRotation = Eigen::AngleAxisf(-0.5 * pi_t, Eigen::Vector3f::UnitZ()).matrix();
1255 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1256 :
1257 4 : const RealVector_t ro({{1.5, -2.5, 1.5}});
1258 4 : INFO("ro := ", ro.format(vecfmt));
1259 :
1260 4 : const RealVector_t rd({{0, 1, 0}});
1261 4 : INFO("rd := ", rd.format(vecfmt));
1262 :
1263 4 : const RealRay_t ray(ro, rd);
1264 :
1265 4 : checkTransformationBasic(ray, centerOfRotation, expectedRotation);
1266 4 : }
1267 :
1268 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [0, -1, 0]")
1269 4 : {
1270 4 : auto expectedRotation = Eigen::AngleAxisf(0.5 * pi_t, Eigen::Vector3f::UnitZ()).matrix();
1271 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1272 :
1273 4 : const RealVector_t ro({{1.5, 5.5, 1.5}});
1274 4 : INFO("ro := ", ro.format(vecfmt));
1275 :
1276 4 : const RealVector_t rd({{0, -1, 0}});
1277 4 : INFO("rd := ", rd.format(vecfmt));
1278 :
1279 4 : const RealRay_t ray(ro, rd);
1280 :
1281 4 : checkTransformationBasic(ray, centerOfRotation, expectedRotation);
1282 4 : }
1283 :
1284 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [0, 0, 1]")
1285 4 : {
1286 4 : auto expectedRotation = Eigen::AngleAxisf(0.5 * pi_t, Eigen::Vector3f::UnitY()).matrix();
1287 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1288 :
1289 4 : const RealVector_t ro({{1.5, 1.5, -2.5}});
1290 4 : INFO("ro := ", ro.format(vecfmt));
1291 :
1292 4 : const RealVector_t rd({{0, 0, 1}});
1293 4 : INFO("rd := ", rd.format(vecfmt));
1294 :
1295 4 : const RealRay_t ray(ro, rd);
1296 :
1297 4 : checkTransformationBasic(ray, centerOfRotation, expectedRotation);
1298 4 : }
1299 :
1300 : TEST_CASE("TraversalTransformation: Traversing a 3D grid, dir [0, 0, -1]")
1301 4 : {
1302 4 : auto expectedRotation = Eigen::AngleAxisf(-0.5 * pi_t, Eigen::Vector3f::UnitY()).matrix();
1303 4 : const RealVector_t centerOfRotation({{1.5, 1.5, 1.5}});
1304 :
1305 4 : const RealVector_t ro({{1.5, 1.5, 5.5}});
1306 4 : INFO("ro := ", ro.format(vecfmt));
1307 :
1308 4 : const RealVector_t rd({{0, 0, -1}});
1309 4 : INFO("rd := ", rd.format(vecfmt));
1310 :
1311 4 : const RealRay_t ray(ro, rd);
1312 :
1313 4 : checkTransformationBasic(ray, centerOfRotation, expectedRotation);
1314 4 : }
1315 :
1316 : TEST_CASE("SliceTraversal: Traversing a 2D grid diagonally, dir [1, 0, 0]")
1317 1 : {
1318 1 : IndexVector_t size({{3, 3, 3}});
1319 :
1320 1 : BoundingBox aabb(size);
1321 :
1322 1 : RealVector_t rd({{1, 0, 0}});
1323 1 : rd.normalize();
1324 :
1325 1 : CAPTURE(aabb);
1326 :
1327 1 : WHEN("Traversing the grid through the center of the top left corner")
1328 1 : {
1329 1 : const RealVector_t ro({{-1.5, 0, 0}});
1330 :
1331 1 : const RealRay_t ray(ro, rd);
1332 :
1333 : // list of points we expect to visit
1334 1 : std::deque<RealVector_t> visitedVoxels;
1335 1 : visitedVoxels.emplace_back(RealVector_t{{0.5, 0, 0}});
1336 1 : visitedVoxels.emplace_back(RealVector_t{{1.5, 0, 0}});
1337 1 : visitedVoxels.emplace_back(RealVector_t{{2.5, 0, 0}});
1338 :
1339 1 : auto counter = checkTraversal(aabb, ray, visitedVoxels);
1340 :
1341 1 : THEN("Exactly one step is taken")
1342 1 : {
1343 1 : CHECK_EQ(counter, 3);
1344 1 : }
1345 1 : }
1346 1 : }
|