File indexing completed on 2025-01-18 09:12:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/GenericCuboidVolumeBounds.hpp"
0013 #include "Acts/Geometry/Volume.hpp"
0014 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0015 #include "Acts/Utilities/BoundingBox.hpp"
0016 #include "Acts/Utilities/Frustum.hpp"
0017 #include "Acts/Utilities/Ray.hpp"
0018 #include "Acts/Visualization/IVisualization3D.hpp"
0019 #include "Acts/Visualization/PlyVisualization3D.hpp"
0020
0021 #include <algorithm>
0022 #include <array>
0023 #include <cmath>
0024 #include <cstdio>
0025 #include <filesystem>
0026 #include <fstream>
0027 #include <iostream>
0028 #include <memory>
0029 #include <numbers>
0030 #include <set>
0031 #include <sstream>
0032 #include <string>
0033 #include <utility>
0034 #include <vector>
0035
0036 namespace Acts::Test {
0037
0038 struct Object {};
0039
0040 using ObjectBBox = Acts::AxisAlignedBoundingBox<Object, double, 3>;
0041
0042 using Vector2F = Eigen::Matrix<double, 2, 1>;
0043 using Vector3F = Eigen::Matrix<double, 3, 1>;
0044 using AngleAxis3F = Eigen::AngleAxis<double>;
0045
0046 std::filesystem::path tmp_path = []() {
0047 auto tmpPath = std::filesystem::temp_directory_path() / "acts_unit_tests";
0048 std::filesystem::create_directory(tmpPath);
0049 std::cout << "Writing test output to: " << tmpPath << std::endl;
0050 return tmpPath;
0051 }();
0052
0053 std::ofstream tmp(const std::string& path) {
0054 return std::ofstream{(tmp_path / path).string()};
0055 }
0056
0057 BOOST_AUTO_TEST_CASE(box_construction) {
0058 BOOST_TEST_CONTEXT("2D") {
0059 Object o;
0060 using Box = Acts::AxisAlignedBoundingBox<Object, double, 2>;
0061 Box bb(&o, {-1, -1}, {2, 2});
0062
0063 typename Box::transform_type rot;
0064 rot = Eigen::Rotation2D<double>(std::numbers::pi / 7.);
0065 Box bb_rot = bb.transformed(rot);
0066
0067 CHECK_CLOSE_ABS(bb_rot.min(), Vector2F(-1.76874, -1.33485), 1e-4);
0068 CHECK_CLOSE_ABS(bb_rot.max(), Vector2F(2.23582, 2.66971), 1e-4);
0069 }
0070
0071 BOOST_TEST_CONTEXT("3D") {
0072 Object o;
0073 using Box = Acts::AxisAlignedBoundingBox<Object, double, 3>;
0074 Box bb(&o, {-1, -1, -1}, {2, 2, 2});
0075
0076 typename Box::transform_type rot;
0077 rot = AngleAxis3F(std::numbers::pi / 3., Vector3F::UnitZ());
0078 Box bb_rot = bb.transformed(rot);
0079
0080 CHECK_CLOSE_ABS(bb_rot.min(), Vector3F(-2.23205, -1.36603, -1), 1e-4);
0081 CHECK_CLOSE_ABS(bb_rot.max(), Vector3F(1.86603, 2.73205, 2), 1e-4);
0082
0083 rot *= AngleAxis3F(std::numbers::pi / 5., Vector3F(1, 1, 0).normalized());
0084 Box bb_rot2 = bb.transformed(rot);
0085
0086 CHECK_CLOSE_ABS(bb_rot2.min(), Vector3F(-2.40848, -1.51816, -2.0559), 1e-4);
0087 CHECK_CLOSE_ABS(bb_rot2.max(), Vector3F(2.61021, 3.03631, 2.86491), 1e-4);
0088 }
0089 }
0090
0091 BOOST_AUTO_TEST_CASE(intersect_points) {
0092 using VertexType = ObjectBBox::VertexType;
0093
0094 Object o;
0095 ObjectBBox bb(&o, {0, 0, 0}, {1, 1, 1});
0096 VertexType p;
0097
0098 p = {0.5, 0.5, 0.5};
0099 BOOST_CHECK(bb.intersect(p));
0100 p = {0.25, 0.25, 0.25};
0101 BOOST_CHECK(bb.intersect(p));
0102 p = {0.75, 0.75, 0.75};
0103 BOOST_CHECK(bb.intersect(p));
0104
0105
0106 p = {0, 0, 0};
0107 BOOST_CHECK(bb.intersect(p));
0108
0109 p = {1.0, 1.0, 1.0};
0110 BOOST_CHECK(!bb.intersect(p));
0111
0112
0113 p = {2, 0, 0};
0114 BOOST_CHECK(!bb.intersect(p));
0115 p = {0, 2, 0};
0116 BOOST_CHECK(!bb.intersect(p));
0117 p = {0, 0, 2};
0118 BOOST_CHECK(!bb.intersect(p));
0119 p = {2, 2, 0};
0120 BOOST_CHECK(!bb.intersect(p));
0121 p = {2, 0, 2};
0122 BOOST_CHECK(!bb.intersect(p));
0123 p = {2, 2, 2};
0124 BOOST_CHECK(!bb.intersect(p));
0125
0126 p = {-1, 0, 0};
0127 BOOST_CHECK(!bb.intersect(p));
0128 p = {0, -1, 0};
0129 BOOST_CHECK(!bb.intersect(p));
0130 p = {0, 0, -1};
0131 BOOST_CHECK(!bb.intersect(p));
0132 p = {-1, -1, 0};
0133 BOOST_CHECK(!bb.intersect(p));
0134 p = {-1, 0, -1};
0135 BOOST_CHECK(!bb.intersect(p));
0136 p = {-1, -1, -1};
0137 BOOST_CHECK(!bb.intersect(p));
0138 }
0139
0140 BOOST_AUTO_TEST_CASE(intersect_rays) {
0141 BOOST_TEST_CONTEXT("2D") {
0142 using Box = AxisAlignedBoundingBox<Object, double, 2>;
0143
0144 Object o;
0145 Box bb(&o, {-1, -1}, {1, 1});
0146
0147
0148
0149 Ray<double, 2> ray({-2, 0}, {1, 0});
0150 BOOST_CHECK(bb.intersect(ray));
0151
0152 ray = {{-2, 2}, {1, 0}};
0153 BOOST_CHECK(!bb.intersect(ray));
0154
0155 ray = {{-2, -2}, {1, 0}};
0156 BOOST_CHECK(!bb.intersect(ray));
0157
0158
0159
0160
0161
0162
0163 ray = {{-2, -1}, {1, 0}};
0164 BOOST_CHECK(bb.intersect(ray));
0165
0166
0167 ray = {{2, 0}, {1, 0}};
0168 BOOST_CHECK(!bb.intersect(ray));
0169
0170
0171
0172 ray = {{2, 0}, {-1, 0}};
0173 BOOST_CHECK(bb.intersect(ray));
0174
0175 ray = {{2, 2}, {-1, 0}};
0176 BOOST_CHECK(!bb.intersect(ray));
0177
0178 ray = {{2, -2}, {-1, 0}};
0179 BOOST_CHECK(!bb.intersect(ray));
0180
0181
0182
0183
0184
0185
0186 ray = {{2, -1}, {-1, 0}};
0187 BOOST_CHECK(bb.intersect(ray));
0188
0189
0190
0191 ray = {{0, -2}, {0, 1}};
0192 BOOST_CHECK(bb.intersect(ray));
0193
0194 ray = {{2, -2}, {0, 1}};
0195 BOOST_CHECK(!bb.intersect(ray));
0196
0197 ray = {{-2, -2}, {0, 1}};
0198 BOOST_CHECK(!bb.intersect(ray));
0199
0200
0201 ray = {{1, -2}, {0, 1}};
0202 BOOST_CHECK(!bb.intersect(ray));
0203
0204
0205 ray = {{-1, -2}, {0, 1}};
0206 BOOST_CHECK(!bb.intersect(ray));
0207
0208
0209 ray = {{0, -2}, {0, -1}};
0210 BOOST_CHECK(!bb.intersect(ray));
0211
0212
0213
0214 ray = {{0, 2}, {0, -1}};
0215 BOOST_CHECK(bb.intersect(ray));
0216
0217 ray = {{2, 2}, {0, -1}};
0218 BOOST_CHECK(!bb.intersect(ray));
0219
0220 ray = {{-2, 2}, {0, -1}};
0221 BOOST_CHECK(!bb.intersect(ray));
0222
0223
0224 ray = {{1, 2}, {0, -1}};
0225 BOOST_CHECK(!bb.intersect(ray));
0226
0227
0228 ray = {{-1, 2}, {0, -1}};
0229 BOOST_CHECK(!bb.intersect(ray));
0230
0231
0232 ray = {{0, 2}, {0, 1}};
0233 BOOST_CHECK(!bb.intersect(ray));
0234
0235
0236
0237 ray = {{-2, 0}, {0.5, 0.25}};
0238 BOOST_CHECK(bb.intersect(ray));
0239
0240 ray = {{-2, 0}, {0.5, 0.4}};
0241 BOOST_CHECK(bb.intersect(ray));
0242
0243 ray = {{-2, 0}, {0.5, 0.6}};
0244 BOOST_CHECK(!bb.intersect(ray));
0245
0246 ray = {{-2, 0}, {0.5, 0.1}};
0247 BOOST_CHECK(bb.intersect(ray));
0248
0249 ray = {{-2, 0}, {0.5, -0.4}};
0250 BOOST_CHECK(bb.intersect(ray));
0251
0252 ray = {{-2, 0}, {0.5, -0.6}};
0253 BOOST_CHECK(!bb.intersect(ray));
0254
0255 ray = {{-2, 0}, {0.1, 0.5}};
0256 BOOST_CHECK(!bb.intersect(ray));
0257
0258
0259 ray = {{0, 0}, {-1, 0}};
0260 BOOST_CHECK(bb.intersect(ray));
0261 ray = {{0, 0}, {1, 0}};
0262 BOOST_CHECK(bb.intersect(ray));
0263 ray = {{0, 0}, {0, -1}};
0264 BOOST_CHECK(bb.intersect(ray));
0265 ray = {{0, 0}, {0, 1}};
0266 BOOST_CHECK(bb.intersect(ray));
0267 }
0268
0269 BOOST_TEST_CONTEXT("3D visualize") {
0270 Object o;
0271
0272
0273 ObjectBBox bb3(&o, {-1, -1, -1}, {1, 1, 1});
0274 Ray<double, 3> ray3({0, 0, -2}, {0, 0, 1});
0275 BOOST_CHECK(bb3.intersect(ray3));
0276
0277 PlyVisualization3D<double> ply;
0278
0279 ray3.draw(ply);
0280 auto os = tmp("ray3d.ply");
0281 os << ply << std::flush;
0282 os.close();
0283 }
0284
0285 BOOST_TEST_CONTEXT("3D") {
0286 using VertexType3 = ObjectBBox::VertexType;
0287 Object o;
0288
0289
0290 ObjectBBox bb3(&o, {-1, -1, -1}, {1, 1, 1});
0291 Ray<double, 3> ray3({0, 0, -2}, {0, 0, 1});
0292 BOOST_CHECK(bb3.intersect(ray3));
0293
0294
0295 ray3 = {{0, 0, -2}, {0, 0, -1}};
0296 BOOST_CHECK(!bb3.intersect(ray3));
0297
0298 ray3 = {{0, 2, -2}, {0, 0, 1}};
0299 BOOST_CHECK(!bb3.intersect(ray3));
0300
0301 ray3 = {{0, -2, -2}, {0, 0, 1}};
0302 BOOST_CHECK(!bb3.intersect(ray3));
0303
0304
0305
0306
0307
0308
0309 ray3 = {{0, -1, -2}, {0, 0, 1}};
0310 BOOST_CHECK(bb3.intersect(ray3));
0311
0312
0313 ray3 = {{-1, 0, -2}, {0, 0, 1}};
0314 BOOST_CHECK(!bb3.intersect(ray3));
0315
0316
0317 ray3 = {{1, 0, -2}, {0, 0, 1}};
0318 BOOST_CHECK(!bb3.intersect(ray3));
0319
0320 ray3 = {{-0.95, 0, -2}, {0, 0, 1}};
0321 BOOST_CHECK(bb3.intersect(ray3));
0322
0323
0324 ObjectBBox::VertexType p(0, 0, -2);
0325
0326 ray3 = {p, VertexType3(1, 1, 1) - p};
0327 BOOST_CHECK(bb3.intersect(ray3));
0328
0329 ray3 = {p, VertexType3(-1, 1, 1) - p};
0330 BOOST_CHECK(bb3.intersect(ray3));
0331
0332 ray3 = {p, VertexType3(-1, -1, 1) - p};
0333 BOOST_CHECK(bb3.intersect(ray3));
0334
0335 ray3 = {p, VertexType3(1, -1, 1) - p};
0336 BOOST_CHECK(bb3.intersect(ray3));
0337
0338 ray3 = {p, VertexType3(1.1, 0, -1) - p};
0339 BOOST_CHECK(!bb3.intersect(ray3));
0340
0341 ray3 = {p, VertexType3(-1.1, 0, -1) - p};
0342 BOOST_CHECK(!bb3.intersect(ray3));
0343
0344 ray3 = {p, VertexType3(0, 1.1, -1) - p};
0345 BOOST_CHECK(!bb3.intersect(ray3));
0346
0347 ray3 = {p, VertexType3(0, -1.1, -1) - p};
0348 BOOST_CHECK(!bb3.intersect(ray3));
0349
0350 ray3 = {p, VertexType3(0.9, 0, -1) - p};
0351 BOOST_CHECK(bb3.intersect(ray3));
0352
0353 ray3 = {p, VertexType3(-0.9, 0, -1) - p};
0354 BOOST_CHECK(bb3.intersect(ray3));
0355
0356 ray3 = {p, VertexType3(0, 0.9, -1) - p};
0357 BOOST_CHECK(bb3.intersect(ray3));
0358
0359 ray3 = {p, VertexType3(0, -0.9, -1) - p};
0360 BOOST_CHECK(bb3.intersect(ray3));
0361
0362 ray3 = {{0, 0, 0}, {1, 0, 0}};
0363 BOOST_CHECK(bb3.intersect(ray3));
0364 ray3 = {{0, 0, 0}, {0, 1, 0}};
0365 BOOST_CHECK(bb3.intersect(ray3));
0366 ray3 = {{0, 0, 0}, {0, 0, 1}};
0367 BOOST_CHECK(bb3.intersect(ray3));
0368
0369 ray3 = {{0, 0, 0}, {-1, 0, 0}};
0370 BOOST_CHECK(bb3.intersect(ray3));
0371 ray3 = {{0, 0, 0}, {0, -1, 0}};
0372 BOOST_CHECK(bb3.intersect(ray3));
0373 ray3 = {{0, 0, 0}, {0, 0, -1}};
0374 BOOST_CHECK(bb3.intersect(ray3));
0375 }
0376 }
0377
0378 BOOST_AUTO_TEST_CASE(ray_obb_intersect) {
0379 using Ray = Ray<double, 3>;
0380
0381 std::array<Vector3, 8> vertices;
0382 vertices = {{{0, 0, 0},
0383 {2, 0, 0.4},
0384 {2, 1, 0.4},
0385 {0, 1, 0},
0386 {0, 0, 1},
0387 {1.8, 0, 1},
0388 {1.8, 1, 1},
0389 {0, 1, 1}}};
0390 auto cubo = std::make_shared<GenericCuboidVolumeBounds>(vertices);
0391 auto trf = Transform3(
0392 Translation3(Vector3(0, 8, -5)) *
0393 AngleAxis3(std::numbers::pi / 3., Vector3(1, -3, 9).normalized()));
0394
0395 Volume vol(trf, cubo);
0396
0397 PlyVisualization3D<double> ply;
0398
0399 Transform3 trl = Transform3::Identity();
0400 trl.translation() = trf.translation();
0401
0402 cubo->draw(ply);
0403
0404 auto obb = vol.orientedBoundingBox();
0405 obb.draw(ply, {200, 0, 0});
0406
0407 ply.clear();
0408
0409 Vector3 origin(10, -20, 6);
0410 Vector3 centroid(0., 0., 0.);
0411
0412 for (const auto& vtx_ : vertices) {
0413 Vector3 vtx = trf * vtx_;
0414 centroid += vtx;
0415 }
0416
0417
0418 centroid *= 0.125;
0419
0420
0421 for (const auto& vtx_ : vertices) {
0422 Vector3 vtx = trf * vtx_;
0423
0424
0425
0426 Ray ray(origin, (vtx - origin).normalized());
0427 ray = ray.transformed(trf.inverse());
0428 BOOST_CHECK(obb.intersect(ray));
0429 ray.draw(ply, (vtx - origin).norm());
0430
0431
0432
0433 vtx += (vtx - centroid);
0434 ray = Ray(origin, (vtx - origin).normalized());
0435 ray = ray.transformed(trf.inverse());
0436 BOOST_CHECK(!obb.intersect(ray));
0437 ray.draw(ply, (vtx - origin).norm());
0438 }
0439 }
0440
0441 BOOST_AUTO_TEST_CASE(frustum_intersect) {
0442 BOOST_TEST_CONTEXT("2D") {
0443 auto make_svg = [](const std::string& fname, std::size_t width,
0444 std::size_t height) {
0445 auto os = tmp(fname);
0446 os << "<?xml version=\"1.0\" standalone=\"no\"?>\n";
0447 os << "<svg width=\"" << width << "\" height=\"" << height
0448 << "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
0449 return os;
0450 };
0451
0452 using Frustum2 = Frustum<double, 2, 2>;
0453
0454 std::ofstream os;
0455
0456 const std::size_t svgWidth = 1000;
0457 const std::size_t svgHeight = svgWidth;
0458 const std::size_t nSteps = 10;
0459
0460
0461 const double min = -20;
0462 const double max = 20;
0463 os = make_svg("frust2d_parameters.svg", svgWidth, svgHeight);
0464
0465 const double step = (max - min) / nSteps;
0466 for (std::size_t i = 0; i <= nSteps; i++) {
0467 for (std::size_t j = 0; j <= nSteps; j++) {
0468 Vector2F dir(1, 0);
0469 Vector2F origin(min + step * i, min + step * j);
0470 origin.x() *= 1.10;
0471 Eigen::Rotation2D<double> rot(2 * std::numbers::pi / nSteps * i);
0472 double angle = std::numbers::pi / 2. / nSteps * j;
0473 Frustum2 fr(origin, rot * dir, angle);
0474 fr.svg(os, svgWidth, svgHeight, 2);
0475 }
0476 }
0477
0478 os << "</svg>";
0479 os.close();
0480
0481 const double unit = 20.;
0482
0483 using Box = AxisAlignedBoundingBox<Object, double, 2>;
0484 Object o;
0485 Box::Size size(Eigen::Matrix<double, 2, 1>(2, 2));
0486
0487 const double minX = -20.;
0488 const double minY = -20.;
0489 const double maxX = 20.;
0490 const double maxY = 20.;
0491 const double stepX = (maxX - minX) / nSteps;
0492 const double stepY = (maxY - minY) / nSteps;
0493
0494 std::set<std::size_t> idxsAct;
0495
0496
0497 std::vector<std::pair<Frustum2, std::set<std::size_t>>> frExp;
0498 frExp = {
0499 {Frustum2({0, 0}, {1, 0}, std::numbers::pi / 2.),
0500 {60, 70, 71, 72, 80, 81, 82, 83, 84, 90, 91, 92,
0501 93, 94, 95, 96, 100, 101, 102, 103, 104, 105, 106, 107,
0502 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120}
0503 },
0504 {Frustum2({0, 0}, {1, 0}, 0.5 * std::numbers::pi / 2.),
0505 {60, 71, 81, 82, 83, 92, 93, 94, 102,
0506 103, 104, 105, 106, 113, 114, 115, 116, 117}
0507 },
0508 {Frustum2({0, 0}, {1, 0}, 0.2 * std::numbers::pi / 2.),
0509 {60, 71, 82, 93, 104, 114, 115, 116}
0510 },
0511 {Frustum2({0, 0}, {1, 0}, 3 * std::numbers::pi / 4.),
0512 {60, 68, 69, 70, 71, 72, 73, 74, 77, 78, 79, 80, 81, 82, 83,
0513 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
0514 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
0515 112, 113, 114, 115, 116, 117, 118, 119, 120}
0516 },
0517 {Frustum2({0, 0}, {0, 1}, 0.5 * std::numbers::pi / 2.),
0518 {42, 43, 51, 52, 53, 54, 60, 61, 62, 63, 64, 65, 73, 74, 75, 76, 86, 87}
0519 },
0520 {Frustum2({0, 0}, {-1, 0}, 0.5 * std::numbers::pi / 2.),
0521 {3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 26, 27, 28, 37, 38, 39, 49, 60}
0522 },
0523 {Frustum2({0, 0}, {0, -1}, 0.5 * std::numbers::pi / 2.),
0524 {33, 34, 44, 45, 46, 47, 55, 56, 57, 58, 59, 60, 66, 67, 68, 69, 77, 78}
0525 },
0526 {Frustum2({0, 0}, {1, 1}, 0.5 * std::numbers::pi / 2.),
0527 {60, 72, 73, 74, 83, 84, 85, 86, 87, 94, 95, 96, 97, 98, 106, 107,
0528 108, 109, 117, 118, 119, 120}
0529 },
0530 {Frustum2({0, 0}, {-1, 1}, 0.5 * std::numbers::pi / 2.),
0531 {7, 8, 9, 10, 18, 19, 20, 21, 28, 29, 30, 31, 32, 39, 40, 41, 42,
0532 43, 50, 51, 52, 60}
0533 },
0534 {Frustum2({0, 0}, {-1, -1}, 0.5 * std::numbers::pi / 2.),
0535 {0, 1, 2, 3, 11, 12, 13, 14, 22, 23, 24, 25, 26, 33, 34, 35, 36,
0536 37, 46, 47, 48, 60}
0537 },
0538 {Frustum2({0, 0}, {1, -1}, 0.5 * std::numbers::pi / 2.),
0539 {60, 68, 69, 70, 77, 78, 79, 80, 81, 88, 89, 90, 91, 92, 99, 100,
0540 101, 102, 110, 111, 112, 113}
0541 },
0542 {Frustum2({1, 1}, {1, -1}, std::numbers::pi / 2.),
0543 {55, 56, 57, 58, 59, 60, 66, 67, 68, 69, 70, 71, 77, 78, 79, 80,
0544 81, 82, 88, 89, 90, 91, 92, 93, 99, 100, 101, 102, 103, 104, 110, 111, 112, 113, 114, 115}
0545 },
0546 {Frustum2({-1, -1}, {1, -1}, std::numbers::pi / 2.),
0547 {55, 56, 57, 58, 59, 60, 66, 67, 68, 69, 70, 71, 77, 78, 79, 80,
0548 81, 82, 88, 89, 90, 91, 92, 93, 99, 100, 101, 102, 103, 104, 110, 111, 112, 113, 114, 115}
0549 },
0550 {Frustum2({10, -10}, {1, 1}, 0.5 * std::numbers::pi / 2.),
0551 {91, 92, 102, 103, 104, 105, 114, 115, 116, 117, 118, 119}
0552 },
0553 {Frustum2({-10.3, 12.8}, {0.3, -1}, 0.5 * std::numbers::pi / 2.),
0554 {22, 23, 24, 25, 26, 27, 28, 33, 34, 35, 36, 37, 38, 39, 40, 41,
0555 44, 45, 46, 47, 48, 49, 50, 55, 56, 57, 58, 59, 60, 66, 67, 68,
0556 69, 70, 77, 78, 79, 80, 88, 89, 99}
0557 },
0558 {Frustum2({17.2, 19.45}, {-1, -0.1}, 0.5 * std::numbers::pi / 2.),
0559 {5, 6, 7, 8, 9, 10, 17, 18, 19, 20, 21, 28, 29, 30, 31, 32, 40,
0560 41, 42, 43, 51, 52, 53, 54, 63, 64, 65, 74, 75, 76, 86, 87, 97,
0561 98, 109}
0562 },
0563 };
0564
0565
0566 for (std::size_t l = 0; l < frExp.size(); l++) {
0567 const Frustum2& fr = frExp.at(l).first;
0568 const std::set<std::size_t>& idxsExp = frExp.at(l).second;
0569 std::stringstream ss;
0570 ss << "frust2d_test_" << l << ".svg";
0571 os = make_svg(ss.str(), svgWidth, svgHeight);
0572
0573 idxsAct.clear();
0574
0575 std::vector<Box> boxes;
0576 boxes.reserve((nSteps + 1) * (nSteps + 1));
0577 for (std::size_t i = 0; i <= nSteps; i++) {
0578 for (std::size_t j = 0; j <= nSteps; j++) {
0579 boxes.emplace_back(
0580 &o,
0581 Eigen::Matrix<double, 2, 1>{minX + i * stepX, minY + j * stepY},
0582 size);
0583 std::stringstream st;
0584 st << boxes.size() - 1;
0585
0586 std::string color = "red";
0587 if (boxes.back().intersect(fr)) {
0588 color = "green";
0589 idxsAct.insert(boxes.size() - 1);
0590 }
0591
0592 boxes.back().svg(os, svgWidth, svgHeight, unit, st.str(), color);
0593 }
0594 }
0595
0596 BOOST_CHECK(idxsAct == idxsExp);
0597
0598 fr.svg(os, svgWidth, svgHeight, maxX, unit);
0599 os << "</svg>";
0600
0601 os.close();
0602 }
0603 }
0604
0605 PlyVisualization3D<double> helper;
0606 BOOST_TEST_CONTEXT("3D - 3 Sides") {
0607 using Frustum3 = Frustum<double, 3, 3>;
0608 std::ofstream os;
0609 std::size_t n = 10;
0610 const std::size_t nSteps = 5;
0611 double min = -10;
0612 double max = 10;
0613 double step = (max - min) / nSteps;
0614
0615
0616 auto make = [&](double angle, const Vector3F& origin,
0617 std::ofstream& osTmp) {
0618 helper.clear();
0619 double far = 1.;
0620 Frustum3 fr(origin, {0, 0, 1}, angle);
0621 fr.draw(helper, far);
0622 fr = Frustum3(origin, {0, 0, -1}, angle);
0623 fr.draw(helper, far);
0624 fr = Frustum3(origin, {1, 0, 0}, angle);
0625 fr.draw(helper, far);
0626 fr = Frustum3(origin, {-1, 0, 0}, angle);
0627 fr.draw(helper, far);
0628
0629 fr = Frustum3(origin, {0, 1, 0}, angle);
0630 fr.draw(helper, far);
0631 fr = Frustum3(origin, {0, -1, 0}, angle);
0632 fr.draw(helper, far);
0633
0634 osTmp << helper << std::flush;
0635
0636 helper.clear();
0637 };
0638
0639 os = std::ofstream("frust3d_dir.ply");
0640 for (std::size_t i = 0; i <= nSteps; i++) {
0641 for (std::size_t j = 0; j <= nSteps; j++) {
0642 for (std::size_t k = 0; k <= nSteps; k++) {
0643 Vector3F origin(min + i * step, min + j * step, min + k * step);
0644 make(std::numbers::pi / 4., origin, os);
0645 }
0646 }
0647 }
0648 os.close();
0649
0650 os = tmp("frust3D_angle.ply");
0651 helper.clear();
0652 for (std::size_t i = 0; i <= n; i++) {
0653 Vector3F origin(i * 4, 0, 0);
0654 AngleAxis3F rot(std::numbers::pi / n * i, Vector3F::UnitY());
0655 double angle = (std::numbers::pi / 2.) / n * (1 + i);
0656 Vector3F dir(1, 0, 0);
0657 Frustum3 fr(origin, rot * dir, angle);
0658 fr.draw(helper, 2);
0659 }
0660
0661 os << helper << std::flush;
0662 os.close();
0663
0664 std::set<std::size_t> idxsAct;
0665
0666 std::vector<std::pair<Frustum3, std::set<std::size_t>>> frExp;
0667 frExp = {
0668 {Frustum3({0, 0, 0}, {1, 0, 0}, std::numbers::pi / 2.),
0669 {
0670 665, 763, 774, 775, 785, 786, 787, 788, 796, 797, 807,
0671 872, 873, 883, 884, 885, 886, 894, 895, 896, 897, 898,
0672 905, 906, 907, 908, 909, 910, 911, 916, 917, 918, 919,
0673 920, 927, 928, 929, 930, 938, 939, 970, 971, 981, 982,
0674 983, 992, 993, 994, 995, 996, 1003, 1004, 1005, 1006, 1007,
0675 1008, 1009, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1025,
0676 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1036, 1037, 1038,
0677 1039, 1040, 1041, 1042, 1043, 1047, 1048, 1049, 1050, 1051, 1052,
0678 1053, 1058, 1059, 1060, 1061, 1062, 1069, 1070, 1071, 1080, 1081,
0679 1090, 1091, 1092, 1093, 1094, 1101, 1102, 1103, 1104, 1105, 1106,
0680 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1123, 1124, 1125,
0681 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1134, 1135, 1136, 1137,
0682 1138, 1139, 1140, 1141, 1142, 1143, 1145, 1146, 1147, 1148, 1149,
0683 1150, 1151, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1160, 1161,
0684 1162, 1163, 1164, 1165, 1167, 1168, 1169, 1170, 1171, 1172, 1173,
0685 1174, 1175, 1176, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185,
0686 1189, 1190, 1191, 1192, 1193, 1194, 1200, 1201, 1202, 1203, 1204,
0687 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1221, 1222, 1223,
0688 1224, 1225, 1226, 1227, 1228, 1229, 1232, 1233, 1234, 1235, 1236,
0689 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247,
0690 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258,
0691 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269,
0692 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280,
0693 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291,
0694 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302,
0695 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313,
0696 1314, 1315, 1316, 1317, 1320, 1321, 1322, 1323, 1324, 1325, 1326,
0697 1327,
0698 }},
0699 {Frustum3({0, 0, 0}, {0, 1, 0}, std::numbers::pi / 2.),
0700 {93, 102, 103, 104, 105, 106, 112, 113, 114, 115, 116,
0701 117, 118, 203, 213, 214, 215, 223, 224, 225, 226, 227,
0702 233, 234, 235, 236, 237, 238, 239, 324, 333, 334, 335,
0703 336, 337, 343, 344, 345, 346, 347, 348, 349, 353, 354,
0704 355, 356, 357, 358, 359, 360, 361, 434, 444, 445, 446,
0705 454, 455, 456, 457, 458, 464, 465, 466, 467, 468, 469,
0706 470, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482,
0707 483, 555, 564, 565, 566, 567, 568, 574, 575, 576, 577,
0708 578, 579, 580, 584, 585, 586, 587, 588, 589, 590, 591,
0709 592, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603,
0710 604, 665, 675, 676, 677, 685, 686, 687, 688, 689, 695,
0711 696, 697, 698, 699, 700, 701, 704, 705, 706, 707, 708,
0712 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719,
0713 720, 721, 722, 723, 724, 725, 795, 796, 797, 798, 799,
0714 805, 806, 807, 808, 809, 810, 811, 815, 816, 817, 818,
0715 819, 820, 821, 822, 823, 825, 826, 827, 828, 829, 830,
0716 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841,
0717 842, 843, 844, 845, 846, 926, 927, 928, 929, 930, 931,
0718 932, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944,
0719 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955,
0720 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966,
0721 967, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065,
0722 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076,
0723 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087,
0724 1088, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197,
0725 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208,
0726 1209, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329,
0727 1330}},
0728 {Frustum3({0, 0, 0}, {0, 0, 1}, std::numbers::pi / 2.),
0729 {32, 42, 43, 53, 54, 63, 64, 65, 75, 76, 86,
0730 87, 98, 153, 163, 164, 173, 174, 175, 183, 184, 185,
0731 186, 195, 196, 197, 207, 208, 219, 263, 273, 274, 283,
0732 284, 285, 294, 295, 296, 304, 305, 306, 307, 316, 317,
0733 318, 327, 328, 329, 339, 340, 351, 373, 384, 394, 395,
0734 404, 405, 406, 414, 415, 416, 417, 424, 425, 426, 427,
0735 428, 436, 437, 438, 439, 448, 449, 450, 460, 461, 472,
0736 483, 494, 504, 505, 514, 515, 516, 524, 525, 526, 527,
0737 535, 536, 537, 538, 545, 546, 547, 548, 549, 557, 558,
0738 559, 560, 568, 569, 570, 571, 580, 581, 582, 592, 593,
0739 604, 614, 615, 625, 626, 635, 636, 637, 645, 646, 647,
0740 648, 655, 656, 657, 658, 659, 665, 666, 667, 668, 669,
0741 670, 677, 678, 679, 680, 681, 689, 690, 691, 692, 701,
0742 702, 703, 713, 714, 724, 725, 735, 736, 745, 746, 747,
0743 755, 756, 757, 758, 765, 766, 767, 768, 769, 776, 777,
0744 778, 779, 780, 787, 788, 789, 790, 791, 798, 799, 800,
0745 801, 802, 809, 810, 811, 812, 813, 821, 822, 823, 824,
0746 833, 834, 835, 845, 846, 855, 856, 857, 866, 867, 868,
0747 876, 877, 878, 879, 887, 888, 889, 890, 898, 899, 900,
0748 901, 909, 910, 911, 912, 920, 921, 922, 923, 931, 932,
0749 933, 934, 942, 943, 944, 945, 954, 955, 956, 965, 966,
0750 967, 976, 977, 978, 987, 988, 989, 998, 999, 1000, 1009,
0751 1010, 1011, 1020, 1021, 1022, 1031, 1032, 1033, 1042, 1043, 1044,
0752 1053, 1054, 1055, 1064, 1065, 1066, 1075, 1076, 1077, 1086, 1087,
0753 1088, 1098, 1099, 1109, 1110, 1120, 1121, 1131, 1132, 1142, 1143,
0754 1153, 1154, 1164, 1165, 1175, 1176, 1186, 1187, 1197, 1198, 1208,
0755 1209, 1220, 1231, 1242, 1253, 1264, 1275, 1286, 1297, 1308, 1319,
0756 1330}},
0757 {Frustum3({0, 0, 0}, {0, 0, 1}, std::numbers::pi / 4.),
0758 {186, 305, 306, 307, 416, 417, 425, 426, 427, 428, 438, 439,
0759 527, 536, 537, 538, 545, 546, 547, 548, 549, 558, 559, 560,
0760 571, 647, 648, 656, 657, 658, 659, 665, 666, 667, 668, 669,
0761 670, 678, 679, 680, 681, 691, 692, 758, 767, 768, 769, 777,
0762 778, 779, 780, 788, 789, 790, 791, 799, 800, 801, 802, 811,
0763 812, 813, 824, 879, 890, 901, 912, 923, 934, 945}},
0764 {Frustum3({0, 0, 0}, {0, 0, 1}, std::numbers::pi / 8.),
0765 {427, 428, 546, 547, 548, 549, 658, 659, 665, 666, 667, 668, 669, 670,
0766 680, 681, 780, 791, 802}},
0767 {Frustum3({0, 0, 0}, {0, 0, 1}, std::numbers::pi * 3. / 4.),
0768 {8, 9, 10, 19, 20, 21, 29, 30, 31, 32, 40,
0769 41, 42, 43, 51, 52, 53, 54, 61, 62, 63, 64,
0770 65, 73, 74, 75, 76, 84, 85, 86, 87, 95, 96,
0771 97, 98, 107, 108, 109, 118, 119, 120, 129, 130, 131,
0772 140, 141, 142, 150, 151, 152, 153, 161, 162, 163, 164,
0773 171, 172, 173, 174, 175, 182, 183, 184, 185, 186, 193,
0774 194, 195, 196, 197, 205, 206, 207, 208, 216, 217, 218,
0775 219, 228, 229, 230, 239, 240, 241, 250, 251, 252, 260,
0776 261, 262, 263, 271, 272, 273, 274, 282, 283, 284, 285,
0777 292, 293, 294, 295, 296, 303, 304, 305, 306, 307, 314,
0778 315, 316, 317, 318, 326, 327, 328, 329, 337, 338, 339,
0779 340, 348, 349, 350, 351, 360, 361, 362, 370, 371, 372,
0780 373, 381, 382, 383, 384, 392, 393, 394, 395, 402, 403,
0781 404, 405, 406, 413, 414, 415, 416, 417, 424, 425, 426,
0782 427, 428, 435, 436, 437, 438, 439, 446, 447, 448, 449,
0783 450, 458, 459, 460, 461, 469, 470, 471, 472, 480, 481,
0784 482, 483, 491, 492, 493, 494, 502, 503, 504, 505, 513,
0785 514, 515, 516, 523, 524, 525, 526, 527, 534, 535, 536,
0786 537, 538, 544, 545, 546, 547, 548, 549, 556, 557, 558,
0787 559, 560, 567, 568, 569, 570, 571, 579, 580, 581, 582,
0788 590, 591, 592, 593, 601, 602, 603, 604, 612, 613, 614,
0789 615, 623, 624, 625, 626, 633, 634, 635, 636, 637, 644,
0790 645, 646, 647, 648, 655, 656, 657, 658, 659, 665, 666,
0791 667, 668, 669, 670, 677, 678, 679, 680, 681, 688, 689,
0792 690, 691, 692, 699, 700, 701, 702, 703, 711, 712, 713,
0793 714, 722, 723, 724, 725, 733, 734, 735, 736, 743, 744,
0794 745, 746, 747, 754, 755, 756, 757, 758, 765, 766, 767,
0795 768, 769, 776, 777, 778, 779, 780, 787, 788, 789, 790,
0796 791, 798, 799, 800, 801, 802, 809, 810, 811, 812, 813,
0797 820, 821, 822, 823, 824, 831, 832, 833, 834, 835, 843,
0798 844, 845, 846, 854, 855, 856, 857, 864, 865, 866, 867,
0799 868, 875, 876, 877, 878, 879, 886, 887, 888, 889, 890,
0800 897, 898, 899, 900, 901, 908, 909, 910, 911, 912, 919,
0801 920, 921, 922, 923, 930, 931, 932, 933, 934, 941, 942,
0802 943, 944, 945, 952, 953, 954, 955, 956, 964, 965, 966,
0803 967, 975, 976, 977, 978, 986, 987, 988, 989, 997, 998,
0804 999, 1000, 1008, 1009, 1010, 1011, 1019, 1020, 1021, 1022, 1030,
0805 1031, 1032, 1033, 1041, 1042, 1043, 1044, 1052, 1053, 1054, 1055,
0806 1063, 1064, 1065, 1066, 1074, 1075, 1076, 1077, 1085, 1086, 1087,
0807 1088, 1096, 1097, 1098, 1099, 1107, 1108, 1109, 1110, 1118, 1119,
0808 1120, 1121, 1129, 1130, 1131, 1132, 1140, 1141, 1142, 1143, 1151,
0809 1152, 1153, 1154, 1162, 1163, 1164, 1165, 1173, 1174, 1175, 1176,
0810 1184, 1185, 1186, 1187, 1195, 1196, 1197, 1198, 1206, 1207, 1208,
0811 1209, 1217, 1218, 1219, 1220, 1228, 1229, 1230, 1231, 1239, 1240,
0812 1241, 1242, 1250, 1251, 1252, 1253, 1261, 1262, 1263, 1264, 1272,
0813 1273, 1274, 1275, 1283, 1284, 1285, 1286, 1294, 1295, 1296, 1297,
0814 1305, 1306, 1307, 1308, 1316, 1317, 1318, 1319, 1327, 1328, 1329,
0815 1330}},
0816 {Frustum3({1.3, -5.9, 3.5}, {0.2, 0.4, 1}, std::numbers::pi / 3.),
0817 {318, 426, 427, 428, 438, 439, 450, 538, 546, 547, 548,
0818 549, 558, 559, 560, 570, 571, 582, 655, 656, 657, 658,
0819 659, 667, 668, 669, 670, 678, 679, 680, 681, 690, 691,
0820 692, 702, 703, 714, 768, 769, 777, 778, 779, 780, 787,
0821 788, 789, 790, 791, 799, 800, 801, 802, 810, 811, 812,
0822 813, 822, 823, 824, 834, 835, 846, 888, 889, 890, 899,
0823 900, 901, 910, 911, 912, 920, 921, 922, 923, 931, 932,
0824 933, 934, 942, 943, 944, 945, 954, 955, 956, 966, 967,
0825 1000, 1010, 1011, 1021, 1022, 1032, 1033, 1042, 1043, 1044, 1053,
0826 1054, 1055, 1064, 1065, 1066, 1074, 1075, 1076, 1077, 1086, 1087,
0827 1088, 1143, 1154, 1165, 1175, 1176, 1186, 1187, 1197, 1198, 1207,
0828 1208, 1209, 1308, 1319, 1330}}};
0829
0830 for (std::size_t l = 0; l < frExp.size(); l++) {
0831 const Frustum3& fr = frExp.at(l).first;
0832 const std::set<std::size_t>& idxsExp = frExp.at(l).second;
0833 std::stringstream ss;
0834 ss << "frust3d-3s_test_" << l << ".ply";
0835
0836 os = tmp(ss.str());
0837
0838 helper.clear();
0839
0840 idxsAct.clear();
0841
0842 fr.draw(helper, 50);
0843
0844 n = 10;
0845 min = -33;
0846 max = 33;
0847 step = (max - min) / n;
0848
0849 Object o;
0850 using Box = AxisAlignedBoundingBox<Object, double, 3>;
0851 Box::Size size(Eigen::Matrix<double, 3, 1>(2, 2, 2));
0852
0853 std::size_t idx = 0;
0854
0855 for (std::size_t i = 0; i <= n; i++) {
0856 for (std::size_t j = 0; j <= n; j++) {
0857 for (std::size_t k = 0; k <= n; k++) {
0858 Eigen::Matrix<double, 3, 1> pos(min + i * step, min + j * step,
0859 min + k * step);
0860 Box bb(&o, pos, size);
0861
0862 Color color = {255, 0, 0};
0863
0864 if (bb.intersect(fr)) {
0865 color = {0, 255, 0};
0866 idxsAct.insert(idx);
0867 }
0868
0869 bb.draw(helper, color);
0870 idx++;
0871 }
0872 }
0873 }
0874
0875 os << helper << std::flush;
0876 os.close();
0877
0878 BOOST_CHECK(idxsAct == idxsExp);
0879 }
0880 }
0881
0882 BOOST_TEST_CONTEXT("3D - 4 Sides") {
0883 using Frustum34 = Frustum<double, 3, 4>;
0884 const std::size_t n = 10;
0885 double min = -10;
0886 double max = 10;
0887 const std::size_t s = 5;
0888 double step = (max - min) / s;
0889 std::ofstream os;
0890
0891
0892 helper.clear();
0893 os = tmp("frust3d-4s_dir.ply");
0894
0895 const double constAngle = std::numbers::pi / 4.;
0896 for (std::size_t i = 0; i <= s; i++) {
0897 for (std::size_t j = 0; j <= s; j++) {
0898 for (std::size_t k = 0; k <= s; k++) {
0899 Vector3F origin(min + i * step, min + j * step, min + k * step);
0900 Vector3F dir(1, 0, 0);
0901
0902 double piOverS = std::numbers::pi / s;
0903 AngleAxis3F rot;
0904 rot = AngleAxis3F(piOverS * i, Vector3F::UnitX()) *
0905 AngleAxis3F(piOverS * j, Vector3F::UnitY()) *
0906 AngleAxis3F(piOverS * k, Vector3F::UnitZ());
0907
0908 Frustum34 fr(origin, rot * dir, constAngle);
0909 fr.draw(helper, 1);
0910 }
0911 }
0912 }
0913
0914 os << helper << std::flush;
0915 os.close();
0916
0917 os = tmp("frust3d-4s_angle.ply");
0918 helper.clear();
0919
0920 for (std::size_t i = 0; i <= n; i++) {
0921 Vector3F origin(i * 4, 0, 0);
0922 AngleAxis3F rot(std::numbers::pi / n * i, Vector3F::UnitY());
0923 const double angle = (std::numbers::pi / 2.) / n * (1 + i);
0924 Vector3F dir(1, 0, 0);
0925 Frustum34 fr(origin, rot * dir, angle);
0926 fr.draw(helper, 2);
0927 }
0928
0929 os << helper << std::flush;
0930 os.close();
0931
0932 std::set<std::size_t> idxsAct;
0933
0934 std::vector<std::pair<Frustum34, std::set<std::size_t>>> frExp;
0935 frExp = {
0936 {Frustum34({0, 0, 0}, {1, 0, 0}, std::numbers::pi / 2.),
0937 {665, 774, 775, 776, 785, 786, 787, 796, 797, 798, 883,
0938 884, 885, 886, 887, 894, 895, 896, 897, 898, 905, 906,
0939 907, 908, 909, 916, 917, 918, 919, 920, 927, 928, 929,
0940 930, 931, 992, 993, 994, 995, 996, 997, 998, 1003, 1004,
0941 1005, 1006, 1007, 1008, 1009, 1014, 1015, 1016, 1017, 1018, 1019,
0942 1020, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1036, 1037, 1038,
0943 1039, 1040, 1041, 1042, 1047, 1048, 1049, 1050, 1051, 1052, 1053,
0944 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1101, 1102, 1103, 1104,
0945 1105, 1106, 1107, 1108, 1109, 1112, 1113, 1114, 1115, 1116, 1117,
0946 1118, 1119, 1120, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130,
0947 1131, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1145,
0948 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1156, 1157, 1158,
0949 1159, 1160, 1161, 1162, 1163, 1164, 1167, 1168, 1169, 1170, 1171,
0950 1172, 1173, 1174, 1175, 1178, 1179, 1180, 1181, 1182, 1183, 1184,
0951 1185, 1186, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197,
0952 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220,
0953 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231,
0954 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242,
0955 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253,
0956 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264,
0957 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275,
0958 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286,
0959 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297,
0960 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308,
0961 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319,
0962 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330}},
0963 {Frustum34({0, 0, 0}, {0, 1, 0}, std::numbers::pi / 2.),
0964 {110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
0965 221, 222, 223, 224, 225, 226, 227, 228, 229, 231, 232,
0966 233, 234, 235, 236, 237, 238, 239, 240, 241, 332, 333,
0967 334, 335, 336, 337, 338, 342, 343, 344, 345, 346, 347,
0968 348, 349, 350, 352, 353, 354, 355, 356, 357, 358, 359,
0969 360, 361, 362, 443, 444, 445, 446, 447, 453, 454, 455,
0970 456, 457, 458, 459, 463, 464, 465, 466, 467, 468, 469,
0971 470, 471, 473, 474, 475, 476, 477, 478, 479, 480, 481,
0972 482, 483, 554, 555, 556, 564, 565, 566, 567, 568, 574,
0973 575, 576, 577, 578, 579, 580, 584, 585, 586, 587, 588,
0974 589, 590, 591, 592, 594, 595, 596, 597, 598, 599, 600,
0975 601, 602, 603, 604, 665, 675, 676, 677, 685, 686, 687,
0976 688, 689, 695, 696, 697, 698, 699, 700, 701, 705, 706,
0977 707, 708, 709, 710, 711, 712, 713, 715, 716, 717, 718,
0978 719, 720, 721, 722, 723, 724, 725, 796, 797, 798, 806,
0979 807, 808, 809, 810, 816, 817, 818, 819, 820, 821, 822,
0980 826, 827, 828, 829, 830, 831, 832, 833, 834, 836, 837,
0981 838, 839, 840, 841, 842, 843, 844, 845, 846, 927, 928,
0982 929, 930, 931, 937, 938, 939, 940, 941, 942, 943, 947,
0983 948, 949, 950, 951, 952, 953, 954, 955, 957, 958, 959,
0984 960, 961, 962, 963, 964, 965, 966, 967, 1058, 1059, 1060,
0985 1061, 1062, 1063, 1064, 1068, 1069, 1070, 1071, 1072, 1073, 1074,
0986 1075, 1076, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086,
0987 1087, 1088, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197,
0988 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209,
0989 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330}},
0990 {Frustum34({0, 0, 0}, {0, 0, 1}, std::numbers::pi / 2.),
0991 {10, 21, 32, 43, 54, 65, 76, 87, 98, 109, 120,
0992 131, 141, 142, 152, 153, 163, 164, 174, 175, 185, 186,
0993 196, 197, 207, 208, 218, 219, 229, 230, 241, 252, 262,
0994 263, 272, 273, 274, 283, 284, 285, 294, 295, 296, 305,
0995 306, 307, 316, 317, 318, 327, 328, 329, 338, 339, 340,
0996 350, 351, 362, 373, 383, 384, 393, 394, 395, 403, 404,
0997 405, 406, 414, 415, 416, 417, 425, 426, 427, 428, 436,
0998 437, 438, 439, 447, 448, 449, 450, 459, 460, 461, 471,
0999 472, 483, 494, 504, 505, 514, 515, 516, 524, 525, 526,
1000 527, 534, 535, 536, 537, 538, 545, 546, 547, 548, 549,
1001 556, 557, 558, 559, 560, 568, 569, 570, 571, 580, 581,
1002 582, 592, 593, 604, 615, 625, 626, 635, 636, 637, 645,
1003 646, 647, 648, 655, 656, 657, 658, 659, 665, 666, 667,
1004 668, 669, 670, 677, 678, 679, 680, 681, 689, 690, 691,
1005 692, 701, 702, 703, 713, 714, 725, 736, 746, 747, 756,
1006 757, 758, 766, 767, 768, 769, 776, 777, 778, 779, 780,
1007 787, 788, 789, 790, 791, 798, 799, 800, 801, 802, 810,
1008 811, 812, 813, 822, 823, 824, 834, 835, 846, 857, 867,
1009 868, 877, 878, 879, 887, 888, 889, 890, 898, 899, 900,
1010 901, 909, 910, 911, 912, 920, 921, 922, 923, 931, 932,
1011 933, 934, 943, 944, 945, 955, 956, 967, 978, 988, 989,
1012 998, 999, 1000, 1009, 1010, 1011, 1020, 1021, 1022, 1031, 1032,
1013 1033, 1042, 1043, 1044, 1053, 1054, 1055, 1064, 1065, 1066, 1076,
1014 1077, 1088, 1099, 1109, 1110, 1120, 1121, 1131, 1132, 1142, 1143,
1015 1153, 1154, 1164, 1165, 1175, 1176, 1186, 1187, 1197, 1198, 1209,
1016 1220, 1231, 1242, 1253, 1264, 1275, 1286, 1297, 1308, 1319, 1330}},
1017 {Frustum34({0, 0, 0}, {0, 0, 1}, std::numbers::pi / 4.),
1018 {406, 417, 428, 439, 450, 527, 535, 536, 537, 538, 546, 547, 548, 549,
1019 557, 558, 559, 560, 571, 648, 656, 657, 658, 659, 665, 666, 667, 668,
1020 669, 670, 678, 679, 680, 681, 692, 769, 777, 778, 779, 780, 788, 789,
1021 790, 791, 799, 800, 801, 802, 813, 890, 901, 912, 923, 934}},
1022 {Frustum34({0, 0, 0}, {0, 0, 1}, std::numbers::pi / 8.),
1023 {538, 549, 560, 659, 665, 666, 667, 668, 669, 670, 681, 780, 791,
1024 802}},
1025 {Frustum34({0, 0, 0}, {0, 0, 1}, std::numbers::pi * 3. / 4.),
1026 {7, 8, 9, 10, 18, 19, 20, 21, 29, 30, 31,
1027 32, 40, 41, 42, 43, 51, 52, 53, 54, 62, 63,
1028 64, 65, 73, 74, 75, 76, 84, 85, 86, 87, 95,
1029 96, 97, 98, 106, 107, 108, 109, 117, 118, 119, 120,
1030 128, 129, 130, 131, 139, 140, 141, 142, 150, 151, 152,
1031 153, 161, 162, 163, 164, 172, 173, 174, 175, 183, 184,
1032 185, 186, 194, 195, 196, 197, 205, 206, 207, 208, 216,
1033 217, 218, 219, 227, 228, 229, 230, 238, 239, 240, 241,
1034 249, 250, 251, 252, 260, 261, 262, 263, 271, 272, 273,
1035 274, 282, 283, 284, 285, 293, 294, 295, 296, 304, 305,
1036 306, 307, 315, 316, 317, 318, 326, 327, 328, 329, 337,
1037 338, 339, 340, 348, 349, 350, 351, 359, 360, 361, 362,
1038 370, 371, 372, 373, 381, 382, 383, 384, 392, 393, 394,
1039 395, 402, 403, 404, 405, 406, 413, 414, 415, 416, 417,
1040 424, 425, 426, 427, 428, 435, 436, 437, 438, 439, 446,
1041 447, 448, 449, 450, 458, 459, 460, 461, 469, 470, 471,
1042 472, 480, 481, 482, 483, 491, 492, 493, 494, 502, 503,
1043 504, 505, 513, 514, 515, 516, 523, 524, 525, 526, 527,
1044 534, 535, 536, 537, 538, 545, 546, 547, 548, 549, 556,
1045 557, 558, 559, 560, 567, 568, 569, 570, 571, 579, 580,
1046 581, 582, 590, 591, 592, 593, 601, 602, 603, 604, 612,
1047 613, 614, 615, 623, 624, 625, 626, 634, 635, 636, 637,
1048 644, 645, 646, 647, 648, 655, 656, 657, 658, 659, 665,
1049 666, 667, 668, 669, 670, 677, 678, 679, 680, 681, 688,
1050 689, 690, 691, 692, 700, 701, 702, 703, 711, 712, 713,
1051 714, 722, 723, 724, 725, 733, 734, 735, 736, 744, 745,
1052 746, 747, 755, 756, 757, 758, 765, 766, 767, 768, 769,
1053 776, 777, 778, 779, 780, 787, 788, 789, 790, 791, 798,
1054 799, 800, 801, 802, 809, 810, 811, 812, 813, 821, 822,
1055 823, 824, 832, 833, 834, 835, 843, 844, 845, 846, 854,
1056 855, 856, 857, 865, 866, 867, 868, 876, 877, 878, 879,
1057 886, 887, 888, 889, 890, 897, 898, 899, 900, 901, 908,
1058 909, 910, 911, 912, 919, 920, 921, 922, 923, 930, 931,
1059 932, 933, 934, 942, 943, 944, 945, 953, 954, 955, 956,
1060 964, 965, 966, 967, 975, 976, 977, 978, 986, 987, 988,
1061 989, 997, 998, 999, 1000, 1008, 1009, 1010, 1011, 1019, 1020,
1062 1021, 1022, 1030, 1031, 1032, 1033, 1041, 1042, 1043, 1044, 1052,
1063 1053, 1054, 1055, 1063, 1064, 1065, 1066, 1074, 1075, 1076, 1077,
1064 1085, 1086, 1087, 1088, 1096, 1097, 1098, 1099, 1107, 1108, 1109,
1065 1110, 1118, 1119, 1120, 1121, 1129, 1130, 1131, 1132, 1140, 1141,
1066 1142, 1143, 1151, 1152, 1153, 1154, 1162, 1163, 1164, 1165, 1173,
1067 1174, 1175, 1176, 1184, 1185, 1186, 1187, 1195, 1196, 1197, 1198,
1068 1206, 1207, 1208, 1209, 1217, 1218, 1219, 1220, 1228, 1229, 1230,
1069 1231, 1239, 1240, 1241, 1242, 1250, 1251, 1252, 1253, 1261, 1262,
1070 1263, 1264, 1272, 1273, 1274, 1275, 1283, 1284, 1285, 1286, 1294,
1071 1295, 1296, 1297, 1305, 1306, 1307, 1308, 1316, 1317, 1318, 1319,
1072 1327, 1328, 1329, 1330}},
1073 {Frustum34({1.3, -5.9, 3.5}, {0.2, 0.4, 1}, std::numbers::pi / 3.),
1074 {461, 472, 537, 538, 548, 549, 558, 559, 560, 569, 570,
1075 571, 581, 582, 593, 655, 656, 657, 658, 659, 666, 667,
1076 668, 669, 670, 678, 679, 680, 681, 690, 691, 692, 702,
1077 703, 714, 777, 778, 779, 780, 787, 788, 789, 790, 791,
1078 799, 800, 801, 802, 811, 812, 813, 823, 824, 835, 846,
1079 899, 900, 901, 910, 911, 912, 920, 921, 922, 923, 932,
1080 933, 934, 944, 945, 955, 956, 967, 1021, 1022, 1032, 1033,
1081 1042, 1043, 1044, 1053, 1054, 1055, 1064, 1065, 1066, 1076, 1077,
1082 1088, 1143, 1154, 1165, 1175, 1176, 1186, 1187, 1197, 1198, 1209,
1083 1308, 1319, 1330}}};
1084
1085 min = -33;
1086 max = 33;
1087 step = (max - min) / n;
1088
1089 for (std::size_t l = 0; l < frExp.size(); l++) {
1090 const Frustum34& fr = frExp.at(l).first;
1091 const std::set<std::size_t>& idxsExp = frExp.at(l).second;
1092 std::stringstream ss;
1093 ss << "frust3d-4s_test_" << l << ".ply";
1094
1095 os = tmp(ss.str());
1096
1097 helper.clear();
1098
1099 idxsAct.clear();
1100
1101 fr.draw(helper, 50);
1102
1103 Object o;
1104 using Box = AxisAlignedBoundingBox<Object, double, 3>;
1105 Box::Size size(Eigen::Matrix<double, 3, 1>(2, 2, 2));
1106
1107 std::size_t idx = 0;
1108 for (std::size_t i = 0; i <= n; i++) {
1109 for (std::size_t j = 0; j <= n; j++) {
1110 for (std::size_t k = 0; k <= n; k++) {
1111 Eigen::Matrix<double, 3, 1> pos(min + i * step, min + j * step,
1112 min + k * step);
1113 Box bb(&o, pos, size);
1114
1115 Color color = {255, 0, 0};
1116
1117 if (bb.intersect(fr)) {
1118 color = {0, 255, 0};
1119 idxsAct.insert(idx);
1120 }
1121
1122 bb.draw(helper, color);
1123 idx++;
1124 }
1125 }
1126 }
1127
1128 os << helper << std::flush;
1129 os.close();
1130
1131 BOOST_CHECK(idxsAct == idxsExp);
1132 }
1133 }
1134
1135 BOOST_TEST_CONTEXT("3D - 5 Sides") {
1136 using Frustum = Frustum<double, 3, 5>;
1137 using Box = AxisAlignedBoundingBox<Object, double, 3>;
1138 Box::Size size(Acts::Vector3(2, 2, 2));
1139
1140 Object o;
1141
1142 PlyVisualization3D<double> ply;
1143
1144 Frustum fr({0, 0, 0}, {0, 0, 1}, std::numbers::pi / 8.);
1145 fr.draw(ply, 10);
1146
1147 Box bb(&o, {0, 0, 10}, size);
1148 bb.draw(ply);
1149
1150 BOOST_CHECK(bb.intersect(fr));
1151
1152 auto os = tmp("frust3d-5s.ply");
1153 os << ply << std::flush;
1154 os.close();
1155 }
1156
1157 BOOST_TEST_CONTEXT("3D - 10 Sides") {
1158 using Frustum = Frustum<double, 3, 10>;
1159 using Box = AxisAlignedBoundingBox<Object, double, 3>;
1160 Box::Size size(Acts::Vector3(2, 2, 2));
1161
1162 Object o;
1163
1164 PlyVisualization3D<double> ply;
1165
1166 Acts::Vector3 pos = {-12.4205, 29.3578, 44.6207};
1167 Acts::Vector3 dir = {-0.656862, 0.48138, 0.58035};
1168 Frustum fr(pos, dir, 0.972419);
1169 fr.draw(ply, 10);
1170
1171 Box bb(&o, pos + dir * 10, size);
1172 bb.draw(ply);
1173
1174 BOOST_CHECK(bb.intersect(fr));
1175
1176 auto os = tmp("frust3d-10s.ply");
1177 os << ply << std::flush;
1178 os.close();
1179 }
1180
1181 BOOST_TEST_CONTEXT("3D - 4 Sides - Big box") {
1182 using Frustum = Frustum<double, 3, 4>;
1183 using Box = AxisAlignedBoundingBox<Object, double, 3>;
1184
1185 Object o;
1186
1187 PlyVisualization3D<double> ply;
1188
1189 Acts::Vector3 pos = {0, 0, 0};
1190 Acts::Vector3 dir = {0, 0, 1};
1191 Frustum fr(pos, dir, 0.972419);
1192 fr.draw(ply, 10);
1193
1194 Box::Size size(Acts::Vector3(100, 100, 2));
1195 Box bb(&o, pos + dir * 7, size);
1196 bb.draw(ply);
1197
1198 BOOST_CHECK(bb.intersect(fr));
1199
1200 auto os = tmp("frust3d-4s-bigbox.ply");
1201 os << ply << std::flush;
1202 os.close();
1203 }
1204 }
1205
1206 BOOST_AUTO_TEST_CASE(ostream_operator) {
1207 Object o;
1208 using Box = Acts::AxisAlignedBoundingBox<Object, double, 2>;
1209 Box bb(&o, {-1, -1}, {2, 2});
1210
1211 std::stringstream ss;
1212 ss << bb;
1213
1214 BOOST_CHECK(ss.str() == "AABB(ctr=(0.5, 0.5) vmin=(-1, -1) vmax=(2, 2))");
1215 }
1216
1217 }