73 using namespace CLHEP;
112 halfAngTolerance = 0.5*kAngTolerance;
120 std::ostringstream message;
121 message <<
"Invalid swept radius for Solid: " <<
GetName() <<
G4endl
122 <<
" pRtor = " << pRtor <<
", pRmax = " << pRmax;
129 if ( pRmin < pRmax - 1.e2*kCarTolerance && pRmin >= 0 )
131 if (pRmin >= 1.e2*kCarTolerance) { fRmin = pRmin ; }
132 else { fRmin = 0.0 ; }
137 std::ostringstream message;
138 message <<
"Invalid values of radii for Solid: " <<
GetName() <<
G4endl
139 <<
" pRmin = " << pRmin <<
", pRmax = " << pRmax;
146 fRminTolerance = (fRmin)
147 ? 0.5*
std::max( kRadTolerance, fEpsilon*(fRtor-fRmin )) : 0;
148 fRmaxTolerance = 0.5*
std::max( kRadTolerance, fEpsilon*(fRtor+fRmax) );
155 if (pDPhi > 0) { fDPhi = pDPhi ; }
158 std::ostringstream message;
159 message <<
"Invalid Z delta-Phi for Solid: " <<
GetName() <<
G4endl
160 <<
" pDPhi = " << pDPhi;
170 if (fSPhi < 0) { fSPhi =
twopi-std::fmod(std::fabs(fSPhi),
twopi) ; }
171 else { fSPhi = std::fmod(fSPhi,
twopi) ; }
182 :
G4CSGSolid(a), fRmin(0.), fRmax(0.), fRtor(0.), fSPhi(0.),
183 fDPhi(0.), fRminTolerance(0.), fRmaxTolerance(0. ),
184 kRadTolerance(0.), kAngTolerance(0.),
185 halfCarTolerance(0.), halfAngTolerance(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),
205 halfCarTolerance(rhs.halfCarTolerance),
206 halfAngTolerance(rhs.halfAngTolerance)
218 if (
this == &rhs) {
return *
this; }
226 fRmin = rhs.fRmin; fRmax = rhs.fRmax;
227 fRtor = rhs.fRtor; fSPhi = rhs.fSPhi; fDPhi = rhs.fDPhi;
228 fRminTolerance = rhs.fRminTolerance; fRmaxTolerance = rhs.fRmaxTolerance;
229 kRadTolerance = rhs.kRadTolerance; kAngTolerance = rhs.kAngTolerance;
230 halfCarTolerance = rhs.halfCarTolerance;
231 halfAngTolerance = rhs.halfAngTolerance;
258 std::vector<G4double>& roots )
const
271 c[2] = 2*(pRad2 + 2*pDotV*pDotV - Rtor2 - r2 + 2*Rtor2*v.
z()*v.
z()) ;
272 c[3] = 4*(pDotV*(pRad2 - Rtor2 - r2) + 2*Rtor2*p.
z()*v.
z()) ;
273 c[4] = pRad2*pRad2 - 2*pRad2*(Rtor2+r2)
274 + 4*Rtor2*p.
z()*p.
z() + (Rtor2-r2)*(Rtor2-r2) ;
278 num = torusEq.
FindRoots( c, 4, srd, si );
280 for ( i = 0; i < num; i++ )
282 if( si[i] == 0. ) { roots.push_back(srd[i]) ; }
285 std::sort(roots.begin() , roots.end() ) ;
298 G4bool IsDistanceToIn )
const
307 std::vector<G4double> roots ;
308 std::vector<G4double> rootsrefined ;
309 TorusRootsJT(p,v,r,roots) ;
315 for (
size_t k = 0 ; k<roots.size() ; k++ )
319 if ( t < -halfCarTolerance ) { continue ; }
321 if ( t > bigdist && t<kInfinity )
324 TorusRootsJT(ptmp,v,r,rootsrefined) ;
325 if ( rootsrefined.size()==roots.size() )
327 t = t + rootsrefined[k] ;
333 G4double theta = std::atan2(ptmp.
y(),ptmp.
x());
337 if ( theta < - halfAngTolerance ) { theta +=
twopi; }
338 if ( (std::fabs(theta) < halfAngTolerance)
339 && (std::fabs(fSPhi + fDPhi -
twopi) < halfAngTolerance) )
344 if ((fSPhi <= -
pi )&&(theta>halfAngTolerance)) { theta = theta-
twopi; }
349 if ( (theta - fSPhi >= - halfAngTolerance)
350 && (theta - (fSPhi + fDPhi) <= halfAngTolerance) )
355 if ( IsDistanceToIn ==
true )
357 if (std::fabs(t) < halfCarTolerance )
364 p.
y()*(1-fRtor/std::sqrt(p.
x()*p.
x()
370 if ( r ==
GetRmin() ) { scal = -scal ; }
371 if ( scal < 0 ) {
return 0.0 ; }
378 if ( IsDistanceToIn ==
false )
380 if (std::fabs(t) < halfCarTolerance )
386 p.
y()*(1-fRtor/std::sqrt(p.
x()*p.
x()
392 if ( r ==
GetRmin() ) { scal = -scal ; }
393 if ( scal > 0 ) {
return 0.0 ; }
399 if( t > halfCarTolerance )
430 G4double RTorus,delta,diff1,diff2,maxDiff,newMin,newMax;
434 xMin = xoffset - fRmax - fRtor ;
435 xMax = xoffset + fRmax + fRtor ;
455 yMin = yoffset - fRmax - fRtor ;
456 yMax = yoffset + fRmax + fRtor ;
478 zMin = zoffset - fRmax ;
479 zMax = zoffset + fRmax ;
508 if ( yoff1 >= 0 && yoff2 >= 0 )
522 delta = RTorus*RTorus - yoff1*yoff1;
523 diff1 = (delta>0.) ? std::sqrt(delta) : 0.;
524 delta = RTorus*RTorus - yoff2*yoff2;
525 diff2 = (delta>0.) ? std::sqrt(delta) : 0.;
526 maxDiff = (diff1 > diff2) ? diff1:diff2 ;
527 newMin = xoffset - maxDiff ;
528 newMax = xoffset + maxDiff ;
529 pMin = (newMin < xMin) ? xMin : newMin ;
530 pMax = (newMax > xMax) ? xMax : newMax ;
535 xoff1 = xoffset - xMin ;
536 xoff2 = xMax - xoffset ;
537 if (xoff1 >= 0 && xoff2 >= 0 )
550 delta = RTorus*RTorus - xoff1*xoff1;
551 diff1 = (delta>0.) ? std::sqrt(delta) : 0.;
552 delta = RTorus*RTorus - xoff2*xoff2;
553 diff2 = (delta>0.) ? std::sqrt(delta) : 0.;
554 maxDiff = (diff1 > diff2) ? diff1 : diff2 ;
555 newMin = yoffset - maxDiff ;
556 newMax = yoffset + maxDiff ;
557 pMin = (newMin < yMin) ? yMin : newMin ;
558 pMax = (newMax > yMax) ? yMax : newMax ;
577 G4int i, noEntries, noBetweenSections4 ;
578 G4bool existsAfterClip = false ;
583 G4int noPolygonVertices ;
584 vertices = CreateRotatedVertices(pTransform,noPolygonVertices) ;
589 noEntries = vertices->size() ;
590 noBetweenSections4 = noEntries - noPolygonVertices ;
592 for (i=0;i<noEntries;i+=noPolygonVertices)
596 for (i=0;i<noBetweenSections4;i+=noPolygonVertices)
600 if (pMin!=kInfinity||pMax!=-kInfinity)
602 existsAfterClip = true ;
620 existsAfterClip = true ;
626 return existsAfterClip;
636 G4double r2, pt2, pPhi, tolRMin, tolRMax ;
642 r2 = p.
x()*p.
x() + p.
y()*p.
y() ;
643 pt2 = r2 + p.
z()*p.
z() + fRtor*fRtor - 2*fRtor*std::sqrt(r2) ;
645 if (fRmin) tolRMin = fRmin + fRminTolerance ;
648 tolRMax = fRmax - fRmaxTolerance;
650 if (pt2 >= tolRMin*tolRMin && pt2 <= tolRMax*tolRMax )
652 if ( fDPhi ==
twopi || pt2 == 0 )
661 pPhi = std::atan2(p.
y(),p.
x()) ;
663 if ( pPhi < -halfAngTolerance ) { pPhi +=
twopi ; }
666 if ( (std::fabs(pPhi) < halfAngTolerance)
667 && (std::fabs(fSPhi + fDPhi -
twopi) < halfAngTolerance) )
671 if ( (pPhi >= fSPhi + halfAngTolerance)
672 && (pPhi <= fSPhi + fDPhi - halfAngTolerance) )
676 else if ( (pPhi >= fSPhi - halfAngTolerance)
677 && (pPhi <= fSPhi + fDPhi + halfAngTolerance) )
684 if ( (pPhi <= fSPhi +
twopi - halfAngTolerance)
685 && (pPhi >= fSPhi + fDPhi + halfAngTolerance) ) {;}
695 tolRMin = fRmin - fRminTolerance ;
696 tolRMax = fRmax + fRmaxTolerance ;
698 if (tolRMin < 0 ) { tolRMin = 0 ; }
700 if ( (pt2 >= tolRMin*tolRMin) && (pt2 <= tolRMax*tolRMax) )
702 if ( (fDPhi ==
twopi) || (pt2 == 0) )
708 pPhi = std::atan2(p.
y(),p.
x()) ;
710 if ( pPhi < -halfAngTolerance ) { pPhi +=
twopi ; }
713 if ( (std::fabs(pPhi) < halfAngTolerance)
714 && (std::fabs(fSPhi + fDPhi -
twopi) < halfAngTolerance) )
718 if ( (pPhi >= fSPhi - halfAngTolerance)
719 && (pPhi <= fSPhi + fDPhi + halfAngTolerance) )
726 if ( (pPhi <= fSPhi +
twopi - halfAngTolerance)
727 && (pPhi >= fSPhi + fDPhi + halfAngTolerance) ) {;}
747 G4int noSurfaces = 0;
750 G4double distSPhi = kInfinity, distEPhi = kInfinity;
755 1.0e-8*(fRtor+fRmax));
756 const G4double dAngle = 10.0*kAngTolerance;
761 rho2 = p.
x()*p.
x() + p.
y()*p.
y();
762 rho = std::sqrt(rho2);
763 pt2 = rho2+p.
z()*p.
z() +fRtor * (fRtor-2*rho);
765 pt = std::sqrt(pt2) ;
767 G4double distRMax = std::fabs(pt - fRmax);
768 if(fRmin) distRMin = std::fabs(pt - fRmin);
770 if( rho > delta && pt != 0.0 )
772 G4double redFactor= (rho-fRtor)/rho;
783 pPhi = std::atan2(p.
y(),p.
x());
785 if(pPhi < fSPhi-delta) { pPhi +=
twopi; }
786 else if(pPhi > fSPhi+fDPhi+delta) { pPhi -=
twopi; }
788 distSPhi = std::fabs( pPhi - fSPhi );
789 distEPhi = std::fabs(pPhi-fSPhi-fDPhi);
792 nPe =
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);
794 if( distRMax <= delta )
799 else if( fRmin && (distRMin <= delta) )
808 if( (fDPhi <
twopi) && (fRmin-delta <= pt) && (pt <= (fRmax+delta)) )
810 if (distSPhi <= dAngle)
815 if (distEPhi <= dAngle)
821 if ( noSurfaces == 0 )
831 ed <<
" ERROR> Surface Normal was called for Torus,"
832 <<
" with point not on surface." <<
G4endl;
836 ed <<
" ERROR> Surface Normal has not found a surface, "
837 <<
" despite the point being on the surface. " <<
G4endl;
848 ed <<
" Coordinates of point : " << p <<
G4endl;
849 ed <<
" Parameters of solid : " << G4endl << *
this <<
G4endl;
853 G4Exception(
"G4Torus::SurfaceNormal(p)",
"GeomSolids1002",
855 "Failing to find normal, even though point is on surface!" );
859 static const char* NameInside[3]= {
"Inside",
"Surface",
"Outside" };
860 ed <<
" The point is " << NameInside[inIt] <<
" the solid. "<<
G4endl;
861 G4Exception(
"G4Torus::SurfaceNormal(p)",
"GeomSolids1002",
865 norm = ApproxSurfaceNormal(p);
867 else if ( noSurfaces == 1 ) { norm = sumnorm; }
868 else { norm = sumnorm.
unit(); }
885 G4double distRMin,distRMax,distSPhi,distEPhi,distMin;
887 rho2 = p.
x()*p.
x() + p.
y()*p.
y();
888 rho = std::sqrt(rho2) ;
889 pt2 = std::fabs(rho2+p.
z()*p.
z() +fRtor*fRtor - 2*fRtor*rho) ;
890 pt = std::sqrt(pt2) ;
893 G4cout <<
" G4Torus::ApproximateSurfaceNormal called for point " << p
897 distRMax = std::fabs(pt - fRmax) ;
901 distRMin = std::fabs(pt - fRmin) ;
903 if (distRMin < distRMax)
919 if ( (fDPhi <
twopi) && rho )
921 phi = std::atan2(p.
y(),p.
x()) ;
923 if (phi < 0) { phi +=
twopi ; }
925 if (fSPhi < 0 ) { distSPhi = std::fabs(phi-(fSPhi+
twopi))*rho ; }
926 else { distSPhi = std::fabs(phi-fSPhi)*rho ; }
928 distEPhi = std::fabs(phi - fSPhi - fDPhi)*rho ;
930 if (distSPhi < distEPhi)
932 if (distSPhi<distMin) side = kNSPhi ;
936 if (distEPhi < distMin) { side = kNEPhi ; }
943 -p.
y()*(1-fRtor/rho)/pt,
948 p.
y()*(1-fRtor/rho)/pt,
955 norm =
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0) ;
961 "Undefined side for valid surface normal to solid.");
993 G4double snxt=kInfinity, sphi=kInfinity;
1002 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] ;
1198 G4double sinSPhi, cosSPhi, ePhi, sinEPhi, cosEPhi;
1200 G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, zi, vphi ;
1215 G4double pt2 = rho2 + p.
z()*p.
z() + fRtor * (fRtor - 2.0*rho);
1220 pt2= std::fabs( pt2 );
1227 G4double tolRMax = fRmax - fRmaxTolerance ;
1229 G4double vDotNmax = pDotV - fRtor*(v.
x()*p.
x() + v.
y()*p.
y())/rho ;
1230 G4double pDotxyNmax = (1 - fRtor/rho) ;
1232 if( (pt2 > tolRMax*tolRMax) && (vDotNmax >= 0) )
1238 if ( calcNorm && (pDotxyNmax >= -2.*fRmaxTolerance) )
1241 p.
y()*(1 - fRtor/rho)/pt,
1249 snxt = SolveNumericJT(p,v,fRmax,
false);
1256 G4double tolRMin = fRmin + fRminTolerance ;
1258 if ( (pt2 < tolRMin*tolRMin) && (vDotNmax < 0) )
1260 if (calcNorm) { *validNorm = false ; }
1264 sd[0] = SolveNumericJT(p,v,fRmin,
false);
1277 snxt = SolveNumericJT(p,v,fRmax,
false);
1282 sd[0] = SolveNumericJT(p,v,fRmin,
false);
1290 if ( calcNorm && (snxt == 0.0) )
1292 *validNorm = false ;
1300 sinSPhi = std::sin(fSPhi) ;
1301 cosSPhi = std::cos(fSPhi) ;
1302 ePhi = fSPhi + fDPhi ;
1303 sinEPhi = std::sin(ePhi) ;
1304 cosEPhi = std::cos(ePhi) ;
1305 cPhi = fSPhi + fDPhi*0.5 ;
1306 sinCPhi = std::sin(cPhi) ;
1307 cosCPhi = std::cos(cPhi) ;
1312 vphi = std::atan2(v.
y(),v.
x()) ;
1314 if ( vphi < fSPhi - halfAngTolerance ) { vphi +=
twopi; }
1315 else if ( vphi > ePhi + halfAngTolerance ) { vphi -=
twopi; }
1317 if ( p.
x() || p.
y() )
1319 pDistS = p.
x()*sinSPhi - p.
y()*cosSPhi ;
1320 pDistE = -p.
x()*sinEPhi + p.
y()*cosEPhi ;
1324 compS = -sinSPhi*v.
x() + cosSPhi*v.
y() ;
1325 compE = sinEPhi*v.
x() - cosEPhi*v.
y() ;
1328 if( ( (fDPhi <=
pi) && ( (pDistS <= halfCarTolerance)
1329 && (pDistE <= halfCarTolerance) ) )
1330 || ( (fDPhi >
pi) && !((pDistS > halfCarTolerance)
1331 && (pDistE > halfCarTolerance) ) ) )
1337 sphi = pDistS/compS ;
1339 if (sphi >= -halfCarTolerance)
1341 xi = p.
x() + sphi*v.
x() ;
1342 yi = p.
y() + sphi*v.
y() ;
1351 if ( ((fSPhi-halfAngTolerance)<=vphi)
1352 && ((ePhi+halfAngTolerance)>=vphi) )
1357 else if ( yi*cosCPhi-xi*sinCPhi >=0 )
1378 sphi2 = pDistE/compE ;
1384 xi = p.
x() + sphi2*v.
x() ;
1385 yi = p.
y() + sphi2*v.
y() ;
1392 if( !( (fSPhi-halfAngTolerance <= vphi)
1393 && (ePhi+halfAngTolerance >= vphi) ) )
1401 if ( (yi*cosCPhi-xi*sinCPhi) >= 0)
1423 vphi = std::atan2(v.
y(),v.
x());
1425 if ( ( fSPhi-halfAngTolerance <= vphi ) &&
1426 ( vphi <= ( ePhi+halfAngTolerance ) ) )
1446 G4double rhoi2,rhoi,it2,it,iDotxyNmax ;
1455 xi = p.
x() + snxt*v.
x() ;
1456 yi =p.
y() + snxt*v.
y() ;
1457 zi = p.
z() + snxt*v.
z() ;
1458 rhoi2 = xi*xi + yi*yi ;
1459 rhoi = std::sqrt(rhoi2) ;
1460 it2 = std::fabs(rhoi2 + zi*zi + fRtor*fRtor - 2*fRtor*rhoi) ;
1461 it = std::sqrt(it2) ;
1462 iDotxyNmax = (1-fRtor/rhoi) ;
1463 if(iDotxyNmax >= -2.*fRmaxTolerance)
1466 yi*(1-fRtor/rhoi)/it,
1472 *validNorm = false ;
1477 *validNorm = false ;
1488 *validNorm = false ;
1495 *n=
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);
1500 *validNorm = false ;
1510 std::ostringstream message;
1511 G4int oldprc = message.precision(16);
1512 message <<
"Undefined side for valid surface normal to solid."
1514 <<
"Position:" << G4endl << G4endl
1515 <<
"p.x() = " << p.
x()/
mm <<
" mm" << G4endl
1516 <<
"p.y() = " << p.
y()/
mm <<
" mm" << G4endl
1517 <<
"p.z() = " << p.
z()/
mm <<
" mm" << G4endl << G4endl
1518 <<
"Direction:" << G4endl << G4endl
1519 <<
"v.x() = " << v.
x() << G4endl
1520 <<
"v.y() = " << v.
y() << G4endl
1521 <<
"v.z() = " << v.
z() << G4endl << G4endl
1522 <<
"Proposed distance :" << G4endl << G4endl
1523 <<
"snxt = " << snxt/
mm <<
" mm" <<
G4endl;
1524 message.precision(oldprc);
1530 if ( snxt<halfCarTolerance ) { snxt=0 ; }
1543 G4double safePhi,phiC,cosPhiC,sinPhiC,ePhi;
1544 rho2 = p.
x()*p.
x() + p.
y()*p.
y() ;
1545 rho = std::sqrt(rho2) ;
1546 pt2 = std::fabs(rho2 + p.
z()*p.
z() + fRtor*fRtor - 2*fRtor*rho) ;
1547 pt = std::sqrt(pt2) ;
1559 G4cout.precision(oldprc);
1560 G4Exception(
"G4Torus::DistanceToOut(p)",
"GeomSolids1002",
1567 safeR1 = pt - fRmin ;
1568 safeR2 = fRmax -
pt ;
1570 if (safeR1 < safeR2) { safe = safeR1 ; }
1571 else { safe = safeR2 ; }
1582 phiC = fSPhi + fDPhi*0.5 ;
1583 cosPhiC = std::cos(phiC) ;
1584 sinPhiC = std::sin(phiC) ;
1586 if ((p.
y()*cosPhiC-p.
x()*sinPhiC)<=0)
1588 safePhi = -(p.
x()*std::sin(fSPhi) - p.
y()*std::cos(fSPhi)) ;
1592 ePhi = fSPhi + fDPhi ;
1593 safePhi = (p.
x()*std::sin(ePhi) - p.
y()*std::cos(ePhi)) ;
1595 if (safePhi < safe) { safe = safePhi ; }
1597 if (safe < 0) { safe = 0 ; }
1614 G4int& noPolygonVertices )
const
1618 G4double meshAngle,meshRMax,crossAngle,cosCrossAngle,sinCrossAngle,sAngle;
1620 G4int crossSection,noCrossSections;
1634 meshAngle = fDPhi/(noCrossSections - 1) ;
1635 meshRMax = (fRtor + fRmax)/std::cos(meshAngle*0.5) ;
1640 if ( (fDPhi ==
twopi) && (fSPhi == 0) )
1642 sAngle = -meshAngle*0.5 ;
1652 vertices->reserve(noCrossSections*4) ;
1653 for (crossSection=0;crossSection<noCrossSections;crossSection++)
1657 crossAngle=sAngle+crossSection*meshAngle;
1658 cosCrossAngle=std::cos(crossAngle);
1659 sinCrossAngle=std::sin(crossAngle);
1661 rMaxX=meshRMax*cosCrossAngle;
1662 rMaxY=meshRMax*sinCrossAngle;
1663 rMinX=(fRtor-fRmax)*cosCrossAngle;
1664 rMinY=(fRtor-fRmax)*sinCrossAngle;
1675 noPolygonVertices = 4 ;
1682 "Error in allocation of vertices. Out of memory !");
1711 G4int oldprc = os.precision(16);
1712 os <<
"-----------------------------------------------------------\n"
1713 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1714 <<
" ===================================================\n"
1715 <<
" Solid type: G4Torus\n"
1716 <<
" Parameters: \n"
1717 <<
" inner radius: " << fRmin/
mm <<
" mm \n"
1718 <<
" outer radius: " << fRmax/
mm <<
" mm \n"
1719 <<
" swept radius: " << fRtor/
mm <<
" mm \n"
1720 <<
" starting phi: " << fSPhi/
degree <<
" degrees \n"
1721 <<
" delta phi : " << fDPhi/
degree <<
" degrees \n"
1722 <<
"-----------------------------------------------------------\n";
1723 os.precision(oldprc);
1734 G4double cosu, sinu,cosv, sinv, aOut, aIn, aSide, chose, phi, theta, rRand;
1739 cosu = std::cos(phi); sinu = std::sin(phi);
1740 cosv = std::cos(theta); sinv = std::sin(theta);
1744 aOut = (fDPhi)*
twopi*fRtor*fRmax;
1745 aIn = (fDPhi)*
twopi*fRtor*fRmin;
1746 aSide =
pi*(fRmax*fRmax-fRmin*fRmin);
1748 if ((fSPhi == 0) && (fDPhi ==
twopi)){ aSide = 0; }
1754 (fRtor+fRmax*cosv)*sinu, fRmax*sinv);
1756 else if( (chose >= aOut) && (chose < aOut + aIn) )
1759 (fRtor+fRmin*cosv)*sinu, fRmin*sinv);
1761 else if( (chose >= aOut + aIn) && (chose < aOut + aIn + aSide) )
1765 (fRtor+rRand*cosv)*std::sin(fSPhi), rRand*sinv);
1770 return G4ThreeVector ((fRtor+rRand*cosv)*std::cos(fSPhi+fDPhi),
1771 (fRtor+rRand*cosv)*std::sin(fSPhi+fDPhi),
EInside Inside(const G4ThreeVector &p) const
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
ThreeVector shoot(const G4int Ap, const G4int Af)
G4Polyhedron * CreatePolyhedron() const
G4double GetMinYExtent() const
std::ostringstream G4ExceptionDescription
CLHEP::Hep3Vector G4ThreeVector
G4Torus & operator=(const G4Torus &rhs)
std::ostream & StreamInfo(std::ostream &os) const
G4bool IsYLimited() const
G4double GetRadiusInRing(G4double rmin, G4double rmax) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool IsXLimited() const
const G4int kMinMeshSections
virtual void AddSolid(const G4Box &)=0
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4double GetMaxXExtent() const
G4double GetMinZExtent() const
G4GLOB_DLL std::ostream G4cout
G4Polyhedron * fpPolyhedron
G4double GetRadialTolerance() const
std::vector< G4ThreeVector > G4ThreeVectorList
G4Torus(const G4String &pName, G4double pRmin, G4double pRmax, G4double pRtor, G4double pSPhi, G4double pDPhi)
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4ThreeVector GetPointOnSurface() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinXExtent() const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
G4double GetMaxZExtent() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4GeometryType GetEntityType() const
G4double GetMaxYExtent() const
void SetAllParameters(G4double pRmin, G4double pRmax, G4double pRtor, G4double pSPhi, G4double pDPhi)
G4double GetMaxExtent(const EAxis pAxis) const
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4CSGSolid & operator=(const G4CSGSolid &rhs)
G4bool IsZLimited() const
G4int FindRoots(G4double *op, G4int degree, G4double *zeror, G4double *zeroi)
G4double GetAngularTolerance() const
void ClipBetweenSections(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
G4double GetMinExtent(const EAxis pAxis) const
const G4double kMeshAngleDefault
static G4GeometryTolerance * GetInstance()
const G4int kMaxMeshSections