Geant4  10.03
G4UGenericPolycone.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 //
27 // $Id:$
28 //
29 //
30 // Implementation of G4UGenericPolycone wrapper class
31 // --------------------------------------------------------------------
32 
33 #include "G4GenericPolycone.hh"
34 #include "G4UGenericPolycone.hh"
35 
36 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
37 
38 #include "G4GeomTools.hh"
39 #include "G4AffineTransform.hh"
40 #include "G4VPVParameterisation.hh"
41 #include "G4BoundingEnvelope.hh"
42 
43 #include "G4Polyhedron.hh"
44 
45 using namespace CLHEP;
46 
48 //
49 // Constructor (generic parameters)
50 //
51 G4UGenericPolycone::G4UGenericPolycone(const G4String& name,
52  G4double phiStart,
53  G4double phiTotal,
54  G4int numRZ,
55  const G4double r[],
56  const G4double z[] )
57  : G4USolid(name, new UGenericPolycone(name, phiStart, phiTotal, numRZ, r, z))
58 {
59 }
60 
61 
63 //
64 // Fake default constructor - sets only member data and allocates memory
65 // for usage restricted to object persistency.
66 //
67 G4UGenericPolycone::G4UGenericPolycone(__void__& a)
68  : G4USolid(a)
69 {
70 }
71 
72 
74 //
75 // Destructor
76 //
77 G4UGenericPolycone::~G4UGenericPolycone()
78 {
79 }
80 
81 
83 //
84 // Copy constructor
85 //
86 G4UGenericPolycone::G4UGenericPolycone(const G4UGenericPolycone &source)
87  : G4USolid(source)
88 {
89 }
90 
91 
93 //
94 // Assignment operator
95 //
96 G4UGenericPolycone&
97 G4UGenericPolycone::operator=(const G4UGenericPolycone &source)
98 {
99  if (this == &source) return *this;
100 
101  G4USolid::operator=( source );
102 
103  return *this;
104 }
105 
106 G4double G4UGenericPolycone::GetStartPhi() const
107 {
108  return GetShape()->GetStartPhi();
109 }
110 G4double G4UGenericPolycone::GetEndPhi() const
111 {
112  return GetShape()->GetEndPhi();
113 }
114 G4double G4UGenericPolycone::GetSinStartPhi() const
115 {
116  if (!GetShape()->IsOpen()) return 0;
117  G4double phi = GetShape()->GetStartPhi();
118  return std::sin(phi);
119 }
120 G4double G4UGenericPolycone::GetCosStartPhi() const
121 {
122  if (!GetShape()->IsOpen()) return 1;
123  G4double phi = GetShape()->GetStartPhi();
124  return std::cos(phi);
125 }
126 G4double G4UGenericPolycone::GetSinEndPhi() const
127 {
128  if (!GetShape()->IsOpen()) return 0;
129  G4double phi = GetShape()->GetEndPhi();
130  return std::sin(phi);
131 }
132 G4double G4UGenericPolycone::GetCosEndPhi() const
133 {
134  if (!GetShape()->IsOpen()) return 1;
135  G4double phi = GetShape()->GetEndPhi();
136  return std::cos(phi);
137 }
138 G4bool G4UGenericPolycone::IsOpen() const
139 {
140  return GetShape()->IsOpen();
141 }
142 G4int G4UGenericPolycone::GetNumRZCorner() const
143 {
144  return GetShape()->GetNumRZCorner();
145 }
146 G4PolyconeSideRZ G4UGenericPolycone::GetCorner(G4int index) const
147 {
148  UPolyconeSideRZ pside = GetShape()->GetCorner(index);
149  G4PolyconeSideRZ psiderz = { pside.r, pside.z };
150 
151  return psiderz;
152 }
153 
155 //
156 // Get bounding box
157 
158 void
159 G4UGenericPolycone::Extent(G4ThreeVector& pMin, G4ThreeVector& pMax) const
160 {
161  G4double rmin = kInfinity, rmax = -kInfinity;
162  G4double zmin = kInfinity, zmax = -kInfinity;
163 
164  for (G4int i=0; i<GetNumRZCorner(); ++i)
165  {
166  G4PolyconeSideRZ corner = GetCorner(i);
167  if (corner.r < rmin) rmin = corner.r;
168  if (corner.r > rmax) rmax = corner.r;
169  if (corner.z < zmin) zmin = corner.z;
170  if (corner.z > zmax) zmax = corner.z;
171  }
172 
173  if (IsOpen())
174  {
175  G4TwoVector vmin,vmax;
176  G4GeomTools::DiskExtent(rmin,rmax,
177  GetSinStartPhi(),GetCosStartPhi(),
178  GetSinEndPhi(),GetCosEndPhi(),
179  vmin,vmax);
180  pMin.set(vmin.x(),vmin.y(),zmin);
181  pMax.set(vmax.x(),vmax.y(),zmax);
182  }
183  else
184  {
185  pMin.set(-rmax,-rmax, zmin);
186  pMax.set( rmax, rmax, zmax);
187  }
188 
189  // Check correctness of the bounding box
190  //
191  if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
192  {
193  std::ostringstream message;
194  message << "Bad bounding box (min >= max) for solid: "
195  << GetName() << " !"
196  << "\npMin = " << pMin
197  << "\npMax = " << pMax;
198  G4Exception("G4UGenericPolycone::Extent()", "GeomMgt0001",
199  JustWarning, message);
200  StreamInfo(G4cout);
201  }
202 }
203 
205 //
206 // Calculate extent under transform and specified limit
207 
208 G4bool
209 G4UGenericPolycone::CalculateExtent(const EAxis pAxis,
210  const G4VoxelLimits& pVoxelLimit,
211  const G4AffineTransform& pTransform,
212  G4double& pMin, G4double& pMax) const
213 {
214  G4ThreeVector bmin, bmax;
215  G4bool exist;
216 
217  // Check bounding box (bbox)
218  //
219  Extent(bmin,bmax);
220  G4BoundingEnvelope bbox(bmin,bmax);
221 #ifdef G4BBOX_EXTENT
222  if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
223 #endif
224  if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
225  {
226  return exist = (pMin < pMax) ? true : false;
227  }
228 
229  // To find the extent, RZ contour of the polycone is subdivided
230  // in triangles. The extent is calculated as cumulative extent of
231  // all sub-polycones formed by rotation of triangles around Z
232  //
233  G4TwoVectorList contourRZ;
234  G4TwoVectorList triangles;
235  G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
236  G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
237 
238  // get RZ contour, ensure anticlockwise order of corners
239  for (G4int i=0; i<GetNumRZCorner(); ++i)
240  {
241  G4PolyconeSideRZ corner = GetCorner(i);
242  contourRZ.push_back(G4TwoVector(corner.r,corner.z));
243  }
244  G4double area = G4GeomTools::PolygonArea(contourRZ);
245  if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
246 
247  // triangulate RZ countour
248  if (!G4GeomTools::TriangulatePolygon(contourRZ,triangles))
249  {
250  std::ostringstream message;
251  message << "Triangulation of RZ contour has failed for solid: "
252  << GetName() << " !"
253  << "\nExtent has been calculated using boundary box";
254  G4Exception("G4UGenericPolycone::CalculateExtent()",
255  "GeomMgt1002", JustWarning, message);
256  return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
257  }
258 
259  // set trigonometric values
260  const G4int NSTEPS = 24; // number of steps for whole circle
261  G4double astep = (360/NSTEPS)*deg; // max angle for one step
262 
263  G4double sphi = GetStartPhi();
264  G4double ephi = GetEndPhi();
265  G4double dphi = IsOpen() ? ephi-sphi : twopi;
266  G4int ksteps = (dphi <= astep) ? 1 : (G4int)((dphi-deg)/astep) + 1;
267  G4double ang = dphi/ksteps;
268 
269  G4double sinHalf = std::sin(0.5*ang);
270  G4double cosHalf = std::cos(0.5*ang);
271  G4double sinStep = 2.*sinHalf*cosHalf;
272  G4double cosStep = 1. - 2.*sinHalf*sinHalf;
273 
274  G4double sinStart = GetSinStartPhi();
275  G4double cosStart = GetCosStartPhi();
276  G4double sinEnd = GetSinEndPhi();
277  G4double cosEnd = GetCosEndPhi();
278 
279  // define vectors and arrays
280  std::vector<const G4ThreeVectorList *> polygons;
281  polygons.resize(ksteps+2);
282  G4ThreeVectorList pols[NSTEPS+2];
283  for (G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
284  for (G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
285  G4double r0[6],z0[6]; // contour with original edges of triangle
286  G4double r1[6]; // shifted radii of external edges of triangle
287 
288  // main loop along triangles
289  pMin = kInfinity;
290  pMax =-kInfinity;
291  G4int ntria = triangles.size()/3;
292  for (G4int i=0; i<ntria; ++i)
293  {
294  G4int i3 = i*3;
295  for (G4int k=0; k<3; ++k)
296  {
297  G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
298  G4int k2 = k*2;
299  // set contour with original edges of triangle
300  r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
301  r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
302  // set shifted radii
303  r1[k2+0] = r0[k2+0];
304  r1[k2+1] = r0[k2+1];
305  if (z0[k2+1] - z0[k2+0] <= 0) continue;
306  r1[k2+0] /= cosHalf;
307  r1[k2+1] /= cosHalf;
308  }
309 
310  // rotate countour, set sequence of 6-sided polygons
311  G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
312  G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
313  for (G4int j=0; j<6; ++j)
314  {
315  pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
316  }
317  for (G4int k=1; k<ksteps+1; ++k)
318  {
319  for (G4int j=0; j<6; ++j)
320  {
321  pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
322  }
323  G4double sinTmp = sinCur;
324  sinCur = sinCur*cosStep + cosCur*sinStep;
325  cosCur = cosCur*cosStep - sinTmp*sinStep;
326  }
327  for (G4int j=0; j<6; ++j)
328  {
329  pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
330  }
331 
332  // set sub-envelope and adjust extent
333  G4double emin,emax;
334  G4BoundingEnvelope benv(polygons);
335  if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
336  if (emin < pMin) pMin = emin;
337  if (emax > pMax) pMax = emax;
338  if (eminlim > pMin && emaxlim < pMax) return true; // max possible extent
339  }
340  return (pMin < pMax);
341 }
342 
344 //
345 // CreatePolyhedron
346 
347 G4Polyhedron* G4UGenericPolycone::CreatePolyhedron() const
348 {
349 
350 
351  // The following code prepares for:
352  // HepPolyhedron::createPolyhedron(int Nnodes, int Nfaces,
353  // const double xyz[][3],
354  // const int faces_vec[][4])
355  // Here is an extract from the header file HepPolyhedron.h:
373  const G4int numSide =
374  G4int(G4Polyhedron::GetNumberOfRotationSteps()
375  * (GetEndPhi() - GetStartPhi()) / twopi) + 1;
376  G4int nNodes;
377  G4int nFaces;
378  typedef G4double double3[3];
379  double3* xyz;
380  typedef G4int int4[4];
381  int4* faces_vec;
382  if (IsOpen())
383  {
384  // Triangulate open ends. Simple ear-chopping algorithm...
385  // I'm not sure how robust this algorithm is (J.Allison).
386  //
387  std::vector<G4bool> chopped(GetNumRZCorner(), false);
388  std::vector<G4int*> triQuads;
389  G4int remaining = GetNumRZCorner();
390  G4int iStarter = 0;
391  while (remaining >= 3) // Loop checking, 13.08.2015, G.Cosmo
392  {
393  // Find unchopped corners...
394  //
395  G4int A = -1, B = -1, C = -1;
396  G4int iStepper = iStarter;
397  do // Loop checking, 13.08.2015, G.Cosmo
398  {
399  if (A < 0) { A = iStepper; }
400  else if (B < 0) { B = iStepper; }
401  else if (C < 0) { C = iStepper; }
402  do // Loop checking, 13.08.2015, G.Cosmo
403  {
404  if (++iStepper >= GetNumRZCorner()) { iStepper = 0; }
405  }
406  while (chopped[iStepper]);
407  }
408  while (C < 0 && iStepper != iStarter);
409 
410  // Check triangle at B is pointing outward (an "ear").
411  // Sign of z cross product determines...
412  //
413  G4double BAr = GetCorner(A).r - GetCorner(B).r;
414  G4double BAz = GetCorner(A).z - GetCorner(B).z;
415  G4double BCr = GetCorner(C).r - GetCorner(B).r;
416  G4double BCz = GetCorner(C).z - GetCorner(B).z;
417  if (BAr * BCz - BAz * BCr < kCarTolerance)
418  {
419  G4int* tq = new G4int[3];
420  tq[0] = A + 1;
421  tq[1] = B + 1;
422  tq[2] = C + 1;
423  triQuads.push_back(tq);
424  chopped[B] = true;
425  --remaining;
426  }
427  else
428  {
429  do // Loop checking, 13.08.2015, G.Cosmo
430  {
431  if (++iStarter >= GetNumRZCorner()) { iStarter = 0; }
432  }
433  while (chopped[iStarter]);
434  }
435  }
436  // Transfer to faces...
437  //
438  nNodes = (numSide + 1) * GetNumRZCorner();
439  nFaces = numSide * GetNumRZCorner() + 2 * triQuads.size();
440  faces_vec = new int4[nFaces];
441  G4int iface = 0;
442  G4int addition = GetNumRZCorner() * numSide;
443  G4int d = GetNumRZCorner() - 1;
444  for (G4int iEnd = 0; iEnd < 2; ++iEnd)
445  {
446  for (size_t i = 0; i < triQuads.size(); ++i)
447  {
448  // Negative for soft/auxiliary/normally invisible edges...
449  //
450  G4int a, b, c;
451  if (iEnd == 0)
452  {
453  a = triQuads[i][0];
454  b = triQuads[i][1];
455  c = triQuads[i][2];
456  }
457  else
458  {
459  a = triQuads[i][0] + addition;
460  b = triQuads[i][2] + addition;
461  c = triQuads[i][1] + addition;
462  }
463  G4int ab = std::abs(b - a);
464  G4int bc = std::abs(c - b);
465  G4int ca = std::abs(a - c);
466  faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
467  faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
468  faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
469  faces_vec[iface][3] = 0;
470  ++iface;
471  }
472  }
473 
474  // Continue with sides...
475 
476  xyz = new double3[nNodes];
477  const G4double dPhi = (GetEndPhi() - GetStartPhi()) / numSide;
478  G4double phi = GetStartPhi();
479  G4int ixyz = 0;
480  for (G4int iSide = 0; iSide < numSide; ++iSide)
481  {
482  for (G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
483  {
484  xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
485  xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
486  xyz[ixyz][2] = GetCorner(iCorner).z;
487  if (iSide == 0) // startPhi
488  {
489  if (iCorner < GetNumRZCorner() - 1)
490  {
491  faces_vec[iface][0] = ixyz + 1;
492  faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
493  faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
494  faces_vec[iface][3] = ixyz + 2;
495  }
496  else
497  {
498  faces_vec[iface][0] = ixyz + 1;
499  faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
500  faces_vec[iface][2] = ixyz + 2;
501  faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
502  }
503  }
504  else if (iSide == numSide - 1) // endPhi
505  {
506  if (iCorner < GetNumRZCorner() - 1)
507  {
508  faces_vec[iface][0] = ixyz + 1;
509  faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
510  faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
511  faces_vec[iface][3] = -(ixyz + 2);
512  }
513  else
514  {
515  faces_vec[iface][0] = ixyz + 1;
516  faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
517  faces_vec[iface][2] = ixyz + 2;
518  faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
519  }
520  }
521  else
522  {
523  if (iCorner < GetNumRZCorner() - 1)
524  {
525  faces_vec[iface][0] = ixyz + 1;
526  faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
527  faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
528  faces_vec[iface][3] = -(ixyz + 2);
529  }
530  else
531  {
532  faces_vec[iface][0] = ixyz + 1;
533  faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
534  faces_vec[iface][2] = ixyz + 2;
535  faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
536  }
537  }
538  ++iface;
539  ++ixyz;
540  }
541  phi += dPhi;
542  }
543 
544  // Last corners...
545 
546  for (G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
547  {
548  xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
549  xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
550  xyz[ixyz][2] = GetCorner(iCorner).z;
551  ++ixyz;
552  }
553  }
554  else // !phiIsOpen - i.e., a complete 360 degrees.
555  {
556  nNodes = numSide * GetNumRZCorner();
557  nFaces = numSide * GetNumRZCorner();;
558  xyz = new double3[nNodes];
559  faces_vec = new int4[nFaces];
560  const G4double dPhi = (GetEndPhi() - GetStartPhi()) / numSide;
561  G4double phi = GetStartPhi();
562  G4int ixyz = 0, iface = 0;
563  for (G4int iSide = 0; iSide < numSide; ++iSide)
564  {
565  for (G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
566  {
567  xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
568  xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
569  xyz[ixyz][2] = GetCorner(iCorner).z;
570 
571  if (iSide < numSide - 1)
572  {
573  if (iCorner < GetNumRZCorner() - 1)
574  {
575  faces_vec[iface][0] = ixyz + 1;
576  faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
577  faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
578  faces_vec[iface][3] = -(ixyz + 2);
579  }
580  else
581  {
582  faces_vec[iface][0] = ixyz + 1;
583  faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
584  faces_vec[iface][2] = ixyz + 2;
585  faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
586  }
587  }
588  else // Last side joins ends...
589  {
590  if (iCorner < GetNumRZCorner() - 1)
591  {
592  faces_vec[iface][0] = ixyz + 1;
593  faces_vec[iface][1] = -(ixyz + GetNumRZCorner() - nFaces + 1);
594  faces_vec[iface][2] = ixyz + GetNumRZCorner() - nFaces + 2;
595  faces_vec[iface][3] = -(ixyz + 2);
596  }
597  else
598  {
599  faces_vec[iface][0] = ixyz + 1;
600  faces_vec[iface][1] = -(ixyz - nFaces + GetNumRZCorner() + 1);
601  faces_vec[iface][2] = ixyz - nFaces + 2;
602  faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
603  }
604  }
605  ++ixyz;
606  ++iface;
607  }
608  phi += dPhi;
609  }
610  }
611  G4Polyhedron* polyhedron = new G4Polyhedron;
612  G4int prob = polyhedron->createPolyhedron(nNodes, nFaces, xyz, faces_vec);
613  delete [] faces_vec;
614  delete [] xyz;
615  if (prob)
616  {
617  std::ostringstream message;
618  message << "Problem creating G4Polyhedron for: " << GetName();
619  G4Exception("G4GenericPolycone::CreatePolyhedron()", "GeomSolids1002",
620  JustWarning, message);
621  delete polyhedron;
622  return 0;
623  }
624  else
625  {
626  return polyhedron;
627  }
628 }
629 
630 #endif // G4GEOM_USE_USOLIDS
static const G4double kInfinity
Definition: geomdefs.hh:42
CLHEP::Hep3Vector G4ThreeVector
std::vector< ExP01TrackerHit * > a
Definition: ExP01Classes.hh:33
std::vector< G4TwoVector > G4TwoVectorList
Definition: G4GeomTools.hh:50
static G4double PolygonArea(const G4TwoVectorList &polygon)
Definition: G4GeomTools.cc:82
double C(double temp)
const char * name(G4int ptype)
double B(double temperature)
int G4int
Definition: G4Types.hh:78
static constexpr double twopi
Definition: G4SIunits.hh:76
G4GLOB_DLL std::ostream G4cout
double A(double temperature)
bool G4bool
Definition: G4Types.hh:79
const G4double kCarTolerance
static G4bool TriangulatePolygon(const G4TwoVectorList &polygon, G4TwoVectorList &result)
Definition: G4GeomTools.cc:178
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
static const G4double emax
static const G4double ab
EAxis
Definition: geomdefs.hh:54
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:42
double G4double
Definition: G4Types.hh:76
static constexpr double deg
Definition: G4SIunits.hh:152
G4double GetMaxExtent(const EAxis pAxis) const
G4double GetMinExtent(const EAxis pAxis) const
static G4bool DiskExtent(G4double rmin, G4double rmax, G4double startPhi, G4double delPhi, G4TwoVector &pmin, G4TwoVector &pmax)
Definition: G4GeomTools.cc:378