ATLAS Offline Software
Loading...
Searching...
No Matches
TrapezoidVolumeBounds.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// TrapezoidVolumeBounds.cxx, (c) ATLAS Detector software
8
9// Trk
11
13
14// TrkSurfaces
18// Gaudi
19#include "GaudiKernel/MsgStream.h"
20#include "GaudiKernel/SystemOfUnits.h"
21// STD
22#include <cmath>
23#include <iomanip>
24#include <iostream>
25
36
38 double minhalex,
39 double maxhalex,
40 double haley,
41 double halez)
42 : VolumeBounds()
43 , m_minHalfX(minhalex)
44 , m_maxHalfX(maxhalex)
45 , m_halfY(haley)
46 , m_halfZ(halez)
47 , m_alpha(0.)
48 , m_beta(0.)
50{
51 m_alpha = atan((m_maxHalfX - m_minHalfX) / 2 / m_halfY) + 0.5 * M_PI;
53}
54
56 double minhalex,
57 double haley,
58 double halez,
59 double alpha,
60 double beta)
61 : VolumeBounds()
62 , m_minHalfX(minhalex)
63 , m_maxHalfX(0.)
64 , m_halfY(haley)
65 , m_halfZ(halez)
66 , m_alpha(alpha)
67 , m_beta(beta)
69{
70 double gamma = (alpha > beta) ? (alpha - 0.5 * M_PI) : (beta - 0.5 * M_PI);
71 m_maxHalfX = m_minHalfX + (2. * m_halfY) * tan(gamma);
72}
73
85
87
90{
91 if (this != &trabo) {
92 m_minHalfX = trabo.m_minHalfX;
93 m_maxHalfX = trabo.m_maxHalfX;
94 m_halfY = trabo.m_halfY;
95 m_halfZ = trabo.m_halfZ;
96 m_alpha = trabo.m_alpha;
97 m_beta = trabo.m_beta;
99 }
100 return *this;
101}
102
103std::vector<std::unique_ptr<Trk::Surface>>
105 (const Amg::Transform3D& transform)
106{
107 auto retsf = std::vector<std::unique_ptr<Trk::Surface>>();
108
109 // face surfaces xy
110 Amg::RotationMatrix3D trapezoidRotation(transform.rotation());
111 Amg::Vector3D trapezoidX(trapezoidRotation.col(0));
112 Amg::Vector3D trapezoidY(trapezoidRotation.col(1));
113 Amg::Vector3D trapezoidZ(trapezoidRotation.col(2));
114 Amg::Vector3D trapezoidCenter(transform.translation());
115
116 // (1) - at negative local z
117 retsf.push_back(std::make_unique<Trk::PlaneSurface>(
119 transform *
120 Amg::AngleAxis3D(180 * Gaudi::Units::deg, Amg::Vector3D(0., 1., 0.)) *
122 this->faceXYTrapezoidBounds()));
123 // (2) - at positive local z
124 retsf.push_back(std::make_unique<Trk::PlaneSurface>(
126 transform *
128 this->faceXYTrapezoidBounds()));
129 // face surfaces yz
130 // transmute cyclical
131 // (3) - at point A, attached to alpha opening angle
132 // the yz bound are created in such a way that the surface y-direction has to
133 // become the z-direction. The resulting surface normal has to point in
134 // y-direction. This is achieved by rotating the plane surface by -90
135 // degrees around the x-axis.
136 // Then, the plane has to be rotated around the z-axis by alpha.
137 //
138 // double c=cos(M_PI/2);
139 // double s=sin(M_PI/2);
140 // Amg::RotationMatrix3D rotate_to_xz;
141 // rotate_to_xz << 1.f, 0.f, 0.f, // 1 0 0
142 // 0.f, c, -s, // 0 0 -1
143 // 0.f, s, c; // 0 1 0
144 //
145 // s=sin(-alpha());
146 // c=cos(-alpha());
147 // Amg::RotationMatrix3D rotate_left;
148 // rotate_left << c, s, 0.f,
149 // -s, c, 0.f,
150 // 0.f, 0.f, 1.f;
151 //
152 // Amg::RotationMatrix3D rotateToFaceAlpha( rotate_left * rotate_to_xz);
153 Amg::RotationMatrix3D rotateToFaceAlpha;
154 {
155 double s=sin(-alpha());
156 double c=cos(-alpha());
157 rotateToFaceAlpha << c, 0.f, s,
158 -s, 0.f, c,
159 0.f, -1.f, 0.f;
160 }
161
162 std::shared_ptr<RectangleBounds> faceAlphaBounds = this->faceAlphaRectangleBounds();
163 Amg::Vector3D faceAlphaPosition0(
164 -0.5 * (this->minHalflengthX() + this->maxHalflengthX()), 0., 0.);
165 Amg::Vector3D faceAlphaPosition = transform * faceAlphaPosition0;
166 retsf.push_back(std::make_unique<Trk::PlaneSurface>( Amg::Translation3D(faceAlphaPosition)
167 * Amg::Transform3D(trapezoidRotation * rotateToFaceAlpha),
168 faceAlphaBounds));
169 // (4) - at point B, attached to beta opening angle
170 // same as above but rotate to the right by beta
171 Amg::RotationMatrix3D rotateToFaceBeta;
172 {
173 double s=sin(beta());
174 double c=cos(beta());
175 rotateToFaceBeta << c, 0.f, s,
176 -s, 0.f, c,
177 0.f, -1.f, 0.f;
178 }
179
180 std::shared_ptr<RectangleBounds> faceBetaBounds = this->faceBetaRectangleBounds();
181 // Amg::Vector3D
182 // faceBetaPosition(B+faceBetaRotation.colX()*faceBetaBounds->halflengthX());
183 Amg::Vector3D faceBetaPosition0(
184 0.5 * (this->minHalflengthX() + this->maxHalflengthX()), 0., 0.);
185 Amg::Vector3D faceBetaPosition = transform * faceBetaPosition0;
186 retsf.push_back(std::make_unique<Trk::PlaneSurface>( Amg::Translation3D(faceBetaPosition)
187 * Amg::Transform3D(trapezoidRotation * rotateToFaceBeta),
188 faceBetaBounds));
189 retsf.push_back(std::make_unique<Trk::PlaneSurface>(
191 transform *
192 Amg::AngleAxis3D(180. * Gaudi::Units::deg, Amg::Vector3D(1., 0., 0.)) *
194 Amg::AngleAxis3D(-90 * Gaudi::Units::deg, Amg::Vector3D(0., 1., 0.)) *
195 Amg::AngleAxis3D(-90. * Gaudi::Units::deg, Amg::Vector3D(1., 0., 0.))),
197 // (6) - at positive local x
198 retsf.push_back(std::make_unique<Trk::PlaneSurface>(
200 transform *
202 Amg::AngleAxis3D(-90 * Gaudi::Units::deg, Amg::Vector3D(0., 1., 0.)) *
203 Amg::AngleAxis3D(-90. * Gaudi::Units::deg, Amg::Vector3D(1., 0., 0.))),
204 this->faceZXRectangleBoundsTop()));
205
206 return retsf;
207}
208
209// faces in xy
210std::shared_ptr<Trk::TrapezoidBounds>
212{
213 return std::make_shared<Trk::TrapezoidBounds>(m_minHalfX, m_maxHalfX, m_halfY);
214}
215
216std::shared_ptr<Trk::RectangleBounds>
218{
219 return std::make_shared<Trk::RectangleBounds>(m_halfY / cos(m_alpha - 0.5 * M_PI), m_halfZ);
220}
221
222std::shared_ptr<Trk::RectangleBounds>
224{
225 return std::make_shared<Trk::RectangleBounds>(m_halfY / cos(m_beta - 0.5 * M_PI), m_halfZ);
226}
227
228std::shared_ptr<Trk::RectangleBounds>
230{
231 return std::make_shared<Trk::RectangleBounds>(m_halfZ, m_minHalfX);
232}
233
234std::shared_ptr<Trk::RectangleBounds>
236{
237 // double delta = (m_alpha < m_beta) ? m_alpha - M_PI/2. : m_beta - M_PI/2.;
238 // return new Trk::RectangleBounds(m_halfZ,
239 // 0.5*(m_minHalfX+m_minHalfX+2.*m_halfY/cos(delta)));
240 return std::make_shared<Trk::RectangleBounds>(m_halfZ, m_maxHalfX);
241}
242
243bool
245{
246 if (std::abs(pos.z()) > m_halfZ + tol)
247 return false;
248 if (std::abs(pos.y()) > m_halfY + tol)
249 return false;
250 std::shared_ptr<Trk::TrapezoidBounds> faceXYBounds = this->faceXYTrapezoidBounds();
251 Amg::Vector2D locp(pos.x(), pos.y());
252 bool inside(faceXYBounds->inside(locp, tol, tol));
253 return inside;
254}
255
256// ostream operator overload
257MsgStream&
259{
260 std::stringstream temp_sl;
261 temp_sl << std::setiosflags(std::ios::fixed);
262 temp_sl << std::setprecision(7);
263 temp_sl
264 << "Trk::TrapezoidVolumeBounds: (minhalfX, halfY, halfZ, alpha, beta) = ";
265 temp_sl << "(" << m_minHalfX << ", " << m_halfY << ", " << m_halfZ;
266 temp_sl << ", " << m_alpha << ", " << m_beta << ")";
267 sl << temp_sl.str();
268 return sl;
269}
270
271std::ostream&
272Trk::TrapezoidVolumeBounds::dump(std::ostream& sl) const
273{
274 std::stringstream temp_sl;
275 temp_sl << std::setiosflags(std::ios::fixed);
276 temp_sl << std::setprecision(7);
277 temp_sl
278 << "Trk::TrapezoidVolumeBounds: (minhalfX, halfY, halfZ, alpha, beta) = ";
279 temp_sl << "(" << m_minHalfX << ", " << m_halfY << ", " << m_halfZ;
280 temp_sl << ", " << m_alpha << ", " << m_beta << ")";
281 sl << temp_sl.str();
282 return sl;
283}
284
#define M_PI
Bounds for a trapezoidal shaped Volume, the decomposeToSurfaces method creates a vector of 6 surfaces...
MsgStream & dump(MsgStream &sl) const override final
Output Method for MsgStream.
double halflengthZ() const
This method returns the halflength in local z.
std::shared_ptr< RectangleBounds > faceAlphaRectangleBounds() const
This method returns the associated RecantleBounds of the face PlaneSurface attached to alpha (negativ...
std::shared_ptr< RectangleBounds > faceZXRectangleBoundsBottom() const
This method returns the associated RecantleBounds of the face PlaneSurface parallel to local zx plane...
double minHalflengthX() const
This method returns the minimal halflength in local x.
double halflengthY() const
This method returns the halflength in local y.
virtual std::vector< std::unique_ptr< Trk::Surface > > decomposeToSurfaces(const Amg::Transform3D &transform) override final
Method to decompose the Bounds into Surfaces.
double m_alpha
opening angle alpha (in point A)
SixObjectsAccessor m_objectAccessor
There's only one single object Acessor for the moment has to be implemented if Cuboids are used more ...
TrapezoidVolumeBounds()
Default Constructor.
std::shared_ptr< RectangleBounds > faceZXRectangleBoundsTop() const
This method returns the associated RecantleBounds of the face PlaneSurface parallel to local zx plane...
double alpha() const
This method returns the opening angle in point A (negative local x)
std::shared_ptr< TrapezoidBounds > faceXYTrapezoidBounds() const
This method returns the associated TrapezoidBounds of the face PlaneSurface parallel to local xy plan...
TrapezoidVolumeBounds & operator=(const TrapezoidVolumeBounds &bobo)
Assignment operator.
double m_maxHalfX
maximal halflength in x
double m_beta
opening angle beta (in point B)
virtual ~TrapezoidVolumeBounds()
Destructor.
double m_minHalfX
minimal halflength in x
double beta() const
This method returns the opening angle in point B (negative local x)
std::shared_ptr< RectangleBounds > faceBetaRectangleBounds() const
This method returns the associated RecantleBounds of the face PlaneSurface attached to beta (positive...
double maxHalflengthX() const
This method returns the maximal halflength in local x.
bool inside(const Amg::Vector3D &, double tol=0.) const override final
This method checks if position in the 3D volume frame is inside the cylinder.
VolumeBounds()
Default Constructor.
Eigen::AngleAxisd AngleAxis3D
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Translation< double, 3 > Translation3D