ATLAS Offline Software
Loading...
Searching...
No Matches
VolumeIntersection.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// VolumeConverter.cxx, (c) ATLAS Detector software
8
10
12
13// Trk
24
25// GeoModel
26#include "GeoModelKernel/GeoShapeShift.h"
27#include "GeoModelKernel/GeoShapeUnion.h"
28#include "GeoModelKernel/GeoTrd.h"
29
30// STL
31#include <iostream>
32namespace{
33std::unique_ptr<Amg::Transform3D> makeTransform(const Amg::Transform3D& trf) {
34 return std::make_unique<Amg::Transform3D>(trf);
35 }
36}
37std::pair<bool, std::unique_ptr<Trk::Volume>>
39 const Volume& volB) {
40
41 // if combination of shifted polygons, calculable
42 Trk::PolygonCache pgA = polygonXY(volA);
43 Trk::PolygonCache pgB = polygonXY(volB);
44
45 if (pgA.nVtx > 0 && pgB.nVtx > 0) {
46 // check orientation of xy face
47 Amg::Vector3D a0 = pgA.vertices[1] - pgA.vertices[0];
48 Amg::Vector3D a1 = pgA.vertices[2] - pgA.vertices[1];
49 Amg::Vector3D b0 = pgB.vertices[1] - pgB.vertices[0];
50 Amg::Vector3D b1 = pgB.vertices[2] - pgB.vertices[1];
51
52 if (std::abs((a0.cross(a1).unit()).dot(b0.cross(b1).unit())) < 1.e-3) {
53 if (std::abs((a0.cross(a1).unit()).dot(b1)) < 1.e-3)
54 pgB = polygonXY(volB, 1); // xy -> yz, only if cuboid-like
55 else if (std::abs((a0.cross(a1).unit()).dot(b0)) < 1.e-3)
56 pgB = polygonXY(volB, 2); // xy -> zx, only if cuboid-like
57 // new check orientation of xy face
58 b0 = pgB.vertices[1] - pgB.vertices[0];
59 b1 = pgB.vertices[2] - pgB.vertices[1];
60 }
61 if (std::abs(std::abs((a0.cross(a1).unit()).dot(b0.cross(b1).unit())) -
62 1.) > 1.e-3) {
63 return std::make_pair(false, nullptr);
64 }
65
66 Amg::Transform3D trf{Amg::Transform3D::Identity()};
67 const Amg::Vector3D norm = a0.cross(a1).unit();
68 if (norm.z() != 1.) { // rotate to align with z axis
69 trf = Amg::getRotateY3D(-norm.theta()) *
70 Amg::getRotateZ3D(-norm.phi());
71 for (Amg::Vector3D& vertex : pgA.vertices) {
72 vertex = trf * vertex;
73 }
74 for (Amg::Vector3D& vertex : pgB.vertices) {
75 vertex = trf * vertex;
76 }
77 pgA.center = trf * pgA.center;
78 pgB.center = trf * pgB.center;
79 }
80 // overlap in z
81 pgA.minZ = std::min(pgA.vertices[0].z(),
82 2 * pgA.center.z() - pgA.vertices[0].z());
83 pgA.maxZ = std::max(pgA.vertices[0].z(),
84 2 * pgA.center.z() - pgA.vertices[0].z());
85 pgB.minZ = std::min(pgB.vertices[0].z(),
86 2 * pgB.center.z() - pgB.vertices[0].z());
87 pgB.maxZ = std::max(pgB.vertices[0].z(),
88 2 * pgB.center.z() - pgB.vertices[0].z());
89
90 if (pgA.minZ > pgB.maxZ || pgB.minZ > pgA.maxZ) {
91 return std::make_pair(true, nullptr);
92 } // no overlap in z
93
95 std::unique_ptr<Trk::Volume> overlap;
96 if (result.nVtx > 0) {
97 auto spb = std::make_shared<Trk::SimplePolygonBrepVolumeBounds>(result.xyVertices, 0.5 * (result.maxZ - result.minZ));
98 Amg::Transform3D transf = trf.inverse() *
99 Amg::Translation3D(0., 0., 0.5 * (result.maxZ + result.minZ));
100 overlap = std::make_unique<Trk::Volume>(makeTransform(transf), spb);
101 }
102 return std::make_pair(true, std::move(overlap));
103 } // end shifted polygons
104
105 return std::make_pair(false, nullptr);
106}
107
110
111 // retrieve xy vertices (size+1)
112 for (const Amg::Vector3D& vtx : pgA.vertices)
113 pgA.xyVertices.emplace_back(vtx.x(), vtx.y());
114 pgA.xyVertices.emplace_back(pgA.vertices.front().x(), pgA.vertices.front().y());
115 for (const Amg::Vector3D& vtx : pgB.vertices)
116 pgB.xyVertices.emplace_back(vtx.x(), vtx.y());
117 pgB.xyVertices.emplace_back(pgB.vertices.front().x(), pgB.vertices.front().y());
118 // find common
119 for (const std::pair<double, double>& vtx : pgA.xyVertices) {
120 pgA.commonVertices.push_back(inside(vtx, pgB.xyVertices));
121 }
122 for (const std::pair<double, double>& vtx : pgB.xyVertices) {
123 pgB.commonVertices.push_back(inside(vtx, pgA.xyVertices));
124 }
125 // edges
126 for (int ia = 0; ia < pgA.nVtx; ia++) {
127 pgA.edges.emplace_back(
128 pgA.xyVertices[ia + 1].first - pgA.xyVertices[ia].first,
129 pgA.xyVertices[ia + 1].second - pgA.xyVertices[ia].second);
130 }
131 for (int ib = 0; ib < pgB.nVtx; ib++) {
132 pgB.edges.emplace_back(
133 pgB.xyVertices[ib + 1].first - pgB.xyVertices[ib].first,
134 pgB.xyVertices[ib + 1].second - pgB.xyVertices[ib].second);
135 }
136 // edge intersections
137 std::vector<Trk::EdgeCross> edge_cross;
138 for (int ia = 0; ia < pgA.nVtx; ia++) {
139 for (int ib = 0; ib < pgB.nVtx; ib++) {
140 double rs = det(pgA.edges[ia], pgB.edges[ib], false);
141 double qps = det(pgB.xyVertices[ib], pgB.edges[ib], false) -
142 det(pgA.xyVertices[ia], pgB.edges[ib], false);
143 double rpq = det(pgA.edges[ia], pgA.xyVertices[ia], false) -
144 det(pgA.edges[ia], pgB.xyVertices[ib], false);
145 if (rs == 0 && rpq == 0) {
146 double t0 =
147 det(pgA.edges[ia], pgA.edges[ia], true) > 0
148 ? (det(pgB.xyVertices[ib], pgA.edges[ia], true) -
149 det(pgA.xyVertices[ia], pgA.edges[ia], true)) /
150 det(pgA.edges[ia], pgA.edges[ia], true)
151 : 0;
152 double t1 =
153 det(pgA.edges[ia], pgA.edges[ia], true) > 0
154 ? t0 + det(pgB.edges[ib], pgA.edges[ia], true) /
155 det(pgA.edges[ia], pgA.edges[ia], true)
156 : 0;
157 if (t0 > 0 && t0 < 1.)
158 edge_cross.emplace_back(
159 std::make_pair(ia, ib), std::make_pair(t0, -1));
160 if (t1 > 0 && t1 < 1.)
161 edge_cross.emplace_back(
162 std::make_pair(ia, ib), std::make_pair(t1, -1));
163 } else if (rs != 0 && qps / rs > 0 && qps / rs < 1 &&
164 rpq / rs > 0 && rpq / rs < 1) {
165 edge_cross.emplace_back(std::make_pair(ia, ib),
166 std::make_pair(qps / rs, rpq / rs));
167 }
168 }
169 }
170 // collect new vertices : first in edge-crossing format
171 std::vector<Trk::EdgeCross> setVtx;
172 for (int ia = 0; ia < pgA.nVtx; ia++) {
173 if (pgA.commonVertices[ia])
174 setVtx.emplace_back(std::make_pair(ia, -1),
175 std::make_pair(0., -1.));
176 for (const Trk::EdgeCross& ie : edge_cross) {
177 if (ie.edge_id.first == ia) {
178 if (!setVtx.empty() && setVtx.back().edge_id.first == ia &&
179 setVtx.back().edge_pos.first > ie.edge_pos.first)
180 setVtx.insert(setVtx.end() - 1, ie);
181 else
182 setVtx.push_back(ie);
183 }
184 } // loop over edge crossings
185 }
186 // insert common vertices from polygonB
187 for (int ib = 0; ib < pgB.nVtx; ib++) {
188 if (pgB.commonVertices[ib]) {
189 int nlow = ib == 0 ? pgB.nVtx : ib - 1;
190 // find entry with nearest intersection along edge
191 std::vector<Trk::EdgeCross>::iterator it = setVtx.begin();
192 std::vector<Trk::EdgeCross>::iterator itb = setVtx.end();
193 while (it != setVtx.end()) {
194 if ((*it).edge_id.second == nlow) {
195 if (itb == setVtx.end() ||
196 (*it).edge_pos.second > (*itb).edge_pos.second)
197 itb = it;
198 }
199 ++it;
200 }
201 setVtx.insert(
202 itb, Trk::EdgeCross(
203 std::make_pair(ib, -2),
204 std::make_pair(
205 0., -1.))); // -2 indicates vertex coming from B
206 }
207 }
208
209 // TODO verify the ordering
210
211 // calculate position of vertices and fill the cache
213 pgon.minZ = std::max(pgA.minZ, pgB.minZ);
214 pgon.maxZ = std::min(pgA.maxZ, pgB.maxZ);
215 pgon.nVtx = setVtx.size() < 3 ? 0 : setVtx.size();
216
217 if (pgon.nVtx < 3)
218 return pgon;
219
220 for (auto vtx : setVtx) {
221 if (vtx.edge_id.second == -1)
222 pgon.xyVertices.push_back(pgA.xyVertices[vtx.edge_id.first]);
223 else if (vtx.edge_id.second == -2)
224 pgon.xyVertices.push_back(pgB.xyVertices[vtx.edge_id.first]);
225 else { // calculate intersection
226 Amg::Vector2D vpos{pgA.xyVertices[vtx.edge_id.first].first,
227 pgA.xyVertices[vtx.edge_id.first].second};
228 Amg::Vector2D vdir{pgA.edges[vtx.edge_id.first].first,
229 pgA.edges[vtx.edge_id.first].second};
230 Amg::Vector2D vint = vpos + vtx.edge_pos.first * vdir;
231 pgon.xyVertices.emplace_back(vint.x(), vint.y());
232 }
233 }
234
235 return pgon;
236}
237
239 int swap) {
240
241 const CuboidVolumeBounds* box =
242 dynamic_cast<const Trk::CuboidVolumeBounds*>(&(vol.volumeBounds()));
243 const TrapezoidVolumeBounds* trd =
244 dynamic_cast<const Trk::TrapezoidVolumeBounds*>(&(vol.volumeBounds()));
245 const DoubleTrapezoidVolumeBounds* trdd =
246 dynamic_cast<const Trk::DoubleTrapezoidVolumeBounds*>(
247 &(vol.volumeBounds()));
248 const PrismVolumeBounds* prism =
249 dynamic_cast<const Trk::PrismVolumeBounds*>(&(vol.volumeBounds()));
251 dynamic_cast<const Trk::SimplePolygonBrepVolumeBounds*>(
252 &(vol.volumeBounds()));
253
254 bool isPolygon = (box || trd || prism || spb || trdd);
255
256 if (!isPolygon)
257 return Trk::PolygonCache{};
258
259 Trk::PolygonCache cache;
260
261 double hz = 0.;
262 std::vector<Amg::Vector3D> vtxLocal;
263
264 if (swap > 0 &&
265 (box || (trd && trd->minHalflengthX() ==
266 trd->maxHalflengthX()))) { // swapping faces
267
268 if (swap == 1) {
269 if (box) {
270 hz = box->halflengthX();
271 cache.nVtx = 4;
272 vtxLocal.emplace_back(box->halflengthX(), box->halflengthY(),
273 box->halflengthZ());
274 vtxLocal.emplace_back(box->halflengthX(), -box->halflengthY(),
275 box->halflengthZ());
276 vtxLocal.emplace_back(box->halflengthX(), -box->halflengthY(),
277 -box->halflengthZ());
278 vtxLocal.emplace_back(box->halflengthX(), box->halflengthY(),
279 -box->halflengthZ());
280 } else if (trd) {
281 hz = trd->minHalflengthX();
282 cache.nVtx = 4;
283 vtxLocal.emplace_back(trd->minHalflengthX(), trd->halflengthY(),
284 trd->halflengthZ());
285 vtxLocal.emplace_back(trd->minHalflengthX(),
286 -trd->halflengthY(), trd->halflengthZ());
287 vtxLocal.emplace_back(trd->maxHalflengthX(),
288 -trd->halflengthY(), -trd->halflengthZ());
289 vtxLocal.emplace_back(trd->maxHalflengthX(), trd->halflengthY(),
290 -trd->halflengthZ());
291 }
292 } else if (swap == 2) {
293 if (box) {
294 hz = box->halflengthY();
295 cache.nVtx = 4;
296 vtxLocal.emplace_back(box->halflengthX(), box->halflengthY(),
297 box->halflengthZ());
298 vtxLocal.emplace_back(-box->halflengthX(), box->halflengthY(),
299 box->halflengthZ());
300 vtxLocal.emplace_back(-box->halflengthX(), box->halflengthY(),
301 -box->halflengthZ());
302 vtxLocal.emplace_back(box->halflengthX(), box->halflengthY(),
303 -box->halflengthZ());
304 } else if (trd) {
305 hz = trd->halflengthY();
306 cache.nVtx = 4;
307 vtxLocal.emplace_back(trd->minHalflengthX(), trd->halflengthY(),
308 trd->halflengthZ());
309 vtxLocal.emplace_back(-trd->minHalflengthX(),
310 trd->halflengthY(), trd->halflengthZ());
311 vtxLocal.emplace_back(-trd->minHalflengthX(),
312 trd->halflengthY(), -trd->halflengthZ());
313 vtxLocal.emplace_back(trd->minHalflengthX(), trd->halflengthY(),
314 -trd->halflengthZ());
315 }
316 }
317 cache.hZ = hz;
318 cache.center = vol.transform().translation();
319
320 for (const Amg::Vector3D& vtxloc : vtxLocal) {
321 Amg::Vector3D vtx = vol.transform() * vtxloc;
322 cache.vertices.push_back(std::move(vtx));
323 }
324 return cache;
325 } // end swap
326
327 if (box) {
328 hz = box->halflengthZ();
329 cache.nVtx = 4;
330 vtxLocal.emplace_back(box->halflengthX(), box->halflengthY(),
331 box->halflengthZ());
332 vtxLocal.emplace_back(-box->halflengthX(), box->halflengthY(),
333 box->halflengthZ());
334 vtxLocal.emplace_back(-box->halflengthX(), -box->halflengthY(),
335 box->halflengthZ());
336 vtxLocal.emplace_back(box->halflengthX(), -box->halflengthY(),
337 box->halflengthZ());
338 } else if (trd) {
339 hz = trd->halflengthZ();
340 cache.nVtx = 4;
341 vtxLocal.emplace_back(trd->minHalflengthX(), -trd->halflengthY(),
342 trd->halflengthZ());
343 vtxLocal.emplace_back(-trd->minHalflengthX(), -trd->halflengthY(),
344 trd->halflengthZ());
345 vtxLocal.emplace_back(-trd->maxHalflengthX(), trd->halflengthY(),
346 trd->halflengthZ());
347 vtxLocal.emplace_back(trd->maxHalflengthX(), trd->halflengthY(),
348 trd->halflengthZ());
349 } else if (trdd) {
350 hz = trdd->halflengthZ();
351 cache.nVtx = 6;
352 vtxLocal.emplace_back(trdd->maxHalflengthX(), 2 * trdd->halflengthY2(),
353 trdd->halflengthZ());
354 vtxLocal.emplace_back(-trdd->maxHalflengthX(), 2 * trdd->halflengthY2(),
355 trdd->halflengthZ());
356 vtxLocal.emplace_back(-trdd->medHalflengthX(), 0., trdd->halflengthZ());
357 vtxLocal.emplace_back(-trdd->minHalflengthX(),
358 -2 * trdd->halflengthY1(), trdd->halflengthZ());
359 vtxLocal.emplace_back(trdd->minHalflengthX(), -2 * trdd->halflengthY1(),
360 trdd->halflengthZ());
361 vtxLocal.emplace_back(trdd->medHalflengthX(), 0., trdd->halflengthZ());
362 } else if (prism) {
363 hz = prism->halflengthZ();
364 const std::vector<std::pair<double, double>> vtcs = prism->xyVertices();
365 for (const auto& vtc : vtcs)
366 vtxLocal.emplace_back(vtc.first, vtc.second, prism->halflengthZ());
367 cache.nVtx = vtcs.size();
368 } else if (spb) {
369 hz = spb->halflengthZ();
370 const std::vector<std::pair<double, double>> vtcs = spb->xyVertices();
371 for (const auto& vtc : vtcs)
372 vtxLocal.emplace_back(vtc.first, vtc.second, spb->halflengthZ());
373 cache.nVtx = vtcs.size();
374 }
375
376 cache.hZ = hz;
377 cache.center = vol.transform().translation();
378
379 for (const Amg::Vector3D& vtxloc : vtxLocal) {
380 Amg::Vector3D vtx = vol.transform() * vtxloc;
381 cache.vertices.push_back(std::move(vtx));
382 }
383
384 return cache;
385}
386
388 const std::pair<double, double>& vtx,
389 const std::vector<std::pair<double, double>>& pgon) {
390
391 // GM code
392 bool in = false;
393 size_t nv = pgon.size();
394 for (size_t i = 0, k = nv - 1; i < nv; k = i++) {
395 if ((pgon[i].second > vtx.second) != (pgon[k].second > vtx.second)) {
396 double ctg = (pgon[k].first - pgon[i].first) /
397 (pgon[k].second - pgon[i].second);
398 in ^= (vtx.first <
399 (vtx.second - pgon[i].second) * ctg + pgon[i].first);
400 }
401 }
402 return in;
403}
404
405double Trk::VolumeIntersection::det(const std::pair<double, double>& a,
406 const std::pair<double, double>& b,
407 bool dot) {
408
409 if (dot)
410 return (a.first * b.first + a.second * b.second);
411
412 return (a.first * b.second - a.second * b.first);
413}
414
415std::pair<bool, std::unique_ptr<Trk::Volume>>
417 const Volume& volB) {
418
419 // if combination of shifted polygons, calculable
420 Trk::PolygonCache pgA = polygonXY(volA);
421 Trk::PolygonCache pgB = polygonXY(volB);
422
423 const Trk::CylinderVolumeBounds *cylA{nullptr};
424 const Trk::CylinderVolumeBounds *cylB{nullptr};
425 if (pgA.nVtx == 0)
426 cylA = dynamic_cast<const Trk::CylinderVolumeBounds*>(
427 &(volA.volumeBounds()));
428 if (pgB.nVtx == 0)
429 cylB = dynamic_cast<const Trk::CylinderVolumeBounds*>(
430 &(volB.volumeBounds()));
431
432 if (cylA && cylB) {
433 double distance_center = (volA.center() - volB.center()).norm();
434 if (distance_center >
435 std::hypot(cylA->outerRadius(), cylA->halflengthZ()) +
436 std::hypot(cylB->outerRadius(), cylB->halflengthZ())) {
437 return std::make_pair(true, nullptr);
438 }
439 }
440
441 if (pgA.nVtx > 0 && pgB.nVtx > 0) {
442 // check orientation of xy face
443 Amg::Vector3D a0{pgA.vertices[1] - pgA.vertices[0]};
444 Amg::Vector3D a1{pgA.vertices[2] - pgA.vertices[1]};
445 Amg::Vector3D b0{pgB.vertices[1] - pgB.vertices[0]};
446 Amg::Vector3D b1{pgB.vertices[2] - pgB.vertices[1]};
447 if (std::abs((b0.cross(b1).unit()).dot(a0.cross(a1).unit())) < 1.e-3) {
448 if (std::abs((b0.cross(b1).unit()).dot(a1)) < 1.e-3)
449 pgA = polygonXY(volA, 1); // xy -> yz, only if cuboid-like
450 else if (std::abs((b0.cross(b1).unit()).dot(a0)) < 1.e-3)
451 pgA = polygonXY(volA, 2); // xy -> zx, only if cuboid-like
452 // new check orientation of xy face
453 a0 = pgA.vertices[1] - pgA.vertices[0];
454 a1 = pgA.vertices[2] - pgA.vertices[1];
455 }
456 if (std::abs(std::abs((b0.cross(b1).unit()).dot(a0.cross(a1).unit())) -
457 1.) > 1.e-3) {
458 return std::make_pair(false, nullptr);
459 }
460
461 Amg::Transform3D trf{Amg::Transform3D::Identity()};
462 Amg::Vector3D norm = a0.cross(a1).unit();
463 if (norm.z() != 1.) { // rotate to align with z axis
464 trf = Amg::AngleAxis3D(-norm.theta(), Amg::Vector3D::UnitY()) *
465 Amg::AngleAxis3D(-norm.phi(), Amg::Vector3D::UnitZ());
466
467 for (Amg::Vector3D& vtx : pgA.vertices) {
468 vtx = trf * vtx;
469 }
470 for (Amg::Vector3D& vtx : pgB.vertices) {
471 vtx = trf * vtx;
472 }
473 pgA.center = trf * pgA.center;
474 pgB.center = trf * pgB.center;
475 }
476 // overlap in z
477 pgA.minZ = std::min(pgA.vertices[0].z(),
478 2 * pgA.center.z() - pgA.vertices[0].z());
479 pgA.maxZ = std::max(pgA.vertices[0].z(),
480 2 * pgA.center.z() - pgA.vertices[0].z());
481 pgB.minZ = std::min(pgB.vertices[0].z(),
482 2 * pgB.center.z() - pgB.vertices[0].z());
483 pgB.maxZ = std::max(pgB.vertices[0].z(),
484 2 * pgB.center.z() - pgB.vertices[0].z());
485
486 if (pgA.minZ > pgB.maxZ || pgB.minZ > pgA.maxZ) {
487 return std::make_pair(true, nullptr);
488 } // no overlap in z
489
491 std::unique_ptr<Trk::Volume> overlap{};
492 if (result.nVtx > 0) {
493 auto spb = std::make_shared<Trk::SimplePolygonBrepVolumeBounds>(result.xyVertices,
494 0.5 * (result.maxZ - result.minZ));
495 Amg::Transform3D transf = trf.inverse() *
496 Amg::Translation3D(0., 0., 0.5 * (result.maxZ + result.minZ));
497 overlap = std::make_unique<Trk::Volume>(makeTransform(transf), spb);
498 }
499 return std::make_pair(true, std::move(overlap));
500 } // end shifted polygons
501
502 return std::make_pair(false, nullptr);
503}
void swap(DataVector< T > &a, DataVector< T > &b)
See DataVector<T, BASE>::swap().
static Double_t rs
static Double_t a
static Double_t t0
Bounds for a cubical Volume, the decomposeToSurfaces method creates a vector of 6 surfaces:
double halflengthX() const
This method returns the halflength in local x.
double halflengthY() const
This method returns the halflength in local y.
double halflengthZ() const
This method returns the halflength in local z.
Bounds for a cylindrical Volume, the decomposeToSurfaces method creates a vector of up to 6 surfaces:
double halflengthZ() const
This method returns the halflengthZ.
double outerRadius() const
This method returns the outer radius.
Bounds for a double trapezoidal shaped Volume, the decomposeToSurfaces method creates a vector of 8 s...
double minHalflengthX() const
This method returns the X halflength at minimal Y.
double halflengthZ() const
This method returns the halflength in local z.
double halflengthY1() const
This method returns the halflength1 in local y.
double halflengthY2() const
This method returns the halflength2 in local y.
double maxHalflengthX() const
This method returns the X halflength at maximal Y (local coordinates)
double medHalflengthX() const
This method returns the (maximal) halflength in local x.
Bounds for the transcript of triangular prism.
const std::vector< std::pair< double, double > > & xyVertices() const
This method returns the set of xy generating vertices.
double halflengthZ() const
This method returns the halflength in local z.
Bounds for the exact transcript of the GeoSimplePolygonBrep; volume defined by combination of symm....
double halflengthZ() const
This method returns the halflength in local z.
const std::vector< std::pair< double, double > > & xyVertices() const
This method returns the set of xy generating vertices.
Bounds for a trapezoidal shaped Volume, the decomposeToSurfaces method creates a vector of 6 surfaces...
double halflengthZ() const
This method returns the halflength in local z.
double minHalflengthX() const
This method returns the minimal halflength in local x.
double halflengthY() const
This method returns the halflength in local y.
double maxHalflengthX() const
This method returns the maximal halflength in local x.
static std::pair< bool, std::unique_ptr< Trk::Volume > > intersect(const Volume &volA, const Volume &volB)
static std::pair< bool, std::unique_ptr< Trk::Volume > > intersectApproximative(const Volume &volA, const Volume &volB)
static Trk::PolygonCache intersectPgon(Trk::PolygonCache &, Trk::PolygonCache &)
static PolygonCache polygonXY(const Volume &inVol, int swap=0)
static double det(const std::pair< double, double > &a, const std::pair< double, double > &b, bool)
static bool inside(const std::pair< double, double > &vtx, const std::vector< std::pair< double, double > > &pgon)
Base class for all volumes inside the tracking realm, it defines the interface for inherited Volume c...
Definition Volume.h:36
const Amg::Vector3D & center() const
returns the center of the volume
Definition Volume.h:90
const Amg::Transform3D & transform() const
Return methods for geometry transform.
Definition Volume.h:83
const VolumeBounds & volumeBounds() const
returns the volumeBounds()
Definition Volume.h:96
double a0
Definition globals.cxx:27
Eigen::AngleAxisd AngleAxis3D
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
Eigen::Translation< double, 3 > Translation3D
std::unique_ptr< Amg::Transform3D > makeTransform(const Amg::Transform3D &trf)
Definition dot.py:1
std::vector< std::pair< double, double > > xyVertices
std::vector< Amg::Vector3D > vertices
std::vector< std::pair< double, double > > edges
std::vector< bool > commonVertices