34#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
49G4UGenericPolycone::G4UGenericPolycone(
const G4String& name,
55 : Base_t(
name, phiStart, phiTotal, numRZ, r, z)
57 wrStart = phiStart;
while (wrStart < 0) wrStart += twopi;
59 if (wrDelta <= 0 || wrDelta >= twopi*(1-
DBL_EPSILON))
65 for (
G4int i=0; i<numRZ; ++i)
67 rzcorners.emplace_back(r[i],z[i]);
69 std::vector<G4int> iout;
78G4UGenericPolycone::G4UGenericPolycone(
const G4UGenericPolycone& source)
81 wrStart = source.wrStart;
82 wrDelta = source.wrDelta;
83 rzcorners = source.rzcorners;
92G4UGenericPolycone::operator=(
const G4UGenericPolycone& source)
94 if (
this == &source)
return *
this;
96 Base_t::operator=( source );
97 wrStart = source.wrStart;
98 wrDelta = source.wrDelta;
99 rzcorners = source.rzcorners;
104G4double G4UGenericPolycone::GetStartPhi()
const
108G4double G4UGenericPolycone::GetEndPhi()
const
110 return (wrStart + wrDelta);
112G4double G4UGenericPolycone::GetSinStartPhi()
const
114 if (IsOpen())
return 0.;
116 return std::sin(phi);
118G4double G4UGenericPolycone::GetCosStartPhi()
const
120 if (IsOpen())
return 1.;
122 return std::cos(phi);
124G4double G4UGenericPolycone::GetSinEndPhi()
const
126 if (IsOpen())
return 0.;
128 return std::sin(phi);
130G4double G4UGenericPolycone::GetCosEndPhi()
const
132 if (IsOpen())
return 1.;
134 return std::cos(phi);
136G4bool G4UGenericPolycone::IsOpen()
const
138 return (wrDelta < twopi);
140G4int G4UGenericPolycone::GetNumRZCorner()
const
142 return rzcorners.size();
156G4VSolid* G4UGenericPolycone::Clone()
const
158 return new G4UGenericPolycone(*
this);
169 G4double rmin = kInfinity, rmax = -kInfinity;
170 G4double zmin = kInfinity, zmax = -kInfinity;
172 for (
G4int i=0; i<GetNumRZCorner(); ++i)
175 if (corner.
r < rmin) rmin = corner.
r;
176 if (corner.
r > rmax) rmax = corner.
r;
177 if (corner.
z < zmin) zmin = corner.
z;
178 if (corner.
z > zmax) zmax = corner.
z;
185 GetSinStartPhi(),GetCosStartPhi(),
186 GetSinEndPhi(),GetCosEndPhi(),
188 pMin.
set(vmin.
x(),vmin.
y(),zmin);
189 pMax.
set(vmax.
x(),vmax.
y(),zmax);
193 pMin.
set(-rmax,-rmax, zmin);
194 pMax.
set( rmax, rmax, zmax);
199 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
201 std::ostringstream message;
202 message <<
"Bad bounding box (min >= max) for solid: "
204 <<
"\npMin = " << pMin
205 <<
"\npMax = " << pMax;
206 G4Exception(
"G4UGenericPolycone::BoundingLimits()",
"GeomMgt0001",
217G4UGenericPolycone::CalculateExtent(
const EAxis pAxis,
227 BoundingLimits(bmin,bmax);
230 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
232 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
234 return exist = pMin < pMax;
247 for (
G4int i=0; i<GetNumRZCorner(); ++i)
250 contourRZ.emplace_back(corner.
r,corner.
z);
253 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
258 std::ostringstream message;
259 message <<
"Triangulation of RZ contour has failed for solid: "
261 <<
"\nExtent has been calculated using boundary box";
262 G4Exception(
"G4UGenericPolycone::CalculateExtent()",
264 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
268 const G4int NSTEPS = 24;
273 G4double dphi = IsOpen() ? ephi-sphi : twopi;
274 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-deg)/astep) + 1;
277 G4double sinHalf = std::sin(0.5*ang);
278 G4double cosHalf = std::cos(0.5*ang);
279 G4double sinStep = 2.*sinHalf*cosHalf;
280 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
282 G4double sinStart = GetSinStartPhi();
283 G4double cosStart = GetCosStartPhi();
288 std::vector<const G4ThreeVectorList *> polygons;
289 polygons.resize(ksteps+2);
291 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
292 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
299 G4int ntria = triangles.size()/3;
300 for (
G4int i=0; i<ntria; ++i)
303 for (
G4int k=0; k<3; ++k)
305 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
308 r0[k2+0] = triangles[e0].x();
z0[k2+0] = triangles[e0].y();
309 r0[k2+1] = triangles[e1].x();
z0[k2+1] = triangles[e1].y();
313 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
319 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
320 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
321 for (
G4int j=0; j<6; ++j)
323 pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
325 for (
G4int k=1; k<ksteps+1; ++k)
327 for (
G4int j=0; j<6; ++j)
329 pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
332 sinCur = sinCur*cosStep + cosCur*sinStep;
333 cosCur = cosCur*cosStep - sinTmp*sinStep;
335 for (
G4int j=0; j<6; ++j)
337 pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
343 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
344 if (emin < pMin) pMin = emin;
345 if (emax > pMax) pMax = emax;
346 if (eminlim > pMin && emaxlim < pMax)
return true;
348 return (pMin < pMax);
355G4Polyhedron* G4UGenericPolycone::CreatePolyhedron()
const
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...
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)