34#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
50G4UTorus::G4UTorus(
const G4String& pName,
53 : Base_t(pName, rmin, rmax, rtor, sphi, dphi)
60G4UTorus::G4UTorus(
const G4UTorus& rhs)
68G4UTorus& G4UTorus::operator = (
const G4UTorus& rhs)
72 if (
this == &rhs) {
return *
this; }
76 Base_t::operator=(rhs);
110G4double G4UTorus::GetSinStartPhi()
const
112 return std::sin(sphi());
115G4double G4UTorus::GetCosStartPhi()
const
117 return std::cos(sphi());
120G4double G4UTorus::GetSinEndPhi()
const
122 return std::sin(sphi()+dphi());
125G4double G4UTorus::GetCosEndPhi()
const
127 return std::cos(sphi()+dphi());
132 Base_t::SetRMin(arg);
133 fRebuildPolyhedron =
true;
138 Base_t::SetRMax(arg);
139 fRebuildPolyhedron =
true;
144 Base_t::SetRTor(arg);
145 fRebuildPolyhedron =
true;
150 Base_t::SetSPhi(arg);
151 fRebuildPolyhedron =
true;
156 Base_t::SetDPhi(arg);
157 fRebuildPolyhedron =
true;
168 fRebuildPolyhedron =
true;
189 return new G4UTorus(*
this);
198 static G4bool checkBBox =
true;
208 if (GetDPhi() >= twopi)
210 pMin.
set(-rext,-rext,-dz);
211 pMax.
set( rext, rext, dz);
217 GetSinStartPhi(),GetCosStartPhi(),
218 GetSinEndPhi(),GetCosEndPhi(),
220 pMin.
set(vmin.
x(),vmin.
y(),-dz);
221 pMax.
set(vmax.
x(),vmax.
y(), dz);
226 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
228 std::ostringstream message;
229 message <<
"Bad bounding box (min >= max) for solid: "
231 <<
"\npMin = " << pMin
232 <<
"\npMax = " << pMax;
233 G4Exception(
"G4UTorus::BoundingLimits()",
"GeomMgt0001",
243 Base_t::Extent(vmin,vmax);
251 std::ostringstream message;
252 message <<
"Inconsistency in bounding boxes for solid: "
254 <<
"\nBBox min: wrapper = " << pMin <<
" solid = " << vmin
255 <<
"\nBBox max: wrapper = " << pMax <<
" solid = " << vmax;
256 G4Exception(
"G4UTorus::BoundingLimits()",
"GeomMgt0001",
268G4UTorus::CalculateExtent(
const EAxis pAxis,
277 BoundingLimits(bmin,bmax);
282 if (
true)
return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
284 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
286 return exist = pMin < pMax;
294 G4double sinStart = GetSinStartPhi();
295 G4double cosStart = GetCosStartPhi();
303 static const G4int NPHI = 24;
304 static const G4int NDISK = 16;
305 static const G4double sinHalfDisk = std::sin(pi/NDISK);
306 static const G4double cosHalfDisk = std::cos(pi/NDISK);
307 static const G4double sinStepDisk = 2.*sinHalfDisk*cosHalfDisk;
308 static const G4double cosStepDisk = 1. - 2.*sinHalfDisk*sinHalfDisk;
311 G4int kphi = (dphi <= astep) ? 1 : (
G4int)((dphi-deg)/astep) + 1;
314 G4double sinHalf = std::sin(0.5*ang);
315 G4double cosHalf = std::cos(0.5*ang);
316 G4double sinStep = 2.*sinHalf*cosHalf;
317 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
321 for (
auto & pol : pols) pol.resize(4);
323 std::vector<const G4ThreeVectorList *> polygons;
324 polygons.resize(NDISK+1);
325 for (
G4int k=0; k<NDISK+1; ++k) polygons[k] = &pols[k];
331 if ((rtor-rmin*sinHalfDisk)/cosHalf > (rtor+rmin*sinHalfDisk)) rmin = 0;
335 for (
G4int k=0; k<NDISK; ++k)
337 G4double rmincur = rtor + rmin*cosCurDisk;
338 if (cosCurDisk < 0 && rmin > 0) rmincur /= cosHalf;
339 rzmin[k].
set(rmincur,rmin*sinCurDisk);
341 G4double rmaxcur = rtor + rmax*cosCurDisk;
342 if (cosCurDisk > 0) rmaxcur /= cosHalf;
343 rzmax[k].
set(rmaxcur,rmax*sinCurDisk);
346 sinCurDisk = sinCurDisk*cosStepDisk + cosCurDisk*sinStepDisk;
347 cosCurDisk = cosCurDisk*cosStepDisk - sinTmpDisk*sinStepDisk;
356 G4double sinCur1 = 0, cosCur1 = 0, sinCur2 = 0, cosCur2 = 0;
357 for (
G4int i=0; i<kphi+1; ++i)
363 sinCur2 = sinCur1*cosHalf + cosCur1*sinHalf;
364 cosCur2 = cosCur1*cosHalf - sinCur1*sinHalf;
370 sinCur2 = (i == kphi) ? sinEnd : sinCur1*cosStep + cosCur1*sinStep;
371 cosCur2 = (i == kphi) ? cosEnd : cosCur1*cosStep - sinCur1*sinStep;
373 for (
G4int k=0; k<NDISK; ++k)
375 G4double r1 = rzmin[k].
x(), r2 = rzmax[k].
x();
376 G4double z1 = rzmin[k].
y(), z2 = rzmax[k].
y();
377 pols[k][0].set(r1*cosCur1,r1*sinCur1,z1);
378 pols[k][1].set(r2*cosCur1,r2*sinCur1,z2);
379 pols[k][2].set(r2*cosCur2,r2*sinCur2,z2);
380 pols[k][3].set(r1*cosCur2,r1*sinCur2,z1);
382 pols[NDISK] = pols[0];
387 DiskExtent(rint,rext,sinCur1,cosCur1,sinCur2,cosCur2,vmin,vmax);
394 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
395 if (emin < pMin) pMin = emin;
396 if (emax > pMax) pMax = emax;
397 if (eminlim > pMin && emaxlim < pMax)
break;
399 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)
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...
G4Torus represents a torus or torus segment with curved sides parallel to the z-axis....
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