50 using namespace CLHEP;
    61   : 
G4CSGSolid(pName), fRMin(pRMin), fRMax(pRMax), fDz(pDz), fSPhi(0), fDPhi(0)
    73     std::ostringstream message;
    74     message << 
"Negative Z half-length (" << pDz << 
") in solid: " << 
GetName();
    77   if ( (pRMin >= pRMax) || (pRMin < 0) ) 
    79     std::ostringstream message;
    80     message << 
"Invalid values for radii in solid: " << 
GetName()
    82             << 
"        pRMin = " << pRMin << 
", pRMax = " << pRMax;
   142    if (
this == &rhs)  { 
return *
this; }
   187     G4double diff1, diff2, maxDiff, newMin, newMax;
   188     G4double xoff1, xoff2, yoff1, yoff2, delta;
   191     xMin = xoffset - 
fRMax;
   192     xMax = xoffset + 
fRMax;
   214     yMin    = yoffset - 
fRMax;
   215     yMax    = yoffset + 
fRMax;
   237     zMin    = zoffset - 
fDz;
   238     zMax    = zoffset + 
fDz;
   263         yoff1 = yoffset - yMin;
   264         yoff2 = yMax    - yoffset;
   266         if ( (yoff1 >= 0) && (yoff2 >= 0) ) 
   276           delta   = fRMax*fRMax - yoff1*yoff1;
   277           diff1   = (delta>0.) ? std::sqrt(delta) : 0.;
   278           delta   = fRMax*fRMax - yoff2*yoff2;
   279           diff2   = (delta>0.) ? std::sqrt(delta) : 0.;
   280           maxDiff = (diff1 > diff2) ? diff1:diff2;
   281           newMin  = xoffset - maxDiff;
   282           newMax  = xoffset + maxDiff;
   283           pMin    = (newMin < xMin) ? xMin : newMin;
   284           pMax    = (newMax > xMax) ? xMax : newMax;
   290         xoff1 = xoffset - xMin;
   291         xoff2 = xMax - xoffset;
   293         if ( (xoff1 >= 0) && (xoff2 >= 0) ) 
   303           delta   = fRMax*fRMax - xoff1*xoff1;
   304           diff1   = (delta>0.) ? std::sqrt(delta) : 0.;
   305           delta   = fRMax*fRMax - xoff2*xoff2;
   306           diff2   = (delta>0.) ? std::sqrt(delta) : 0.;
   307           maxDiff = (diff1 > diff2) ? diff1 : diff2;
   308           newMin  = yoffset - maxDiff;
   309           newMax  = yoffset + maxDiff;
   310           pMin    = (newMin < yMin) ? yMin : newMin;
   311           pMax    = (newMax > yMax) ? yMax : newMax;
   330     G4int i, noEntries, noBetweenSections4;
   331     G4bool existsAfterClip = 
false;
   337     noEntries = vertices->size();
   338     noBetweenSections4 = noEntries - 4;
   340     for ( i = 0 ; i < noEntries ; i += 4 )
   344     for ( i = 0 ; i < noBetweenSections4 ; i += 4 )
   350       existsAfterClip = 
true;
   368         existsAfterClip = 
true;
   374     return existsAfterClip;
   390     r2 = p.
x()*p.
x() + p.
y()*p.
y() ;
   393     else       { tolRMin = 0 ; }
   397     if ((r2 >= tolRMin*tolRMin) && (r2 <= tolRMax*tolRMax))
   415           pPhi = std::atan2(p.
y(),p.
x()) ;
   458       if ( tolRMin < 0 )  { tolRMin = 0; }
   460       if ( (r2 >= tolRMin*tolRMin) && (r2 <= tolRMax*tolRMax) )
   462         if (
fPhiFullTube || (r2 <=halfRadTolerance*halfRadTolerance) )
   468           pPhi = std::atan2(p.
y(),p.
x()) ;
   499     r2      = p.
x()*p.
x() + p.
y()*p.
y() ;
   503     if ( tolRMin < 0 )  { tolRMin = 0; }
   505     if ( (r2 >= tolRMin*tolRMin) && (r2 <= tolRMax*tolRMax) )
   507       if (
fPhiFullTube || (r2 <=halfRadTolerance*halfRadTolerance))
   513         pPhi = std::atan2(p.
y(),p.
x()) ;
   552   G4int noSurfaces = 0;
   561   rho = std::sqrt(p.
x()*p.
x() + p.
y()*p.
y());
   563   distRMin = std::fabs(rho - 
fRMin);
   564   distRMax = std::fabs(rho - 
fRMax);
   565   distZ    = std::fabs(std::fabs(p.
z()) - 
fDz);
   571       pPhi = std::atan2(p.
y(),p.
x());
   576       distSPhi = std::fabs(pPhi - 
fSPhi);       
   615     if ( p.
z() >= 0.)  { sumnorm += nZ; }
   616     else               { sumnorm -= nZ; }
   618   if ( noSurfaces == 0 )
   621     G4Exception(
"G4Tubs::SurfaceNormal(p)", 
"GeomSolids1002",
   624     G4cout<< 
"G4Tubs::SN ( "<<p.
x()<<
", "<<p.
y()<<
", "<<p.
z()<<
" ); "   626     G4cout.precision(oldprc) ;
   630   else if ( noSurfaces == 1 )  { norm = sumnorm; }
   631   else                         { norm = sumnorm.
unit(); }
   646   G4double distZ, distRMin, distRMax, distSPhi, distEPhi, distMin ;
   648   rho = std::sqrt(p.
x()*p.
x() + p.
y()*p.
y()) ;
   650   distRMin = std::fabs(rho - 
fRMin) ;
   651   distRMax = std::fabs(rho - 
fRMax) ;
   652   distZ    = std::fabs(std::fabs(p.
z()) - 
fDz) ;
   654   if (distRMin < distRMax) 
   656     if ( distZ < distRMin )
   669     if ( distZ < distRMax )
   682     phi = std::atan2(p.
y(),p.
x()) ;
   684     if ( phi < 0 )  { phi += 
twopi; }
   688       distSPhi = std::fabs(phi - (
fSPhi + 
twopi))*rho ;
   692       distSPhi = std::fabs(phi - 
fSPhi)*rho ;
   694     distEPhi = std::fabs(phi - 
fSPhi - 
fDPhi)*rho ;
   696     if (distSPhi < distEPhi) 
   698       if ( distSPhi < distMin )
   705       if ( distEPhi < distMin )
   744                   "Undefined side for valid surface normal to solid.");
   778   G4double tolORMax2, tolIRMin2, tolODz, tolIDz ;
   783   G4double Dist, sd, xi, yi, zi, rho2, inum, iden, cosPsi, Comp ;
   806   if (std::fabs(p.
z()) >= tolIDz)
   808     if ( p.
z()*v.
z() < 0 )    
   810       sd = (std::fabs(p.
z()) - 
fDz)/std::fabs(v.
z()) ;  
   812       if(sd < 0.0)  { sd = 0.0; }
   814       xi   = p.
x() + sd*v.
x() ;                
   815       yi   = p.
y() + sd*v.
y() ;
   816       rho2 = xi*xi + yi*yi ;
   820       if ((tolIRMin2 <= rho2) && (rho2 <= tolIRMax2))
   827           iden   = std::sqrt(rho2) ;
   839       if ( snxt<halfCarTolerance )  { snxt=0; }
   856   t1 = 1.0 - v.
z()*v.
z() ;
   857   t2 = p.
x()*v.
x() + p.
y()*v.
y() ;
   858   t3 = p.
x()*p.
x() + p.
y()*p.
y() ;
   864     if ((t3 >= tolORMax2) && (t2<0))   
   874         sd = c/(-b+std::sqrt(d));
   879             G4double fTerm = sd-std::fmod(sd,dRmax);
   884           zi = p.
z() + sd*v.
z() ;
   885           if (std::fabs(zi)<=tolODz)
   895               xi     = p.
x() + sd*v.
x() ;
   896               yi     = p.
y() + sd*v.
y() ;
   909       if ((t3 > tolIRMin2) && (t2 < 0) && (std::fabs(p.
z()) <= tolIDz))
   916           iden   = std::sqrt(t3) ;
   937                 snxt = c/(-b+std::sqrt(d)); 
   939                 if ( snxt < halfCarTolerance ) { snxt=0; }
   957           c = t3 - fRMax*
fRMax; 
   968               snxt= c/(-b+std::sqrt(d)); 
   970               if ( snxt < halfCarTolerance ) { snxt=0; }
   990         sd =( b > 0. )? c/(-b - std::sqrt(d)) : (-b + std::sqrt(d));
   991         if (sd >= -halfCarTolerance)  
   995           if(sd < 0.0)  { sd = 0.0; }
   998             G4double fTerm = sd-std::fmod(sd,dRmax);
  1001           zi = p.
z() + sd*v.
z() ;
  1002           if (std::fabs(zi) <= tolODz)
  1012               xi     = p.
x() + sd*v.
x() ;
  1013               yi     = p.
y() + sd*v.
y() ;
  1048       if ( Dist < halfCarTolerance )
  1054           if ( sd < 0 )  { sd = 0.0; }
  1055           zi = p.
z() + sd*v.
z() ;
  1056           if ( std::fabs(zi) <= tolODz )
  1058             xi   = p.
x() + sd*v.
x() ;
  1059             yi   = p.
y() + sd*v.
y() ;
  1060             rho2 = xi*xi + yi*yi ;
  1062             if ( ( (rho2 >= tolIRMin2) && (rho2 <= tolIRMax2) )
  1063               || ( (rho2 >  tolORMin2) && (rho2 <  tolIRMin2)
  1066               || ( (rho2 > tolIRMax2) && (rho2 < tolORMax2)
  1088       if ( Dist < halfCarTolerance )
  1094           if ( sd < 0 )  { sd = 0; }
  1095           zi = p.
z() + sd*v.
z() ;
  1096           if ( std::fabs(zi) <= tolODz )
  1098             xi   = p.
x() + sd*v.
x() ;
  1099             yi   = p.
y() + sd*v.
y() ;
  1100             rho2 = xi*xi + yi*yi ;
  1101             if ( ( (rho2 >= tolIRMin2) && (rho2 <= tolIRMax2) )
  1102                 || ( (rho2 > tolORMin2)  && (rho2 < tolIRMin2)
  1105                 || ( (rho2 > tolIRMax2) && (rho2 < tolORMax2)
  1119   if ( snxt<halfCarTolerance )  { snxt=0; }
  1151   G4double safe=0.0, rho, safe1, safe2, safe3 ;
  1154   rho   = std::sqrt(p.
x()*p.
x() + p.
y()*p.
y()) ;
  1155   safe1 = 
fRMin - rho ;
  1156   safe2 = rho - 
fRMax ;
  1157   safe3 = std::fabs(p.
z()) - 
fDz ;
  1159   if ( safe1 > safe2 ) { safe = safe1; }
  1160   else                 { safe = safe2; }
  1161   if ( safe3 > safe )  { safe = safe3; }
  1169     if ( cosPsi < std::cos(
fDPhi*0.5) )
  1181       if ( safePhi > safe )  { safe = safePhi; }
  1184   if ( safe < 0 )  { safe = 0; }
  1205   G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, vphi, roi2 ;
  1211     pdist = 
fDz - p.
z() ;
  1214       snxt = pdist/v.
z() ;
  1227   else if ( v.
z() < 0 )
  1229     pdist = 
fDz + p.
z() ;
  1233       snxt = -pdist/v.
z() ;
  1263   t1   = 1.0 - v.
z()*v.
z() ;      
  1264   t2   = p.
x()*v.
x() + p.
y()*v.
y() ;
  1265   t3   = p.
x()*p.
x() + p.
y()*p.
y() ;
  1268   else  { roi2 = snxt*snxt*t1 + 2*snxt*t2 + t3; }        
  1288         if( d2 >= 0 ) { srd = c/( -b - std::sqrt(d2)); }
  1307       roMin2 = t3 - t2*t2/
t1 ; 
  1323             srd = c/(-b+std::sqrt(d2)); 
  1328             if ( calcNorm ) { *validNorm = 
false; }  
  1339             srd     = -b + std::sqrt(d2) ;
  1363           srd     = -b + std::sqrt(d2) ;
  1386       vphi = std::atan2(v.
y(),v.
x()) ;
  1392       if ( p.
x() || p.
y() )  
  1415             sphi = pDistS/compS ;
  1419               xi = p.
x() + sphi*v.
x() ;
  1420               yi = p.
y() + sphi*v.
y() ;
  1459             sphi2 = pDistE/compE ;
  1465               xi = p.
x() + sphi2*v.
x() ;
  1466               yi = p.
y() + sphi2*v.
y() ;
  1477                   else                                { sphi = 0.0 ;   }
  1488                 else                               { sphi = 0.0 ;   }
  1534         xi = p.
x() + snxt*v.
x() ;
  1535         yi = p.
y() + snxt*v.
y() ;
  1541         *validNorm = false ;  
  1552           *validNorm = false ;
  1564           *validNorm = false ;
  1581         std::ostringstream message;
  1582         G4int oldprc = message.precision(16);
  1583         message << 
"Undefined side for valid surface normal to solid."  1585                 << 
"Position:"  << G4endl << G4endl
  1586                 << 
"p.x() = "   << p.
x()/
mm << 
" mm" << G4endl
  1587                 << 
"p.y() = "   << p.
y()/
mm << 
" mm" << G4endl
  1588                 << 
"p.z() = "   << p.
z()/
mm << 
" mm" << G4endl << G4endl
  1589                 << 
"Direction:" << G4endl << G4endl
  1590                 << 
"v.x() = "   << v.
x() << G4endl
  1591                 << 
"v.y() = "   << v.
y() << G4endl
  1592                 << 
"v.z() = "   << v.
z() << G4endl << G4endl
  1593                 << 
"Proposed distance :" << G4endl << G4endl
  1594                 << 
"snxt = "    << snxt/
mm << 
" mm" << 
G4endl ;
  1595         message.precision(oldprc) ;
  1596         G4Exception(
"G4Tubs::DistanceToOut(p,v,..)", 
"GeomSolids1002",
  1612   G4double safe=0.0, rho, safeR1, safeR2, safeZ, safePhi ;
  1613   rho = std::sqrt(p.
x()*p.
x() + p.
y()*p.
y()) ;
  1625     G4cout.precision(oldprc) ;
  1626     G4Exception(
"G4Tubs::DistanceToOut(p)", 
"GeomSolids1002",
  1633     safeR1 = rho   - 
fRMin ;
  1634     safeR2 = 
fRMax - rho ;
  1636     if ( safeR1 < safeR2 ) { safe = safeR1 ; }
  1637     else                   { safe = safeR2 ; }
  1641     safe = 
fRMax - rho ;
  1643   safeZ = 
fDz - std::fabs(p.
z()) ;
  1645   if ( safeZ < safe )  { safe = safeZ ; }
  1659     if (safePhi < safe)  { safe = safePhi ; }
  1661   if ( safe < 0 )  { safe = 0 ; }
  1682   G4double meshAngle, meshRMax, crossAngle,
  1683            cosCrossAngle, sinCrossAngle, sAngle;
  1684   G4double rMaxX, rMaxY, rMinX, rMinY, meshRMin ;
  1685   G4int crossSection, noCrossSections;
  1701   meshAngle = 
fDPhi/(noCrossSections - 1) ;
  1711   else                                { sAngle =  
fSPhi ; }
  1717     vertices->reserve(noCrossSections*4);
  1718     for (crossSection = 0 ; crossSection < noCrossSections ; crossSection++ )
  1722       crossAngle    = sAngle + crossSection*meshAngle ;
  1723       cosCrossAngle = std::cos(crossAngle) ;
  1724       sinCrossAngle = std::sin(crossAngle) ;
  1726       rMaxX = meshRMax*cosCrossAngle ;
  1727       rMaxY = meshRMax*sinCrossAngle ;
  1736         rMinX = meshRMin*cosCrossAngle ;
  1737         rMinY = meshRMin*sinCrossAngle ;
  1755                 "Error in allocation of vertices. Out of memory !");
  1784   G4int oldprc = os.precision(16);
  1785   os << 
"-----------------------------------------------------------\n"  1786      << 
"    *** Dump for solid - " << 
GetName() << 
" ***\n"  1787      << 
"    ===================================================\n"  1788      << 
" Solid type: G4Tubs\n"  1789      << 
" Parameters: \n"  1790      << 
"    inner radius : " << 
fRMin/
mm << 
" mm \n"  1791      << 
"    outer radius : " << 
fRMax/
mm << 
" mm \n"  1792      << 
"    half length Z: " << 
fDz/
mm << 
" mm \n"  1793      << 
"    starting phi : " << 
fSPhi/
degree << 
" degrees \n"  1794      << 
"    delta phi    : " << 
fDPhi/
degree << 
" degrees \n"  1795      << 
"-----------------------------------------------------------\n";
  1796   os.precision(oldprc);
  1807   G4double xRand, yRand, zRand, phi, cosphi, sinphi, chose,
  1808            aOne, aTwo, aThr, aFou;
  1817   cosphi = std::cos(phi);
  1818   sinphi = std::sin(phi);
  1826   if( (chose >=0) && (chose < aOne) )
  1828     xRand = fRMax*cosphi;
  1829     yRand = fRMax*sinphi;
  1833   else if( (chose >= aOne) && (chose < aOne + aTwo) )
  1835     xRand = fRMin*cosphi;
  1836     yRand = fRMin*sinphi;
  1840   else if( (chose >= aOne + aTwo) && (chose < aOne + aTwo + aThr) )
  1842     xRand = rRand*cosphi;
  1843     yRand = rRand*sinphi;
  1847   else if( (chose >= aOne + aTwo + aThr) && (chose < aOne + aTwo + 2.*aThr) )
  1849     xRand = rRand*cosphi;
  1850     yRand = rRand*sinphi;
  1854   else if( (chose >= aOne + aTwo + 2.*aThr)
  1855         && (chose < aOne + aTwo + 2.*aThr + aFou) )
  1857     xRand = rRand*std::cos(
fSPhi);
  1858     yRand = rRand*std::sin(
fSPhi);
 G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
 
ThreeVector shoot(const G4int Ap, const G4int Af)
 
void ClipBetweenSections(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
G4double GetMinXExtent() const
 
std::ostream & StreamInfo(std::ostream &os) const
 
static const G4double kInfinity
 
G4double GetMinYExtent() const
 
CLHEP::Hep3Vector G4ThreeVector
 
void DescribeYourselfTo(G4VGraphicsScene &scene) const
 
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
 
G4double GetRadiusInRing(G4double rmin, G4double rmax) const
 
G4double GetMinZExtent() const
 
G4bool IsYLimited() const
 
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
G4bool IsXLimited() const
 
void CheckPhiAngles(G4double sPhi, G4double dPhi)
 
const G4int kMinMeshSections
 
virtual void AddSolid(const G4Box &)=0
 
G4double GetMaxZExtent() const
 
G4double GetMaxXExtent() const
 
G4OTubs & operator=(const G4OTubs &rhs)
 
G4GLOB_DLL std::ostream G4cout
 
G4double GetRadialTolerance() const
 
G4GeometryType GetEntityType() const
 
G4double halfRadTolerance
 
G4OTubs(const G4String &pName, G4double pRMin, G4double pRMax, G4double pDz, G4double pSPhi, G4double pDPhi)
 
static const double twopi
 
std::vector< G4ThreeVector > G4ThreeVectorList
 
G4ThreeVector GetPointOnSurface() const
 
EInside Inside(const G4ThreeVector &p) const
 
G4double GetAngularTolerance() const
 
G4Polyhedron * CreatePolyhedron() const
 
G4double GetMinExtent(const EAxis pAxis) const
 
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
 
G4bool IsZLimited() const
 
G4double halfAngTolerance
 
G4double halfCarTolerance
 
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
 
virtual G4ThreeVector ApproxSurfaceNormal(const G4ThreeVector &p) const
 
static const double degree
 
G4double GetMaxExtent(const EAxis pAxis) const
 
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform) const
 
G4double GetMaxYExtent() const
 
G4CSGSolid & operator=(const G4CSGSolid &rhs)
 
const G4double kMeshAngleDefault
 
static G4GeometryTolerance * GetInstance()
 
const G4int kMaxMeshSections
 
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const