38 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
47 using namespace CLHEP;
54 G4UTorus::G4UTorus(
const G4String& pName,
57 : G4USolid(pName, new UTorus(pName, rmin, rmax, rtor, sphi, dphi))
65 G4UTorus::G4UTorus( __void__&
a )
73 G4UTorus::~G4UTorus() { }
79 G4UTorus::G4UTorus(
const G4UTorus& rhs)
87 G4UTorus& G4UTorus::operator = (
const G4UTorus& rhs)
91 if (
this == &rhs) {
return *
this; }
95 G4USolid::operator=(rhs);
106 return GetShape()->GetRmin();
111 return GetShape()->GetRmax();
116 return GetShape()->GetRtor();
121 return GetShape()->GetSPhi();
126 return GetShape()->GetDPhi();
129 G4double G4UTorus::GetSinStartPhi()
const
131 G4double phi = GetShape()->GetSPhi();
132 return std::sin(phi);
135 G4double G4UTorus::GetCosStartPhi()
const
137 G4double phi = GetShape()->GetSPhi();
138 return std::cos(phi);
141 G4double G4UTorus::GetSinEndPhi()
const
143 G4double phi = GetShape()->GetSPhi() +
144 GetShape()->GetDPhi();
145 return std::sin(phi);
148 G4double G4UTorus::GetCosEndPhi()
const
150 G4double phi = GetShape()->GetSPhi() +
151 GetShape()->GetDPhi();
152 return std::cos(phi);
155 void G4UTorus::SetRmin(
G4double arg)
157 GetShape()->SetRmin(arg);
158 fRebuildPolyhedron =
true;
161 void G4UTorus::SetRmax(
G4double arg)
163 GetShape()->SetRmax(arg);
164 fRebuildPolyhedron =
true;
167 void G4UTorus::SetRtor(
G4double arg)
169 GetShape()->SetRtor(arg);
170 fRebuildPolyhedron =
true;
173 void G4UTorus::SetSPhi(
G4double arg)
175 GetShape()->SetSPhi(arg);
176 fRebuildPolyhedron =
true;
179 void G4UTorus::SetDPhi(
G4double arg)
181 GetShape()->SetDPhi(arg);
182 fRebuildPolyhedron =
true;
188 GetShape()->SetRmin(arg1);
189 GetShape()->SetRmax(arg2);
190 GetShape()->SetRtor(arg3);
191 GetShape()->SetSPhi(arg4);
192 GetShape()->SetDPhi(arg5);
193 fRebuildPolyhedron =
true;
214 return new G4UTorus(*
this);
223 static G4bool checkBBox =
true;
233 if (GetDPhi() >=
twopi)
235 pMin.set(-rext,-rext,-dz);
236 pMax.set( rext, rext, dz);
242 GetSinStartPhi(),GetCosStartPhi(),
243 GetSinEndPhi(),GetCosEndPhi(),
245 pMin.set(vmin.x(),vmin.y(),-dz);
246 pMax.set(vmax.x(),vmax.y(), dz);
251 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
253 std::ostringstream message;
254 message <<
"Bad bounding box (min >= max) for solid: "
256 <<
"\npMin = " << pMin
257 <<
"\npMax = " << pMax;
267 GetShape()->Extent(vmin,vmax);
275 std::ostringstream message;
276 message <<
"Inconsistency in bounding boxes for solid: "
278 <<
"\nBBox min: wrapper = " << pMin <<
" solid = " << vmin
279 <<
"\nBBox max: wrapper = " << pMax <<
" solid = " << vmax;
291 G4UTorus::CalculateExtent(
const EAxis pAxis,
305 if (
true)
return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
307 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
309 return exist = (pMin < pMax) ?
true :
false;
317 G4double sinStart = GetSinStartPhi();
318 G4double cosStart = GetCosStartPhi();
326 static const G4int NPHI = 24;
327 static const G4int NDISK = 16;
328 static const G4double sinHalfDisk = std::sin(
pi/NDISK);
329 static const G4double cosHalfDisk = std::cos(
pi/NDISK);
330 static const G4double sinStepDisk = 2.*sinHalfDisk*cosHalfDisk;
331 static const G4double cosStepDisk = 1. - 2.*sinHalfDisk*sinHalfDisk;
334 G4int kphi = (dphi <= astep) ? 1 : (
G4int)((dphi-
deg)/astep) + 1;
337 G4double sinHalf = std::sin(0.5*ang);
338 G4double cosHalf = std::cos(0.5*ang);
339 G4double sinStep = 2.*sinHalf*cosHalf;
340 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
344 for (
G4int k=0; k<NDISK+1; ++k) pols[k].resize(4);
346 std::vector<const G4ThreeVectorList *> polygons;
347 polygons.resize(NDISK+1);
348 for (
G4int k=0; k<NDISK+1; ++k) polygons[k] = &pols[k];
354 if ((rtor-rmin*sinHalfDisk)/cosHalf > (rtor+rmin*sinHalfDisk)) rmin = 0;
358 for (
G4int k=0; k<NDISK; ++k)
360 G4double rmincur = rtor + rmin*cosCurDisk;
361 if (cosCurDisk < 0 && rmin > 0) rmincur /= cosHalf;
362 rzmin[k].set(rmincur,rmin*sinCurDisk);
364 G4double rmaxcur = rtor + rmax*cosCurDisk;
365 if (cosCurDisk > 0) rmaxcur /= cosHalf;
366 rzmax[k].set(rmaxcur,rmax*sinCurDisk);
369 sinCurDisk = sinCurDisk*cosStepDisk + cosCurDisk*sinStepDisk;
370 cosCurDisk = cosCurDisk*cosStepDisk - sinTmpDisk*sinStepDisk;
379 G4double sinCur1 = 0, cosCur1 = 0, sinCur2 = 0, cosCur2 = 0;
380 for (
G4int i=0; i<kphi+1; ++i)
386 sinCur2 = sinCur1*cosHalf + cosCur1*sinHalf;
387 cosCur2 = cosCur1*cosHalf - sinCur1*sinHalf;
393 sinCur2 = (i == kphi) ? sinEnd : sinCur1*cosStep + cosCur1*sinStep;
394 cosCur2 = (i == kphi) ? cosEnd : cosCur1*cosStep - sinCur1*sinStep;
396 for (
G4int k=0; k<NDISK; ++k)
398 G4double r1 = rzmin[k].x(), r2 = rzmax[k].x();
399 G4double z1 = rzmin[k].y(), z2 = rzmax[k].y();
400 pols[k][0].set(r1*cosCur1,r1*sinCur1,z1);
401 pols[k][1].set(r2*cosCur1,r2*sinCur1,z2);
402 pols[k][2].set(r2*cosCur2,r2*sinCur2,z2);
403 pols[k][3].set(r1*cosCur2,r1*sinCur2,z1);
405 pols[NDISK] = pols[0];
410 DiskExtent(rint,rext,sinCur1,cosCur1,sinCur2,cosCur2,vmin,vmax);
411 bmin.setX(vmin.x()); bmin.setY(vmin.y());
412 bmax.setX(vmax.x()); bmax.setY(vmax.y());
417 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
418 if (emin < pMin) pMin = emin;
419 if (emax > pMax) pMax =
emax;
420 if (eminlim > pMin && emaxlim < pMax)
break;
422 return (pMin < pMax);
438 #endif // G4GEOM_USE_USOLIDS
static const G4double kInfinity
CLHEP::Hep3Vector G4ThreeVector
std::vector< ExP01TrackerHit * > a
static constexpr double twopi
G4GLOB_DLL std::ostream G4cout
const G4double kCarTolerance
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static const G4double emax
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
CLHEP::Hep2Vector G4TwoVector
static constexpr double pi
static constexpr double deg
G4double GetMaxExtent(const EAxis pAxis) const
G4double GetMinExtent(const EAxis pAxis) const