31              double pRMin, 
double pRMax,
 
   33              double pSPhi, 
double pDPhi)
 
   34   : 
VUSolid(pName.c_str()), fRMin(pRMin), fRMax(pRMax), fDz(pDz), fSPhi(0), fDPhi(0)
 
   43     std::ostringstream message;
 
   44     message << 
"Negative Z half-length (" << pDz << 
") in solid: " << 
GetName();
 
   47   if ((pRMin >= pRMax) || (pRMin < 0))   
 
   49     std::ostringstream message;
 
   50     message << 
"Invalid values for radii in solid: " << 
GetName()
 
   52             << 
"pRMin = " << pRMin << 
", pRMax = " << pRMax;
 
   67   : 
VUSolid(
""), fCubicVolume(0.), fSurfaceArea(0.),
 
   68     kRadTolerance(0.), kAngTolerance(0.),
 
   69     fRMin(0.), fRMax(0.), fDz(0.), fSPhi(0.), fDPhi(0.),
 
   70     fSinCPhi(0.), fCosCPhi(0.), fCosHDPhiOT(0.), fCosHDPhiIT(0.),
 
   71     fSinSPhi(0.), fCosSPhi(0.), fSinEPhi(0.), fCosEPhi(0.),
 
   72     fSinSPhiDPhi(0.), fCosSPhiDPhi(0.),
 
   91     fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
 
   92     kRadTolerance(rhs.kRadTolerance), kAngTolerance(rhs.kAngTolerance),
 
   93     fRMin(rhs.fRMin), fRMax(rhs.fRMax), fDz(rhs.fDz),
 
   94     fSPhi(rhs.fSPhi), fDPhi(rhs.fDPhi),
 
   95     fSinCPhi(rhs.fSinCPhi), fCosCPhi(rhs.fSinCPhi),
 
   96     fCosHDPhiOT(rhs.fCosHDPhiOT), fCosHDPhiIT(rhs.fCosHDPhiOT),
 
   97     fSinSPhi(rhs.fSinSPhi), fCosSPhi(rhs.fCosSPhi),
 
   98     fSinEPhi(rhs.fSinEPhi), fCosEPhi(rhs.fCosEPhi),
 
   99     fSinSPhiDPhi(rhs.fSinSPhiDPhi), fCosSPhiDPhi(rhs.fCosSPhiDPhi),
 
  100     fPhiFullTube(rhs.fPhiFullTube)
 
  119   VUSolid::operator=(rhs);
 
  155   double r2, pPhi, tolRMin, tolRMax;
 
  161   if (std::fabs(p.
z) <= 
fDz - halfCarTolerance)
 
  163     r2 = p.
x * p.
x + p.
y * p.
y;
 
  167       tolRMin = 
fRMin + halfRadTolerance;
 
  174     tolRMax = 
fRMax - halfRadTolerance;
 
  176     if ((r2 >= tolRMin * tolRMin) && (r2 <= tolRMax * tolRMax))
 
  187         if ((tolRMin == 0) && (std::fabs(p.
x) <= halfCarTolerance)
 
  188             && (std::fabs(p.
y) <= halfCarTolerance))
 
  194           pPhi = std::atan2(p.
y, p.
x);
 
  195           if (pPhi < -halfAngTolerance)
 
  202             if ((std::fabs(pPhi) < halfAngTolerance)
 
  207             if ((pPhi >= 
fSPhi + halfAngTolerance)
 
  208                 && (pPhi <= 
fSPhi + 
fDPhi - halfAngTolerance))
 
  212             else if ((pPhi >= 
fSPhi - halfAngTolerance)
 
  213                      && (pPhi <= 
fSPhi + 
fDPhi + halfAngTolerance))
 
  221                 && (pPhi >= 
fSPhi + 
fDPhi + halfAngTolerance))
 
  226                      && (pPhi >= 
fSPhi + 
fDPhi - halfAngTolerance))
 
  240       tolRMin = 
fRMin - halfRadTolerance;
 
  241       tolRMax = 
fRMax + halfRadTolerance;
 
  248       if ((r2 >= tolRMin * tolRMin) && (r2 <= tolRMax * tolRMax))
 
  250         if (
fPhiFullTube || (r2 <= halfRadTolerance * halfRadTolerance))
 
  257           pPhi = std::atan2(p.
y, p.
x);
 
  259           if (pPhi < -halfAngTolerance)
 
  265             if ((std::fabs(pPhi) < halfAngTolerance)
 
  270             if ((pPhi >= 
fSPhi - halfAngTolerance)
 
  271                 && (pPhi <= 
fSPhi + 
fDPhi + halfAngTolerance))
 
  279                 && (pPhi >= 
fSPhi + 
fDPhi + halfAngTolerance))
 
  292   else if (std::fabs(p.
z) <= 
fDz + halfCarTolerance)
 
  295     r2 = p.
x * p.
x + p.
y * p.
y;
 
  296     tolRMin = 
fRMin - halfRadTolerance;
 
  297     tolRMax = 
fRMax + halfRadTolerance;
 
  304     if ((r2 >= tolRMin * tolRMin) && (r2 <= tolRMax * tolRMax))
 
  306       if (
fPhiFullTube || (r2 <= halfRadTolerance * halfRadTolerance))
 
  313         pPhi = std::atan2(p.
y, p.
x);
 
  315         if (pPhi < -halfAngTolerance)
 
  321           if ((std::fabs(pPhi) < halfAngTolerance)
 
  326           if ((pPhi >= 
fSPhi - halfAngTolerance)
 
  327               && (pPhi <= 
fSPhi + 
fDPhi + halfAngTolerance))
 
  335               && (pPhi >= 
fSPhi + 
fDPhi + halfAngTolerance))
 
  360   double distZ, distRMin, distRMax;
 
  370   rho = std::sqrt(p.
x * p.
x + p.
y * p.
y);
 
  372   distRMin = std::fabs(rho - 
fRMin);
 
  373   distRMax = std::fabs(rho - 
fRMax);
 
  374   distZ   = std::fabs(std::fabs(p.
z) - 
fDz);
 
  378     if (rho > halfCarTolerance)
 
  380       pPhi = std::atan2(p.
y, p.
x);
 
  382       if (pPhi < 
fSPhi - halfCarTolerance)
 
  386       else if (pPhi > 
fSPhi + 
fDPhi + halfCarTolerance)
 
  391       distSPhi = std::fabs(pPhi - 
fSPhi);
 
  402   if (rho > halfCarTolerance)
 
  407   if (distRMax <= halfCarTolerance)
 
  412   if (
fRMin && (distRMin <= halfCarTolerance))
 
  419     if (distSPhi <= halfAngTolerance)
 
  424     if (distEPhi <= halfAngTolerance)
 
  430   if (distZ <= halfCarTolerance)
 
  446                       Warning, 1, 
"Point p is not on surface !?");
 
  447     int oldprc = cout.precision(20);
 
  448     cout << 
"UTubs::SN ( " << p.
x << 
", " << p.
y << 
", " << p.
z << 
" ); " 
  449          << std::endl << std::endl;
 
  450     cout.precision(oldprc);
 
  454   else if (noSurfaces == 1)
 
  460     norm = sumnorm.
Unit();
 
  478   double distZ, distRMin, distRMax, distSPhi, distEPhi, distMin;
 
  480   rho = std::sqrt(p.
x * p.
x + p.
y * p.
y);
 
  482   distRMin = std::fabs(rho - 
fRMin);
 
  483   distRMax = std::fabs(rho - 
fRMax);
 
  484   distZ   = std::fabs(std::fabs(p.
z) - 
fDz);
 
  486   if (distRMin < distRMax) 
 
  488     if (distZ < distRMin)
 
  501     if (distZ < distRMax)
 
  514     phi = std::atan2(p.
y, p.
x);
 
  527       distSPhi = std::fabs(phi - 
fSPhi) * rho;
 
  529     distEPhi = std::fabs(phi - 
fSPhi - 
fDPhi) * rho;
 
  531     if (distSPhi < distEPhi) 
 
  533       if (distSPhi < distMin)
 
  540       if (distEPhi < distMin)
 
  585                         "Undefined side for valid surface normal to solid.");
 
  617   double tolORMin2, tolIRMax2;  
 
  618   double tolORMax2, tolIRMin2, tolODz, tolIDz;
 
  619   const double dRmax = 100.*
fRMax;
 
  626   double Dist, sd, xi, yi, zi, rho2, inum, iden, cosPsi, Comp;
 
  627   double t1, t2, t3, b, c, d;    
 
  633     tolORMin2 = (
fRMin - halfRadTolerance) * (
fRMin - halfRadTolerance);
 
  634     tolIRMin2 = (
fRMin + halfRadTolerance) * (
fRMin + halfRadTolerance);
 
  641   tolORMax2 = (
fRMax + halfRadTolerance) * (
fRMax + halfRadTolerance);
 
  642   tolIRMax2 = (
fRMax - halfRadTolerance) * (
fRMax - halfRadTolerance);
 
  646   tolIDz = 
fDz - halfCarTolerance;
 
  647   tolODz = 
fDz + halfCarTolerance;
 
  649   if (std::fabs(p.
z) >= tolIDz)
 
  653       sd = (std::fabs(p.
z) - 
fDz) / std::fabs(v.
z); 
 
  662       rho2 = xi * xi + yi * yi;
 
  666       if ((tolIRMin2 <= rho2) && (rho2 <= tolIRMax2))
 
  673           iden   = std::sqrt(rho2);
 
  674           cosPsi = inum / iden;
 
  688       if (snxt < halfCarTolerance)
 
  708   t1 = 1.0 - v.
z * v.
z;
 
  709   t2 = p.
x * v.
x + p.
y * v.
y;
 
  710   t3 = p.
x * p.
x + p.
y * p.
y;
 
  716     if ((t3 >= tolORMax2) && (t2 < 0)) 
 
  726         sd = c / (-b + std::sqrt(d));
 
  732             double fTerm = sd - std::fmod(sd, dRmax);
 
  738           if (std::fabs(zi) <= tolODz)
 
  765       if ((t3 > tolIRMin2) && (t2 < 0) && (std::fabs(p.
z) <= tolIDz))
 
  772           iden   = std::sqrt(t3);
 
  773           cosPsi = inum / iden;
 
  782             c = t3 - fRMax * 
fRMax;
 
  793                 snxt = c / (-b + std::sqrt(d)); 
 
  795                 if (snxt < halfCarTolerance)
 
  816           c = t3 - fRMax * 
fRMax;
 
  827               snxt = c / (-b + std::sqrt(d)); 
 
  829               if (snxt < halfCarTolerance)
 
  852         sd = (b > 0.) ? c / (-b - std::sqrt(d)) : (-b + std::sqrt(d));
 
  853         if (sd >= -halfCarTolerance)  
 
  864             double fTerm = sd - std::fmod(sd, dRmax);
 
  868           if (std::fabs(zi) <= tolODz)
 
  914       if (Dist < halfCarTolerance)
 
  925           if (std::fabs(zi) <= tolODz)
 
  929             rho2 = xi * xi + yi * yi;
 
  931             if (((rho2 >= tolIRMin2) && (rho2 <= tolIRMax2))
 
  932                 || ((rho2 > tolORMin2) && (rho2 < tolIRMin2)
 
  935                 || ((rho2 > tolIRMax2) && (rho2 < tolORMax2)
 
  960       if (Dist < halfCarTolerance)
 
  971           if (std::fabs(zi) <= tolODz)
 
  975             rho2 = xi * xi + yi * yi;
 
  976             if (((rho2 >= tolIRMin2) && (rho2 <= tolIRMax2))
 
  977                 || ((rho2 > tolORMin2)  && (rho2 < tolIRMin2)
 
  980                 || ((rho2 > tolIRMax2) && (rho2 < tolORMax2)
 
  997   if (snxt < halfCarTolerance)
 
 1032   double safe = 0.0, rho, safe1, safe2, safe3;
 
 1036   rho  = std::sqrt(p.
x * p.
x + p.
y * p.
y);
 
 1037   safe1 = 
fRMin - rho;
 
 1038   safe2 = rho - 
fRMax;
 
 1039   safe3 = std::fabs(p.
z) - 
fDz;
 
 1057     if ((outside) && (safePhi > safe))
 
 1065     safe = 0; 
return safe; 
 
 1067   if (!aAccurate) 
return safe;
 
 1072     safsq += safe1 * safe1;
 
 1077     safsq += safe2 * safe2;
 
 1082     safsq += safe3 * safe3;
 
 1085   if (count == 1) 
return safe;
 
 1086   return std::sqrt(safsq);
 
 1099   double deltaR, t1, t2, t3, b, c, 
d2, roMin2;
 
 1106   double pDistS, compS, pDistE, compE, sphi2, xi, yi, vphi, roi2;
 
 1113     if (pdist > halfCarTolerance)
 
 1129     if (pdist > halfCarTolerance)
 
 1131       snxt = -pdist / v.
z;
 
 1158   t1   = 1.0 - v.
z * v.
z;   
 
 1159   t2   = p.
x * v.
x + p.
y * v.
y;
 
 1160   t3   = p.
x * p.
x + p.
y * p.
y;
 
 1168     roi2 = snxt * snxt * t1 + 2 * snxt * t2 + t3;  
 
 1191           srd = c / (-b - std::sqrt(d2));
 
 1210       roMin2 = t3 - t2 * t2 / t1; 
 
 1226             srd = c / (-b + std::sqrt(d2));
 
 1243             srd    = -b + std::sqrt(d2);
 
 1264           srd    = -b + std::sqrt(d2);
 
 1284       vphi = std::atan2(v.
y, v.
x);
 
 1286       if (vphi < 
fSPhi - halfAngTolerance)
 
 1290       else if (vphi > 
fSPhi + 
fDPhi + halfAngTolerance)
 
 1311                                         && (pDistE <= halfCarTolerance)))
 
 1313                                             && (pDistE >  halfCarTolerance))))
 
 1319             sphi = pDistS / compS;
 
 1321             if (sphi >= -halfCarTolerance)
 
 1323               xi = p.
x + sphi * v.
x;
 
 1324               yi = p.
y + sphi * v.
y;
 
 1332                 if (((
fSPhi - halfAngTolerance) <= vphi)
 
 1333                     && ((
fSPhi + 
fDPhi + halfAngTolerance) >= vphi))
 
 1345                 if (pDistS > -halfCarTolerance)
 
 1363             sphi2 = pDistE / compE;
 
 1367             if ((sphi2 > -halfCarTolerance) && (sphi2 < sphi))
 
 1369               xi = p.
x + sphi2 * v.
x;
 
 1370               yi = p.
y + sphi2 * v.
y;
 
 1376                 if (!((
fSPhi - halfAngTolerance <= vphi)
 
 1377                       && (
fSPhi + 
fDPhi + halfAngTolerance >= vphi)))
 
 1380                   if (pDistE <= -halfCarTolerance)
 
 1397                   if (pDistE <= -halfCarTolerance)
 
 1419         if ((
fSPhi - halfAngTolerance <= vphi)
 
 1420             && (vphi <= 
fSPhi + 
fDPhi + halfAngTolerance))
 
 1450         xi = p.
x + snxt * v.
x;
 
 1451         yi = p.
y + snxt * v.
y;
 
 1457         xi = p.
x + snxt * v.
x;
 
 1458         yi = p.
y + snxt * v.
y;
 
 1502         std::ostringstream message;
 
 1503         int oldprc = message.precision(16);
 
 1504         message << 
"Undefined side for valid surface normal to solid." 
 1506                 << 
"Position:"  << std::endl << std::endl
 
 1507                 << 
"p.x = "  << p.
x << 
" mm" << std::endl
 
 1508                 << 
"p.y = "  << p.
y << 
" mm" << std::endl
 
 1509                 << 
"p.z = "  << p.
z << 
" mm" << std::endl << std::endl
 
 1510                 << 
"Direction:" << std::endl << std::endl
 
 1511                 << 
"v.x = "  << v.
x << std::endl
 
 1512                 << 
"v.y = "  << v.
y << std::endl
 
 1513                 << 
"v.z = "  << v.
z << std::endl << std::endl
 
 1514                 << 
"Proposed distance :" << std::endl << std::endl
 
 1515                 << 
"snxt = "    << snxt << 
" mm" << std::endl;
 
 1516         message.precision(oldprc);
 
 1518                           Warning, 1, message.str().c_str());
 
 1522   if (snxt < halfCarTolerance)
 
 1536   double safe = 0.0, rho, safeZ;
 
 1537   rho = std::sqrt(p.
x * p.
x + p.
y * p.
y);
 
 1542     int oldprc = cout.precision(16);
 
 1545     cout << 
"Position:" << std::endl << std::endl;
 
 1546     cout << 
"p.x = "   << p.
x << 
" mm" << std::endl;
 
 1547     cout << 
"p.y = "   << p.
y << 
" mm" << std::endl;
 
 1548     cout << 
"p.z = "   << p.
z << 
" mm" << std::endl << std::endl;
 
 1549     cout.precision(oldprc);
 
 1551                       Warning, 1, 
"Point p is outside !?");
 
 1555   safeZ = 
fDz - std::fabs(p.
z);
 
 1576   return std::string(
"Tubs");
 
 1585   return new UTubs(*
this);
 
 1594   int oldprc = os.precision(16);
 
 1595   os << 
"-----------------------------------------------------------\n" 
 1596      << 
"                *** Dump for solid - " << 
GetName() << 
" ***\n" 
 1597      << 
"                ===================================================\n" 
 1598      << 
" Solid type: UTubs\n" 
 1599      << 
" Parameters: \n" 
 1600      << 
"                inner radius : " << 
fRMin << 
" mm \n" 
 1601      << 
"                outer radius : " << 
fRMax << 
" mm \n" 
 1602      << 
"                half length Z: " << 
fDz << 
" mm \n" 
 1605      << 
"-----------------------------------------------------------\n";
 
 1606   os.precision(oldprc);
 
 1617   double xRand, yRand, zRand, phi, cosphi, sinphi, chose,
 
 1618          aOne, aTwo, aThr, aFou;
 
 1623   aThr = 0.5 * 
fDPhi * (fRMax * fRMax - fRMin * 
fRMin);
 
 1627   cosphi = std::cos(phi);
 
 1628   sinphi = std::sin(phi);
 
 1639   if ((chose >= 0) && (chose < aOne))
 
 1641     xRand = fRMax * cosphi;
 
 1642     yRand = fRMax * sinphi;
 
 1644     return UVector3(xRand, yRand, zRand);
 
 1646   else if ((chose >= aOne) && (chose < aOne + aTwo))
 
 1648     xRand = fRMin * cosphi;
 
 1649     yRand = fRMin * sinphi;
 
 1651     return UVector3(xRand, yRand, zRand);
 
 1653   else if ((chose >= aOne + aTwo) && (chose < aOne + aTwo + aThr))
 
 1655     xRand = rRand * cosphi;
 
 1656     yRand = rRand * sinphi;
 
 1658     return UVector3(xRand, yRand, zRand);
 
 1660   else if ((chose >= aOne + aTwo + aThr) && (chose < aOne + aTwo + 2.*aThr))
 
 1662     xRand = rRand * cosphi;
 
 1663     yRand = rRand * sinphi;
 
 1665     return UVector3(xRand, yRand, zRand);
 
 1667   else if ((chose >= aOne + aTwo + 2.*aThr)
 
 1668            && (chose < aOne + aTwo + 2.*aThr + aFou))
 
 1673     return UVector3(xRand, yRand, zRand);
 
 1680     return UVector3(xRand, yRand, zRand);
 
double GetStartPhiAngle() const 
static double frTolerance
double GetZHalfLength() const 
double SafetyFromOutside(const UVector3 &p, bool precise=false) const 
double SafetyFromInside(const UVector3 &p, bool precise=false) const 
virtual void GetParametersList(int, double *) const 
const std::string & GetName() const 
double GetInnerRadius() const 
VUSolid::EnumInside Inside(const UVector3 &p) const 
static double Tolerance()
void CheckPhiAngles(double sPhi, double dPhi)
static const double kInfinity
double DistanceToOut(const UVector3 &p, const UVector3 &v, UVector3 &n, bool &validNorm, double aPstep=UUtils::kInfinity) const 
double GetDeltaPhiAngle() const 
UGeometryType GetEntityType() const 
bool Normal(const UVector3 &p, UVector3 &normal) const 
virtual UVector3 ApproxSurfaceNormal(const UVector3 &p) const 
UTubs & operator=(const UTubs &rhs)
static double faTolerance
UVector3 GetPointOnSurface() const 
void Extent(UVector3 &aMin, UVector3 &aMax) const 
double GetRadiusInRing(double rmin, double rmax)
std::ostream & StreamInfo(std::ostream &os) const 
double GetOuterRadius() const 
std::string UGeometryType
double SafetyToPhi(const UVector3 &p, const double rho, bool &outside) const 
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const 
double Random(double min=0.0, double max=1.0)
double SafetyFromInsideR(const UVector3 &p, const double rho, bool precise=false) const