77 using namespace CLHEP;
121 std::ostringstream message;
122 message <<
"Invalid swept radius for Solid: " <<
GetName() <<
G4endl
123 <<
" pRtor = " << pRtor <<
", pRmax = " << pRmax;
130 if ( pRmin < pRmax - 1.e2*kCarTolerance && pRmin >= 0 )
132 if (pRmin >= 1.e2*kCarTolerance) { fRmin = pRmin ; }
133 else { fRmin = 0.0 ; }
138 std::ostringstream message;
139 message <<
"Invalid values of radii for Solid: " <<
GetName() <<
G4endl
140 <<
" pRmin = " << pRmin <<
", pRmax = " << pRmax;
147 fRminTolerance = (fRmin)
148 ? 0.5*std::max( kRadTolerance, fEpsilon*(fRtor-fRmin )) : 0;
149 fRmaxTolerance = 0.5*std::max( kRadTolerance, fEpsilon*(fRtor+fRmax) );
156 if (pDPhi > 0) { fDPhi = pDPhi ; }
159 std::ostringstream message;
160 message <<
"Invalid Z delta-Phi for Solid: " <<
GetName() <<
G4endl
161 <<
" pDPhi = " << pDPhi;
171 if (fSPhi < 0) { fSPhi =
twopi-std::fmod(std::fabs(fSPhi),
twopi) ; }
172 else { fSPhi = std::fmod(fSPhi,
twopi) ; }
183 :
G4CSGSolid(a), fRmin(0.), fRmax(0.), fRtor(0.), fSPhi(0.),
184 fDPhi(0.), fRminTolerance(0.), fRmaxTolerance(0. ),
185 kRadTolerance(0.), kAngTolerance(0.)
201 :
G4CSGSolid(rhs), fRmin(rhs.fRmin),fRmax(rhs.fRmax),
202 fRtor(rhs.fRtor),fSPhi(rhs.fSPhi),fDPhi(rhs.fDPhi),
203 fRminTolerance(rhs.fRminTolerance), fRmaxTolerance(rhs.fRmaxTolerance),
204 kRadTolerance(rhs.kRadTolerance), kAngTolerance(rhs.kAngTolerance)
216 if (
this == &rhs) {
return *
this; }
224 fRmin = rhs.fRmin; fRmax = rhs.fRmax;
225 fRtor = rhs.fRtor; fSPhi = rhs.fSPhi; fDPhi = rhs.fDPhi;
226 fRminTolerance = rhs.fRminTolerance; fRmaxTolerance = rhs.fRmaxTolerance;
227 kRadTolerance = rhs.kRadTolerance; kAngTolerance = rhs.kAngTolerance;
254 std::vector<G4double>& roots )
const
267 c[2] = 2*(pRad2 + 2*pDotV*pDotV - Rtor2 - r2 + 2*Rtor2*v.
z()*v.
z()) ;
268 c[3] = 4*(pDotV*(pRad2 - Rtor2 - r2) + 2*Rtor2*p.
z()*v.
z()) ;
269 c[4] = pRad2*pRad2 - 2*pRad2*(Rtor2+r2)
270 + 4*Rtor2*p.
z()*p.
z() + (Rtor2-r2)*(Rtor2-r2) ;
274 num = torusEq.
FindRoots( c, 4, srd, si );
276 for ( i = 0; i < num; i++ )
278 if( si[i] == 0. ) { roots.push_back(srd[i]) ; }
281 std::sort(roots.begin() , roots.end() ) ;
294 G4bool IsDistanceToIn )
const
300 static const G4double halfAngTolerance = 0.5*kAngTolerance;
305 std::vector<G4double> roots ;
306 std::vector<G4double> rootsrefined ;
307 TorusRootsJT(p,v,r,roots) ;
313 for (
size_t k = 0 ; k<roots.size() ; k++ )
317 if ( t < -halfCarTolerance ) { continue ; }
319 if ( t > bigdist && t<kInfinity )
322 TorusRootsJT(ptmp,v,r,rootsrefined) ;
323 if ( rootsrefined.size()==roots.size() )
325 t = t + rootsrefined[k] ;
331 G4double theta = std::atan2(ptmp.
y(),ptmp.
x());
335 if ( theta < - halfAngTolerance ) { theta +=
twopi; }
336 if ( (std::fabs(theta) < halfAngTolerance)
337 && (std::fabs(fSPhi + fDPhi -
twopi) < halfAngTolerance) )
342 if ((fSPhi <= -
pi )&&(theta>halfAngTolerance)) { theta = theta-
twopi; }
347 if ( (theta - fSPhi >= - halfAngTolerance)
348 && (theta - (fSPhi + fDPhi) <= halfAngTolerance) )
353 if ( IsDistanceToIn ==
true )
355 if (std::fabs(t) < halfCarTolerance )
362 p.
y()*(1-fRtor/std::sqrt(p.
x()*p.
x()
368 if ( r ==
GetRmin() ) { scal = -scal ; }
369 if ( scal < 0 ) {
return 0.0 ; }
376 if ( IsDistanceToIn ==
false )
378 if (std::fabs(t) < halfCarTolerance )
384 p.
y()*(1-fRtor/std::sqrt(p.
x()*p.
x()
390 if ( r ==
GetRmin() ) { scal = -scal ; }
391 if ( scal > 0 ) {
return 0.0 ; }
397 if( t > halfCarTolerance )
428 G4double RTorus,delta,diff1,diff2,maxDiff,newMin,newMax;
432 xMin = xoffset - fRmax - fRtor ;
433 xMax = xoffset + fRmax + fRtor ;
453 yMin = yoffset - fRmax - fRtor ;
454 yMax = yoffset + fRmax + fRtor ;
476 zMin = zoffset - fRmax ;
477 zMax = zoffset + fRmax ;
506 if ( yoff1 >= 0 && yoff2 >= 0 )
520 delta = RTorus*RTorus - yoff1*yoff1;
521 diff1 = (delta>0.) ? std::sqrt(delta) : 0.;
522 delta = RTorus*RTorus - yoff2*yoff2;
523 diff2 = (delta>0.) ? std::sqrt(delta) : 0.;
524 maxDiff = (diff1 > diff2) ? diff1:diff2 ;
525 newMin = xoffset - maxDiff ;
526 newMax = xoffset + maxDiff ;
527 pMin = (newMin < xMin) ? xMin : newMin ;
528 pMax = (newMax > xMax) ? xMax : newMax ;
533 xoff1 = xoffset - xMin ;
534 xoff2 = xMax - xoffset ;
535 if (xoff1 >= 0 && xoff2 >= 0 )
548 delta = RTorus*RTorus - xoff1*xoff1;
549 diff1 = (delta>0.) ? std::sqrt(delta) : 0.;
550 delta = RTorus*RTorus - xoff2*xoff2;
551 diff2 = (delta>0.) ? std::sqrt(delta) : 0.;
552 maxDiff = (diff1 > diff2) ? diff1 : diff2 ;
553 newMin = yoffset - maxDiff ;
554 newMax = yoffset + maxDiff ;
555 pMin = (newMin < yMin) ? yMin : newMin ;
556 pMax = (newMax > yMax) ? yMax : newMax ;
575 G4int i, noEntries, noBetweenSections4 ;
576 G4bool existsAfterClip = false ;
581 G4int noPolygonVertices ;
582 vertices = CreateRotatedVertices(pTransform,noPolygonVertices) ;
587 noEntries = vertices->size() ;
588 noBetweenSections4 = noEntries - noPolygonVertices ;
590 for (i=0;i<noEntries;i+=noPolygonVertices)
594 for (i=0;i<noBetweenSections4;i+=noPolygonVertices)
598 if (pMin!=kInfinity||pMax!=-kInfinity)
600 existsAfterClip = true ;
618 existsAfterClip = true ;
624 return existsAfterClip;
634 G4double r2, pt2, pPhi, tolRMin, tolRMax ;
637 static const G4double halfAngTolerance = 0.5*kAngTolerance;
640 r2 = p.
x()*p.
x() + p.
y()*p.
y() ;
641 pt2 = r2 + p.
z()*p.
z() + fRtor*fRtor - 2*fRtor*std::sqrt(r2) ;
643 if (fRmin) tolRMin = fRmin + fRminTolerance ;
646 tolRMax = fRmax - fRmaxTolerance;
648 if (pt2 >= tolRMin*tolRMin && pt2 <= tolRMax*tolRMax )
650 if ( fDPhi ==
twopi || pt2 == 0 )
659 pPhi = std::atan2(p.
y(),p.
x()) ;
661 if ( pPhi < -halfAngTolerance ) { pPhi +=
twopi ; }
664 if ( (std::fabs(pPhi) < halfAngTolerance)
665 && (std::fabs(fSPhi + fDPhi -
twopi) < halfAngTolerance) )
669 if ( (pPhi >= fSPhi + halfAngTolerance)
670 && (pPhi <= fSPhi + fDPhi - halfAngTolerance) )
674 else if ( (pPhi >= fSPhi - halfAngTolerance)
675 && (pPhi <= fSPhi + fDPhi + halfAngTolerance) )
682 if ( (pPhi <= fSPhi +
twopi - halfAngTolerance)
683 && (pPhi >= fSPhi + fDPhi + halfAngTolerance) ) {;}
693 tolRMin = fRmin - fRminTolerance ;
694 tolRMax = fRmax + fRmaxTolerance ;
696 if (tolRMin < 0 ) { tolRMin = 0 ; }
698 if ( (pt2 >= tolRMin*tolRMin) && (pt2 <= tolRMax*tolRMax) )
700 if ( (fDPhi ==
twopi) || (pt2 == 0) )
706 pPhi = std::atan2(p.
y(),p.
x()) ;
708 if ( pPhi < -halfAngTolerance ) { pPhi +=
twopi ; }
711 if ( (std::fabs(pPhi) < halfAngTolerance)
712 && (std::fabs(fSPhi + fDPhi -
twopi) < halfAngTolerance) )
716 if ( (pPhi >= fSPhi - halfAngTolerance)
717 && (pPhi <= fSPhi + fDPhi + halfAngTolerance) )
724 if ( (pPhi <= fSPhi +
twopi - halfAngTolerance)
725 && (pPhi >= fSPhi + fDPhi + halfAngTolerance) ) {;}
745 G4int noSurfaces = 0;
748 G4double distSPhi = kInfinity, distEPhi = kInfinity;
753 1.0
e-8*(fRtor+fRmax));
754 const G4double dAngle = 10.0*kAngTolerance;
759 rho2 = p.
x()*p.
x() + p.
y()*p.
y();
760 rho = std::sqrt(rho2);
761 pt2 = rho2+p.
z()*p.
z() +fRtor * (fRtor-2*rho);
762 pt2 = std::max(pt2, 0.0);
763 pt = std::sqrt(pt2) ;
765 G4double distRMax = std::fabs(pt - fRmax);
766 if(fRmin) distRMin = std::fabs(pt - fRmin);
768 if( rho > delta && pt != 0.0 )
770 G4double redFactor= (rho-fRtor)/rho;
781 pPhi = std::atan2(p.
y(),p.
x());
783 if(pPhi < fSPhi-delta) { pPhi +=
twopi; }
784 else if(pPhi > fSPhi+fDPhi+delta) { pPhi -=
twopi; }
786 distSPhi = std::fabs( pPhi - fSPhi );
787 distEPhi = std::fabs(pPhi-fSPhi-fDPhi);
790 nPe =
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);
792 if( distRMax <= delta )
797 else if( fRmin && (distRMin <= delta) )
806 if( (fDPhi <
twopi) && (fRmin-delta <= pt) && (pt <= (fRmax+delta)) )
808 if (distSPhi <= dAngle)
813 if (distEPhi <= dAngle)
819 if ( noSurfaces == 0 )
829 ed <<
" ERROR> Surface Normal was called for Torus,"
830 <<
" with point not on surface." <<
G4endl;
834 ed <<
" ERROR> Surface Normal has not found a surface, "
835 <<
" despite the point being on the surface. " <<
G4endl;
846 ed <<
" Coordinates of point : " << p <<
G4endl;
847 ed <<
" Parameters of solid : " << G4endl << *
this <<
G4endl;
851 G4Exception(
"G4Torus::SurfaceNormal(p)",
"GeomSolids1002",
853 "Failing to find normal, even though point is on surface!" );
857 static const char* NameInside[3]= {
"Inside",
"Surface",
"Outside" };
858 ed <<
" The point is " << NameInside[inIt] <<
" the solid. "<<
G4endl;
859 G4Exception(
"G4Torus::SurfaceNormal(p)",
"GeomSolids1002",
863 norm = ApproxSurfaceNormal(p);
865 else if ( noSurfaces == 1 ) { norm = sumnorm; }
866 else { norm = sumnorm.
unit(); }
883 G4double distRMin,distRMax,distSPhi,distEPhi,distMin;
885 rho2 = p.
x()*p.
x() + p.
y()*p.
y();
886 rho = std::sqrt(rho2) ;
887 pt2 = std::fabs(rho2+p.
z()*p.
z() +fRtor*fRtor - 2*fRtor*rho) ;
888 pt = std::sqrt(pt2) ;
891 G4cout <<
" G4Torus::ApproximateSurfaceNormal called for point " << p
895 distRMax = std::fabs(pt - fRmax) ;
899 distRMin = std::fabs(pt - fRmin) ;
901 if (distRMin < distRMax)
917 if ( (fDPhi <
twopi) && rho )
919 phi = std::atan2(p.
y(),p.
x()) ;
921 if (phi < 0) { phi +=
twopi ; }
923 if (fSPhi < 0 ) { distSPhi = std::fabs(phi-(fSPhi+
twopi))*rho ; }
924 else { distSPhi = std::fabs(phi-fSPhi)*rho ; }
926 distEPhi = std::fabs(phi - fSPhi - fDPhi)*rho ;
928 if (distSPhi < distEPhi)
930 if (distSPhi<distMin) side = kNSPhi ;
934 if (distEPhi < distMin) { side = kNEPhi ; }
941 -p.
y()*(1-fRtor/rho)/pt,
946 p.
y()*(1-fRtor/rho)/pt,
953 norm =
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0) ;
959 "Undefined side for valid surface normal to solid.");
991 G4double snxt=kInfinity, sphi=kInfinity;
1000 G4double cPhi,sinCPhi=0.,cosCPhi=0.;
1015 if ( fDPhi <
twopi )
1019 cPhi = fSPhi + hDPhi ;
1020 sinCPhi = std::sin(cPhi) ;
1021 cosCPhi = std::cos(cPhi) ;
1028 if (fRmin > fRminTolerance)
1030 tolORMin2 = (fRmin - fRminTolerance)*(fRmin - fRminTolerance) ;
1036 tolORMax2 = (fRmax + fRmaxTolerance)*(fRmax + fRmaxTolerance) ;
1042 snxt = SolveNumericJT(p,v,fRmax,
true);
1046 sd[0] = SolveNumericJT(p,v,fRmin,
true);
1047 if ( sd[0] < snxt ) { snxt = sd[0] ; }
1062 sinSPhi = std::sin(fSPhi) ;
1063 cosSPhi = std::cos(fSPhi) ;
1064 Comp = v.
x()*sinSPhi - v.
y()*cosSPhi ;
1068 Dist = (p.
y()*cosSPhi - p.
x()*sinSPhi) ;
1070 if (Dist < halfCarTolerance)
1075 if ( sphi < 0 ) { sphi = 0 ; }
1077 xi = p.
x() + sphi*v.
x() ;
1078 yi = p.
y() + sphi*v.
y() ;
1079 zi = p.
z() + sphi*v.
z() ;
1080 rhoi2 = xi*xi + yi*yi ;
1081 it2 = std::fabs(rhoi2 + zi*zi + Rtor2 - 2*fRtor*std::sqrt(rhoi2)) ;
1083 if ( it2 >= tolORMin2 && it2 <= tolORMax2 )
1088 if ((yi*cosCPhi-xi*sinCPhi)<=0) { snxt=sphi; }
1094 sinEPhi=std::sin(ePhi);
1095 cosEPhi=std::cos(ePhi);
1096 Comp=-(v.
x()*sinEPhi-v.
y()*cosEPhi);
1100 Dist = -(p.
y()*cosEPhi - p.
x()*sinEPhi) ;
1102 if (Dist < halfCarTolerance )
1108 if (sphi < 0 ) { sphi = 0 ; }
1110 xi = p.
x() + sphi*v.
x() ;
1111 yi = p.
y() + sphi*v.
y() ;
1112 zi = p.
z() + sphi*v.
z() ;
1113 rhoi2 = xi*xi + yi*yi ;
1114 it2 = std::fabs(rhoi2 + zi*zi + Rtor2 - 2*fRtor*std::sqrt(rhoi2)) ;
1116 if (it2 >= tolORMin2 && it2 <= tolORMax2)
1121 if ((yi*cosCPhi-xi*sinCPhi)>=0) { snxt=sphi; }
1127 if(snxt < halfCarTolerance) { snxt = 0.0 ; }
1142 G4double phiC, cosPhiC, sinPhiC, safePhi, ePhi, cosPsi ;
1145 rho2 = p.
x()*p.
x() + p.
y()*p.
y() ;
1146 rho = std::sqrt(rho2) ;
1147 pt2 = std::fabs(rho2 + p.
z()*p.
z() + fRtor*fRtor - 2*fRtor*rho) ;
1148 pt = std::sqrt(pt2) ;
1150 safe1 = fRmin -
pt ;
1151 safe2 = pt - fRmax ;
1153 if (safe1 > safe2) { safe = safe1; }
1154 else { safe = safe2; }
1156 if ( fDPhi <
twopi && rho )
1158 phiC = fSPhi + fDPhi*0.5 ;
1159 cosPhiC = std::cos(phiC) ;
1160 sinPhiC = std::sin(phiC) ;
1161 cosPsi = (p.
x()*cosPhiC + p.
y()*sinPhiC)/rho ;
1163 if (cosPsi < std::cos(fDPhi*0.5) )
1165 if ((p.
y()*cosPhiC - p.
x()*sinPhiC) <= 0 )
1167 safePhi = std::fabs(p.
x()*std::sin(fSPhi) - p.
y()*std::cos(fSPhi)) ;
1171 ePhi = fSPhi + fDPhi ;
1172 safePhi = std::fabs(p.
x()*std::sin(ePhi) - p.
y()*std::cos(ePhi)) ;
1174 if (safePhi > safe) { safe = safePhi ; }
1177 if (safe < 0 ) { safe = 0 ; }
1193 ESide side = kNull, sidephi = kNull ;
1194 G4double snxt = kInfinity, sphi, sd[4] ;
1197 static const G4double halfAngTolerance = 0.5*kAngTolerance;
1201 G4double sinSPhi, cosSPhi, ePhi, sinEPhi, cosEPhi;
1203 G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, zi, vphi ;
1218 G4double pt2 = rho2 + p.
z()*p.
z() + fRtor * (fRtor - 2.0*rho);
1223 pt2= std::fabs( pt2 );
1230 G4double tolRMax = fRmax - fRmaxTolerance ;
1232 G4double vDotNmax = pDotV - fRtor*(v.
x()*p.
x() + v.
y()*p.
y())/rho ;
1233 G4double pDotxyNmax = (1 - fRtor/rho) ;
1235 if( (pt2 > tolRMax*tolRMax) && (vDotNmax >= 0) )
1241 if ( calcNorm && (pDotxyNmax >= -2.*fRmaxTolerance) )
1244 p.
y()*(1 - fRtor/rho)/pt,
1252 snxt = SolveNumericJT(p,v,fRmax,
false);
1259 G4double tolRMin = fRmin + fRminTolerance ;
1261 if ( (pt2 < tolRMin*tolRMin) && (vDotNmax < 0) )
1263 if (calcNorm) { *validNorm = false ; }
1267 sd[0] = SolveNumericJT(p,v,fRmin,
false);
1280 snxt = SolveNumericJT(p,v,fRmax,
false);
1285 sd[0] = SolveNumericJT(p,v,fRmin,
false);
1293 if ( calcNorm && (snxt == 0.0) )
1295 *validNorm = false ;
1303 sinSPhi = std::sin(fSPhi) ;
1304 cosSPhi = std::cos(fSPhi) ;
1305 ePhi = fSPhi + fDPhi ;
1306 sinEPhi = std::sin(ePhi) ;
1307 cosEPhi = std::cos(ePhi) ;
1308 cPhi = fSPhi + fDPhi*0.5 ;
1309 sinCPhi = std::sin(cPhi) ;
1310 cosCPhi = std::cos(cPhi) ;
1315 vphi = std::atan2(v.
y(),v.
x()) ;
1317 if ( vphi < fSPhi - halfAngTolerance ) { vphi +=
twopi; }
1318 else if ( vphi > ePhi + halfAngTolerance ) { vphi -=
twopi; }
1320 if ( p.
x() || p.
y() )
1322 pDistS = p.
x()*sinSPhi - p.
y()*cosSPhi ;
1323 pDistE = -p.
x()*sinEPhi + p.
y()*cosEPhi ;
1327 compS = -sinSPhi*v.
x() + cosSPhi*v.
y() ;
1328 compE = sinEPhi*v.
x() - cosEPhi*v.
y() ;
1331 if( ( (fDPhi <=
pi) && ( (pDistS <= halfCarTolerance)
1332 && (pDistE <= halfCarTolerance) ) )
1333 || ( (fDPhi >
pi) && !((pDistS > halfCarTolerance)
1334 && (pDistE > halfCarTolerance) ) ) )
1340 sphi = pDistS/compS ;
1342 if (sphi >= -halfCarTolerance)
1344 xi = p.
x() + sphi*v.
x() ;
1345 yi = p.
y() + sphi*v.
y() ;
1354 if ( ((fSPhi-halfAngTolerance)<=vphi)
1355 && ((ePhi+halfAngTolerance)>=vphi) )
1360 else if ( yi*cosCPhi-xi*sinCPhi >=0 )
1381 sphi2 = pDistE/compE ;
1387 xi = p.
x() + sphi2*v.
x() ;
1388 yi = p.
y() + sphi2*v.
y() ;
1395 if( !( (fSPhi-halfAngTolerance <= vphi)
1396 && (ePhi+halfAngTolerance >= vphi) ) )
1404 if ( (yi*cosCPhi-xi*sinCPhi) >= 0)
1426 vphi = std::atan2(v.
y(),v.
x());
1428 if ( ( fSPhi-halfAngTolerance <= vphi ) &&
1429 ( vphi <= ( ePhi+halfAngTolerance ) ) )
1449 G4double rhoi2,rhoi,it2,it,iDotxyNmax ;
1458 xi = p.
x() + snxt*v.
x() ;
1459 yi =p.
y() + snxt*v.
y() ;
1460 zi = p.
z() + snxt*v.
z() ;
1461 rhoi2 = xi*xi + yi*yi ;
1462 rhoi = std::sqrt(rhoi2) ;
1463 it2 = std::fabs(rhoi2 + zi*zi + fRtor*fRtor - 2*fRtor*rhoi) ;
1464 it = std::sqrt(it2) ;
1465 iDotxyNmax = (1-fRtor/rhoi) ;
1466 if(iDotxyNmax >= -2.*fRmaxTolerance)
1469 yi*(1-fRtor/rhoi)/it,
1475 *validNorm = false ;
1480 *validNorm = false ;
1491 *validNorm = false ;
1498 *n=
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);
1503 *validNorm = false ;
1513 std::ostringstream message;
1514 G4int oldprc = message.precision(16);
1515 message <<
"Undefined side for valid surface normal to solid."
1517 <<
"Position:" << G4endl << G4endl
1518 <<
"p.x() = " << p.
x()/
mm <<
" mm" << G4endl
1519 <<
"p.y() = " << p.
y()/
mm <<
" mm" << G4endl
1520 <<
"p.z() = " << p.
z()/
mm <<
" mm" << G4endl << G4endl
1521 <<
"Direction:" << G4endl << G4endl
1522 <<
"v.x() = " << v.
x() << G4endl
1523 <<
"v.y() = " << v.
y() << G4endl
1524 <<
"v.z() = " << v.
z() << G4endl << G4endl
1525 <<
"Proposed distance :" << G4endl << G4endl
1526 <<
"snxt = " << snxt/
mm <<
" mm" <<
G4endl;
1527 message.precision(oldprc);
1533 if ( snxt<halfCarTolerance ) { snxt=0 ; }
1546 G4double safePhi,phiC,cosPhiC,sinPhiC,ePhi;
1547 rho2 = p.
x()*p.
x() + p.
y()*p.
y() ;
1548 rho = std::sqrt(rho2) ;
1549 pt2 = std::fabs(rho2 + p.
z()*p.
z() + fRtor*fRtor - 2*fRtor*rho) ;
1550 pt = std::sqrt(pt2) ;
1562 G4cout.precision(oldprc);
1563 G4Exception(
"G4Torus::DistanceToOut(p)",
"GeomSolids1002",
1570 safeR1 = pt - fRmin ;
1571 safeR2 = fRmax -
pt ;
1573 if (safeR1 < safeR2) { safe = safeR1 ; }
1574 else { safe = safeR2 ; }
1585 phiC = fSPhi + fDPhi*0.5 ;
1586 cosPhiC = std::cos(phiC) ;
1587 sinPhiC = std::sin(phiC) ;
1589 if ((p.
y()*cosPhiC-p.
x()*sinPhiC)<=0)
1591 safePhi = -(p.
x()*std::sin(fSPhi) - p.
y()*std::cos(fSPhi)) ;
1595 ePhi = fSPhi + fDPhi ;
1596 safePhi = (p.
x()*std::sin(ePhi) - p.
y()*std::cos(ePhi)) ;
1598 if (safePhi < safe) { safe = safePhi ; }
1600 if (safe < 0) { safe = 0 ; }
1617 G4int& noPolygonVertices )
const
1621 G4double meshAngle,meshRMax,crossAngle,cosCrossAngle,sinCrossAngle,sAngle;
1623 G4int crossSection,noCrossSections;
1637 meshAngle = fDPhi/(noCrossSections - 1) ;
1638 meshRMax = (fRtor + fRmax)/std::cos(meshAngle*0.5) ;
1643 if ( (fDPhi ==
twopi) && (fSPhi == 0) )
1645 sAngle = -meshAngle*0.5 ;
1655 vertices->reserve(noCrossSections*4) ;
1656 for (crossSection=0;crossSection<noCrossSections;crossSection++)
1660 crossAngle=sAngle+crossSection*meshAngle;
1661 cosCrossAngle=std::cos(crossAngle);
1662 sinCrossAngle=std::sin(crossAngle);
1664 rMaxX=meshRMax*cosCrossAngle;
1665 rMaxY=meshRMax*sinCrossAngle;
1666 rMinX=(fRtor-fRmax)*cosCrossAngle;
1667 rMinY=(fRtor-fRmax)*sinCrossAngle;
1678 noPolygonVertices = 4 ;
1685 "Error in allocation of vertices. Out of memory !");
1714 G4int oldprc = os.precision(16);
1715 os <<
"-----------------------------------------------------------\n"
1716 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1717 <<
" ===================================================\n"
1718 <<
" Solid type: G4Torus\n"
1719 <<
" Parameters: \n"
1720 <<
" inner radius: " << fRmin/
mm <<
" mm \n"
1721 <<
" outer radius: " << fRmax/
mm <<
" mm \n"
1722 <<
" swept radius: " << fRtor/
mm <<
" mm \n"
1723 <<
" starting phi: " << fSPhi/
degree <<
" degrees \n"
1724 <<
" delta phi : " << fDPhi/
degree <<
" degrees \n"
1725 <<
"-----------------------------------------------------------\n";
1726 os.precision(oldprc);
1737 G4double cosu, sinu,cosv, sinv, aOut, aIn, aSide, chose, phi, theta, rRand;
1739 phi = RandFlat::shoot(fSPhi,fSPhi+fDPhi);
1740 theta = RandFlat::shoot(0.,
twopi);
1742 cosu = std::cos(phi); sinu = std::sin(phi);
1743 cosv = std::cos(theta); sinv = std::sin(theta);
1747 aOut = (fDPhi)*
twopi*fRtor*fRmax;
1748 aIn = (fDPhi)*
twopi*fRtor*fRmin;
1749 aSide =
pi*(fRmax*fRmax-fRmin*fRmin);
1751 if ((fSPhi == 0) && (fDPhi ==
twopi)){ aSide = 0; }
1752 chose = RandFlat::shoot(0.,aOut + aIn + 2.*aSide);
1757 (fRtor+fRmax*cosv)*sinu, fRmax*sinv);
1759 else if( (chose >= aOut) && (chose < aOut + aIn) )
1762 (fRtor+fRmin*cosv)*sinu, fRmin*sinv);
1764 else if( (chose >= aOut + aIn) && (chose < aOut + aIn + aSide) )
1768 (fRtor+rRand*cosv)*std::sin(fSPhi), rRand*sinv);
1773 return G4ThreeVector ((fRtor+rRand*cosv)*std::cos(fSPhi+fDPhi),
1774 (fRtor+rRand*cosv)*std::sin(fSPhi+fDPhi),
1817 fSPhi, fSPhi + fDPhi);