59 #if !defined(G4GEOM_USE_USPHERE)
74 using namespace CLHEP;
93 :
G4CSGSolid(pName), fEpsilon(2.e-11), fSPhi(0.0),
94 fFullPhiSphere(true), fFullThetaSphere(true)
104 if ( (pRmin >= pRmax) || (pRmax < 1.1*
kRadTolerance) || (pRmin < 0) )
106 std::ostringstream message;
107 message <<
"Invalid radii for Solid: " <<
GetName() <<
G4endl
108 <<
" pRmin = " << pRmin <<
", pRmax = " << pRmax;
109 G4Exception(
"G4Sphere::G4Sphere()",
"GeomSolids0002",
128 :
G4CSGSolid(a), fRminTolerance(0.), fRmaxTolerance(0.),
129 kAngTolerance(0.), kRadTolerance(0.), fEpsilon(0.),
130 fRmin(0.), fRmax(0.), fSPhi(0.), fDPhi(0.), fSTheta(0.),
131 fDTheta(0.), sinCPhi(0.), cosCPhi(0.), cosHDPhiOT(0.), cosHDPhiIT(0.),
132 sinSPhi(0.), cosSPhi(0.), sinEPhi(0.), cosEPhi(0.), hDPhi(0.), cPhi(0.),
133 ePhi(0.), sinSTheta(0.), cosSTheta(0.), sinETheta(0.), cosETheta(0.),
134 tanSTheta(0.), tanSTheta2(0.), tanETheta(0.), tanETheta2(0.), eTheta(0.),
135 fFullPhiSphere(false), fFullThetaSphere(false), fFullSphere(true),
136 halfCarTolerance(0.), halfAngTolerance(0.)
153 :
G4CSGSolid(rhs), fRminTolerance(rhs.fRminTolerance),
154 fRmaxTolerance(rhs.fRmaxTolerance), kAngTolerance(rhs.kAngTolerance),
155 kRadTolerance(rhs.kRadTolerance), fEpsilon(rhs.fEpsilon),
156 fRmin(rhs.fRmin), fRmax(rhs.fRmax), fSPhi(rhs.fSPhi), fDPhi(rhs.fDPhi),
157 fSTheta(rhs.fSTheta), fDTheta(rhs.fDTheta),
158 sinCPhi(rhs.sinCPhi), cosCPhi(rhs.cosCPhi),
159 cosHDPhiOT(rhs.cosHDPhiOT), cosHDPhiIT(rhs.cosHDPhiIT),
160 sinSPhi(rhs.sinSPhi), cosSPhi(rhs.cosSPhi),
161 sinEPhi(rhs.sinEPhi), cosEPhi(rhs.cosEPhi),
162 hDPhi(rhs.hDPhi), cPhi(rhs.cPhi), ePhi(rhs.ePhi),
163 sinSTheta(rhs.sinSTheta), cosSTheta(rhs.cosSTheta),
164 sinETheta(rhs.sinETheta), cosETheta(rhs.cosETheta),
165 tanSTheta(rhs.tanSTheta), tanSTheta2(rhs.tanSTheta2),
166 tanETheta(rhs.tanETheta), tanETheta2(rhs.tanETheta2), eTheta(rhs.eTheta),
167 fFullPhiSphere(rhs.fFullPhiSphere), fFullThetaSphere(rhs.fFullThetaSphere),
168 fFullSphere(rhs.fFullSphere),
169 halfCarTolerance(rhs.halfCarTolerance),
170 halfAngTolerance(rhs.halfAngTolerance)
182 if (
this == &rhs) {
return *
this; }
244 G4double diff1,diff2,delta,maxDiff,newMin,newMax;
323 if ((yoff1>=0) && (yoff2>=0))
335 delta=fRmax*fRmax-yoff1*yoff1;
336 diff1=(delta>0.) ? std::sqrt(delta) : 0.;
337 delta=fRmax*fRmax-yoff2*yoff2;
338 diff2=(delta>0.) ? std::sqrt(delta) : 0.;
339 maxDiff=(diff1>diff2) ? diff1:diff2;
340 newMin=xoffset-maxDiff;
341 newMax=xoffset+maxDiff;
342 pMin=(newMin<xMin) ? xMin : newMin;
343 pMax=(newMax>xMax) ? xMax : newMax;
349 if ((xoff1>=0) && (xoff2>=0))
361 delta=fRmax*fRmax-xoff1*xoff1;
362 diff1=(delta>0.) ? std::sqrt(delta) : 0.;
363 delta=fRmax*fRmax-xoff2*xoff2;
364 diff2=(delta>0.) ? std::sqrt(delta) : 0.;
365 maxDiff=(diff1>diff2) ? diff1:diff2;
366 newMin=yoffset-maxDiff;
367 newMax=yoffset+maxDiff;
368 pMin=(newMin<yMin) ? yMin : newMin;
369 pMax=(newMax>yMax) ? yMax : newMax;
386 G4int i,j,noEntries,noBetweenSections;
387 G4bool existsAfterClip=
false;
392 G4int noPolygonVertices ;
398 noEntries=vertices->size();
399 noBetweenSections=noEntries-noPolygonVertices;
402 for (i=0;i<noEntries;i+=noPolygonVertices)
404 for(j=0;j<(noPolygonVertices/2)-1;j++)
406 ThetaPolygon.push_back((*vertices)[i+j]) ;
407 ThetaPolygon.push_back((*vertices)[i+j+1]) ;
408 ThetaPolygon.push_back((*vertices)[i+noPolygonVertices-2-j]) ;
409 ThetaPolygon.push_back((*vertices)[i+noPolygonVertices-1-j]) ;
411 ThetaPolygon.clear() ;
414 for (i=0;i<noBetweenSections;i+=noPolygonVertices)
416 for(j=0;j<noPolygonVertices-1;j++)
418 ThetaPolygon.push_back((*vertices)[i+j]) ;
419 ThetaPolygon.push_back((*vertices)[i+j+1]) ;
420 ThetaPolygon.push_back((*vertices)[i+noPolygonVertices+j+1]) ;
421 ThetaPolygon.push_back((*vertices)[i+noPolygonVertices+j]) ;
423 ThetaPolygon.clear() ;
425 ThetaPolygon.push_back((*vertices)[i+noPolygonVertices-1]) ;
426 ThetaPolygon.push_back((*vertices)[i]) ;
427 ThetaPolygon.push_back((*vertices)[i+noPolygonVertices]) ;
428 ThetaPolygon.push_back((*vertices)[i+2*noPolygonVertices-1]) ;
430 ThetaPolygon.clear() ;
435 existsAfterClip=
true;
456 existsAfterClip=
true;
462 return existsAfterClip;
474 G4double rho,rho2,rad2,tolRMin,tolRMax;
483 rho2 = p.x()*p.x() + p.y()*p.y() ;
484 rad2 = rho2 + p.z()*p.z() ;
489 tolRMax = Rmax_minus;
507 if ( (rad2 <= Rmax_minus*Rmax_minus) && (rad2 >= Rmin_plus*Rmin_plus) )
513 tolRMax =
fRmax + halfRmaxTolerance;
515 if ( (rad2 <= tolRMax*tolRMax) && (rad2 >= tolRMin*tolRMin) )
529 pPhi = std::atan2(p.y(),p.x()) ;
548 rho = std::sqrt(rho2);
549 pTheta = std::atan2(rho,p.z());
588 G4int noSurfaces = 0;
589 G4double rho, rho2, radius, pTheta, pPhi=0.;
596 rho2 = p.x()*p.x()+p.y()*p.y();
597 radius = std::sqrt(rho2+p.z()*p.z());
598 rho = std::sqrt(rho2);
601 if (
fRmin) distRMin = std::fabs(radius-
fRmin);
605 pPhi = std::atan2(p.y(),p.x());
614 distSPhi = std::fabs( pPhi-
fSPhi );
615 distEPhi = std::fabs( pPhi-
ePhi );
629 pTheta = std::atan2(rho,p.z());
630 distSTheta = std::fabs(pTheta-
fSTheta);
631 distETheta = std::fabs(pTheta-
eTheta);
655 if( radius ) { nR =
G4ThreeVector(p.x()/radius,p.y()/radius,p.z()/radius); }
686 else { sumnorm += nTs; }
692 else { sumnorm += nTe; }
693 if(sumnorm.z() == 0.) { sumnorm += nZ; }
696 if ( noSurfaces == 0 )
699 G4Exception(
"G4Sphere::SurfaceNormal(p)",
"GeomSolids1002",
704 else if ( noSurfaces == 1 ) { norm = sumnorm; }
705 else { norm = sumnorm.unit(); }
719 G4double rho,rho2,radius,pPhi,pTheta;
720 G4double distRMin,distRMax,distSPhi,distEPhi,
721 distSTheta,distETheta,distMin;
723 rho2=p.x()*p.x()+p.y()*p.y();
724 radius=std::sqrt(rho2+p.z()*p.z());
731 distRMax=std::fabs(radius-
fRmax);
734 distRMin=std::fabs(radius-
fRmin);
736 if (distRMin<distRMax)
758 pPhi = std::atan2(p.y(),p.x());
759 if (pPhi<0) { pPhi += twopi; }
765 distSPhi=std::fabs(pPhi-(
fSPhi+twopi))*rho;
769 distSPhi=std::fabs(pPhi-
fSPhi)*rho;
776 if (distSPhi<distEPhi)
778 if (distSPhi<distMin)
786 if (distEPhi<distMin)
800 pTheta=std::atan2(rho,p.z());
801 distSTheta=std::fabs(pTheta-
fSTheta)*radius;
806 if (distSTheta<distETheta)
808 if (distSTheta<distMin)
810 distMin = distSTheta ;
816 if (distETheta<distMin)
818 distMin = distETheta ;
827 norm=
G4ThreeVector(-p.x()/radius,-p.y()/radius,-p.z()/radius);
852 "Undefined side for valid surface normal to solid.");
892 G4double rho2, rad2, pDotV2d, pDotV3d, pTheta ;
893 G4double tolSTheta=0., tolETheta=0. ;
899 ? (
fRmin-halfRminTolerance)*(
fRmin-halfRminTolerance) : 0;
901 (
fRmin+halfRminTolerance)*(
fRmin+halfRminTolerance);
903 (
fRmax+halfRmaxTolerance)*(
fRmax+halfRmaxTolerance);
905 (
fRmax-halfRmaxTolerance)*(
fRmax-halfRmaxTolerance);
909 G4double xi, yi, zi, rhoi, rhoi2, radi2, iTheta ;
926 rho2 = p.x()*p.x() + p.y()*p.y() ;
927 rad2 = rho2 + p.z()*p.z() ;
928 pTheta = std::atan2(std::sqrt(rho2),p.z()) ;
930 pDotV2d = p.x()*v.x() + p.y()*v.y() ;
931 pDotV3d = pDotV2d + p.z()*v.z() ;
962 d2 = pDotV3d*pDotV3d - c ;
966 sd = -pDotV3d - std::sqrt(d2) ;
972 G4double fTerm = sd-std::fmod(sd,dRmax);
975 xi = p.x() + sd*v.x() ;
976 yi = p.y() + sd*v.y() ;
977 rhoi = std::sqrt(xi*xi + yi*yi) ;
987 zi = p.z() + sd*v.z() ;
992 iTheta = std::atan2(rhoi,zi) ;
993 if ( (iTheta >= tolSTheta) && (iTheta <= tolETheta) )
1008 zi = p.z() + sd*v.z() ;
1013 iTheta = std::atan2(rhoi,zi) ;
1014 if ( (iTheta >= tolSTheta) && (iTheta <= tolETheta) )
1036 d2 = pDotV3d*pDotV3d - c ;
1038 if ( (rad2 > tolIRMax2)
1092 d2 = pDotV3d*pDotV3d - c ;
1097 if ( (c > -halfRminTolerance) && (rad2 < tolIRMin2)
1144 sd = -pDotV3d + std::sqrt(d2) ;
1145 if ( sd >= halfRminTolerance )
1147 xi = p.x() + sd*v.x() ;
1148 yi = p.y() + sd*v.y() ;
1149 rhoi = std::sqrt(xi*xi+yi*yi) ;
1159 zi = p.z() + sd*v.z() ;
1164 iTheta = std::atan2(rhoi,zi) ;
1165 if ( (iTheta >= tolSTheta) && (iTheta<=tolETheta) )
1180 zi = p.z() + sd*v.z() ;
1185 iTheta = std::atan2(rhoi,zi) ;
1186 if ( (iTheta >= tolSTheta) && (iTheta <= tolETheta) )
1229 xi = p.x() + sd*v.x() ;
1230 yi = p.y() + sd*v.y() ;
1231 zi = p.z() + sd*v.z() ;
1232 rhoi2 = xi*xi + yi*yi ;
1233 radi2 = rhoi2 + zi*zi ;
1244 if ( (radi2 <= tolORMax2)
1245 && (radi2 >= tolORMin2)
1254 iTheta = std::atan2(std::sqrt(rhoi2),zi) ;
1255 if ( (iTheta >= tolSTheta) && (iTheta <= tolETheta) )
1260 if ((yi*
cosCPhi-xi*sinCPhi) <= 0)
1291 xi = p.x() + sd*v.x() ;
1292 yi = p.y() + sd*v.y() ;
1293 zi = p.z() + sd*v.z() ;
1294 rhoi2 = xi*xi + yi*yi ;
1295 radi2 = rhoi2 + zi*zi ;
1306 if ( (radi2 <= tolORMax2)
1307 && (radi2 >= tolORMin2)
1316 iTheta = std::atan2(std::sqrt(rhoi2),zi) ;
1317 if ( (iTheta >= tolSTheta) && (iTheta <= tolETheta) )
1322 if ((yi*
cosCPhi-xi*sinCPhi) >= 0)
1364 dist2STheta = rho2 - p.z()*p.z()*
tanSTheta2 ;
1378 if ( pTheta < tolSTheta )
1388 c = dist2STheta/t1 ;
1395 zi = p.z() + sd*v.z();
1397 if ( (sd < 0) || (zi*(
fSTheta - halfpi) > 0) )
1401 if ((sd >= 0) && (sd < snxt))
1403 xi = p.x() + sd*v.x();
1404 yi = p.y() + sd*v.y();
1405 zi = p.z() + sd*v.z();
1406 rhoi2 = xi*xi + yi*yi;
1407 radi2 = rhoi2 + zi*zi;
1408 if ( (radi2 <= tolORMax2)
1409 && (radi2 >= tolORMin2)
1410 && (zi*(
fSTheta - halfpi) <= 0) )
1439 c = dist2ETheta/t1 ;
1447 if ( (sd >= 0) && (sd < snxt) )
1449 xi = p.x() + sd*v.x() ;
1450 yi = p.y() + sd*v.y() ;
1451 zi = p.z() + sd*v.z() ;
1452 rhoi2 = xi*xi + yi*yi ;
1453 radi2 = rhoi2 + zi*zi ;
1455 if ( (radi2 <= tolORMax2)
1456 && (radi2 >= tolORMin2)
1457 && (zi*(
eTheta - halfpi) <= 0) )
1477 else if ( pTheta > tolETheta )
1488 c = dist2ETheta/t1 ;
1495 zi = p.z() + sd*v.z();
1497 if ( (sd < 0) || (zi*(
eTheta - halfpi) > 0) )
1501 if ( (sd >= 0) && (sd < snxt) )
1503 xi = p.x() + sd*v.x() ;
1504 yi = p.y() + sd*v.y() ;
1505 zi = p.z() + sd*v.z() ;
1506 rhoi2 = xi*xi + yi*yi ;
1507 radi2 = rhoi2 + zi*zi ;
1509 if ( (radi2 <= tolORMax2)
1510 && (radi2 >= tolORMin2)
1511 && (zi*(
eTheta - halfpi) <= 0) )
1540 c = dist2STheta/t1 ;
1548 if ( (sd >= 0) && (sd < snxt) )
1550 xi = p.x() + sd*v.x() ;
1551 yi = p.y() + sd*v.y() ;
1552 zi = p.z() + sd*v.z() ;
1553 rhoi2 = xi*xi + yi*yi ;
1554 radi2 = rhoi2 + zi*zi ;
1556 if ( (radi2 <= tolORMax2)
1557 && (radi2 >= tolORMin2)
1558 && (zi*(
fSTheta - halfpi) <= 0) )
1586 if ( (t2>=0 && tolIRMin2<rad2 && rad2<tolIRMax2 &&
fSTheta<halfpi)
1587 || (t2<0 && tolIRMin2<rad2 && rad2<tolIRMax2 && fSTheta>halfpi)
1588 || (v.z()<0 && tolIRMin2<rad2 && rad2<tolIRMax2 &&
fSTheta==halfpi) )
1610 c = dist2STheta/t1 ;
1619 xi = p.x() + sd*v.x() ;
1620 yi = p.y() + sd*v.y() ;
1621 zi = p.z() + sd*v.z() ;
1622 rhoi2 = xi*xi + yi*yi ;
1623 radi2 = rhoi2 + zi*zi ;
1625 if ( (radi2 <= tolORMax2)
1626 && (radi2 >= tolORMin2)
1627 && (zi*(fSTheta - halfpi) <= 0) )
1655 if ( ((t2<0) && (
eTheta < halfpi)
1656 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2))
1657 || ((t2>=0) && (
eTheta > halfpi)
1658 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2))
1659 || ((v.z()>0) && (
eTheta == halfpi)
1660 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2)) )
1682 c = dist2ETheta/t1 ;
1691 && (sd < snxt) && (
eTheta > halfpi) )
1693 xi = p.x() + sd*v.x() ;
1694 yi = p.y() + sd*v.y() ;
1695 zi = p.z() + sd*v.z() ;
1696 rhoi2 = xi*xi + yi*yi ;
1697 radi2 = rhoi2 + zi*zi ;
1699 if ( (radi2 <= tolORMax2)
1700 && (radi2 >= tolORMin2)
1701 && (zi*(
eTheta - halfpi) <= 0) )
1730 c = dist2STheta/t1 ;
1738 if ((sd >= 0) && (sd < snxt))
1740 xi = p.x() + sd*v.x() ;
1741 yi = p.y() + sd*v.y() ;
1742 zi = p.z() + sd*v.z() ;
1743 rhoi2 = xi*xi + yi*yi ;
1744 radi2 = rhoi2 + zi*zi ;
1746 if ( (radi2 <= tolORMax2)
1747 && (radi2 >= tolORMin2)
1748 && (zi*(
fSTheta - halfpi) <= 0) )
1771 c = dist2ETheta/t1 ;
1779 if ((sd >= 0) && (sd < snxt))
1781 xi = p.x() + sd*v.x() ;
1782 yi = p.y() + sd*v.y() ;
1783 zi = p.z() + sd*v.z() ;
1784 rhoi2 = xi*xi + yi*yi ;
1785 radi2 = rhoi2 + zi*zi ;
1787 if ( (radi2 <= tolORMax2)
1788 && (radi2 >= tolORMin2)
1789 && (zi*(
eTheta - halfpi) <= 0) )
1822 G4double safe=0.0,safeRMin,safeRMax,safePhi,safeTheta;
1826 rho2=p.x()*p.x()+p.y()*p.y();
1827 rds=std::sqrt(rho2+p.z()*p.z());
1828 rho=std::sqrt(rho2);
1837 if (safeRMin>safeRMax)
1859 if (cosPsi<std::cos(
hDPhi))
1871 if (safePhi>safe) { safe=safePhi; }
1879 pTheta=std::acos(p.z()/rds);
1880 if (pTheta<0) { pTheta+=
pi; }
1883 if (dTheta1>dTheta2)
1887 safeTheta=rds*std::sin(dTheta1);
1888 if (safe<=safeTheta)
1898 safeTheta=rds*std::sin(dTheta2);
1899 if (safe<=safeTheta)
1907 if (safe<0) { safe=0; }
1935 G4double pDistS,compS,pDistE,compE,sphi2,vphi;
1937 G4double rho2,rad2,pDotV2d,pDotV3d;
1944 G4double dist2STheta, dist2ETheta, distTheta;
1949 rho2 = p.x()*p.x()+p.y()*p.y();
1950 rad2 = rho2+p.z()*p.z();
1952 pDotV2d = p.x()*v.x()+p.y()*v.y();
1953 pDotV3d = pDotV2d+p.z()*v.z();
1971 if( (rad2 <= Rmax_plus*Rmax_plus) && (rad2 >= Rmin_minus*Rmin_minus) )
1986 d2 = pDotV3d*pDotV3d - c;
1989 && ((pDotV3d >=0) || (d2 < 0)) )
2001 snxt = -pDotV3d+std::sqrt(d2);
2013 d2 = pDotV3d*pDotV3d - c;
2020 if(calcNorm) { *validNorm =
false; }
2027 sd = -pDotV3d-std::sqrt(d2);
2072 if ( std::fabs( p.z() ) <= halfRmaxTolerance )
2081 stheta = -p.z()/v.z();
2091 distTheta = std::sqrt(rho2)-p.z()*
tanSTheta;
2097 if(std::fabs(distTheta) < halfRmaxTolerance)
2099 if( (
fSTheta < halfpi) && (p.z() > 0.) )
2101 if( calcNorm ) { *validNorm =
false; }
2104 else if( (
fSTheta > halfpi) && (p.z() <= 0) )
2111 rhoSecTheta = std::sqrt(rho2*(1+
tanSTheta2));
2122 stheta = -0.5*dist2STheta/t2;
2128 if( std::fabs(distTheta) < halfRmaxTolerance )
2130 if( (
fSTheta > halfpi) && (t2 >= 0.) )
2137 rhoSecTheta = std::sqrt(rho2*(1+
tanSTheta2));
2147 else if( (
fSTheta < halfpi) && (t2 < 0.) && (p.z() >=0.) )
2149 if( calcNorm ) { *validNorm =
false; }
2165 if ( ((std::fabs(
s) < halfRmaxTolerance) && (t2 < 0.))
2166 || (sd < 0.) || ( (sd > 0.) && (p.z() + sd*v.z() > 0.) ) )
2170 if( (sd > halfRmaxTolerance) && (p.z() + sd*v.z() <= 0.) )
2180 if ( ( (std::fabs(sd) < halfRmaxTolerance) && (t2 >= 0.) )
2181 || (sd < 0.) || ( (sd > 0.) && (p.z() + sd*v.z() < 0.) ) )
2185 if( (sd > halfRmaxTolerance) && (p.z() + sd*v.z() >= 0.) )
2201 if ( std::fabs( p.z() ) <= halfRmaxTolerance )
2225 distTheta = std::sqrt(rho2)-p.z()*
tanETheta;
2231 if(std::fabs(distTheta) < halfRmaxTolerance)
2233 if( (
eTheta > halfpi) && (p.z() < 0.) )
2235 if( calcNorm ) { *validNorm =
false; }
2238 else if ( (
eTheta < halfpi) && (p.z() >= 0) )
2245 rhoSecTheta = std::sqrt(rho2*(1+
tanETheta2));
2255 sd = -0.5*dist2ETheta/t2;
2266 if ( std::fabs(distTheta) < halfRmaxTolerance )
2268 if( (
eTheta < halfpi) && (t2 >= 0.) )
2275 rhoSecTheta = std::sqrt(rho2*(1+
tanETheta2));
2284 else if ( (
eTheta > halfpi)
2285 && (t2 < 0.) && (p.z() <=0.) )
2287 if( calcNorm ) { *validNorm =
false; }
2303 if( ((std::fabs(sd) < halfRmaxTolerance) && (t2 < 0.))
2308 if( sd > halfRmaxTolerance )
2321 if ( ((std::fabs(sd) < halfRmaxTolerance) && (t2 >= 0.))
2322 || (sd < 0.) || ( (sd > 0.) && (p.z() + sd*v.z() > 0.) ) )
2326 if( (sd > halfRmaxTolerance) && (p.z() + sd*v.z() <= 0.) )
2346 if ( p.x() || p.y() )
2359 if ( (pDistS <= 0) && (pDistE <= 0) )
2365 sphi = pDistS/compS ;
2366 xi = p.x()+sphi*v.x() ;
2367 yi = p.y()+sphi*v.y() ;
2373 vphi = std::atan2(v.y(),v.x());
2395 sphi2=pDistE/compE ;
2398 xi = p.x()+sphi2*v.x() ;
2399 yi = p.y()+sphi2*v.y() ;
2407 vphi = std::atan2(v.y(),v.x()) ;
2414 else { sphi = 0.0; }
2432 else if ((pDistS >= 0) && (pDistE >= 0))
2434 if ( pDistS <= pDistE )
2444 if ( (compS < 0) && (compE < 0) ) { sphi = 0; }
2452 if ( (compS >= 0) && (compE >= 0) ) { sphi =
kInfinity; }
2456 else if ( (pDistS > 0) && (pDistE < 0) )
2464 sphi = pDistE/compE ;
2465 xi = p.x() + sphi*v.x() ;
2466 yi = p.y() + sphi*v.y() ;
2473 vphi = std::atan2(v.y(),v.x());
2502 sphi = pDistE/compE ;
2503 xi = p.x() + sphi*v.x() ;
2504 yi = p.y() + sphi*v.y() ;
2511 vphi = std::atan2(v.y(),v.x());
2547 xi=p.x()+sphi*v.x();
2548 yi=p.y()+sphi*v.y();
2555 vphi = std::atan2(v.y(),v.x()) ;
2584 sphi = pDistS/compS ;
2585 xi = p.x()+sphi*v.x() ;
2586 yi = p.y()+sphi*v.y() ;
2593 vphi = std::atan2(v.y(),v.x()) ;
2628 if ( v.x() || v.y() )
2630 vphi = std::atan2(v.y(),v.x()) ;
2663 xi=p.x()+snxt*v.x();
2664 yi=p.y()+snxt*v.y();
2665 zi=p.z()+snxt*v.z();
2680 else { *validNorm=
false; }
2689 else { *validNorm=
false; }
2700 xi = p.x() + snxt*v.x();
2701 yi = p.y() + snxt*v.y();
2705 rhoSecTheta = std::sqrt(rho2*(1+
tanSTheta2));
2715 else { *validNorm=
false; }
2724 else if (
eTheta < halfpi )
2726 xi=p.x()+snxt*v.x();
2727 yi=p.y()+snxt*v.y();
2731 rhoSecTheta = std::sqrt(rho2*(1+
tanETheta2));
2741 else { *validNorm=
false; }
2747 std::ostringstream message;
2748 G4int oldprc = message.precision(16);
2749 message <<
"Undefined side for valid surface normal to solid."
2751 <<
"Position:" << G4endl << G4endl
2752 <<
"p.x() = " << p.x()/
mm <<
" mm" << G4endl
2753 <<
"p.y() = " << p.y()/
mm <<
" mm" << G4endl
2754 <<
"p.z() = " << p.z()/
mm <<
" mm" << G4endl << G4endl
2755 <<
"Direction:" << G4endl << G4endl
2756 <<
"v.x() = " << v.x() << G4endl
2757 <<
"v.y() = " << v.y() << G4endl
2758 <<
"v.z() = " << v.z() << G4endl << G4endl
2759 <<
"Proposed distance :" << G4endl << G4endl
2760 <<
"snxt = " << snxt/
mm <<
" mm" <<
G4endl;
2761 message.precision(oldprc);
2771 std::ostringstream message;
2772 G4int oldprc = message.precision(16);
2773 message <<
"Logic error: snxt = kInfinity ???" << G4endl
2774 <<
"Position:" << G4endl << G4endl
2775 <<
"p.x() = " << p.x()/
mm <<
" mm" << G4endl
2776 <<
"p.y() = " << p.y()/
mm <<
" mm" << G4endl
2777 <<
"p.z() = " << p.z()/
mm <<
" mm" << G4endl << G4endl
2778 <<
"Rp = "<< std::sqrt( p.x()*p.x()+p.y()*p.y()+p.z()*p.z() )/
mm
2779 <<
" mm" << G4endl << G4endl
2780 <<
"Direction:" << G4endl << G4endl
2781 <<
"v.x() = " << v.x() << G4endl
2782 <<
"v.y() = " << v.y() << G4endl
2783 <<
"v.z() = " << v.z() << G4endl << G4endl
2784 <<
"Proposed distance :" << G4endl << G4endl
2785 <<
"snxt = " << snxt/
mm <<
" mm" <<
G4endl;
2786 message.precision(oldprc);
2800 G4double safe=0.0,safeRMin,safeRMax,safePhi,safeTheta;
2803 rho2=p.x()*p.x()+p.y()*p.y();
2804 rds=std::sqrt(rho2+p.z()*p.z());
2805 rho=std::sqrt(rho2);
2817 G4cout.precision(old_prc) ;
2819 "GeomSolids1002",
JustWarning,
"Point p is outside !?" );
2825 safeRMax =
fRmax-rds;
2829 safeRMin = rds-
fRmin;
2830 safe =
std::min( safeRMin, safeRMax );
2864 pTheta=std::acos(p.z()/rds);
2865 if (pTheta<0) { pTheta+=
pi; }
2869 { dTheta2=
eTheta-pTheta;}
2871 safeTheta=rds*std::sin(
std::min(dTheta1, dTheta2) );
2878 safe =
std::min( safe, safeTheta );
2881 if (safe<0.0) { safe=0; }
2900 G4int& noPolygonVertices )
const
2904 G4double meshAnglePhi,meshRMax,crossAnglePhi,
2905 coscrossAnglePhi,sincrossAnglePhi,sAnglePhi;
2906 G4double meshTheta,crossTheta,startTheta;
2907 G4double rMaxX,rMaxY,rMinX,rMinY,rMinZ,rMaxZ;
2908 G4int crossSectionPhi,noPhiCrossSections,crossSectionTheta,noThetaSections;
2922 meshAnglePhi=
fDPhi/(noPhiCrossSections-1);
2929 sAnglePhi = -meshAnglePhi*0.5;
2948 meshTheta=
fDTheta/(noThetaSections-1);
2955 startTheta = -meshTheta*0.5;
2962 meshRMax = (meshAnglePhi >= meshTheta) ?
2963 fRmax/std::cos(meshAnglePhi*0.5) :
fRmax/std::cos(meshTheta*0.5);
2967 if (vertices && cosCrossTheta && sinCrossTheta)
2969 vertices->reserve(noPhiCrossSections*(noThetaSections*2));
2970 for (crossSectionPhi=0;
2971 crossSectionPhi<noPhiCrossSections; crossSectionPhi++)
2973 crossAnglePhi=sAnglePhi+crossSectionPhi*meshAnglePhi;
2974 coscrossAnglePhi=std::cos(crossAnglePhi);
2975 sincrossAnglePhi=std::sin(crossAnglePhi);
2976 for (crossSectionTheta=0;
2977 crossSectionTheta<noThetaSections;crossSectionTheta++)
2981 crossTheta=startTheta+crossSectionTheta*meshTheta;
2982 cosCrossTheta[crossSectionTheta]=std::cos(crossTheta);
2983 sinCrossTheta[crossSectionTheta]=std::sin(crossTheta);
2985 rMinX=
fRmin*sinCrossTheta[crossSectionTheta]*coscrossAnglePhi;
2986 rMinY=
fRmin*sinCrossTheta[crossSectionTheta]*sincrossAnglePhi;
2987 rMinZ=
fRmin*cosCrossTheta[crossSectionTheta];
2994 for (crossSectionTheta=noThetaSections-1;
2995 crossSectionTheta>=0; crossSectionTheta--)
2997 rMaxX=meshRMax*sinCrossTheta[crossSectionTheta]*coscrossAnglePhi;
2998 rMaxY=meshRMax*sinCrossTheta[crossSectionTheta]*sincrossAnglePhi;
2999 rMaxZ=meshRMax*cosCrossTheta[crossSectionTheta];
3006 noPolygonVertices = noThetaSections*2 ;
3013 "Error in allocation of vertices. Out of memory !");
3016 delete [] cosCrossTheta;
3017 delete [] sinCrossTheta;
3046 G4int oldprc = os.precision(16);
3047 os <<
"-----------------------------------------------------------\n"
3048 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
3049 <<
" ===================================================\n"
3050 <<
" Solid type: G4Sphere\n"
3051 <<
" Parameters: \n"
3052 <<
" inner radius: " <<
fRmin/
mm <<
" mm \n"
3053 <<
" outer radius: " <<
fRmax/
mm <<
" mm \n"
3054 <<
" starting phi of segment : " <<
fSPhi/
degree <<
" degrees \n"
3055 <<
" delta phi of segment : " <<
fDPhi/
degree <<
" degrees \n"
3056 <<
" starting theta of segment: " <<
fSTheta/
degree <<
" degrees \n"
3057 <<
" delta theta of segment : " <<
fDTheta/
degree <<
" degrees \n"
3058 <<
"-----------------------------------------------------------\n";
3059 os.precision(oldprc);
3070 G4double zRand, aOne, aTwo, aThr, aFou, aFiv, chose, phi, sinphi, cosphi;
3071 G4double height1, height2, slant1, slant2, costheta, sintheta, rRand;
3086 cosphi = std::cos(phi);
3087 sinphi = std::sin(phi);
3089 sintheta = std::sqrt(1.-
sqr(costheta));
3098 if( (chose>=0.) && (chose<aOne) )
3103 else if( (chose>=aOne) && (chose<aOne+aTwo) )
3108 else if( (chose>=aOne+aTwo) && (chose<aOne+aTwo+aThr) )
3121 else if( (chose>=aOne+aTwo+aThr) && (chose<aOne+aTwo+aThr+aFou) )
3134 else if( (chose>=aOne+aTwo+aThr+aFou) && (chose<aOne+aTwo+aThr+aFou+aFiv) )
3137 rRand*sintheta*
sinSPhi,rRand*costheta);
3142 rRand*sintheta*
sinEPhi,rRand*costheta);
ThreeVector shoot(const G4int Ap, const G4int Af)
G4double halfCarTolerance
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
static const G4double kInfinity
G4double GetMinYExtent() const
CLHEP::Hep3Vector G4ThreeVector
G4bool IsYLimited() const
G4double GetRadiusInRing(G4double rmin, G4double rmax) const
G4Polyhedron * CreatePolyhedron() const
G4bool IsXLimited() const
const G4int kMinMeshSections
virtual void AddSolid(const G4Box &)=0
G4Sphere(const G4String &pName, G4double pRmin, G4double pRmax, G4double pSPhi, G4double pDPhi, G4double pSTheta, G4double pDTheta)
G4ThreeVector GetPointOnSurface() const
G4double GetMaxXExtent() const
G4double GetMinZExtent() const
G4GLOB_DLL std::ostream G4cout
void CalculateClippedPolygonExtent(G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
void CheckThetaAngles(G4double sTheta, G4double dTheta)
G4double GetRadialTolerance() const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform, G4int &noPolygonVertices) const
EInside Inside(const G4ThreeVector &p) const
void CheckPhiAngles(G4double sPhi, G4double dPhi)
std::vector< G4ThreeVector > G4ThreeVectorList
G4GeometryType GetEntityType() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4ThreeVector ApproxSurfaceNormal(const G4ThreeVector &p) const
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4Sphere & operator=(const G4Sphere &rhs)
G4double GetMinXExtent() const
G4double GetMaxZExtent() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
std::ostream & StreamInfo(std::ostream &os) const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
static const double degree
G4VisExtent GetExtent() const
G4double GetSurfaceArea()
G4double GetMaxYExtent() const
G4double GetMaxExtent(const EAxis pAxis) const
G4CSGSolid & operator=(const G4CSGSolid &rhs)
G4bool IsZLimited() const
G4double halfAngTolerance
G4double GetAngularTolerance() const
G4double GetMinExtent(const EAxis pAxis) const
const G4double kMeshAngleDefault
static G4GeometryTolerance * GetInstance()
const G4int kMaxMeshSections
void DescribeYourselfTo(G4VGraphicsScene &scene) const