34#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
48G4UCutTubs::G4UCutTubs(
const G4String& pName,
54 : Base_t(pName, pRMin, pRMax, pDz, pSPhi, pDPhi,
55 pLowNorm.x(), pLowNorm.y(), pLowNorm.z(),
56 pHighNorm.x(), pHighNorm.y(), pHighNorm.z())
64G4UCutTubs::G4UCutTubs(
const G4UCutTubs& rhs)
73G4UCutTubs& G4UCutTubs::operator = (
const G4UCutTubs& rhs)
77 if (
this == &rhs) {
return *
this; }
81 Base_t::operator=(rhs);
90G4double G4UCutTubs::GetInnerRadius()
const
94G4double G4UCutTubs::GetOuterRadius()
const
98G4double G4UCutTubs::GetZHalfLength()
const
102G4double G4UCutTubs::GetStartPhiAngle()
const
106G4double G4UCutTubs::GetDeltaPhiAngle()
const
110G4double G4UCutTubs::GetSinStartPhi()
const
112 return std::sin(GetStartPhiAngle());
114G4double G4UCutTubs::GetCosStartPhi()
const
116 return std::cos(GetStartPhiAngle());
118G4double G4UCutTubs::GetSinEndPhi()
const
120 return std::sin(GetStartPhiAngle()+GetDeltaPhiAngle());
122G4double G4UCutTubs::GetCosEndPhi()
const
124 return std::cos(GetStartPhiAngle()+GetDeltaPhiAngle());
128 U3Vector lc = BottomNormal();
129 return {lc.x(), lc.y(), lc.z()};
133 U3Vector
hc = TopNormal();
134 return {
hc.x(),
hc.y(),
hc.z()};
137void G4UCutTubs::SetInnerRadius(
G4double newRMin)
140 fRebuildPolyhedron =
true;
142void G4UCutTubs::SetOuterRadius(
G4double newRMax)
145 fRebuildPolyhedron =
true;
147void G4UCutTubs::SetZHalfLength(
G4double newDz)
150 fRebuildPolyhedron =
true;
155 fRebuildPolyhedron =
true;
157void G4UCutTubs::SetDeltaPhiAngle(
G4double newDPhi)
160 fRebuildPolyhedron =
true;
169 return new G4UCutTubs(*
this);
178 static G4bool checkBBox =
true;
185 G4double sinSphi = GetSinStartPhi();
186 G4double cosSphi = GetCosStartPhi();
191 G4double mag, topx, topy, dists, diste;
198 mag = std::sqrt(norm.
x()*norm.
x() + norm.
y()*norm.
y());
199 topx = (mag == 0) ? 0 : -rmax*norm.x()/mag;
200 topy = (mag == 0) ? 0 : -rmax*norm.
y()/mag;
201 dists = sinSphi*topx - cosSphi*topy;
202 diste = -sinEphi*topx + cosEphi*topy;
206 if (dists > 0 && diste > 0)iftop =
false;
211 if (dists <= 0 && diste <= 0) iftop =
true;
215 zmin = -(norm.
x()*topx + norm.
y()*topy)/norm.
z() - dz;
219 G4double z1 = -rmin*(norm.
x()*cosSphi + norm.
y()*sinSphi)/norm.
z() - dz;
220 G4double z2 = -rmin*(norm.
x()*cosEphi + norm.
y()*sinEphi)/norm.
z() - dz;
221 G4double z3 = -rmax*(norm.
x()*cosSphi + norm.
y()*sinSphi)/norm.
z() - dz;
222 G4double z4 = -rmax*(norm.
x()*cosEphi + norm.
y()*sinEphi)/norm.
z() - dz;
223 zmin = std::min(std::min(std::min(z1,z2),z3),z4);
229 norm = GetHighNorm();
230 mag = std::sqrt(norm.
x()*norm.
x() + norm.
y()*norm.
y());
231 topx = (mag == 0) ? 0 : -rmax*norm.x()/mag;
232 topy = (mag == 0) ? 0 : -rmax*norm.
y()/mag;
233 dists = sinSphi*topx - cosSphi*topy;
234 diste = -sinEphi*topx + cosEphi*topy;
238 if (dists > 0 && diste > 0) iftop =
false;
243 if (dists <= 0 && diste <= 0) iftop =
true;
247 zmax = -(norm.
x()*topx + norm.
y()*topy)/norm.
z() + dz;
251 G4double z1 = -rmin*(norm.
x()*cosSphi + norm.
y()*sinSphi)/norm.
z() + dz;
252 G4double z2 = -rmin*(norm.
x()*cosEphi + norm.
y()*sinEphi)/norm.
z() + dz;
253 G4double z3 = -rmax*(norm.
x()*cosSphi + norm.
y()*sinSphi)/norm.
z() + dz;
254 G4double z4 = -rmax*(norm.
x()*cosEphi + norm.
y()*sinEphi)/norm.
z() + dz;
255 zmax = std::max(std::max(std::max(z1,z2),z3),z4);
260 if (GetDeltaPhiAngle() < twopi)
264 GetSinStartPhi(),GetCosStartPhi(),
265 GetSinEndPhi(),GetCosEndPhi(),
267 pMin.
set(vmin.
x(),vmin.
y(), zmin);
268 pMax.
set(vmax.
x(),vmax.
y(), zmax);
272 pMin.
set(-rmax,-rmax, zmin);
273 pMax.
set( rmax, rmax, zmax);
278 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
280 std::ostringstream message;
281 message <<
"Bad bounding box (min >= max) for solid: "
283 <<
"\npMin = " << pMin
284 <<
"\npMax = " << pMax;
285 G4Exception(
"G4CUutTubs::BoundingLimits()",
"GeomMgt0001",
286 JustWarning, message);
303 std::ostringstream message;
304 message <<
"Inconsistency in bounding boxes for solid: "
306 <<
"\nBBox min: wrapper = " << pMin <<
" solid = " << vmin
307 <<
"\nBBox max: wrapper = " << pMax <<
" solid = " << vmax;
308 G4Exception(
"G4UCutTubs::BoundingLimits()",
"GeomMgt0001",
320G4UCutTubs::CalculateExtent(
const EAxis pAxis,
329 BoundingLimits(bmin,bmax);
334 if (
true)
return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
336 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
338 return exist = pMin < pMax;
350 const G4int NSTEPS = 24;
352 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-deg)/astep) + 1;
355 G4double sinHalf = std::sin(0.5*ang);
356 G4double cosHalf = std::cos(0.5*ang);
357 G4double sinStep = 2.*sinHalf*cosHalf;
358 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
363 if (rmin == 0 && dphi == twopi)
369 for (
G4int k=0; k<NSTEPS; ++k)
371 baseA[k].set(rext*cosCur,rext*sinCur,zmin);
372 baseB[k].set(rext*cosCur,rext*sinCur,zmax);
375 sinCur = sinCur*cosStep + cosCur*sinStep;
376 cosCur = cosCur*cosStep - sinTmp*sinStep;
378 std::vector<const G4ThreeVectorList *> polygons(2);
379 polygons[0] = &baseA;
380 polygons[1] = &baseB;
382 exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
386 G4double sinStart = GetSinStartPhi();
387 G4double cosStart = GetCosStartPhi();
390 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
391 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
395 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(4);
396 pols[0][0].set(rmin*cosStart,rmin*sinStart,zmax);
397 pols[0][1].set(rmin*cosStart,rmin*sinStart,zmin);
398 pols[0][2].set(rmax*cosStart,rmax*sinStart,zmin);
399 pols[0][3].set(rmax*cosStart,rmax*sinStart,zmax);
400 for (
G4int k=1; k<ksteps+1; ++k)
402 pols[k][0].set(rmin*cosCur,rmin*sinCur,zmax);
403 pols[k][1].set(rmin*cosCur,rmin*sinCur,zmin);
404 pols[k][2].set(rext*cosCur,rext*sinCur,zmin);
405 pols[k][3].set(rext*cosCur,rext*sinCur,zmax);
408 sinCur = sinCur*cosStep + cosCur*sinStep;
409 cosCur = cosCur*cosStep - sinTmp*sinStep;
411 pols[ksteps+1][0].set(rmin*cosEnd,rmin*sinEnd,zmax);
412 pols[ksteps+1][1].set(rmin*cosEnd,rmin*sinEnd,zmin);
413 pols[ksteps+1][2].set(rmax*cosEnd,rmax*sinEnd,zmin);
414 pols[ksteps+1][3].set(rmax*cosEnd,rmax*sinEnd,zmax);
417 std::vector<const G4ThreeVectorList *> polygons;
418 polygons.resize(ksteps+2);
419 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
421 exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
440 newz = -GetZHalfLength()
441 - (p.
x()*fLowNorm.
x()+p.
y()*fLowNorm.
y())/fLowNorm.
z();
446 if(fHighNorm.
z()!=0.)
448 newz = GetZHalfLength()
449 - (p.
x()*fHighNorm.
x()+p.
y()*fHighNorm.
y())/fHighNorm.
z();
462 typedef G4int G4int4[4];
472 auto xyz =
new G4double3[
nn];
473 auto faces =
new G4int4[nf] ;
495 G4int* iEdge=
nullptr;
497 for(
G4int i=0; i<nf; ++i)
502 faces[i][k]=iNodes[k];
504 for(
G4int k=n; k<4; ++k)
509 ph->createPolyhedron(nn,nf,xyz,faces);
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
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...
G4Point3D GetVertex(G4int index) const
void GetFacet(G4int iFace, G4int &n, G4int *iNodes, G4int *edgeFlags=nullptr, G4int *iFaces=nullptr) const
G4int GetNoFacets() const
G4int GetNoVertices() const
const G4double hc
[MeV*fm]