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;
1033 double safePhi, cosPsi;
1035 rho = std::sqrt(p.
x * p.
x + p.
y * p.
y);
1036 safe1 =
fRMin - rho;
1037 safe2 = rho -
fRMax;
1038 safe3 = std::fabs(p.
z) -
fDz;
1059 if (cosPsi < std::cos(
fDPhi * 0.5))
1079 safe = 0;
return safe;
1081 if (!aAccurate)
return safe;
1086 safsq += safe1 * safe1;
1091 safsq += safe2 * safe2;
1096 safsq += safe3 * safe3;
1099 if (count == 1)
return safe;
1100 return std::sqrt(safsq);
1113 double deltaR, t1, t2, t3, b, c,
d2, roMin2;
1120 double pDistS, compS, pDistE, compE, sphi2, xi, yi, vphi, roi2;
1127 if (pdist > halfCarTolerance)
1146 if (pdist > halfCarTolerance)
1148 snxt = -pdist / v.
z;
1178 t1 = 1.0 - v.
z * v.
z;
1179 t2 = p.
x * v.
x + p.
y * v.
y;
1180 t3 = p.
x * p.
x + p.
y * p.
y;
1188 roi2 = snxt * snxt * t1 + 2 * snxt * t2 + t3;
1211 srd = c / (-b - std::sqrt(d2));
1234 roMin2 = t3 - t2 * t2 / t1;
1250 srd = c / (-b + std::sqrt(d2));
1269 srd = -b + std::sqrt(d2);
1293 srd = -b + std::sqrt(d2);
1316 vphi = std::atan2(v.
y, v.
x);
1318 if (vphi <
fSPhi - halfAngTolerance)
1322 else if (vphi >
fSPhi +
fDPhi + halfAngTolerance)
1343 && (pDistE <= halfCarTolerance)))
1345 && (pDistE > halfCarTolerance))))
1351 sphi = pDistS / compS;
1353 if (sphi >= -halfCarTolerance)
1355 xi = p.
x + sphi * v.
x;
1356 yi = p.
y + sphi * v.
y;
1364 if (((
fSPhi - halfAngTolerance) <= vphi)
1365 && ((
fSPhi +
fDPhi + halfAngTolerance) >= vphi))
1377 if (pDistS > -halfCarTolerance)
1395 sphi2 = pDistE / compE;
1399 if ((sphi2 > -halfCarTolerance) && (sphi2 < sphi))
1401 xi = p.
x + sphi2 * v.
x;
1402 yi = p.
y + sphi2 * v.
y;
1408 if (!((
fSPhi - halfAngTolerance <= vphi)
1409 && (
fSPhi +
fDPhi + halfAngTolerance >= vphi)))
1412 if (pDistE <= -halfCarTolerance)
1429 if (pDistE <= -halfCarTolerance)
1451 if ((
fSPhi - halfAngTolerance <= vphi)
1452 && (vphi <=
fSPhi +
fDPhi + halfAngTolerance))
1482 xi = p.
x + snxt * v.
x;
1483 yi = p.
y + snxt * v.
y;
1529 std::ostringstream message;
1530 int oldprc = message.precision(16);
1531 message <<
"Undefined side for valid surface normal to solid."
1533 <<
"Position:" << std::endl << std::endl
1534 <<
"p.x = " << p.
x <<
" mm" << std::endl
1535 <<
"p.y = " << p.
y <<
" mm" << std::endl
1536 <<
"p.z = " << p.
z <<
" mm" << std::endl << std::endl
1537 <<
"Direction:" << std::endl << std::endl
1538 <<
"v.x = " << v.
x << std::endl
1539 <<
"v.y = " << v.
y << std::endl
1540 <<
"v.z = " << v.
z << std::endl << std::endl
1541 <<
"Proposed distance :" << std::endl << std::endl
1542 <<
"snxt = " << snxt <<
" mm" << std::endl;
1543 message.precision(oldprc);
1545 Warning, 1, message.str().c_str());
1549 if (snxt < halfCarTolerance)
1564 double safe = 0.0, rho, safeR1, safeR2, safeZ, safePhi;
1565 rho = std::sqrt(p.
x * p.
x + p.
y * p.
y);
1570 int oldprc = cout.precision(16);
1573 cout <<
"Position:" << std::endl << std::endl;
1574 cout <<
"p.x = " << p.
x <<
" mm" << std::endl;
1575 cout <<
"p.y = " << p.
y <<
" mm" << std::endl;
1576 cout <<
"p.z = " << p.
z <<
" mm" << std::endl << std::endl;
1577 cout.precision(oldprc);
1579 Warning, 1,
"Point p is outside !?");
1585 safeR1 = rho -
fRMin;
1586 safeR2 =
fRMax - rho;
1588 if (safeR1 < safeR2)
1601 safeZ =
fDz - std::fabs(p.
z);
1640 return std::string(
"Tubs");
1649 return new UTubs(*
this);
1658 int oldprc = os.precision(16);
1659 os <<
"-----------------------------------------------------------\n"
1660 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1661 <<
" ===================================================\n"
1662 <<
" Solid type: UTubs\n"
1663 <<
" Parameters: \n"
1664 <<
" inner radius : " <<
fRMin <<
" mm \n"
1665 <<
" outer radius : " <<
fRMax <<
" mm \n"
1666 <<
" half length Z: " <<
fDz <<
" mm \n"
1669 <<
"-----------------------------------------------------------\n";
1670 os.precision(oldprc);
1681 double xRand, yRand, zRand, phi, cosphi, sinphi, chose,
1682 aOne, aTwo, aThr, aFou;
1687 aThr = 0.5 *
fDPhi * (fRMax * fRMax - fRMin *
fRMin);
1691 cosphi = std::cos(phi);
1692 sinphi = std::sin(phi);
1703 if ((chose >= 0) && (chose < aOne))
1705 xRand = fRMax * cosphi;
1706 yRand = fRMax * sinphi;
1708 return UVector3(xRand, yRand, zRand);
1710 else if ((chose >= aOne) && (chose < aOne + aTwo))
1712 xRand = fRMin * cosphi;
1713 yRand = fRMin * sinphi;
1715 return UVector3(xRand, yRand, zRand);
1717 else if ((chose >= aOne + aTwo) && (chose < aOne + aTwo + aThr))
1719 xRand = rRand * cosphi;
1720 yRand = rRand * sinphi;
1722 return UVector3(xRand, yRand, zRand);
1724 else if ((chose >= aOne + aTwo + aThr) && (chose < aOne + aTwo + 2.*aThr))
1726 xRand = rRand * cosphi;
1727 yRand = rRand * sinphi;
1729 return UVector3(xRand, yRand, zRand);
1731 else if ((chose >= aOne + aTwo + 2.*aThr)
1732 && (chose < aOne + aTwo + 2.*aThr + aFou))
1737 return UVector3(xRand, yRand, zRand);
1744 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
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)