Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/specific/src/G4UPolyhedra.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 G4UPolyhedra wrapper class
 27 //
 28 // 31.10.13 G.Cosmo, CERN
 29 // --------------------------------------------------------------------
 30 
 31 #include "G4Polyhedra.hh"
 32 #include "G4UPolyhedra.hh"
 33 
 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
 35 
 36 #include "G4GeomTools.hh"
 37 #include "G4GeometryTolerance.hh"
 38 #include "G4AffineTransform.hh"
 39 #include "G4VPVParameterisation.hh"
 40 #include "G4BoundingEnvelope.hh"
 41 
 42 using namespace CLHEP;
 43 
 44 ////////////////////////////////////////////////////////////////////////
 45 //
 46 // Constructor (GEANT3 style parameters)
 47 //
 48 // GEANT3 PGON radii are specified in the distance to the norm of each face.
 49 //
 50 G4UPolyhedra::G4UPolyhedra(const G4String& name,
 51                                  G4double phiStart,
 52                                  G4double phiTotal,
 53                                  G4int numSide,
 54                                  G4int numZPlanes,
 55                            const G4double zPlane[],
 56                            const G4double rInner[],
 57                            const G4double rOuter[]  )
 58   : Base_t(name, phiStart, phiTotal, numSide,
 59            numZPlanes, zPlane, rInner, rOuter)
 60 {
 61   fGenericPgon = false;
 62   SetOriginalParameters();
 63   wrStart = phiStart;
 64   while (wrStart < 0)
 65   {
 66     wrStart += twopi;
 67   }
 68   wrDelta = phiTotal;
 69   if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL_EPSILON))
 70   {
 71     wrDelta = twopi;
 72   }
 73   wrNumSide = numSide;
 74   G4double convertRad = 1./std::cos(0.5*wrDelta/wrNumSide);
 75   rzcorners.resize(0);
 76   for (G4int i=0; i<numZPlanes; ++i)
 77   {
 78     G4double z = zPlane[i];
 79     G4double r = rOuter[i]*convertRad;
 80     rzcorners.emplace_back(r,z);
 81   }
 82   for (G4int i=numZPlanes-1; i>=0; --i)
 83   {
 84     G4double z = zPlane[i];
 85     G4double r = rInner[i]*convertRad;
 86     rzcorners.emplace_back(r,z);
 87   }
 88   std::vector<G4int> iout;
 89   G4GeomTools::RemoveRedundantVertices(rzcorners,iout,2*kCarTolerance);
 90 }
 91 
 92 
 93 ////////////////////////////////////////////////////////////////////////
 94 //
 95 // Constructor (generic parameters)
 96 //
 97 G4UPolyhedra::G4UPolyhedra(const G4String& name,
 98                                  G4double phiStart,
 99                                  G4double phiTotal,
100                                  G4int    numSide,
101                                  G4int    numRZ,
102                            const G4double r[],
103                            const G4double z[]   )
104   : Base_t(name, phiStart, phiTotal, numSide, numRZ, r, z)
105 {
106   fGenericPgon = true;
107   SetOriginalParameters();
108   wrStart = phiStart;
109   while (wrStart < 0.)
110   {
111     wrStart += twopi;
112   }
113   wrDelta = phiTotal;
114   if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL_EPSILON))
115   {
116     wrDelta = twopi;
117   }
118   wrNumSide = numSide;
119   rzcorners.resize(0);
120   for (G4int i=0; i<numRZ; ++i)
121   {
122     rzcorners.emplace_back(r[i],z[i]);
123   }
124   std::vector<G4int> iout;
125   G4GeomTools::RemoveRedundantVertices(rzcorners,iout,2*kCarTolerance);
126 }
127 
128 
129 ////////////////////////////////////////////////////////////////////////
130 //
131 // Fake default constructor - sets only member data and allocates memory
132 //                            for usage restricted to object persistency.
133 //
134 G4UPolyhedra::G4UPolyhedra( __void__& a )
135   : Base_t(a)
136 {
137 }
138 
139 
140 ////////////////////////////////////////////////////////////////////////
141 //
142 // Destructor
143 //
144 G4UPolyhedra::~G4UPolyhedra() = default;
145 
146 
147 ////////////////////////////////////////////////////////////////////////
148 //
149 // Copy constructor
150 //
151 G4UPolyhedra::G4UPolyhedra( const G4UPolyhedra& source )
152   : Base_t( source )
153 {
154   fGenericPgon = source.fGenericPgon;
155   fOriginalParameters = source.fOriginalParameters;
156   wrStart   = source.wrStart;
157   wrDelta   = source.wrDelta;
158   wrNumSide = source.wrNumSide;
159   rzcorners = source.rzcorners;
160 }
161 
162 
163 ////////////////////////////////////////////////////////////////////////
164 //
165 // Assignment operator
166 //
167 G4UPolyhedra& G4UPolyhedra::operator=( const G4UPolyhedra& source )
168 {
169   if (this == &source) return *this;
170 
171   Base_t::operator=( source );
172   fGenericPgon = source.fGenericPgon;
173   fOriginalParameters = source.fOriginalParameters;
174   wrStart   = source.wrStart;
175   wrDelta   = source.wrDelta;
176   wrNumSide = source.wrNumSide;
177   rzcorners = source.rzcorners;
178 
179   return *this;
180 }
181 
182 
183 ////////////////////////////////////////////////////////////////////////
184 //
185 // Accessors & modifiers
186 //
187 G4int G4UPolyhedra::GetNumSide() const
188 {
189   return wrNumSide;
190 }
191 G4double G4UPolyhedra::GetStartPhi() const
192 {
193   return wrStart;
194 }
195 G4double G4UPolyhedra::GetEndPhi() const
196 {
197   return (wrStart + wrDelta);
198 }
199 G4double G4UPolyhedra::GetSinStartPhi() const
200 {
201   G4double phi = GetStartPhi();
202   return std::sin(phi);
203 }
204 G4double G4UPolyhedra::GetCosStartPhi() const
205 {
206   G4double phi = GetStartPhi();
207   return std::cos(phi);
208 }
209 G4double G4UPolyhedra::GetSinEndPhi() const
210 {
211   G4double phi = GetEndPhi();
212   return std::sin(phi);
213 }
214 G4double G4UPolyhedra::GetCosEndPhi() const
215 {
216   G4double phi = GetEndPhi();
217   return std::cos(phi);
218 }
219 G4bool G4UPolyhedra::IsOpen() const
220 {
221   return (wrDelta < twopi);
222 }
223 G4bool G4UPolyhedra::IsGeneric() const
224 {
225   return fGenericPgon;
226 }
227 G4int G4UPolyhedra::GetNumRZCorner() const
228 {
229   return rzcorners.size();
230 }
231 G4PolyhedraSideRZ G4UPolyhedra::GetCorner(G4int index) const
232 {
233   G4TwoVector rz = rzcorners.at(index);
234   G4PolyhedraSideRZ psiderz = { rz.x(), rz.y() };
235 
236   return psiderz;
237 }
238 G4PolyhedraHistorical* G4UPolyhedra::GetOriginalParameters() const
239 {
240   return new G4PolyhedraHistorical(fOriginalParameters);
241 }
242 void G4UPolyhedra::SetOriginalParameters()
243 {
244   G4double startPhi = GetPhiStart();
245   G4double deltaPhi = GetPhiDelta();
246   G4int numPlanes   = GetZSegmentCount() + 1;
247   G4int numSides    = GetSideCount();
248 
249   fOriginalParameters.Start_angle   = startPhi;
250   fOriginalParameters.Opening_angle = deltaPhi;
251   fOriginalParameters.Num_z_planes  = numPlanes;
252   fOriginalParameters.numSide       = numSides;
253 
254   delete [] fOriginalParameters.Z_values;
255   delete [] fOriginalParameters.Rmin;
256   delete [] fOriginalParameters.Rmax;
257   fOriginalParameters.Z_values = new G4double[numPlanes];
258   fOriginalParameters.Rmin = new G4double[numPlanes];
259   fOriginalParameters.Rmax = new G4double[numPlanes];
260 
261   G4double convertRad = fGenericPgon
262                       ? 1.0 : std::cos(0.5*deltaPhi/numSides);
263   for (G4int i=0; i<numPlanes; ++i)
264   {
265     fOriginalParameters.Z_values[i] = GetZPlanes()[i];
266     fOriginalParameters.Rmax[i]     = GetRMax()[i]/convertRad;
267     fOriginalParameters.Rmin[i]     = GetRMin()[i]/convertRad;
268   }
269 }
270 void G4UPolyhedra::SetOriginalParameters(G4PolyhedraHistorical* pars)
271 {
272   fOriginalParameters = *pars;
273   fRebuildPolyhedron = true;
274   Reset();
275 }
276 
277 G4bool G4UPolyhedra::Reset()
278 {
279   if (fGenericPgon)
280   {
281     std::ostringstream message;
282     message << "Solid " << GetName() << " built using generic construct."
283             << G4endl << "Not applicable to the generic construct !";
284     G4Exception("G4UPolyhedra::Reset()", "GeomSolids1001",
285                 JustWarning, message, "Parameters NOT reset.");
286     return true;  // error code set
287   }
288 
289   //
290   // Rebuild polyhedra based on original parameters
291   //
292   wrStart = fOriginalParameters.Start_angle;
293   while (wrStart < 0.)
294   {
295     wrStart += twopi;
296   }
297   wrDelta = fOriginalParameters.Opening_angle;
298   if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL_EPSILON))
299   {
300     wrDelta = twopi;
301   }
302   wrNumSide = fOriginalParameters.numSide;
303   rzcorners.resize(0);
304   for (G4int i=0; i<fOriginalParameters.Num_z_planes; ++i)
305   {
306     G4double z = fOriginalParameters.Z_values[i];
307     G4double r = fOriginalParameters.Rmax[i];
308     rzcorners.emplace_back(r,z);
309   }
310   for (G4int i=fOriginalParameters.Num_z_planes-1; i>=0; --i)
311   {
312     G4double z = fOriginalParameters.Z_values[i];
313     G4double r = fOriginalParameters.Rmin[i];
314     rzcorners.emplace_back(r,z);
315   }
316   std::vector<G4int> iout;
317   G4GeomTools::RemoveRedundantVertices(rzcorners,iout,2*kCarTolerance);
318 
319   return false;  // error code unset
320 }
321 
322 
323 ////////////////////////////////////////////////////////////////////////
324 //
325 // Dispatch to parameterisation for replication mechanism dimension
326 // computation & modification.
327 //
328 void G4UPolyhedra::ComputeDimensions(G4VPVParameterisation* p,
329                                      const G4int n,
330                                      const G4VPhysicalVolume* pRep)
331 {
332   p->ComputeDimensions(*(G4Polyhedra*)this,n,pRep);
333 }
334 
335 
336 //////////////////////////////////////////////////////////////////////////
337 //
338 // Make a clone of the object
339 
340 G4VSolid* G4UPolyhedra::Clone() const
341 {
342   return new G4UPolyhedra(*this);
343 }
344 
345 
346 //////////////////////////////////////////////////////////////////////////
347 //
348 // Get bounding box
349 
350 void G4UPolyhedra::BoundingLimits(G4ThreeVector& pMin,
351                                   G4ThreeVector& pMax) const
352 {
353   static G4bool checkBBox = true;
354   static G4bool checkPhi  = true;
355 
356   G4double rmin = kInfinity, rmax = -kInfinity;
357   G4double zmin = kInfinity, zmax = -kInfinity;
358   for (G4int i=0; i<GetNumRZCorner(); ++i)
359   {
360     G4PolyhedraSideRZ corner = GetCorner(i);
361     if (corner.r < rmin) rmin = corner.r;
362     if (corner.r > rmax) rmax = corner.r;
363     if (corner.z < zmin) zmin = corner.z;
364     if (corner.z > zmax) zmax = corner.z;
365   }
366 
367   G4double sphi    = GetStartPhi();
368   G4double ephi    = GetEndPhi();
369   G4double dphi    = IsOpen() ? ephi-sphi : twopi;
370   G4int    ksteps  = GetNumSide();
371   G4double astep   = dphi/ksteps;
372   G4double sinStep = std::sin(astep);
373   G4double cosStep = std::cos(astep);
374 
375   G4double sinCur = GetSinStartPhi();
376   G4double cosCur = GetCosStartPhi();
377   if (!IsOpen()) rmin = 0.;
378   G4double xmin = rmin*cosCur, xmax = xmin;
379   G4double ymin = rmin*sinCur, ymax = ymin;
380   for (G4int k=0; k<ksteps+1; ++k)
381   {
382     G4double x = rmax*cosCur;
383     if (x < xmin) xmin = x;
384     if (x > xmax) xmax = x;
385     G4double y = rmax*sinCur;
386     if (y < ymin) ymin = y;
387     if (y > ymax) ymax = y;
388     if (rmin > 0.)
389     {
390       G4double xx = rmin*cosCur;
391       if (xx < xmin) xmin = xx;
392       if (xx > xmax) xmax = xx;
393       G4double yy = rmin*sinCur;
394       if (yy < ymin) ymin = yy;
395       if (yy > ymax) ymax = yy;
396     }
397     G4double sinTmp = sinCur;
398     sinCur = sinCur*cosStep + cosCur*sinStep;
399     cosCur = cosCur*cosStep - sinTmp*sinStep;
400   }
401   pMin.set(xmin,ymin,zmin);
402   pMax.set(xmax,ymax,zmax);
403 
404   // Check correctness of the bounding box
405   //
406   if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
407   {
408     std::ostringstream message;
409     message << "Bad bounding box (min >= max) for solid: "
410             << GetName() << " !"
411             << "\npMin = " << pMin
412             << "\npMax = " << pMax;
413     G4Exception("G4UPolyhedra::BoundingLimits()", "GeomMgt0001",
414                 JustWarning, message);
415     StreamInfo(G4cout);
416   }
417 
418   // Check consistency of bounding boxes
419   //
420   if (checkBBox)
421   {
422     U3Vector vmin, vmax;
423     Extent(vmin,vmax);
424     if (std::abs(pMin.x()-vmin.x()) > kCarTolerance ||
425         std::abs(pMin.y()-vmin.y()) > kCarTolerance ||
426         std::abs(pMin.z()-vmin.z()) > kCarTolerance ||
427         std::abs(pMax.x()-vmax.x()) > kCarTolerance ||
428         std::abs(pMax.y()-vmax.y()) > kCarTolerance ||
429         std::abs(pMax.z()-vmax.z()) > kCarTolerance)
430     {
431       std::ostringstream message;
432       message << "Inconsistency in bounding boxes for solid: "
433               << GetName() << " !"
434               << "\nBBox min: wrapper = " << pMin << " solid = " << vmin
435               << "\nBBox max: wrapper = " << pMax << " solid = " << vmax;
436       G4Exception("G4UPolyhedra::BoundingLimits()", "GeomMgt0001",
437                   JustWarning, message);
438       checkBBox = false;
439     }
440   }
441 
442   // Check consistency of angles
443   //
444   if (checkPhi)
445   {
446     if (GetStartPhi() != GetPhiStart()  ||
447         GetEndPhi()   != GetPhiEnd()    ||
448         GetNumSide()  != GetSideCount() ||
449         IsOpen()      != (Base_t::GetPhiDelta() < twopi))
450     {
451       std::ostringstream message;
452       message << "Inconsistency in Phi angles or # of sides for solid: "
453               << GetName() << " !"
454               << "\nPhi start  : wrapper = " << GetStartPhi()
455               << " solid = " <<     GetPhiStart()
456               << "\nPhi end    : wrapper = " << GetEndPhi()
457               << " solid = " <<     GetPhiEnd()
458               << "\nPhi # sides: wrapper = " << GetNumSide()
459               << " solid = " <<     GetSideCount()
460               << "\nPhi is open: wrapper = " << (IsOpen() ? "true" : "false")
461               << " solid = "
462               << ((Base_t::GetPhiDelta() < twopi) ? "true" : "false");
463       G4Exception("G4UPolyhedra::BoundingLimits()", "GeomMgt0001",
464                   JustWarning, message);
465       checkPhi = false;
466     }
467   }
468 }
469 
470 //////////////////////////////////////////////////////////////////////////
471 //
472 // Calculate extent under transform and specified limit
473 
474 G4bool
475 G4UPolyhedra::CalculateExtent(const EAxis pAxis,
476                               const G4VoxelLimits& pVoxelLimit,
477                               const G4AffineTransform& pTransform,
478                                     G4double& pMin, G4double& pMax) const
479 {
480   G4ThreeVector bmin, bmax;
481   G4bool exist;
482 
483   // Check bounding box (bbox)
484   //
485   BoundingLimits(bmin,bmax);
486   G4BoundingEnvelope bbox(bmin,bmax);
487 #ifdef G4BBOX_EXTENT
488   if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
489 #endif
490   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
491   {
492     return exist = pMin < pMax;
493   }
494 
495   // To find the extent, RZ contour of the polycone is subdivided
496   // in triangles. The extent is calculated as cumulative extent of
497   // all sub-polycones formed by rotation of triangles around Z
498   //
499   G4TwoVectorList contourRZ;
500   G4TwoVectorList triangles;
501   std::vector<G4int> iout;
502   G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
503   G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
504 
505   // get RZ contour, ensure anticlockwise order of corners
506   for (G4int i=0; i<GetNumRZCorner(); ++i)
507   {
508     G4PolyhedraSideRZ corner = GetCorner(i);
509     contourRZ.emplace_back(corner.r,corner.z);
510   }
511   G4GeomTools::RemoveRedundantVertices(contourRZ,iout,2*kCarTolerance);
512   G4double area = G4GeomTools::PolygonArea(contourRZ);
513   if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
514 
515   // triangulate RZ countour
516   if (!G4GeomTools::TriangulatePolygon(contourRZ,triangles))
517   {
518     std::ostringstream message;
519     message << "Triangulation of RZ contour has failed for solid: "
520             << GetName() << " !"
521             << "\nExtent has been calculated using boundary box";
522     G4Exception("G4UPolyhedra::CalculateExtent()",
523                 "GeomMgt1002",JustWarning,message);
524     return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
525   }
526 
527   // set trigonometric values
528   G4double sphi     = GetStartPhi();
529   G4double ephi     = GetEndPhi();
530   G4double dphi     = IsOpen() ? ephi-sphi : twopi;
531   G4int    ksteps   = GetNumSide();
532   G4double astep    = dphi/ksteps;
533   G4double sinStep  = std::sin(astep);
534   G4double cosStep  = std::cos(astep);
535   G4double sinStart = GetSinStartPhi();
536   G4double cosStart = GetCosStartPhi();
537 
538   // allocate vector lists
539   std::vector<const G4ThreeVectorList *> polygons;
540   polygons.resize(ksteps+1);
541   for (G4int k=0; k<ksteps+1; ++k)
542   {
543     polygons[k] = new G4ThreeVectorList(3);
544   }
545 
546   // main loop along triangles
547   pMin =  kInfinity;
548   pMax = -kInfinity;
549   G4int ntria = triangles.size()/3;
550   for (G4int i=0; i<ntria; ++i)
551   {
552     G4double sinCur = sinStart;
553     G4double cosCur = cosStart;
554     G4int i3 = i*3;
555     for (G4int k=0; k<ksteps+1; ++k) // rotate triangle
556     {
557       auto ptr = const_cast<G4ThreeVectorList*>(polygons[k]);
558       auto iter = ptr->begin();
559       iter->set(triangles[i3+0].x()*cosCur,
560                 triangles[i3+0].x()*sinCur,
561                 triangles[i3+0].y());
562       iter++;
563       iter->set(triangles[i3+1].x()*cosCur,
564                 triangles[i3+1].x()*sinCur,
565                 triangles[i3+1].y());
566       iter++;
567       iter->set(triangles[i3+2].x()*cosCur,
568                 triangles[i3+2].x()*sinCur,
569                 triangles[i3+2].y());
570 
571       G4double sinTmp = sinCur;
572       sinCur = sinCur*cosStep + cosCur*sinStep;
573       cosCur = cosCur*cosStep - sinTmp*sinStep;
574     }
575 
576     // set sub-envelope and adjust extent
577     G4double emin,emax;
578     G4BoundingEnvelope benv(polygons);
579     if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
580     if (emin < pMin) pMin = emin;
581     if (emax > pMax) pMax = emax;
582     if (eminlim > pMin && emaxlim < pMax) break; // max possible extent
583   }
584   // free memory
585   for (G4int k=0; k<ksteps+1; ++k) { delete polygons[k]; polygons[k]=nullptr;}
586   return (pMin < pMax);
587 }
588 
589 
590 ////////////////////////////////////////////////////////////////////////
591 //
592 // CreatePolyhedron
593 //
594 G4Polyhedron* G4UPolyhedra::CreatePolyhedron() const
595 {
596   return new G4PolyhedronPgon(wrStart, wrDelta, wrNumSide, rzcorners);
597 }
598 
599 #endif  // G4GEOM_USE_USOLIDS
600