Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GenericCuboidVolumeBoundsTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file GenericCuboidVolumeBoundsTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/unit_test.hpp>
10 
23 
24 #include <array>
25 #include <cmath>
26 #include <fstream>
27 #include <memory>
28 #include <utility>
29 #include <vector>
30 
31 namespace Acts {
32 namespace Test {
33 
35 
36 BOOST_AUTO_TEST_SUITE(Volumes)
37 
38 BOOST_AUTO_TEST_CASE(construction_test) {
39  std::array<Vector3, 8> vertices;
40  vertices = {{{0, 0, 0},
41  {2, 0, 0},
42  {2, 1, 0},
43  {0, 1, 0},
44  {0, 0, 1},
45  {2, 0, 1},
46  {2, 1, 1},
47  {0, 1, 1}}};
48  GenericCuboidVolumeBounds cubo(vertices);
49 
50  BOOST_CHECK(cubo.inside({0.5, 0.5, 0.5}));
51  BOOST_CHECK(cubo.inside({1.5, 0.5, 0.5}));
52  BOOST_CHECK(!cubo.inside({2.5, 0.5, 0.5}));
53  BOOST_CHECK(!cubo.inside({0.5, 1.5, 0.5}));
54  BOOST_CHECK(!cubo.inside({0.5, 0.5, 1.5}));
55  BOOST_CHECK(!cubo.inside({-0.5, 0.5, 0.5}));
56 
57  BOOST_CHECK(!cubo.inside({2.2, 1, 1}, 0.1));
58  BOOST_CHECK(cubo.inside({2.2, 1, 1}, 0.21));
59  BOOST_CHECK(cubo.inside({2.2, 1, 1}, 0.3));
60 }
61 
62 BOOST_AUTO_TEST_CASE(GenericCuboidBoundsOrientedSurfaces) {
63  std::array<Vector3, 8> vertices;
64  vertices = {{{0, 0, 0},
65  {2, 0, 0},
66  {2, 1, 0},
67  {0, 1, 0},
68  {0, 0, 1},
69  {2, 0, 1},
70  {2, 1, 1},
71  {0, 1, 1}}};
72  GenericCuboidVolumeBounds cubo(vertices);
73 
74  auto is_in = [](const auto& tvtx, const auto& vertices_) {
75  for (const auto& vtx : vertices_) {
76  if (checkCloseAbs(vtx, tvtx, 1e-9)) {
77  return true;
78  }
79  }
80  return false;
81  };
82 
83  auto surfaces = cubo.orientedSurfaces(Transform3::Identity());
84  for (const auto& srf : surfaces) {
85  auto pbounds = dynamic_cast<const PlanarBounds*>(&srf.first->bounds());
86  for (const auto& vtx : pbounds->vertices()) {
87  Vector3 glob = srf.first->localToGlobal(gctx, vtx, {});
88  // check if glob is in actual vertex list
89  BOOST_CHECK(is_in(glob, vertices));
90  }
91  }
92 
93  vertices = {{{0, 0, 0},
94  {2, 0, 0.4},
95  {2, 1, 0.4},
96  {0, 1, 0},
97  {0, 0, 1},
98  {1.8, 0, 1},
99  {1.8, 1, 1},
100  {0, 1, 1}}};
101  cubo = GenericCuboidVolumeBounds(vertices);
102 
103  surfaces = cubo.orientedSurfaces(Transform3::Identity());
104  for (const auto& srf : surfaces) {
105  auto pbounds = dynamic_cast<const PlanarBounds*>(&srf.first->bounds());
106  for (const auto& vtx : pbounds->vertices()) {
107  Vector3 glob = srf.first->localToGlobal(gctx, vtx, {});
108  // check if glob is in actual vertex list
109  BOOST_CHECK(is_in(glob, vertices));
110  }
111  }
112 
113  Transform3 trf;
114  trf = Translation3(Vector3(0, 8, -5)) *
115  AngleAxis3(M_PI / 3., Vector3(1, -3, 9).normalized());
116 
117  surfaces = cubo.orientedSurfaces(trf);
118  for (const auto& srf : surfaces) {
119  auto pbounds = dynamic_cast<const PlanarBounds*>(&srf.first->bounds());
120  for (const auto& vtx : pbounds->vertices()) {
121  Vector3 glob = srf.first->localToGlobal(gctx, vtx, {});
122  // check if glob is in actual vertex list
123  BOOST_CHECK(is_in(trf.inverse() * glob, vertices));
124  }
125  }
126 }
127 
129  std::array<Vector3, 8> vertices;
130  vertices = {{{0, 0, 0},
131  {2, 0, 0},
132  {2, 1, 0},
133  {0, 1, 0},
134  {0, 0, 1},
135  {2, 0, 1},
136  {2, 1, 1},
137  {0, 1, 1}}};
138  GenericCuboidVolumeBounds cubo(vertices);
140  cubo.draw(ply);
141 
142  std::ofstream os("cuboid.ply");
143  os << ply << std::flush;
144  os.close();
145 }
146 
147 BOOST_AUTO_TEST_CASE(bounding_box_creation) {
148  float tol = 1e-4;
149  std::array<Vector3, 8> vertices;
150  vertices = {{{0, 0, 0},
151  {2, 0, 0.4},
152  {2, 1, 0.4},
153  {0, 1, 0},
154  {0, 0, 1},
155  {1.8, 0, 1},
156  {1.8, 1, 1},
157  {0, 1, 1}}};
158 
159  GenericCuboidVolumeBounds gcvb(vertices);
160  auto bb = gcvb.boundingBox();
161 
162  Transform3 rot;
163  rot = AngleAxis3(M_PI / 2., Vector3::UnitX());
164 
165  BOOST_CHECK_EQUAL(bb.entity(), nullptr);
166  BOOST_CHECK_EQUAL(bb.max(), Vector3(2, 1, 1));
167  BOOST_CHECK_EQUAL(bb.min(), Vector3(0., 0., 0.));
168 
169  bb = gcvb.boundingBox(&rot);
170 
171  BOOST_CHECK_EQUAL(bb.entity(), nullptr);
172  CHECK_CLOSE_ABS(bb.max(), Vector3(2, 0, 1), tol);
173  BOOST_CHECK_EQUAL(bb.min(), Vector3(0, -1, 0));
174 
175  rot = AngleAxis3(M_PI / 2., Vector3::UnitZ());
176  bb = gcvb.boundingBox(&rot);
177  BOOST_CHECK_EQUAL(bb.entity(), nullptr);
178  CHECK_CLOSE_ABS(bb.max(), Vector3(0, 2, 1), tol);
179  CHECK_CLOSE_ABS(bb.min(), Vector3(-1, 0., 0.), tol);
180 
181  rot = AngleAxis3(0.542, Vector3::UnitZ()) *
182  AngleAxis3(M_PI / 5., Vector3(1, 3, 6).normalized());
183 
184  bb = gcvb.boundingBox(&rot);
185  BOOST_CHECK_EQUAL(bb.entity(), nullptr);
186  CHECK_CLOSE_ABS(bb.max(), Vector3(1.00976, 2.26918, 1.11988), tol);
187  CHECK_CLOSE_ABS(bb.min(), Vector3(-0.871397, 0, -0.0867708), tol);
188 
189  // Check recreation from bound values
190  const auto boundValues = gcvb.values();
191  BOOST_CHECK(boundValues.size() == 24u);
192 
193  auto bValueArrray =
194  to_array<GenericCuboidVolumeBounds::BoundValues::eSize, ActsScalar>(
195  boundValues);
196  GenericCuboidVolumeBounds gcvbCopy(bValueArrray);
197  BOOST_CHECK(gcvbCopy.values().size() == 24u);
198 
199  // Redo the check from above
200  rot = AngleAxis3(0.542, Vector3::UnitZ()) *
201  AngleAxis3(M_PI / 5., Vector3(1, 3, 6).normalized());
202 
203  bb = gcvbCopy.boundingBox(&rot);
204  BOOST_CHECK_EQUAL(bb.entity(), nullptr);
205  CHECK_CLOSE_ABS(bb.max(), Vector3(1.00976, 2.26918, 1.11988), tol);
206  CHECK_CLOSE_ABS(bb.min(), Vector3(-0.871397, 0, -0.0867708), tol);
207 }
208 
209 BOOST_AUTO_TEST_CASE(GenericCuboidVolumeBoundarySurfaces) {
210  std::array<Vector3, 8> vertices;
211  vertices = {{{0, 0, 0},
212  {4, 0, 0},
213  {4, 2, 0},
214  {0, 2, 0},
215  {0, 0, 2},
216  {4, 0, 2},
217  {4, 2, 2},
218  {0, 2, 2}}};
219 
220  GenericCuboidVolumeBounds cubo(vertices);
221 
222  auto gcvbOrientedSurfaces = cubo.orientedSurfaces(Transform3::Identity());
223  BOOST_CHECK_EQUAL(gcvbOrientedSurfaces.size(), 6);
224 
225  for (auto& os : gcvbOrientedSurfaces) {
226  auto geoCtx = GeometryContext();
227  auto osCenter = os.first->center(geoCtx);
228  auto osNormal = os.first->normal(geoCtx);
229  // Check if you step inside the volume with the oriented normal
230  Vector3 insideGcvb = osCenter + os.second * osNormal;
231  Vector3 outsideGcvb = osCenter - os.second * osNormal;
232  BOOST_CHECK(cubo.inside(insideGcvb));
233  BOOST_CHECK(!cubo.inside(outsideGcvb));
234  }
235 }
236 
237 BOOST_AUTO_TEST_SUITE_END()
238 } // namespace Test
239 } // namespace Acts