Geant4-11
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
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
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
70//
71// Destructor
72//
73G4UGenericTrap::~G4UGenericTrap()
74{
75}
76
77
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
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
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
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
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
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
static const G4double pMax
static const G4double pMin
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 x() const
double y() const
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)