Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4UGenericTrap.cc
Go to the documentation of this file.
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 of G4UGenericTrap wrapper class
27//
28// 30.10.13 G.Cosmo, CERN
29// --------------------------------------------------------------------
30
31#include "G4GenericTrap.hh"
32#include "G4UGenericTrap.hh"
33
34#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
35
36#include "G4AffineTransform.hh"
38#include "G4BoundingEnvelope.hh"
39
40#include "G4Polyhedron.hh"
42
43using namespace CLHEP;
44
45////////////////////////////////////////////////////////////////////////
46//
47// Constructor (generic parameters)
48//
49G4UGenericTrap::G4UGenericTrap(const G4String& name, G4double halfZ,
50 const std::vector<G4TwoVector>& vertices)
51 : Base_t(name), fVisSubdivisions(0)
52{
53 SetZHalfLength(halfZ);
54 Initialise(vertices);
55}
56
57
58////////////////////////////////////////////////////////////////////////
59//
60// Fake default constructor - sets only member data and allocates memory
61// for usage restricted to object persistency.
62//
63G4UGenericTrap::G4UGenericTrap(__void__& a)
64 : Base_t(a), fVisSubdivisions(0), fVertices()
65{
66}
67
68
69//////////////////////////////////////////////////////////////////////////
70//
71// Destructor
72//
73G4UGenericTrap::~G4UGenericTrap()
74{
75}
76
77
78//////////////////////////////////////////////////////////////////////////
79//
80// Copy constructor
81//
82G4UGenericTrap::G4UGenericTrap(const G4UGenericTrap& source)
83 : Base_t(source), fVisSubdivisions(source.fVisSubdivisions),
84 fVertices(source.fVertices)
85
86{
87}
88
89
90//////////////////////////////////////////////////////////////////////////
91//
92// Assignment operator
93//
94G4UGenericTrap&
95G4UGenericTrap::operator=(const G4UGenericTrap& source)
96{
97 if (this == &source) return *this;
98
99 Base_t::operator=( source );
100 fVertices = source.fVertices;
101 fVisSubdivisions = source.fVisSubdivisions;
102
103 return *this;
104}
105
106//////////////////////////////////////////////////////////////////////////
107//
108// Accessors & modifiers
109//
110G4double G4UGenericTrap::GetZHalfLength() const
111{
112 return GetDZ();
113}
114G4int G4UGenericTrap::GetNofVertices() const
115{
116 return fVertices.size();
117}
118G4TwoVector G4UGenericTrap::GetVertex(G4int index) const
119{
120 return G4TwoVector(GetVerticesX()[index], GetVerticesY()[index]);
121}
122const std::vector<G4TwoVector>& G4UGenericTrap::GetVertices() const
123{
124 return fVertices;
125}
126G4double G4UGenericTrap::GetTwistAngle(G4int index) const
127{
128 return GetTwist(index);
129}
130G4bool G4UGenericTrap::IsTwisted() const
131{
132 return !IsPlanar();
133}
134G4int G4UGenericTrap::GetVisSubdivisions() const
135{
136 return fVisSubdivisions;
137}
138
139void G4UGenericTrap::SetVisSubdivisions(G4int subdiv)
140{
141 fVisSubdivisions = subdiv;
142}
143
144void G4UGenericTrap::SetZHalfLength(G4double halfZ)
145{
146 SetDZ(halfZ);
147}
148
149void G4UGenericTrap::Initialise(const std::vector<G4TwoVector>& v)
150{
151 G4double verticesx[8], verticesy[8];
152 for (G4int i=0; i<8; ++i)
153 {
154 fVertices.push_back(v[i]);
155 verticesx[i] = v[i].x();
156 verticesy[i] = v[i].y();
157 }
158 Initialize(verticesx, verticesy, GetZHalfLength());
159}
160
161/////////////////////////////////////////////////////////////////////////
162//
163// Get bounding box
164
165void G4UGenericTrap::BoundingLimits(G4ThreeVector& pMin,
166 G4ThreeVector& pMax) const
167{
168 U3Vector vmin, vmax;
169 Extent(vmin,vmax);
170 pMin.set(vmin.x(),vmin.y(),vmin.z());
171 pMax.set(vmax.x(),vmax.y(),vmax.z());
172
173 // Check correctness of the bounding box
174 //
175 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
176 {
177 std::ostringstream message;
178 message << "Bad bounding box (min >= max) for solid: "
179 << GetName() << " !"
180 << "\npMin = " << pMin
181 << "\npMax = " << pMax;
182 G4Exception("G4UGenericTrap::BoundingLimits()", "GeomMgt0001",
183 JustWarning, message);
184 StreamInfo(G4cout);
185 }
186}
187
188//////////////////////////////////////////////////////////////////////////
189//
190// Calculate extent under transform and specified limit
191
192G4bool
193G4UGenericTrap::CalculateExtent(const EAxis pAxis,
194 const G4VoxelLimits& pVoxelLimit,
195 const G4AffineTransform& pTransform,
196 G4double& pMin, G4double& pMax) const
197{
198 G4ThreeVector bmin, bmax;
199 G4bool exist;
200
201 // Check bounding box (bbox)
202 //
203 BoundingLimits(bmin,bmax);
204 G4BoundingEnvelope bbox(bmin,bmax);
205#ifdef G4BBOX_EXTENT
206 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
207#endif
208 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
209 {
210 return exist = (pMin < pMax) ? true : false;
211 }
212
213 // Set bounding envelope (benv) and calculate extent
214 //
215 // To build the bounding envelope with plane faces each side face of
216 // the trapezoid is subdivided in triangles. Subdivision is done by
217 // duplication of vertices in the bases in a way that the envelope be
218 // a convex polyhedron (some faces of the envelope can be degenerate)
219 //
220 G4double dz = GetZHalfLength();
221 G4ThreeVectorList baseA(8), baseB(8);
222 for (G4int i=0; i<4; ++i)
223 {
224 G4TwoVector va = GetVertex(i);
225 G4TwoVector vb = GetVertex(i+4);
226 baseA[2*i].set(va.x(),va.y(),-dz);
227 baseB[2*i].set(vb.x(),vb.y(), dz);
228 }
229 for (G4int i=0; i<4; ++i)
230 {
231 G4int k1=2*i, k2=(2*i+2)%8;
232 G4double ax = (baseA[k2].x()-baseA[k1].x());
233 G4double ay = (baseA[k2].y()-baseA[k1].y());
234 G4double bx = (baseB[k2].x()-baseB[k1].x());
235 G4double by = (baseB[k2].y()-baseB[k1].y());
236 G4double znorm = ax*by - ay*bx;
237 baseA[k1+1] = (znorm < 0.0) ? baseA[k2] : baseA[k1];
238 baseB[k1+1] = (znorm < 0.0) ? baseB[k1] : baseB[k2];
239 }
240
241 std::vector<const G4ThreeVectorList *> polygons(2);
242 polygons[0] = &baseA;
243 polygons[1] = &baseB;
244
245 G4BoundingEnvelope benv(bmin,bmax,polygons);
246 exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
247 return exist;
248}
249
250//////////////////////////////////////////////////////////////////////////
251//
252// CreatePolyhedron()
253//
254G4Polyhedron* G4UGenericTrap::CreatePolyhedron() const
255{
256 // Approximation of Twisted Side
257 // Construct extra Points, if Twisted Side
258 //
259 G4PolyhedronArbitrary* polyhedron;
260 size_t nVertices, nFacets;
261 G4double fDz = GetZHalfLength();
262
263 G4int subdivisions=0;
264 G4int i;
265 if(IsTwisted())
266 {
267 if ( GetVisSubdivisions() != 0 )
268 {
269 subdivisions=GetVisSubdivisions();
270 }
271 else
272 {
273 // Estimation of Number of Subdivisions for smooth visualisation
274 //
275 G4double maxTwist=0.;
276 for(i=0; i<4; ++i)
277 {
278 if(GetTwistAngle(i)>maxTwist) { maxTwist=GetTwistAngle(i); }
279 }
280
281 // Computes bounding vectors for the shape
282 //
283 G4double Dx,Dy;
284 G4ThreeVector minVec, maxVec;
285 BoundingLimits(minVec,maxVec);
286 Dx = 0.5*(maxVec.x()- minVec.y());
287 Dy = 0.5*(maxVec.y()- minVec.y());
288 if (Dy > Dx) { Dx=Dy; }
289
290 subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
291 if (subdivisions<4) { subdivisions=4; }
292 if (subdivisions>30) { subdivisions=30; }
293 }
294 }
295 G4int sub4=4*subdivisions;
296 nVertices = 8+subdivisions*4;
297 nFacets = 6+subdivisions*4;
298 G4double cf=1./(subdivisions+1);
299 polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets);
300
301 // Add Vertex
302 //
303 for (i=0; i<4; ++i)
304 {
305 polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(),
306 GetVertex(i).y(),-fDz));
307 }
308 for(i=0; i<subdivisions; ++i)
309 {
310 for(G4int j=0; j<4 ; ++j)
311 {
312 G4TwoVector u=GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j));
313 polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1)));
314 }
315 }
316 for (i=4; i<8; ++i)
317 {
318 polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(),
319 GetVertex(i).y(),fDz));
320 }
321
322 // Add Facets
323 //
324 polyhedron->AddFacet(1,4,3,2); //Z-plane
325 for (i=0; i<subdivisions+1; ++i)
326 {
327 G4int is=i*4;
328 polyhedron->AddFacet(5+is,8+is,4+is,1+is);
329 polyhedron->AddFacet(8+is,7+is,3+is,4+is);
330 polyhedron->AddFacet(7+is,6+is,2+is,3+is);
331 polyhedron->AddFacet(6+is,5+is,1+is,2+is);
332 }
333 polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane
334
335 polyhedron->SetReferences();
336 polyhedron->InvertFacets();
337
338 return (G4Polyhedron*) polyhedron;
339}
340
341#endif // G4GEOM_USE_USOLIDS
std::vector< G4ThreeVector > G4ThreeVectorList
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
CLHEP::Hep3Vector G4ThreeVector
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:36
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4GLOB_DLL std::ostream G4cout
double x() const
double y() const
double z() const
double x() const
double y() const
void set(double x, double y, double z)
void AddFacet(const G4int iv1, const G4int iv2, const G4int iv3, const G4int iv4=0)
void AddVertex(const G4ThreeVector &v)
EAxis
Definition: geomdefs.hh:54
Definition: DoubConv.h:17
const char * name(G4int ptype)