34#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
47G4UPolycone::G4UPolycone(
const G4String& name,
54 : Base_t(
name, phiStart, phiTotal, numZPlanes, zPlane, rInner, rOuter)
57 SetOriginalParameters();
64 if (wrDelta <= 0 || wrDelta >= twopi*(1-
DBL_EPSILON))
70 for (
G4int i=0; i<numZPlanes; ++i)
74 rzcorners.emplace_back(r,z);
76 for (
G4int i=numZPlanes-1; i>=0; --i)
80 rzcorners.emplace_back(r,z);
82 std::vector<G4int> iout;
91G4UPolycone::G4UPolycone(
const G4String& name,
97 : Base_t(
name, phiStart, phiTotal, numRZ, r, z)
100 SetOriginalParameters();
101 wrStart = phiStart;
while (wrStart < 0) wrStart += twopi;
103 if (wrDelta <= 0 || wrDelta >= twopi*(1-
DBL_EPSILON))
109 for (
G4int i=0; i<numRZ; ++i)
111 rzcorners.emplace_back(r[i],z[i]);
113 std::vector<G4int> iout;
122G4UPolycone::G4UPolycone(
const G4UPolycone& source )
125 fGenericPcon = source.fGenericPcon;
126 fOriginalParameters = source.fOriginalParameters;
127 wrStart = source.wrStart;
128 wrDelta = source.wrDelta;
129 rzcorners = source.rzcorners;
137G4UPolycone& G4UPolycone::operator=(
const G4UPolycone& source )
139 if (
this == &source)
return *
this;
141 Base_t::operator=( source );
142 fGenericPcon = source.fGenericPcon;
143 fOriginalParameters = source.fOriginalParameters;
144 wrStart = source.wrStart;
145 wrDelta = source.wrDelta;
146 rzcorners = source.rzcorners;
156G4double G4UPolycone::GetStartPhi()
const
160G4double G4UPolycone::GetDeltaPhi()
const
164G4double G4UPolycone::GetEndPhi()
const
166 return (wrStart + wrDelta);
168G4double G4UPolycone::GetSinStartPhi()
const
170 if (!IsOpen())
return 0.;
172 return std::sin(phi);
174G4double G4UPolycone::GetCosStartPhi()
const
176 if (!IsOpen())
return 1.;
178 return std::cos(phi);
180G4double G4UPolycone::GetSinEndPhi()
const
182 if (!IsOpen())
return 0.;
184 return std::sin(phi);
186G4double G4UPolycone::GetCosEndPhi()
const
188 if (!IsOpen())
return 1.;
190 return std::cos(phi);
192G4bool G4UPolycone::IsOpen()
const
194 return (wrDelta < twopi);
196G4int G4UPolycone::GetNumRZCorner()
const
198 return rzcorners.size();
211void G4UPolycone::SetOriginalParameters()
213 vecgeom::PolyconeHistorical* original_parameters = Base_t::GetOriginalParameters();
215 fOriginalParameters.Start_angle = original_parameters->fHStart_angle;
216 fOriginalParameters.Opening_angle = original_parameters->fHOpening_angle;
217 fOriginalParameters.Num_z_planes = original_parameters->fHNum_z_planes;
219 delete [] fOriginalParameters.Z_values;
220 delete [] fOriginalParameters.Rmin;
221 delete [] fOriginalParameters.Rmax;
223 G4int numPlanes = fOriginalParameters.Num_z_planes;
224 fOriginalParameters.Z_values =
new G4double[numPlanes];
225 fOriginalParameters.Rmin =
new G4double[numPlanes];
226 fOriginalParameters.Rmax =
new G4double[numPlanes];
227 for (
G4int i=0; i<numPlanes; ++i)
229 fOriginalParameters.Z_values[i] = original_parameters->fHZ_values[i];
230 fOriginalParameters.Rmin[i] = original_parameters->fHRmin[i];
231 fOriginalParameters.Rmax[i] = original_parameters->fHRmax[i];
236 fOriginalParameters = *pars;
237 fRebuildPolyhedron =
true;
241G4bool G4UPolycone::Reset()
245 std::ostringstream message;
246 message <<
"Solid " << GetName() <<
" built using generic construct."
247 <<
G4endl <<
"Not applicable to the generic construct !";
248 G4Exception(
"G4UPolycone::Reset()",
"GeomSolids1001",
256 wrStart = fOriginalParameters.Start_angle;
261 wrDelta = fOriginalParameters.Opening_angle;
262 if (wrDelta <= 0. || wrDelta >= twopi*(1-
DBL_EPSILON))
268 for (
G4int i=0; i<fOriginalParameters.Num_z_planes; ++i)
270 G4double z = fOriginalParameters.Z_values[i];
271 G4double r = fOriginalParameters.Rmax[i];
272 rzcorners.emplace_back(r,z);
274 for (
G4int i=fOriginalParameters.Num_z_planes-1; i>=0; --i)
276 G4double z = fOriginalParameters.Z_values[i];
277 G4double r = fOriginalParameters.Rmin[i];
278 rzcorners.emplace_back(r,z);
280 std::vector<G4int> iout;
305 return new G4UPolycone(*
this);
315 static G4bool checkBBox =
true;
316 static G4bool checkPhi =
true;
318 G4double rmin = kInfinity, rmax = -kInfinity;
319 G4double zmin = kInfinity, zmax = -kInfinity;
321 for (
G4int i=0; i<GetNumRZCorner(); ++i)
324 if (corner.
r < rmin) rmin = corner.
r;
325 if (corner.
r > rmax) rmax = corner.
r;
326 if (corner.
z < zmin) zmin = corner.
z;
327 if (corner.
z > zmax) zmax = corner.
z;
334 GetSinStartPhi(),GetCosStartPhi(),
335 GetSinEndPhi(),GetCosEndPhi(),
337 pMin.
set(vmin.
x(),vmin.
y(),zmin);
338 pMax.
set(vmax.
x(),vmax.
y(),zmax);
342 pMin.
set(-rmax,-rmax, zmin);
343 pMax.
set( rmax, rmax, zmax);
348 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
350 std::ostringstream message;
351 message <<
"Bad bounding box (min >= max) for solid: "
353 <<
"\npMin = " << pMin
354 <<
"\npMax = " << pMax;
355 G4Exception(
"G4UPolycone::BoundingLimits()",
"GeomMgt0001",
373 std::ostringstream message;
374 message <<
"Inconsistency in bounding boxes for solid: "
376 <<
"\nBBox min: wrapper = " << pMin <<
" solid = " << vmin
377 <<
"\nBBox max: wrapper = " << pMax <<
" solid = " << vmax;
378 G4Exception(
"G4UPolycone::BoundingLimits()",
"GeomMgt0001",
388 if (GetStartPhi() != Base_t::GetStartPhi() ||
389 GetEndPhi() != Base_t::GetEndPhi() ||
390 IsOpen() != (Base_t::GetDeltaPhi() < twopi))
392 std::ostringstream message;
393 message <<
"Inconsistency in Phi angles or # of sides for solid: "
395 <<
"\nPhi start : wrapper = " << GetStartPhi()
396 <<
" solid = " << Base_t::GetStartPhi()
397 <<
"\nPhi end : wrapper = " << GetEndPhi()
398 <<
" solid = " << Base_t::GetEndPhi()
399 <<
"\nPhi is open: wrapper = " << (IsOpen() ?
"true" :
"false")
401 << ((Base_t::GetDeltaPhi() < twopi) ?
"true" :
"false");
402 G4Exception(
"G4UPolycone::BoundingLimits()",
"GeomMgt0001",
413G4bool G4UPolycone::CalculateExtent(
const EAxis pAxis,
423 BoundingLimits(bmin,bmax);
426 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
428 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
430 return exist = pMin < pMax;
439 std::vector<G4int> iout;
444 for (
G4int i=0; i<GetNumRZCorner(); ++i)
447 contourRZ.emplace_back(corner.
r,corner.
z);
451 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
456 std::ostringstream message;
457 message <<
"Triangulation of RZ contour has failed for solid: "
459 <<
"\nExtent has been calculated using boundary box";
462 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
466 const G4int NSTEPS = 24;
471 G4double dphi = IsOpen() ? ephi-sphi : twopi;
472 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-deg)/astep) + 1;
475 G4double sinHalf = std::sin(0.5*ang);
476 G4double cosHalf = std::cos(0.5*ang);
477 G4double sinStep = 2.*sinHalf*cosHalf;
478 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
480 G4double sinStart = GetSinStartPhi();
481 G4double cosStart = GetCosStartPhi();
486 std::vector<const G4ThreeVectorList *> polygons;
487 polygons.resize(ksteps+2);
489 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
490 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
497 G4int ntria = triangles.size()/3;
498 for (
G4int i=0; i<ntria; ++i)
501 for (
G4int k=0; k<3; ++k)
503 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
506 r0[k2+0] = triangles[e0].x();
z0[k2+0] = triangles[e0].y();
507 r0[k2+1] = triangles[e1].x();
z0[k2+1] = triangles[e1].y();
511 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
517 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
518 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
519 for (
G4int j=0; j<6; ++j) pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
520 for (
G4int k=1; k<ksteps+1; ++k)
522 for (
G4int j=0; j<6; ++j) pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
524 sinCur = sinCur*cosStep + cosCur*sinStep;
525 cosCur = cosCur*cosStep - sinTmp*sinStep;
527 for (
G4int j=0; j<6; ++j) pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
532 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
533 if (emin < pMin) pMin = emin;
534 if (emax > pMax) pMax = emax;
535 if (eminlim > pMin && emaxlim < pMax)
return true;
537 return (pMin < pMax);
const G4double kCarTolerance
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
CLHEP::Hep2Vector G4TwoVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
G4BoundingEnvelope is a helper class to facilitate calculation of the extent of a solid within the li...
G4PolyconeHistorical is a data structure for use in G4Polycone.
G4Polycone represents a composed closed shape (PCON) made of cones and cylinders, along the Z axis wi...
G4VPVParameterisation ia an abstract base class for Parameterisation, able to compute the transformat...
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
G4VSolid is an abstract base class for solids, physical shapes that can be tracked through....
G4VoxelLimits represents limitation/restrictions of space, where restrictions are only made perpendic...
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const
const char * name(G4int ptype)