ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PolyhedronSurfacesTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PolyhedronSurfacesTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2018 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/data/test_case.hpp>
10 #include <boost/test/tools/output_test_stream.hpp>
11 #include <boost/test/unit_test.hpp>
12 
13 // Helper
16 
17 // The class to test
18 #include "Acts/Geometry/Extent.hpp"
20 
21 // Cone surface
24 
25 // Cylinder surface
28 
29 // Disc Surface
34 
35 // Plane Surface
42 
43 // Straw Surface
46 
47 #include "Acts/Utilities/Units.hpp"
49 
50 #include <fstream>
51 #include <tuple>
52 #include <utility>
53 #include <vector>
54 
55 namespace Acts {
56 
57 using namespace UnitLiterals;
58 
59 using IdentifiedPolyderon = std::tuple<std::string, bool, Polyhedron>;
60 
61 namespace Test {
62 
63 // Create a test context
65 
66 std::vector<std::tuple<std::string, bool, unsigned int>> testModes = {
67  {"", false, 72}, {"Triangulate", true, 72}, {"Extremas", false, 1}};
68 
69 auto transform = std::make_shared<Transform3D>(Transform3D::Identity());
70 
71 BOOST_AUTO_TEST_SUITE(Surfaces)
72 
73 
74 BOOST_AUTO_TEST_CASE(ConeSurfacePolyhedrons) {
75  std::vector<IdentifiedPolyderon> testTypes;
76 
77  double hzpmin = 10_mm;
78  double hzpos = 35_mm;
79  double hzneg = -20_mm;
80  double alpha = 0.234;
81  double phiSector = 0.358;
82  ObjTestWriter::writeSectorPlanesObj("ConeSectorPlanes", phiSector, 0., hzpos,
83  hzpos);
84 
85  for (const auto& mode : testModes) {
86  unsigned int segments = std::get<unsigned int>(mode);
87  std::string modename = std::get<std::string>(mode);
88  bool modetrg = std::get<bool>(mode);
89 
91  auto cone = std::make_shared<ConeBounds>(alpha, 0_mm, hzpos);
92  auto oneCone = Surface::makeShared<ConeSurface>(transform, cone);
93  auto oneConePh = oneCone->polyhedronRepresentation(tgContext, segments);
94  size_t expectedFaces = segments < 4 ? 4 : segments;
95  BOOST_CHECK_EQUAL(oneConePh.faces.size(), expectedFaces);
96  BOOST_CHECK_EQUAL(oneConePh.vertices.size(), expectedFaces + 1);
97  // Check the extent in space
98  double r = hzpos * std::tan(alpha);
99  auto extent = oneConePh.extent();
100  CHECK_CLOSE_ABS(extent.ranges[binX].first, -r, 1e-6);
101  CHECK_CLOSE_ABS(extent.ranges[binX].second, r, 1e-6);
102  CHECK_CLOSE_ABS(extent.ranges[binY].first, -r, 1e-6);
103  CHECK_CLOSE_ABS(extent.ranges[binY].second, r, 1e-6);
104  CHECK_CLOSE_ABS(extent.ranges[binR].first, 0_mm, 1e-6);
105  CHECK_CLOSE_ABS(extent.ranges[binR].second, r, 1e-6);
106  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0_mm, 1e-6);
107  CHECK_CLOSE_ABS(extent.ranges[binZ].second, hzpos, 1e-6);
108  testTypes.push_back({"ConeOneFull" + modename, modetrg, oneConePh});
109 
111  auto conePiece = std::make_shared<ConeBounds>(alpha, hzpmin, hzpos);
112  auto oneConePiece = Surface::makeShared<ConeSurface>(transform, conePiece);
113  auto oneConePiecePh =
114  oneConePiece->polyhedronRepresentation(tgContext, segments);
115  expectedFaces = segments < 4 ? 4 : segments;
116  // Check the extent in space
117  double rmin = hzpmin * std::tan(alpha);
118  extent = oneConePiecePh.extent();
119  CHECK_CLOSE_ABS(extent.ranges[binX].first, -r, 1e-6);
120  CHECK_CLOSE_ABS(extent.ranges[binX].second, r, 1e-6);
121  CHECK_CLOSE_ABS(extent.ranges[binY].first, -r, 1e-6);
122  CHECK_CLOSE_ABS(extent.ranges[binY].second, r, 1e-6);
123  CHECK_CLOSE_ABS(extent.ranges[binR].first, rmin, 1e-6);
124  CHECK_CLOSE_ABS(extent.ranges[binR].second, r, 1e-6);
125  CHECK_CLOSE_ABS(extent.ranges[binZ].first, hzpmin, 1e-6);
126  CHECK_CLOSE_ABS(extent.ranges[binZ].second, hzpos, 1e-6);
127  testTypes.push_back(
128  {"ConeOnePieceFull" + modename, modetrg, oneConePiecePh});
129 
130  // The full cone on both sides
131  auto coneBoth = std::make_shared<ConeBounds>(alpha, hzneg, hzpos);
132  auto twoCones = Surface::makeShared<ConeSurface>(transform, coneBoth);
133  auto twoConesPh = twoCones->polyhedronRepresentation(tgContext, segments);
134  expectedFaces = segments < 4 ? 8 : 2 * segments;
135  BOOST_CHECK_EQUAL(twoConesPh.faces.size(), expectedFaces);
136  BOOST_CHECK_EQUAL(twoConesPh.vertices.size(), expectedFaces + 1);
137  extent = twoConesPh.extent();
138  CHECK_CLOSE_ABS(extent.ranges[binX].first, -r, 1e-6);
139  CHECK_CLOSE_ABS(extent.ranges[binX].second, r, 1e-6);
140  CHECK_CLOSE_ABS(extent.ranges[binY].first, -r, 1e-6);
141  CHECK_CLOSE_ABS(extent.ranges[binY].second, r, 1e-6);
142  CHECK_CLOSE_ABS(extent.ranges[binR].first, 0_mm, 1e-6);
143  CHECK_CLOSE_ABS(extent.ranges[binR].second, r, 1e-6);
144  CHECK_CLOSE_ABS(extent.ranges[binZ].first, hzneg, 1e-6);
145  CHECK_CLOSE_ABS(extent.ranges[binZ].second, hzpos, 1e-6);
146  testTypes.push_back({"ConesTwoFull" + modename, modetrg, twoConesPh});
147 
148  // A centered sectoral cone on both sides
149  auto sectoralBoth =
150  std::make_shared<ConeBounds>(alpha, hzneg, hzpos, phiSector, 0.);
151  auto sectoralCones =
152  Surface::makeShared<ConeSurface>(transform, sectoralBoth);
153  auto sectoralConesPh =
154  sectoralCones->polyhedronRepresentation(tgContext, segments);
155  extent = sectoralConesPh.extent();
156  CHECK_CLOSE_ABS(extent.ranges[binX].second, r, 1e-6);
157  CHECK_CLOSE_ABS(extent.ranges[binR].first, 0_mm, 1e-6);
158  CHECK_CLOSE_ABS(extent.ranges[binR].second, r, 1e-6);
159  CHECK_CLOSE_ABS(extent.ranges[binZ].first, hzneg, 1e-6);
160  CHECK_CLOSE_ABS(extent.ranges[binZ].second, hzpos, 1e-6);
161  testTypes.push_back({"ConesSectoral" + modename, modetrg, sectoralConesPh});
162  }
163  ObjTestWriter::writeObj(testTypes);
164 }
165 
167 BOOST_AUTO_TEST_CASE(CylinderSurfacePolyhedrons) {
168  double r = 25_mm;
169  double hZ = 35_mm;
170 
171  double phiSector = 0.458;
172  double averagePhi = -1.345;
173  ObjTestWriter::writeSectorPlanesObj("CylinderCentralSectorPlanes", phiSector,
174  0., 1.5 * r, 1.5 * hZ);
175  ObjTestWriter::writeSectorPlanesObj("CylinderShiftedSectorPlanes", phiSector,
176  averagePhi, 1.5 * r, 1.5 * hZ);
177 
178  std::vector<IdentifiedPolyderon> testTypes;
179 
180  for (const auto& mode : testModes) {
181  unsigned int segments = std::get<unsigned int>(mode);
182  std::string modename = std::get<std::string>(mode);
183  bool modetrg = std::get<bool>(mode);
184 
185  size_t expectedFaces = segments < 4 ? 4 : segments;
186  size_t expectedVertices = segments < 4 ? 8 : 2 * segments;
187 
189  auto cylinder = std::make_shared<CylinderBounds>(r, hZ);
190  auto fullCylinder =
191  Surface::makeShared<CylinderSurface>(transform, cylinder);
192  auto fullCylinderPh =
193  fullCylinder->polyhedronRepresentation(tgContext, segments);
194 
195  BOOST_CHECK_EQUAL(fullCylinderPh.faces.size(), expectedFaces);
196  BOOST_CHECK_EQUAL(fullCylinderPh.vertices.size(), expectedVertices);
197  // Check the extent in space
198  auto extent = fullCylinderPh.extent();
199  CHECK_CLOSE_ABS(extent.ranges[binX].first, -r, 1e-6);
200  CHECK_CLOSE_ABS(extent.ranges[binX].second, r, 1e-6);
201  CHECK_CLOSE_ABS(extent.ranges[binY].first, -r, 1e-6);
202  CHECK_CLOSE_ABS(extent.ranges[binY].second, r, 1e-6);
203  CHECK_CLOSE_ABS(extent.ranges[binR].first, r, 1e-6);
204  CHECK_CLOSE_ABS(extent.ranges[binR].second, r, 1e-6);
205  CHECK_CLOSE_ABS(extent.ranges[binZ].first, -hZ, 1e-6);
206  CHECK_CLOSE_ABS(extent.ranges[binZ].second, hZ, 1e-6);
207  testTypes.push_back({"CylinderFull" + modename, modetrg, fullCylinderPh});
208 
210  auto sectorCentered = std::make_shared<CylinderBounds>(r, phiSector, hZ);
211  auto centerSectoredCylinder =
212  Surface::makeShared<CylinderSurface>(transform, sectorCentered);
213  auto centerSectoredCylinderPh =
214  centerSectoredCylinder->polyhedronRepresentation(tgContext, segments);
215 
216  // Check the extent in space
217  extent = centerSectoredCylinderPh.extent();
218  CHECK_CLOSE_ABS(extent.ranges[binX].first, r * std::cos(phiSector), 1e-6);
219  CHECK_CLOSE_ABS(extent.ranges[binX].second, r, 1e-6);
220  CHECK_CLOSE_ABS(extent.ranges[binY].first, -r * std::sin(phiSector), 1e-6);
221  CHECK_CLOSE_ABS(extent.ranges[binY].second, r * std::sin(phiSector), 1e-6);
222  CHECK_CLOSE_ABS(extent.ranges[binR].first, r, 1e-6);
223  CHECK_CLOSE_ABS(extent.ranges[binR].second, r, 1e-6);
224  CHECK_CLOSE_ABS(extent.ranges[binZ].first, -hZ, 1e-6);
225  CHECK_CLOSE_ABS(extent.ranges[binZ].second, hZ, 1e-6);
226  testTypes.push_back({"CylinderSectorCentered" + modename, modetrg,
227  centerSectoredCylinderPh});
228 
230  auto sectorShifted =
231  std::make_shared<CylinderBounds>(r, averagePhi, phiSector, hZ);
232  auto shiftedSectoredCylinder =
233  Surface::makeShared<CylinderSurface>(transform, sectorShifted);
234  auto shiftedSectoredCylinderPh =
235  shiftedSectoredCylinder->polyhedronRepresentation(tgContext, segments);
236 
237  // Check the extent in space
238  extent = shiftedSectoredCylinderPh.extent();
239  CHECK_CLOSE_ABS(extent.ranges[binR].first, r, 1e-6);
240  CHECK_CLOSE_ABS(extent.ranges[binR].second, r, 1e-6);
241  CHECK_CLOSE_ABS(extent.ranges[binZ].first, -hZ, 1e-6);
242  CHECK_CLOSE_ABS(extent.ranges[binZ].second, hZ, 1e-6);
243  testTypes.push_back({"CylinderSectorShifted" + modename, modetrg,
244  shiftedSectoredCylinderPh});
245  }
246 
247  ObjTestWriter::writeObj(testTypes);
248 }
249 
251 BOOST_AUTO_TEST_CASE(DiscSurfacePolyhedrons) {
252  std::vector<IdentifiedPolyderon> testTypes;
253 
254  double innerR = 10_mm;
255  double outerR = 25_mm;
256 
257  double phiSector = 0.345;
258  double averagePhi = -1.0;
259 
260  double cphi = std::cos(phiSector);
261  double sphi = std::sin(phiSector);
262 
263  std::pair<Vector3D, Vector3D> lineA = {
264  Vector3D(0., 0., 0.), Vector3D(outerR * cphi, outerR * sphi, 0.)};
265  std::pair<Vector3D, Vector3D> lineB = {
266  Vector3D(0., 0., 0.), Vector3D(outerR * cphi, -outerR * sphi, 0.)};
267  ObjTestWriter::writeSectorLinesObj("DiscSectorLines", lineA, lineB);
268 
269  double minPhi = averagePhi - phiSector;
270  double maxPhi = averagePhi + phiSector;
271  lineA = {Vector3D(0., 0., 0.),
272  Vector3D(outerR * std::cos(minPhi), outerR * std::sin(minPhi), 0.)};
273  lineB = {Vector3D(0., 0., 0.),
274  Vector3D(outerR * std::cos(maxPhi), outerR * std::sin(maxPhi), 0.)};
275  ObjTestWriter::writeSectorLinesObj("DiscSectorLinesShifted", lineA, lineB);
276 
277  for (const auto& mode : testModes) {
278  unsigned int segments = std::get<unsigned int>(mode);
279  std::string modename = std::get<std::string>(mode);
280  bool modetrg = std::get<bool>(mode);
281 
282  // Full disc
283  auto disc = std::make_shared<RadialBounds>(0_mm, outerR);
284  auto fullDisc = Surface::makeShared<DiscSurface>(transform, disc);
285  auto fullDiscPh = fullDisc->polyhedronRepresentation(tgContext, segments);
286 
287  unsigned int expectedVertices = segments > 4 ? segments : 4;
288  unsigned int expectedFaces = 1;
289 
290  BOOST_CHECK_EQUAL(fullDiscPh.faces.size(), expectedFaces);
291  BOOST_CHECK_EQUAL(fullDiscPh.vertices.size(), expectedVertices);
292 
293  auto extent = fullDiscPh.extent();
294  CHECK_CLOSE_ABS(extent.ranges[binX].first, -outerR, 1e-6);
295  CHECK_CLOSE_ABS(extent.ranges[binX].second, outerR, 1e-6);
296  CHECK_CLOSE_ABS(extent.ranges[binY].first, -outerR, 1e-6);
297  CHECK_CLOSE_ABS(extent.ranges[binY].second, outerR, 1e-6);
298  CHECK_CLOSE_ABS(extent.ranges[binR].first, 0., 1e-6);
299  CHECK_CLOSE_ABS(extent.ranges[binR].second, outerR, 1e-6);
300  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
301  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
302 
303  testTypes.push_back({"DiscFull" + modename, modetrg, fullDiscPh});
304 
305  // Ring disc
306  auto radial = std::make_shared<RadialBounds>(innerR, outerR);
307  auto radialDisc = Surface::makeShared<DiscSurface>(transform, radial);
308  auto radialPh = radialDisc->polyhedronRepresentation(tgContext, segments);
309  extent = radialPh.extent();
310  CHECK_CLOSE_ABS(extent.ranges[binX].first, -outerR, 1e-6);
311  CHECK_CLOSE_ABS(extent.ranges[binX].second, outerR, 1e-6);
312  CHECK_CLOSE_ABS(extent.ranges[binY].first, -outerR, 1e-6);
313  CHECK_CLOSE_ABS(extent.ranges[binY].second, outerR, 1e-6);
314  CHECK_CLOSE_ABS(extent.ranges[binR].first, innerR, 1e-6);
315  CHECK_CLOSE_ABS(extent.ranges[binR].second, outerR, 1e-6);
316  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
317  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
318  testTypes.push_back({"DiscRing" + modename, modetrg, radialPh});
319 
320  // Sectoral disc - around 0.
321  auto sector = std::make_shared<RadialBounds>(0., outerR, phiSector);
322  auto sectorDisc = Surface::makeShared<DiscSurface>(transform, sector);
323  auto sectorPh = sectorDisc->polyhedronRepresentation(tgContext, segments);
324  extent = sectorPh.extent();
325  CHECK_CLOSE_ABS(extent.ranges[binX].first, 0., 1e-6);
326  CHECK_CLOSE_ABS(extent.ranges[binX].second, outerR, 1e-6);
327  CHECK_CLOSE_ABS(extent.ranges[binY].first, -outerR * std::sin(phiSector),
328  1e-6);
329  CHECK_CLOSE_ABS(extent.ranges[binY].second, outerR * std::sin(phiSector),
330  1e-6);
331  CHECK_CLOSE_ABS(extent.ranges[binR].first, 0., 1e-6);
332  CHECK_CLOSE_ABS(extent.ranges[binR].second, outerR, 1e-6);
333  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
334  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
335  testTypes.push_back({"DiscSectorCentered" + modename, modetrg, sectorPh});
336 
337  // Sectoral ring - around 0.
338  auto sectorRing = std::make_shared<RadialBounds>(innerR, outerR, phiSector);
339  auto sectorRingDisc =
340  Surface::makeShared<DiscSurface>(transform, sectorRing);
341  auto sectorRingDiscPh =
342  sectorRingDisc->polyhedronRepresentation(tgContext, segments);
343  extent = sectorRingDiscPh.extent();
344  CHECK_CLOSE_ABS(extent.ranges[binX].first, innerR * std::cos(phiSector),
345  1e-6);
346  CHECK_CLOSE_ABS(extent.ranges[binX].second, outerR, 1e-6);
347  CHECK_CLOSE_ABS(extent.ranges[binY].first, -outerR * std::sin(phiSector),
348  1e-6);
349  CHECK_CLOSE_ABS(extent.ranges[binY].second, outerR * std::sin(phiSector),
350  1e-6);
351  CHECK_CLOSE_ABS(extent.ranges[binR].first, innerR, 1e-6);
352  CHECK_CLOSE_ABS(extent.ranges[binR].second, outerR, 1e-6);
353  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
354  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
355  testTypes.push_back(
356  {"DiscRingSectorCentered" + modename, modetrg, sectorRingDiscPh});
357 
358  // Sectoral disc - shifted
359  auto sectorRingShifted =
360  std::make_shared<RadialBounds>(innerR, outerR, averagePhi, phiSector);
361  auto sectorRingDiscShifted =
362  Surface::makeShared<DiscSurface>(transform, sectorRingShifted);
363  auto sectorRingDiscShiftedPh =
364  sectorRingDiscShifted->polyhedronRepresentation(tgContext, segments);
365  extent = sectorRingDiscShiftedPh.extent();
366  CHECK_CLOSE_ABS(extent.ranges[binR].first, innerR, 1e-6);
367  CHECK_CLOSE_ABS(extent.ranges[binR].second, outerR, 1e-6);
368  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
369  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
370  testTypes.push_back(
371  {"DiscRingSectorShifted" + modename, modetrg, sectorRingDiscShiftedPh});
372 
373  // Trapezoid for a disc
374  double halfXmin = 10_mm;
375  double halfXmax = 20_mm;
376  auto trapezoidDisc = std::make_shared<DiscTrapezoidBounds>(
377  halfXmin, halfXmax, innerR, outerR, 0.);
378  auto trapezoidDiscSf =
379  Surface::makeShared<DiscSurface>(transform, trapezoidDisc);
380  auto trapezoidDiscSfPh =
381  trapezoidDiscSf->polyhedronRepresentation(tgContext, segments);
382  extent = trapezoidDiscSfPh.extent();
383  CHECK_CLOSE_ABS(extent.ranges[binR].first, innerR, 1e-6);
384  CHECK_CLOSE_ABS(extent.ranges[binR].second, outerR, 1e-6);
385  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
386  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
387  testTypes.push_back(
388  {"DiscTrapezoidCentered" + modename, modetrg, trapezoidDiscSfPh});
389 
390  auto trapezoidDiscShifted = std::make_shared<DiscTrapezoidBounds>(
391  halfXmin, halfXmax, innerR, outerR, averagePhi);
392  auto trapezoidDiscShiftedSf =
393  Surface::makeShared<DiscSurface>(transform, trapezoidDiscShifted);
394  auto trapezoidDiscShiftedSfPh =
395  trapezoidDiscShiftedSf->polyhedronRepresentation(tgContext, segments);
396  extent = trapezoidDiscShiftedSfPh.extent();
397  CHECK_CLOSE_ABS(extent.ranges[binR].first, innerR, 1e-6);
398  CHECK_CLOSE_ABS(extent.ranges[binR].second, outerR, 1e-6);
399  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
400  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
401  testTypes.push_back(
402  {"DiscTrapezoidShifted" + modename, modetrg, trapezoidDiscShiftedSfPh});
403 
404  double minRadius = 7.;
405  double maxRadius = 12.;
406  double minPhiA = 0.75;
407  double maxPhiA = 1.4;
408 
409  Vector2D offset(-2., 2.);
410 
411  auto annulus = std::make_shared<AnnulusBounds>(minRadius, maxRadius,
412  minPhiA, maxPhiA, offset);
413  auto annulusDisc = Surface::makeShared<DiscSurface>(transform, annulus);
414  auto annulusDiscPh =
415  annulusDisc->polyhedronRepresentation(tgContext, segments);
416 
417  testTypes.push_back(
418  {"DiscAnnulus" + modename, modetrg, trapezoidDiscShiftedSfPh});
419  }
420 
421  ObjTestWriter::writeObj(testTypes);
422 }
423 
425 BOOST_AUTO_TEST_CASE(PlaneSurfacePolyhedrons) {
426  std::vector<IdentifiedPolyderon> testTypes;
427 
428  double rhX = 10_mm;
429  double rhY = 25_mm;
430  double shiftY = 50_mm;
431  auto rectangular = std::make_shared<RectangleBounds>(rhX, rhY);
432 
433  // Special test for shifted plane to check rMin/rMax
434  Vector3D shift(0., shiftY, 0.);
435  auto shiftedTransform =
436  std::make_shared<Transform3D>(Transform3D::Identity());
437  shiftedTransform->pretranslate(shift);
438  auto shiftedPlane =
439  Surface::makeShared<PlaneSurface>(shiftedTransform, rectangular);
440  auto shiftedPh = shiftedPlane->polyhedronRepresentation(tgContext, 1);
441  auto shiftedExtent = shiftedPh.extent();
442  // Let's check the extent
443  CHECK_CLOSE_ABS(shiftedExtent.ranges[binX].first, -rhX, 1e-6);
444  CHECK_CLOSE_ABS(shiftedExtent.ranges[binX].second, rhX, 1e-6);
445  CHECK_CLOSE_ABS(shiftedExtent.ranges[binY].first, -rhY + shiftY, 1e-6);
446  CHECK_CLOSE_ABS(shiftedExtent.ranges[binY].second, rhY + shiftY, 1e-6);
447 
448  for (const auto& mode : testModes) {
449  unsigned int segments = std::get<unsigned int>(mode);
450  std::string modename = std::get<std::string>(mode);
451  bool modetrg = std::get<bool>(mode);
452 
454  auto rectangularPlane =
455  Surface::makeShared<PlaneSurface>(transform, rectangular);
456  auto rectangularPh =
457  rectangularPlane->polyhedronRepresentation(tgContext, segments);
458  auto extent = rectangularPh.extent();
459  CHECK_CLOSE_ABS(extent.ranges[binX].first, -rhX, 1e-6);
460  CHECK_CLOSE_ABS(extent.ranges[binX].second, rhX, 1e-6);
461  CHECK_CLOSE_ABS(extent.ranges[binY].first, -rhY, 1e-6);
462  CHECK_CLOSE_ABS(extent.ranges[binY].second, rhY, 1e-6);
463  CHECK_CLOSE_ABS(extent.ranges[binR].first, 0., 1e-6);
464  CHECK_CLOSE_ABS(extent.ranges[binR].second,
465  std::sqrt(rhX * rhX + rhY * rhY), 1e-6);
466  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
467  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
468  BOOST_CHECK(rectangularPh.vertices.size() == 4);
469  BOOST_CHECK(rectangularPh.faces.size() == 1);
470  std::vector<size_t> expectedRect = {0, 1, 2, 3};
471  BOOST_CHECK(rectangularPh.faces[0] == expectedRect);
472  testTypes.push_back({"PlaneRectangle" + modename, modetrg, rectangularPh});
473 
475  double thX1 = 10_mm;
476  double thX2 = 25_mm;
477  double thY = 35_mm;
478 
479  auto trapezoid = std::make_shared<TrapezoidBounds>(thX1, thX2, thY);
480  auto trapezoidalPlane =
481  Surface::makeShared<PlaneSurface>(transform, trapezoid);
482  auto trapezoidalPh =
483  trapezoidalPlane->polyhedronRepresentation(tgContext, segments);
484  extent = trapezoidalPh.extent();
485 
486  double thX = std::max(thX1, thX2);
487  CHECK_CLOSE_ABS(extent.ranges[binX].first, -thX, 1e-6);
488  CHECK_CLOSE_ABS(extent.ranges[binX].second, thX, 1e-6);
489  CHECK_CLOSE_ABS(extent.ranges[binY].first, -thY, 1e-6);
490  CHECK_CLOSE_ABS(extent.ranges[binY].second, thY, 1e-6);
491  CHECK_CLOSE_ABS(extent.ranges[binR].first, 0., 1e-6);
492  CHECK_CLOSE_ABS(extent.ranges[binR].second,
493  std::sqrt(thX * thX + thY * thY), 1e-6);
494  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
495  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
496  BOOST_CHECK(trapezoidalPh.vertices.size() == 4);
497  BOOST_CHECK(trapezoidalPh.faces.size() == 1);
498  std::vector<size_t> expectedTra = {0, 1, 2, 3};
499  BOOST_CHECK(trapezoidalPh.faces[0] == expectedTra);
500  testTypes.push_back({"PlaneTrapezoid" + modename, modetrg, trapezoidalPh});
501 
503  double rMaxX = 30_mm;
504  double rMaxY = 40_mm;
505  auto ellipse = std::make_shared<EllipseBounds>(0., 0., rMaxX, rMaxY);
506  auto ellipsoidPlane = Surface::makeShared<PlaneSurface>(transform, ellipse);
507  auto ellispoidPh =
508  ellipsoidPlane->polyhedronRepresentation(tgContext, segments);
509  extent = ellispoidPh.extent();
510  CHECK_CLOSE_ABS(extent.ranges[binX].first, -rMaxX, 1e-6);
511  CHECK_CLOSE_ABS(extent.ranges[binX].second, rMaxX, 1e-6);
512  CHECK_CLOSE_ABS(extent.ranges[binY].first, -rMaxY, 1e-6);
513  CHECK_CLOSE_ABS(extent.ranges[binY].first, -rMaxY, 1e-6);
514  CHECK_CLOSE_ABS(extent.ranges[binR].first, 0., 1e-6);
515  CHECK_CLOSE_ABS(extent.ranges[binR].second, rMaxY, 1e-6);
516  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
517  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
518 
519  testTypes.push_back({"PlaneFullEllipse" + modename, modetrg, ellispoidPh});
520 
521  double rMinX = 10_mm;
522  double rMinY = 20_mm;
523  auto ellipseRing =
524  std::make_shared<EllipseBounds>(rMinX, rMaxX, rMinY, rMaxY);
525  auto ellipsoidRingPlane =
526  Surface::makeShared<PlaneSurface>(transform, ellipseRing);
527  auto ellispoidRingPh =
528  ellipsoidRingPlane->polyhedronRepresentation(tgContext, segments);
529 
530  extent = ellispoidPh.extent();
531  CHECK_CLOSE_ABS(extent.ranges[binX].first, -rMaxX, 1e-6);
532  CHECK_CLOSE_ABS(extent.ranges[binX].second, rMaxX, 1e-6);
533  CHECK_CLOSE_ABS(extent.ranges[binY].first, -rMaxY, 1e-6);
534  CHECK_CLOSE_ABS(extent.ranges[binY].first, rMinX, 1e-6);
535  CHECK_CLOSE_ABS(extent.ranges[binR].second, rMaxY, 1e-6);
536  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
537  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
538 
539  // BOOST_CHECK(ellispoidPh.vertices.size()==72);
540  testTypes.push_back(
541  {"PlaneRingEllipse" + modename, modetrg, ellispoidRingPh});
542 
544  std::vector<Vector2D> vtxs = {
545  Vector2D(-40_mm, -10_mm), Vector2D(-10_mm, -30_mm),
546  Vector2D(30_mm, -20_mm), Vector2D(10_mm, 20_mm),
547  Vector2D(-20_mm, 50_mm), Vector2D(-30_mm, 30_mm)};
548 
549  auto sextagon = std::make_shared<ConvexPolygonBounds<6>>(vtxs);
550  auto sextagonPlane = Surface::makeShared<PlaneSurface>(transform, sextagon);
551  auto sextagonPlanePh =
552  sextagonPlane->polyhedronRepresentation(tgContext, segments);
553  testTypes.push_back({"PlaneSextagon" + modename, modetrg, sextagonPlanePh});
554 
556  double hMinX = 10_mm;
557  double hMedX = 20_mm;
558  double hMaxX = 15_mm;
559  double hMinY = 40_mm;
560  double hMaxY = 50_mm;
561  auto diamond =
562  std::make_shared<DiamondBounds>(hMinX, hMedX, hMaxX, hMinY, hMaxY);
563  auto diamondPlane = Surface::makeShared<PlaneSurface>(transform, diamond);
564  auto diamondPh =
565  diamondPlane->polyhedronRepresentation(tgContext, segments);
566  BOOST_CHECK(diamondPh.vertices.size() == 6);
567  BOOST_CHECK(diamondPh.faces.size() == 1);
568  extent = diamondPh.extent();
569  CHECK_CLOSE_ABS(extent.ranges[binX].first, -hMedX, 1e-6);
570  CHECK_CLOSE_ABS(extent.ranges[binX].second, hMedX, 1e-6);
571  CHECK_CLOSE_ABS(extent.ranges[binY].first, -hMinY, 1e-6);
572  CHECK_CLOSE_ABS(extent.ranges[binY].second, hMaxY, 1e-6);
573  CHECK_CLOSE_ABS(extent.ranges[binR].first, 0., 1e-6);
574  CHECK_CLOSE_ABS(extent.ranges[binR].second,
575  std::sqrt(hMaxX * hMaxX + hMaxY * hMaxY), 1e-6);
576  CHECK_CLOSE_ABS(extent.ranges[binZ].first, 0., 1e-6);
577  CHECK_CLOSE_ABS(extent.ranges[binZ].second, 0., 1e-6);
578  testTypes.push_back({"PlaneDiamond" + modename, modetrg, diamondPh});
579  }
580  ObjTestWriter::writeObj(testTypes);
581 }
582 
583 BOOST_AUTO_TEST_SUITE_END()
584 
585 } // namespace Test
586 
587 } // namespace Acts