40#if !(defined(G4GEOM_USE_UTORUS) && defined(G4GEOM_USE_SYS_USOLIDS))
67enum ESide {kNull,kRMin,kRMax,kSPhi,kEPhi};
70enum ENorm {kNRMin,kNRMax,kNSPhi,kNEPhi};
110 halfAngTolerance = 0.5*kAngTolerance;
118 std::ostringstream message;
119 message <<
"Invalid swept radius for Solid: " <<
GetName() <<
G4endl
120 <<
" pRtor = " << pRtor <<
", pRmax = " << pRmax;
127 if ( pRmin < pRmax - 1.e2*kCarTolerance && pRmin >= 0 )
130 else { fRmin = 0.0 ; }
135 std::ostringstream message;
136 message <<
"Invalid values of radii for Solid: " <<
GetName() <<
G4endl
137 <<
" pRmin = " << pRmin <<
", pRmax = " << pRmax;
144 fRminTolerance = (fRmin) != 0.0
145 ? 0.5*std::max( kRadTolerance, fEpsilon*(fRtor-fRmin )) : 0;
146 fRmaxTolerance = 0.5*std::max( kRadTolerance, fEpsilon*(fRtor+fRmax) );
150 if ( pDPhi >= twopi ) { fDPhi = twopi ; }
153 if (pDPhi > 0) { fDPhi = pDPhi ; }
156 std::ostringstream message;
157 message <<
"Invalid Z delta-Phi for Solid: " <<
GetName() <<
G4endl
158 <<
" pDPhi = " << pDPhi;
168 if (fSPhi < 0) { fSPhi = twopi-std::fmod(std::fabs(fSPhi),twopi) ; }
169 else { fSPhi = std::fmod(fSPhi,twopi) ; }
171 if (fSPhi+fDPhi > twopi) { fSPhi-=twopi ; }
192 if (
this == &rhs) {
return *
this; }
200 fRmin = rhs.fRmin; fRmax = rhs.fRmax;
201 fRtor = rhs.fRtor; fSPhi = rhs.fSPhi; fDPhi = rhs.fDPhi;
202 fRminTolerance = rhs.fRminTolerance; fRmaxTolerance = rhs.fRmaxTolerance;
203 kRadTolerance = rhs.kRadTolerance; kAngTolerance = rhs.kAngTolerance;
204 halfCarTolerance = rhs.halfCarTolerance;
205 halfAngTolerance = rhs.halfAngTolerance;
232 std::vector<G4double>& roots )
const
238 G4double Rtor2 = fRtor*fRtor, r2 = r*r ;
246 c[2] = 2*( (d + 2*pDotV*pDotV - r2) + 2*Rtor2*v.
z()*v.
z());
247 c[3] = 4*(pDotV*(d - r2) + 2*Rtor2*p.
z()*v.
z()) ;
248 c[4] = (d-r2)*(d-r2) +4*Rtor2*(p.
z()*p.
z()-r2);
252 num = torusEq.
FindRoots( c, 4, srd, si );
254 for ( i = 0; i < num; ++i )
256 if( si[i] == 0. ) { roots.push_back(srd[i]) ; }
259 std::sort(roots.begin() , roots.end() ) ;
272 G4bool IsDistanceToIn )
const
281 std::vector<G4double> roots ;
282 std::vector<G4double> rootsrefined ;
283 TorusRootsJT(p,v,r,roots) ;
289 for ( std::size_t k = 0 ; k<roots.size() ; ++k )
293 if ( t < -halfCarTolerance ) { continue ; }
295 if ( t > bigdist && t<kInfinity )
298 TorusRootsJT(ptmp,v,r,rootsrefined) ;
299 if ( rootsrefined.size()==roots.size() )
301 t = t + rootsrefined[k] ;
307 G4double theta = std::atan2(ptmp.
y(),ptmp.
x());
311 if ( theta < - halfAngTolerance ) { theta += twopi; }
312 if ( (std::fabs(theta) < halfAngTolerance)
313 && (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
318 if ((fSPhi <= -pi )&&(theta>halfAngTolerance)) { theta = theta-twopi; }
323 if ( (theta - fSPhi >= - halfAngTolerance)
324 && (theta - (fSPhi + fDPhi) <= halfAngTolerance) )
329 if ( IsDistanceToIn )
331 if (std::fabs(t) < halfCarTolerance )
337 p.
y()*(1-fRtor/std::hypot(p.
x(),p.
y())),
342 if ( r ==
GetRmin() ) { scal = -scal ; }
343 if ( scal < 0 ) {
return 0.0 ; }
350 if ( !IsDistanceToIn )
352 if (std::fabs(t) < halfCarTolerance )
357 p.
y()*(1-fRtor/std::hypot(p.
x(),p.
y())),
362 if ( r ==
GetRmin() ) { scal = -scal ; }
363 if ( scal > 0 ) {
return 0.0 ; }
369 if( t > halfCarTolerance )
396 pMin.
set(-rext,-rext,-dz);
397 pMax.
set( rext, rext, dz);
406 pMin.
set(vmin.
x(),vmin.
y(),-dz);
407 pMax.
set(vmax.
x(),vmax.
y(), dz);
412 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
414 std::ostringstream message;
415 message <<
"Bad bounding box (min >= max) for solid: "
417 <<
"\npMin = " << pMin
418 <<
"\npMax = " << pMax;
419 G4Exception(
"G4Torus::BoundingLimits()",
"GeomMgt0001",
447 return exist = pMin < pMax;
464 static const G4int NPHI = 24;
465 static const G4int NDISK = 16;
466 static const G4double sinHalfDisk = std::sin(pi/NDISK);
467 static const G4double cosHalfDisk = std::cos(pi/NDISK);
468 static const G4double sinStepDisk = 2.*sinHalfDisk*cosHalfDisk;
469 static const G4double cosStepDisk = 1. - 2.*sinHalfDisk*sinHalfDisk;
472 G4int kphi = (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;
482 for (
auto & pol : pols) { pol.resize(4); }
484 std::vector<const G4ThreeVectorList *> polygons;
485 polygons.resize(NDISK+1);
486 for (
G4int k=0; k<NDISK+1; ++k) { polygons[k] = &pols[k]; }
492 if ((rtor-rmin*sinHalfDisk)/cosHalf > (rtor+rmin*sinHalfDisk)) { rmin = 0; }
496 for (
G4int k=0; k<NDISK; ++k)
498 G4double rmincur = rtor + rmin*cosCurDisk;
499 if (cosCurDisk < 0 && rmin > 0) { rmincur /= cosHalf; }
500 rzmin[k].
set(rmincur,rmin*sinCurDisk);
502 G4double rmaxcur = rtor + rmax*cosCurDisk;
503 if (cosCurDisk > 0) { rmaxcur /= cosHalf; }
504 rzmax[k].
set(rmaxcur,rmax*sinCurDisk);
507 sinCurDisk = sinCurDisk*cosStepDisk + cosCurDisk*sinStepDisk;
508 cosCurDisk = cosCurDisk*cosStepDisk - sinTmpDisk*sinStepDisk;
517 G4double sinCur1 = 0, cosCur1 = 0, sinCur2 = 0, cosCur2 = 0;
518 for (
G4int i=0; i<kphi+1; ++i)
524 sinCur2 = sinCur1*cosHalf + cosCur1*sinHalf;
525 cosCur2 = cosCur1*cosHalf - sinCur1*sinHalf;
531 sinCur2 = (i == kphi) ? sinEnd : sinCur1*cosStep + cosCur1*sinStep;
532 cosCur2 = (i == kphi) ? cosEnd : cosCur1*cosStep - sinCur1*sinStep;
534 for (
G4int k=0; k<NDISK; ++k)
536 G4double r1 = rzmin[k].
x(), r2 = rzmax[k].
x();
537 G4double z1 = rzmin[k].
y(), z2 = rzmax[k].
y();
538 pols[k][0].set(r1*cosCur1,r1*sinCur1,z1);
539 pols[k][1].set(r2*cosCur1,r2*sinCur1,z2);
540 pols[k][2].set(r2*cosCur2,r2*sinCur2,z2);
541 pols[k][3].set(r1*cosCur2,r1*sinCur2,z1);
543 pols[NDISK] = pols[0];
548 DiskExtent(rint,rext,sinCur1,cosCur1,sinCur2,cosCur2,vmin,vmax);
559 if (emin < pMin) { pMin = emin; }
560 if (emax > pMax) { pMax = emax; }
561 if (eminlim > pMin && emaxlim < pMax) {
break; }
563 return (pMin < pMax);
572 G4double r, pt2, pPhi, tolRMin, tolRMax ;
578 r = std::hypot(p.
x(),p.
y());
579 pt2 = p.
z()*p.
z() + (r-fRtor)*(r-fRtor);
581 (fRmin != 0.0) ? (tolRMin = fRmin + fRminTolerance) : (tolRMin = 0);
583 tolRMax = fRmax - fRmaxTolerance;
585 if (pt2 >= tolRMin*tolRMin && pt2 <= tolRMax*tolRMax )
587 if ( fDPhi == twopi || pt2 == 0 )
596 pPhi = std::atan2(p.
y(),p.
x()) ;
598 if ( pPhi < -halfAngTolerance ) { pPhi += twopi ; }
601 if ( (std::fabs(pPhi) < halfAngTolerance)
602 && (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
606 if ( (pPhi >= fSPhi + halfAngTolerance)
607 && (pPhi <= fSPhi + fDPhi - halfAngTolerance) )
611 else if ( (pPhi >= fSPhi - halfAngTolerance)
612 && (pPhi <= fSPhi + fDPhi + halfAngTolerance) )
619 if ( (pPhi <= fSPhi + twopi - halfAngTolerance)
620 && (pPhi >= fSPhi + fDPhi + halfAngTolerance) ) {;}
630 tolRMin = fRmin - fRminTolerance ;
631 tolRMax = fRmax + fRmaxTolerance ;
633 if (tolRMin < 0 ) { tolRMin = 0 ; }
635 if ( (pt2 >= tolRMin*tolRMin) && (pt2 <= tolRMax*tolRMax) )
637 if ( (fDPhi == twopi) || (pt2 == 0) )
643 pPhi = std::atan2(p.
y(),p.
x()) ;
645 if ( pPhi < -halfAngTolerance ) { pPhi += twopi ; }
648 if ( (std::fabs(pPhi) < halfAngTolerance)
649 && (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
653 if ( (pPhi >= fSPhi - halfAngTolerance)
654 && (pPhi <= fSPhi + fDPhi + halfAngTolerance) )
661 if ( (pPhi <= fSPhi + twopi - halfAngTolerance)
662 && (pPhi >= fSPhi + fDPhi + halfAngTolerance) ) {;}
682 G4int noSurfaces = 0;
685 G4double distSPhi = kInfinity, distEPhi = kInfinity;
690 1.0e-8*(fRtor+fRmax));
691 const G4double dAngle = 10.0*kAngTolerance;
696 rho = std::hypot(p.
x(),p.
y());
697 pt = std::hypot(p.
z(),rho-fRtor);
699 G4double distRMax = std::fabs(pt - fRmax);
700 if(fRmin != 0.0) { distRMin = std::fabs(pt - fRmin); }
702 if( rho > delta && pt != 0.0 )
704 G4double redFactor= (rho-fRtor)/rho;
715 pPhi = std::atan2(p.
y(),p.
x());
717 if(pPhi < fSPhi-delta) { pPhi += twopi; }
718 else if(pPhi > fSPhi+fDPhi+delta) { pPhi -= twopi; }
720 distSPhi = std::fabs( pPhi - fSPhi );
721 distEPhi = std::fabs(pPhi-fSPhi-fDPhi);
724 nPe =
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);
726 if( distRMax <= delta )
731 else if( (fRmin != 0.0) && (distRMin <= delta) )
740 if( (fDPhi < twopi) && (fRmin-delta <= pt) && (pt <= (fRmax+delta)) )
742 if (distSPhi <= dAngle)
747 if (distEPhi <= dAngle)
753 if ( noSurfaces == 0 )
763 ed <<
" ERROR> Surface Normal was called for Torus,"
764 <<
" with point not on surface." <<
G4endl;
768 ed <<
" ERROR> Surface Normal has not found a surface, "
769 <<
" despite the point being on the surface. " <<
G4endl;
780 ed <<
" Coordinates of point : " << p <<
G4endl;
781 ed <<
" Parameters of solid : " <<
G4endl << *
this <<
G4endl;
785 G4Exception(
"G4Torus::SurfaceNormal(p)",
"GeomSolids1002",
787 "Failing to find normal, even though point is on surface!");
791 static const char* NameInside[3]= {
"Inside",
"Surface",
"Outside" };
792 ed <<
" The point is " << NameInside[inIt] <<
" the solid. "<<
G4endl;
793 G4Exception(
"G4Torus::SurfaceNormal(p)",
"GeomSolids1002",
797 norm = ApproxSurfaceNormal(p);
799 else if ( noSurfaces == 1 ) { norm = sumnorm; }
800 else { norm = sumnorm.
unit(); }
815 G4double distRMin,distRMax,distSPhi,distEPhi,distMin;
817 rho = std::hypot(p.
x(),p.
y());
818 pt = std::hypot(p.
z(),rho-fRtor);
821 G4cout <<
" G4Torus::ApproximateSurfaceNormal called for point " << p
825 distRMax = std::fabs(pt - fRmax) ;
829 distRMin = std::fabs(pt - fRmin) ;
831 if (distRMin < distRMax)
847 if ( (fDPhi < twopi) && (rho != 0.0) )
849 phi = std::atan2(p.
y(),p.
x()) ;
851 if (phi < 0) { phi += twopi ; }
853 if (fSPhi < 0 ) { distSPhi = std::fabs(phi-(fSPhi+twopi))*rho ; }
854 else { distSPhi = std::fabs(phi-fSPhi)*rho ; }
856 distEPhi = std::fabs(phi - fSPhi - fDPhi)*rho ;
858 if (distSPhi < distEPhi)
860 if (distSPhi<distMin) { side = kNSPhi ; }
864 if (distEPhi < distMin) { side = kNEPhi ; }
871 -p.
y()*(1-fRtor/rho)/pt,
876 p.
y()*(1-fRtor/rho)/pt,
883 norm =
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0) ;
889 "Undefined side for valid surface normal to solid.");
930 G4double distX = std::abs(p.
x()) - boxDx;
931 G4double distY = std::abs(p.
y()) - boxDy;
932 G4double distZ = std::abs(p.
z()) - boxDz;
933 if (distX >= -halfCarTolerance && p.
x()*v.
x() >= 0) {
return kInfinity; }
934 if (distY >= -halfCarTolerance && p.
y()*v.
y() >= 0) {
return kInfinity; }
935 if (distZ >= -halfCarTolerance && p.
z()*v.
z() >= 0) {
return kInfinity; }
941 G4double safe = std::max(std::max(distX,distY),distZ);
944 G4double dist = safe - 1.e-8*safe - boxMin;
946 return (dist >= kInfinity) ? kInfinity : dist;
951 G4double snxt=kInfinity, sphi=kInfinity;
960 G4double cPhi,sinCPhi=0.,cosCPhi=0.;
977 cPhi = fSPhi + hDPhi ;
978 sinCPhi = std::sin(cPhi) ;
979 cosCPhi = std::cos(cPhi) ;
986 if (fRmin > fRminTolerance)
988 tolORMin2 = (fRmin - fRminTolerance)*(fRmin - fRminTolerance) ;
994 tolORMax2 = (fRmax + fRmaxTolerance)*(fRmax + fRmaxTolerance) ;
998 snxt = SolveNumericJT(p,v,fRmax,
true);
1002 sd[0] = SolveNumericJT(p,v,fRmin,
true);
1003 if ( sd[0] < snxt ) { snxt = sd[0] ; }
1018 sinSPhi = std::sin(fSPhi) ;
1019 cosSPhi = std::cos(fSPhi) ;
1020 Comp = v.
x()*sinSPhi - v.
y()*cosSPhi ;
1024 Dist = (p.
y()*cosSPhi - p.
x()*sinSPhi) ;
1026 if (Dist < halfCarTolerance)
1031 if ( sphi < 0 ) { sphi = 0 ; }
1033 xi = p.
x() + sphi*v.
x() ;
1034 yi = p.
y() + sphi*v.
y() ;
1035 zi = p.
z() + sphi*v.
z() ;
1036 rhoi = std::hypot(xi,yi);
1037 it2 = zi*zi + (rhoi-fRtor)*(rhoi-fRtor);
1039 if ( it2 >= tolORMin2 && it2 <= tolORMax2 )
1044 if ((yi*cosCPhi-xi*sinCPhi)<=0) { snxt=sphi; }
1050 sinEPhi=std::sin(ePhi);
1051 cosEPhi=std::cos(ePhi);
1052 Comp=-(v.
x()*sinEPhi-v.
y()*cosEPhi);
1056 Dist = -(p.
y()*cosEPhi - p.
x()*sinEPhi) ;
1058 if (Dist < halfCarTolerance )
1064 if (sphi < 0 ) { sphi = 0 ; }
1066 xi = p.
x() + sphi*v.
x() ;
1067 yi = p.
y() + sphi*v.
y() ;
1068 zi = p.
z() + sphi*v.
z() ;
1069 rhoi = std::hypot(xi,yi);
1070 it2 = zi*zi + (rhoi-fRtor)*(rhoi-fRtor);
1072 if (it2 >= tolORMin2 && it2 <= tolORMax2)
1077 if ((yi*cosCPhi-xi*sinCPhi)>=0) { snxt=sphi; }
1083 if(snxt < halfCarTolerance) { snxt = 0.0 ; }
1098 G4double phiC, cosPhiC, sinPhiC, safePhi, ePhi, cosPsi ;
1101 rho = std::hypot(p.
x(),p.
y());
1102 pt = std::hypot(p.
z(),rho-fRtor);
1103 safe1 = fRmin - pt ;
1104 safe2 = pt - fRmax ;
1106 if (safe1 > safe2) { safe = safe1; }
1107 else { safe = safe2; }
1109 if ( fDPhi < twopi && (rho != 0.0) )
1111 phiC = fSPhi + fDPhi*0.5 ;
1112 cosPhiC = std::cos(phiC) ;
1113 sinPhiC = std::sin(phiC) ;
1114 cosPsi = (p.
x()*cosPhiC + p.
y()*sinPhiC)/rho ;
1116 if (cosPsi < std::cos(fDPhi*0.5) )
1118 if ((p.
y()*cosPhiC - p.
x()*sinPhiC) <= 0 )
1120 safePhi = std::fabs(p.
x()*std::sin(fSPhi) - p.
y()*std::cos(fSPhi)) ;
1124 ePhi = fSPhi + fDPhi ;
1125 safePhi = std::fabs(p.
x()*std::sin(ePhi) - p.
y()*std::cos(ePhi)) ;
1127 if (safePhi > safe) { safe = safePhi ; }
1130 if (safe < 0 ) { safe = 0 ; }
1146 ESide side = kNull, sidephi = kNull ;
1147 G4double snxt = kInfinity, sphi, sd[4] ;
1151 G4double sinSPhi, cosSPhi, ePhi, sinEPhi, cosEPhi;
1153 G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, zi, vphi ;
1171 G4double tolRMax = fRmax - fRmaxTolerance ;
1173 G4double vDotNmax = pDotV - fRtor*(v.
x()*p.
x() + v.
y()*p.
y())/rho ;
1174 G4double pDotxyNmax = (1 - fRtor/rho) ;
1176 if( (pt*pt > tolRMax*tolRMax) && (vDotNmax >= 0) )
1182 if ( calcNorm && (pDotxyNmax >= -2.*fRmaxTolerance) )
1185 p.
y()*(1 - fRtor/rho)/pt,
1193 snxt = SolveNumericJT(p,v,fRmax,
false);
1200 G4double tolRMin = fRmin + fRminTolerance ;
1202 if ( (pt*pt < tolRMin*tolRMin) && (vDotNmax < 0) )
1204 if (calcNorm) { *validNorm = false ; }
1208 sd[0] = SolveNumericJT(p,v,fRmin,
false);
1221 snxt = SolveNumericJT(p,v,fRmax,
false);
1226 sd[0] = SolveNumericJT(p,v,fRmin,
false);
1234 if ( calcNorm && (snxt == 0.0) )
1236 *validNorm = false ;
1244 sinSPhi = std::sin(fSPhi) ;
1245 cosSPhi = std::cos(fSPhi) ;
1246 ePhi = fSPhi + fDPhi ;
1247 sinEPhi = std::sin(ePhi) ;
1248 cosEPhi = std::cos(ePhi) ;
1249 cPhi = fSPhi + fDPhi*0.5 ;
1250 sinCPhi = std::sin(cPhi) ;
1251 cosCPhi = std::cos(cPhi) ;
1256 vphi = std::atan2(v.
y(),v.
x()) ;
1258 if ( vphi < fSPhi - halfAngTolerance ) { vphi += twopi; }
1259 else if ( vphi > ePhi + halfAngTolerance ) { vphi -= twopi; }
1261 if ( (p.
x() != 0.0) || (p.
y() != 0.0) )
1263 pDistS = p.
x()*sinSPhi - p.
y()*cosSPhi ;
1264 pDistE = -p.
x()*sinEPhi + p.
y()*cosEPhi ;
1268 compS = -sinSPhi*v.
x() + cosSPhi*v.
y() ;
1269 compE = sinEPhi*v.
x() - cosEPhi*v.
y() ;
1272 if( ( (fDPhi <= pi) && ( (pDistS <= halfCarTolerance)
1273 && (pDistE <= halfCarTolerance) ) )
1274 || ( (fDPhi > pi) && ((pDistS <= halfCarTolerance)
1275 || (pDistE <= halfCarTolerance) ) ) )
1281 sphi = pDistS/compS ;
1283 if (sphi >= -halfCarTolerance)
1285 xi = p.
x() + sphi*v.
x() ;
1286 yi = p.
y() + sphi*v.
y() ;
1295 if ( ((fSPhi-halfAngTolerance)<=vphi)
1296 && ((ePhi+halfAngTolerance)>=vphi) )
1301 else if ( yi*cosCPhi-xi*sinCPhi >=0 )
1322 sphi2 = pDistE/compE ;
1328 xi = p.
x() + sphi2*v.
x() ;
1329 yi = p.
y() + sphi2*v.
y() ;
1336 if( (fSPhi-halfAngTolerance > vphi)
1337 || (ePhi+halfAngTolerance < vphi) )
1345 if ( (yi*cosCPhi-xi*sinCPhi) >= 0)
1367 vphi = std::atan2(v.
y(),v.
x());
1369 if ( ( fSPhi-halfAngTolerance <= vphi ) &&
1370 ( vphi <= ( ePhi+halfAngTolerance ) ) )
1399 xi = p.
x() + snxt*v.
x() ;
1400 yi = p.
y() + snxt*v.
y() ;
1401 zi = p.
z() + snxt*v.
z() ;
1402 rhoi = std::hypot(xi,yi);
1403 it = hypot(zi,rhoi-fRtor);
1405 iDotxyNmax = (1-fRtor/rhoi) ;
1406 if(iDotxyNmax >= -2.*fRmaxTolerance)
1409 yi*(1-fRtor/rhoi)/it,
1415 *validNorm = false ;
1420 *validNorm = false ;
1431 *validNorm = false ;
1438 *n=
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);
1443 *validNorm = false ;
1453 std::ostringstream message;
1454 G4long oldprc = message.precision(16);
1455 message <<
"Undefined side for valid surface normal to solid."
1458 <<
"p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1459 <<
"p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1462 <<
"v.x() = " << v.
x() <<
G4endl
1463 <<
"v.y() = " << v.
y() <<
G4endl
1466 <<
"snxt = " << snxt/mm <<
" mm" <<
G4endl;
1467 message.precision(oldprc);
1473 if ( snxt<halfCarTolerance ) { snxt=0 ; }
1486 G4double safePhi,phiC,cosPhiC,sinPhiC,ePhi;
1488 rho = std::hypot(p.
x(),p.
y());
1489 pt = std::hypot(p.
z(),rho-fRtor);
1501 G4cout.precision(oldprc);
1502 G4Exception(
"G4Torus::DistanceToOut(p)",
"GeomSolids1002",
1509 safeR1 = pt - fRmin ;
1510 safeR2 = fRmax - pt ;
1512 if (safeR1 < safeR2) { safe = safeR1 ; }
1513 else { safe = safeR2 ; }
1524 phiC = fSPhi + fDPhi*0.5 ;
1525 cosPhiC = std::cos(phiC) ;
1526 sinPhiC = std::sin(phiC) ;
1528 if ((p.
y()*cosPhiC-p.
x()*sinPhiC)<=0)
1530 safePhi = -(p.
x()*std::sin(fSPhi) - p.
y()*std::cos(fSPhi)) ;
1534 ePhi = fSPhi + fDPhi ;
1535 safePhi = (p.
x()*std::sin(ePhi) - p.
y()*std::cos(ePhi)) ;
1537 if (safePhi < safe) { safe = safePhi ; }
1539 if (safe < 0) { safe = 0 ; }
1567 G4long oldprc = os.precision(16);
1568 os <<
"-----------------------------------------------------------\n"
1569 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1570 <<
" ===================================================\n"
1571 <<
" Solid type: G4Torus\n"
1572 <<
" Parameters: \n"
1573 <<
" inner radius: " << fRmin/mm <<
" mm \n"
1574 <<
" outer radius: " << fRmax/mm <<
" mm \n"
1575 <<
" swept radius: " << fRtor/mm <<
" mm \n"
1576 <<
" starting phi: " << fSPhi/degree <<
" degrees \n"
1577 <<
" delta phi : " << fDPhi/degree <<
" degrees \n"
1578 <<
"-----------------------------------------------------------\n";
1579 os.precision(oldprc);
1592 G4double smax = twopi*fRtor*fDPhi*fRmax;
1593 G4double smin = twopi*fRtor*fDPhi*fRmin;
1594 G4double sphi = (fDPhi >= twopi) ? 0. : pi*(rrmax - rrmin);
1600 if (select < 2.*sphi)
1603 phi = fSPhi + fDPhi*(
G4double)(select < sphi);
1604 r = std::sqrt(rrmin + (rrmax - rrmin)*u);
1605 ds = fRtor + r*std::cos(v);
1610 phi = fSPhi + fDPhi*u;
1611 r = (select < 2.*sphi + smax) ? fRmax : fRmin;
1612 ds = fRtor + r*std::cos(v);
1613 for (
auto i = 0; i < 10; ++i)
1617 ds = fRtor + r*std::cos(v);
1620 return { ds*std::cos(phi), ds*std::sin(phi), r*std::sin(v) };
1632 fCubicVolume = fDPhi*CLHEP::pi*fRtor*(fRmax*fRmax-fRmin*fRmin);
1648 if(fDPhi < CLHEP::twopi)
G4TemplateAutoLock< G4Mutex > G4AutoLock
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4QuickRand(uint32_t seed=0)
#define G4MUTEX_INITIALIZER
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...
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool fRebuildPolyhedron
G4CSGSolid(const G4String &pName)
G4CSGSolid & operator=(const G4CSGSolid &rhs)
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4double GetAngularTolerance() const
G4int FindRoots(G4double *op, G4int degree, G4double *zeror, G4double *zeroi)
G4Torus & operator=(const G4Torus &rhs)
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep) override
G4double GetSinEndPhi() const
std::ostream & StreamInfo(std::ostream &os) const override
G4ThreeVector GetPointOnSurface() const override
G4VSolid * Clone() const override
void SetAllParameters(G4double pRmin, G4double pRmax, G4double pRtor, G4double pSPhi, G4double pDPhi)
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
EInside Inside(const G4ThreeVector &p) const override
G4GeometryType GetEntityType() const override
G4double GetSurfaceArea() override
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const override
G4double GetCubicVolume() override
G4Polyhedron * CreatePolyhedron() const override
G4Torus(const G4String &pName, G4double pRmin, G4double pRmax, G4double pRtor, G4double pSPhi, G4double pDPhi)
void DescribeYourselfTo(G4VGraphicsScene &scene) const override
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const override
G4double GetCosStartPhi() const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const override
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
G4double GetCosEndPhi() const
G4double GetSinStartPhi() const
virtual void AddSolid(const G4Box &)=0
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(const G4String &name)
G4VoxelLimits represents limitation/restrictions of space, where restrictions are only made perpendic...
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const