ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4UEllipticalTube.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4UEllipticalTube.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // Implementation for G4UEllipticalTube wrapper class
27 //
28 // 13-08-2019 Gabriele Cosmo, CERN
29 // --------------------------------------------------------------------
30 
31 #include "G4EllipticalTube.hh"
32 #include "G4UEllipticalTube.hh"
33 
34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
35 
36 #include "G4AffineTransform.hh"
37 #include "G4VPVParameterisation.hh"
38 #include "G4PhysicalConstants.hh"
39 #include "G4BoundingEnvelope.hh"
40 #include "G4Polyhedron.hh"
41 
43 //
44 // Constructor - check & set half widths
45 
46 
47 G4UEllipticalTube::G4UEllipticalTube(const G4String& pName,
48  G4double dx,
49  G4double dy,
50  G4double dz )
51  : Base_t(pName, dx, dy, dz)
52 { }
53 
55 //
56 // Fake default constructor - sets only member data and allocates memory
57 // for usage restricted to object persistency.
58 
59 G4UEllipticalTube::G4UEllipticalTube( __void__& a )
60  : Base_t(a)
61 { }
62 
64 //
65 // Destructor
66 
67 G4UEllipticalTube::~G4UEllipticalTube() { }
68 
70 //
71 // Copy constructor
72 
73 G4UEllipticalTube::G4UEllipticalTube(const G4UEllipticalTube& rhs)
74  : Base_t(rhs)
75 { }
76 
78 //
79 // Assignment operator
80 
81 G4UEllipticalTube& G4UEllipticalTube::operator = (const G4UEllipticalTube& rhs)
82 {
83  // Check assignment to self
84  //
85  if (this == &rhs) { return *this; }
86 
87  // Copy base class data
88  //
89  Base_t::operator=(rhs);
90 
91  return *this;
92 }
93 
95 //
96 // Accessors
97 
98 G4double G4UEllipticalTube::GetDx() const
99 {
100  return Base_t::GetDx();
101 }
102 
103 G4double G4UEllipticalTube::GetDy() const
104 {
105  return Base_t::GetDy();
106 }
107 
108 G4double G4UEllipticalTube::GetDz() const
109 {
110  return Base_t::GetDz();
111 }
112 
114 //
115 // Modifiers
116 
117 void G4UEllipticalTube::SetDx(G4double dx)
118 {
119  Base_t::SetDx(dx);
120 }
121 
122 void G4UEllipticalTube::SetDy(G4double dy)
123 {
124  Base_t::SetDy(dy);
125 }
126 
127 void G4UEllipticalTube::SetDz(G4double dz)
128 {
129  Base_t::SetDz(dz);
130 }
131 
133 //
134 // Make a clone of the object
135 
136 G4VSolid* G4UEllipticalTube::Clone() const
137 {
138  return new G4UEllipticalTube(*this);
139 }
140 
142 //
143 // Get bounding box
144 
145 void G4UEllipticalTube::BoundingLimits(G4ThreeVector& pMin,
146  G4ThreeVector& pMax) const
147 {
148  G4double dx = GetDx();
149  G4double dy = GetDy();
150  G4double dz = GetDz();
151 
152  pMin.set(-dx,-dy,-dz);
153  pMax.set( dx, dy, dz);
154 }
155 
157 //
158 // Calculate extent under transform and specified limit
159 
160 G4bool
161 G4UEllipticalTube::CalculateExtent(const EAxis pAxis,
162  const G4VoxelLimits& pVoxelLimit,
163  const G4AffineTransform& pTransform,
164  G4double& pMin, G4double& pMax) const
165 {
166  G4ThreeVector bmin, bmax;
167  G4bool exist;
168 
169  // Check bounding box (bbox)
170  //
171  BoundingLimits(bmin,bmax);
172  G4BoundingEnvelope bbox(bmin,bmax);
173 #ifdef G4BBOX_EXTENT
174  return bbox.CalculateExtent(pAxis,pVoxelLimit, pTransform, pMin, pMax);
175 #endif
176  if (bbox.BoundingBoxVsVoxelLimits(pAxis, pVoxelLimit, pTransform, pMin, pMax))
177  {
178  return exist = (pMin < pMax) ? true : false;
179  }
180 
181  G4double dx = GetDx();
182  G4double dy = GetDy();
183  G4double dz = GetDz();
184 
185  // Set bounding envelope (benv) and calculate extent
186  //
187  const G4int NSTEPS = 24; // number of steps for whole circle
188  G4double ang = twopi/NSTEPS;
189 
190  G4double sinHalf = std::sin(0.5*ang);
191  G4double cosHalf = std::cos(0.5*ang);
192  G4double sinStep = 2.*sinHalf*cosHalf;
193  G4double cosStep = 1. - 2.*sinHalf*sinHalf;
194  G4double sx = dx/cosHalf;
195  G4double sy = dy/cosHalf;
196 
197  G4double sinCur = sinHalf;
198  G4double cosCur = cosHalf;
199  G4ThreeVectorList baseA(NSTEPS), baseB(NSTEPS);
200  for (G4int k=0; k<NSTEPS; ++k)
201  {
202  baseA[k].set(sx*cosCur,sy*sinCur,-dz);
203  baseB[k].set(sx*cosCur,sy*sinCur, dz);
204 
205  G4double sinTmp = sinCur;
206  sinCur = sinCur*cosStep + cosCur*sinStep;
207  cosCur = cosCur*cosStep - sinTmp*sinStep;
208  }
209 
210  std::vector<const G4ThreeVectorList *> polygons(2);
211  polygons[0] = &baseA;
212  polygons[1] = &baseB;
213  G4BoundingEnvelope benv(bmin, bmax, polygons);
214  exist = benv.CalculateExtent(pAxis, pVoxelLimit, pTransform, pMin, pMax);
215  return exist;
216 }
217 
219 //
220 // CreatePolyhedron
221 //
222 G4Polyhedron* G4UEllipticalTube::CreatePolyhedron() const
223 {
224  // create cylinder with radius=1...
225  //
226  G4Polyhedron* eTube = new G4PolyhedronTube(0., 1., GetDz());
227 
228  // apply non-uniform scaling...
229  //
230  eTube->Transform(G4Scale3D(GetDx(), GetDy(), 1.));
231  return eTube;
232 }
233 
234 #endif // G4GEOM_USE_USOLIDS