35 double pRmin,
double pRmax,
36 double pSPhi,
double pDPhi,
37 double pSTheta,
double pDTheta)
38 :
VUSolid(pName), fCubicVolume(0.),
39 fSurfaceArea(0.),fEpsilon(2.e-11),
40 fFullPhiSphere(true), fFullThetaSphere(true)
47 if ((pRmin >= pRmax) || (pRmax < 1.1 *
kRadTolerance) || (pRmin < 0))
49 std::ostringstream message;
50 message <<
"Invalid radii for Solid: " <<
GetName() << std::endl
51 <<
"pRmin = " << pRmin <<
", pRmax = " << pRmax;
79 :
VUSolid(rhs), fCubicVolume(0.),fSurfaceArea(0.),
80 fRminTolerance(rhs.fRminTolerance),
81 kTolerance(rhs.kTolerance), kAngTolerance(rhs.kAngTolerance),
82 kRadTolerance(rhs.kRadTolerance), fEpsilon(rhs.fEpsilon),
83 fRmin(rhs.fRmin), fRmax(rhs.fRmax), fSPhi(rhs.fSPhi), fDPhi(rhs.fDPhi),
84 fSTheta(rhs.fSTheta), fDTheta(rhs.fDTheta),
85 sinCPhi(rhs.sinCPhi), cosCPhi(rhs.cosCPhi),
86 cosHDPhiOT(rhs.cosHDPhiOT), cosHDPhiIT(rhs.cosHDPhiIT),
87 sinSPhi(rhs.sinSPhi), cosSPhi(rhs.cosSPhi),
88 sinEPhi(rhs.sinEPhi), cosEPhi(rhs.cosEPhi),
89 hDPhi(rhs.hDPhi), cPhi(rhs.cPhi), ePhi(rhs.ePhi),
90 sinSTheta(rhs.sinSTheta), cosSTheta(rhs.cosSTheta),
91 sinETheta(rhs.sinETheta), cosETheta(rhs.cosETheta),
92 tanSTheta(rhs.tanSTheta), tanSTheta2(rhs.tanSTheta2),
93 tanETheta(rhs.tanETheta), tanETheta2(rhs.tanETheta2), eTheta(rhs.eTheta),
94 fFullPhiSphere(rhs.fFullPhiSphere), fFullThetaSphere(rhs.fFullThetaSphere),
95 fFullSphere(rhs.fFullSphere)
114 VUSolid::operator=(rhs);
166 double rho, rho2, rad2, tolRMin, tolRMax;
170 const double halfTolerance =
kTolerance * 0.5;
172 const double rMaxMinus =
fRmax - halfTolerance;
173 const double rMinPlus = (
fRmin > 0) ?
fRmin + halfRminTolerance : 0;
175 rho2 = p.
x() * p.
x() + p.
y() * p.
y();
176 rad2 = rho2 + p.
z() * p.
z();
199 if ((rad2 <= rMaxMinus * rMaxMinus) && (rad2 >= rMinPlus * rMinPlus))
205 tolRMax =
fRmax + halfTolerance;
207 if ((rad2 <= tolRMax * tolRMax) && (rad2 >= tolRMin * tolRMin))
221 pPhi = std::atan2(p.
y(), p.
x());
223 if (pPhi <
fSPhi - halfAngTolerance)
227 else if (pPhi >
ePhi + halfAngTolerance)
232 if ((pPhi <
fSPhi - halfAngTolerance)
233 || (pPhi >
ePhi + halfAngTolerance))
240 if ((pPhi <
fSPhi + halfAngTolerance)
241 || (pPhi >
ePhi - halfAngTolerance))
252 rho = std::sqrt(rho2);
253 pTheta = std::atan2(rho, p.
z());
258 || ((eTheta < UUtils::kPi) && (pTheta >
eTheta - halfAngTolerance)) )
276 ||((eTheta < UUtils::kPi )&&(pTheta >
eTheta + halfAngTolerance)) )
294 double rho, rho2, radius, pTheta, pPhi = 0.;
298 UVector3 nR, nPs, nPe, nTs, nTe, nZ(0., 0., 1.);
304 rho2 = p.
x() * p.
x() + p.
y() * p.
y();
305 radius = std::sqrt(rho2 + p.
z() * p.
z());
306 rho = std::sqrt(rho2);
308 double distRMax = std::fabs(radius -
fRmax);
309 if (
fRmin) distRMin = std::fabs(radius -
fRmin);
313 pPhi = std::atan2(p.
y(), p.
x());
315 if (pPhi <
fSPhi - halfAngTolerance)
319 else if (pPhi >
ePhi + halfAngTolerance)
328 distSPhi = std::fabs(pPhi -
fSPhi);
329 distEPhi = std::fabs(pPhi -
ePhi);
343 pTheta = std::atan2(rho, p.
z());
344 distSTheta = std::fabs(pTheta -
fSTheta);
345 distETheta = std::fabs(pTheta -
eTheta);
371 nR =
UVector3(p.
x() / radius, p.
y() / radius, p.
z() / radius);
374 if (distRMax <= halfCarTolerance)
379 if (
fRmin && (distRMin <= halfCarTolerance))
386 if (distSPhi <= halfAngTolerance)
391 if (distEPhi <= halfAngTolerance)
399 if ((distSTheta <= halfAngTolerance) && (
fSTheta > 0.))
422 if (sumnorm.
z() == 0.)
432 UWarning, 1,
"Point p is not on surface !?");
436 else if (noSurfaces == 1)
442 norm = sumnorm.
Unit();
445 return (noSurfaces > 0);
458 double rho, rho2, radius, pPhi, pTheta;
459 double distRMin, distRMax, distSPhi, distEPhi,
460 distSTheta, distETheta, distMin;
462 rho2 = p.
x() * p.
x() + p.
y() * p.
y();
463 radius = std::sqrt(rho2 + p.
z() * p.
z());
464 rho = std::sqrt(rho2);
470 distRMax = std::fabs(radius -
fRmax);
473 distRMin = std::fabs(radius -
fRmin);
475 if (distRMin < distRMax)
496 pPhi = std::atan2(p.
y(), p.
x());
510 distSPhi = std::fabs(pPhi -
fSPhi) * rho;
513 distEPhi = std::fabs(pPhi -
fSPhi -
fDPhi) * rho;
517 if (distSPhi < distEPhi)
519 if (distSPhi < distMin)
527 if (distEPhi < distMin)
541 pTheta = std::atan2(rho, p.
z());
542 distSTheta = std::fabs(pTheta -
fSTheta) * radius;
547 if (distSTheta < distETheta)
549 if (distSTheta < distMin)
551 distMin = distSTheta;
557 if (distETheta < distMin)
559 distMin = distETheta;
568 norm =
UVector3(-p.
x() / radius, -p.
y() / radius, -p.
z() / radius);
571 norm =
UVector3(p.
x() / radius, p.
y() / radius, p.
z() / radius);
593 "Undefined side for valid surface normal to solid.");
632 double rho2, rad2, pDotV2d, pDotV3d, pTheta;
633 double tolSTheta = 0., tolETheta = 0.;
634 const double dRmax = 100.*
fRmax;
638 const double halfTolerance =
kTolerance * 0.5;
640 const double tolORMin2 = (
fRmin > halfRminTolerance)
641 ? (
fRmin - halfRminTolerance) * (
fRmin - halfRminTolerance) : 0;
642 const double tolIRMin2 =
643 (
fRmin + halfRminTolerance) * (
fRmin + halfRminTolerance);
644 const double tolORMax2 =
645 (
fRmax + halfTolerance) * (
fRmax + halfTolerance);
646 const double tolIRMax2 =
647 (
fRmax - halfTolerance) * (
fRmax - halfTolerance);
651 double xi, yi, zi, rhoi, rhoi2, radi2, iTheta;
663 double dist2STheta, dist2ETheta;
668 rho2 = p.
x() * p.
x() + p.
y() * p.
y();
669 rad2 = rho2 + p.
z() * p.
z();
670 pTheta = std::atan2(std::sqrt(rho2), p.
z());
672 pDotV2d = p.
x() * v.
x() + p.
y() * v.
y();
673 pDotV3d = pDotV2d + p.
z() * v.
z();
679 tolSTheta =
fSTheta - halfAngTolerance;
680 tolETheta =
eTheta + halfAngTolerance;
704 d2 = pDotV3d * pDotV3d - c;
708 sd = -pDotV3d - std::sqrt(d2);
715 double fTerm = sd - std::fmod(sd, dRmax);
718 xi = p.
x() + sd * v.
x();
719 yi = p.
y() + sd * v.
y();
720 rhoi = std::sqrt(xi * xi + yi * yi);
730 zi = p.
z() + sd * v.
z();
735 iTheta = std::atan2(rhoi, zi);
736 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
751 zi = p.
z() + sd * v.
z();
756 iTheta = std::atan2(rhoi, zi);
757 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
779 d2 = pDotV3d * pDotV3d - c;
781 if ((rad2 > tolIRMax2)
782 && ((d2 >=
kTolerance * fRmax) && (pDotV3d < 0)))
835 d2 = pDotV3d * pDotV3d - c;
840 if ((c > -halfRminTolerance) && (rad2 < tolIRMin2)
887 sd = -pDotV3d + std::sqrt(d2);
888 if (sd >= halfRminTolerance)
890 xi = p.
x() + sd * v.
x();
891 yi = p.
y() + sd * v.
y();
892 rhoi = std::sqrt(xi * xi + yi * yi);
902 zi = p.
z() + sd * v.
z();
907 iTheta = std::atan2(rhoi, zi);
908 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
923 zi = p.
z() + sd * v.
z();
928 iTheta = std::atan2(rhoi, zi);
929 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
964 if (Dist < halfCarTolerance)
972 xi = p.
x() + sd * v.
x();
973 yi = p.
y() + sd * v.
y();
974 zi = p.
z() + sd * v.
z();
975 rhoi2 = xi * xi + yi * yi ;
976 radi2 = rhoi2 + zi * zi ;
987 if ((radi2 <= tolORMax2)
988 && (radi2 >= tolORMin2)
997 iTheta = std::atan2(std::sqrt(rhoi2), zi);
998 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
1003 if ((yi *
cosCPhi - xi * sinCPhi) <= 0)
1026 if (Dist < halfCarTolerance)
1034 xi = p.
x() + sd * v.
x();
1035 yi = p.
y() + sd * v.
y();
1036 zi = p.
z() + sd * v.
z();
1037 rhoi2 = xi * xi + yi * yi ;
1038 radi2 = rhoi2 + zi * zi ;
1049 if ((radi2 <= tolORMax2)
1050 && (radi2 >= tolORMin2)
1059 iTheta = std::atan2(std::sqrt(rhoi2), zi);
1060 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
1065 if ((yi *
cosCPhi - xi * sinCPhi) >= 0)
1121 if (pTheta < tolSTheta)
1131 c = dist2STheta / t1;
1138 zi = p.
z() + sd * v.
z();
1144 if ((sd >= 0) && (sd < snxt))
1146 xi = p.
x() + sd * v.
x();
1147 yi = p.
y() + sd * v.
y();
1148 zi = p.
z() + sd * v.
z();
1149 rhoi2 = xi * xi + yi * yi;
1150 radi2 = rhoi2 + zi * zi;
1151 if ((radi2 <= tolORMax2)
1152 && (radi2 >= tolORMin2)
1182 c = dist2ETheta / t1;
1190 if ((sd >= 0) && (sd < snxt))
1192 xi = p.
x() + sd * v.
x();
1193 yi = p.
y() + sd * v.
y();
1194 zi = p.
z() + sd * v.
z();
1195 rhoi2 = xi * xi + yi * yi;
1196 radi2 = rhoi2 + zi * zi;
1198 if ((radi2 <= tolORMax2)
1199 && (radi2 >= tolORMin2)
1220 else if (pTheta > tolETheta)
1231 c = dist2ETheta / t1;
1238 zi = p.
z() + sd * v.
z();
1244 if ((sd >= 0) && (sd < snxt))
1246 xi = p.
x() + sd * v.
x();
1247 yi = p.
y() + sd * v.
y();
1248 zi = p.
z() + sd * v.
z();
1249 rhoi2 = xi * xi + yi * yi;
1250 radi2 = rhoi2 + zi * zi;
1252 if ((radi2 <= tolORMax2)
1253 && (radi2 >= tolORMin2)
1283 c = dist2STheta / t1;
1291 if ((sd >= 0) && (sd < snxt))
1293 xi = p.
x() + sd * v.
x();
1294 yi = p.
y() + sd * v.
y();
1295 zi = p.
z() + sd * v.
z();
1296 rhoi2 = xi * xi + yi * yi;
1297 radi2 = rhoi2 + zi * zi;
1299 if ((radi2 <= tolORMax2)
1300 && (radi2 >= tolORMin2)
1322 && (
fSTheta > halfAngTolerance))
1330 || (t2 < 0 && tolIRMin2 < rad2 && rad2 < tolIRMax2 && fSTheta >
UUtils::kPi / 2)
1353 c = dist2STheta / t1;
1360 if ((sd >= halfCarTolerance) && (sd < snxt) && (fSTheta <
UUtils::kPi / 2))
1363 xi = p.
x() + sd * v.
x();
1364 yi = p.
y() + sd * v.
y();
1365 zi = p.
z() + sd * v.
z();
1366 rhoi2 = xi * xi + yi * yi;
1367 radi2 = rhoi2 + zi * zi;
1369 if ((radi2 <= tolORMax2)
1370 && (radi2 >= tolORMin2)
1400 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2))
1402 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2))
1404 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2)))
1426 c = dist2ETheta / t1;
1434 if ((sd >= halfCarTolerance)
1437 xi = p.
x() + sd * v.
x();
1438 yi = p.
y() + sd * v.
y();
1439 zi = p.
z() + sd * v.
z();
1440 rhoi2 = xi * xi + yi * yi;
1441 radi2 = rhoi2 + zi * zi;
1443 if ((radi2 <= tolORMax2)
1444 && (radi2 >= tolORMin2)
1474 c = dist2STheta / t1;
1482 if ((sd >= 0) && (sd < snxt))
1484 xi = p.
x() + sd * v.
x();
1485 yi = p.
y() + sd * v.
y();
1486 zi = p.
z() + sd * v.
z();
1487 rhoi2 = xi * xi + yi * yi;
1488 radi2 = rhoi2 + zi * zi;
1490 if ((radi2 <= tolORMax2)
1491 && (radi2 >= tolORMin2)
1515 c = dist2ETheta / t1;
1523 if ((sd >= 0) && (sd < snxt))
1525 xi = p.
x() + sd * v.
x();
1526 yi = p.
y() + sd * v.
y();
1527 zi = p.
z() + sd * v.
z();
1528 rhoi2 = xi * xi + yi * yi;
1529 radi2 = rhoi2 + zi * zi;
1531 if ((radi2 <= tolORMax2)
1532 && (radi2 >= tolORMin2)
1566 double safe = 0.0, safeRMin, safeRMax, safePhi, safeTheta;
1567 double rho2, rds, rho;
1569 double pTheta, dTheta1, dTheta2;
1570 rho2 = p.
x() * p.
x() + p.
y() * p.
y();
1571 rds = std::sqrt(rho2 + p.
z() * p.
z());
1572 rho = std::sqrt(rho2);
1579 safeRMin =
fRmin - rds;
1580 safeRMax = rds -
fRmax;
1581 if (safeRMin > safeRMax)
1603 if (cosPsi < std::cos(
hDPhi))
1626 pTheta = std::acos(p.
z() / rds);
1632 dTheta2 = pTheta -
eTheta;
1633 if (dTheta1 > dTheta2)
1637 safeTheta = rds * std::sin(dTheta1);
1638 if (safe <= safeTheta)
1648 safeTheta = rds * std::sin(dTheta2);
1649 if (safe <= safeTheta)
1677 const double halfTolerance =
kTolerance * 0.5;
1679 const double rMaxPlus =
fRmax + halfTolerance;
1680 const double Rmin_minus = (
fRmin) ?
fRmin - halfRminTolerance : 0;
1686 double pDistS, compS, pDistE, compE, sphi2, vphi;
1688 double rho2, rad2, pDotV2d, pDotV3d;
1695 double dist2STheta, dist2ETheta, distTheta;
1700 rho2 = p.
x() * p.
x() + p.
y() * p.
y();
1701 rad2 = rho2 + p.
z() * p.
z();
1703 pDotV2d = p.
x() * v.
x() + p.
y() * v.
y();
1704 pDotV3d = pDotV2d + p.
z() * v.
z();
1722 if ((rad2 <= rMaxPlus * rMaxPlus) && (rad2 >= Rmin_minus * Rmin_minus))
1737 d2 = pDotV3d * pDotV3d - c;
1740 && ((pDotV3d >= 0) || (d2 < 0)))
1749 snxt = -pDotV3d + std::sqrt(d2);
1761 d2 = pDotV3d * pDotV3d - c;
1776 sd = -pDotV3d - std::sqrt(d2);
1821 if (std::fabs(p.
z()) <= halfTolerance)
1827 stheta = -p.
z() / v.
z();
1837 distTheta = std::sqrt(rho2) - p.
z() *
tanSTheta;
1839 if (std::fabs(t1) < halfAngTolerance)
1844 if (std::fabs(distTheta) < halfTolerance)
1851 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
1854 p.
y() / rhoSecTheta,
1868 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
1871 p.
y() / rhoSecTheta,
1878 stheta = -0.5 * dist2STheta / t2;
1884 if (std::fabs(distTheta) < halfTolerance)
1891 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
1894 p.
y() / rhoSecTheta,
1908 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
1911 p.
y() / rhoSecTheta,
1923 c = dist2STheta / t1;
1934 if (((std::fabs(sd) < halfTolerance) && (t2 < 0.))
1935 || (sd < 0.) || ((sd > 0.) && (p.
z() + sd * v.
z() > 0.)))
1939 if ((sd > halfTolerance) && (p.
z() + sd * v.
z() <= 0.))
1949 if (((std::fabs(sd) < halfTolerance) && (t2 >= 0.))
1950 || (sd < 0.) || ((sd > 0.) && (p.
z() + sd * v.
z() < 0.)))
1954 if ((sd > halfTolerance) && (p.
z() + sd * v.
z() >= 0.))
1970 if (std::fabs(p.
z()) <= halfTolerance)
1976 sd = -p.
z() / v.
z();
1991 distTheta = std::sqrt(rho2) - p.
z() *
tanETheta;
1993 if (std::fabs(t1) < halfAngTolerance)
1998 if (std::fabs(distTheta) < halfTolerance)
2005 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2007 p.
y() / rhoSecTheta,
2021 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2023 p.
y() / rhoSecTheta,
2033 sd = -0.5 * dist2ETheta / t2;
2044 if (std::fabs(distTheta) < halfTolerance)
2051 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2053 p.
y() / rhoSecTheta,
2060 && (t2 < 0.) && (p.
z() <= 0.))
2065 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2067 p.
y() / rhoSecTheta,
2076 c = dist2ETheta / t1;
2087 if (((std::fabs(sd) < halfTolerance) && (t2 < 0.))
2092 if (sd > halfTolerance)
2105 if (((std::fabs(sd) < halfTolerance) && (t2 >= 0.))
2106 || (sd < 0.) || ((sd > 0.) && (p.
z() + sd * v.
z() > 0.)))
2110 if ((sd > halfTolerance) && (p.
z() + sd * v.
z() <= 0.))
2143 if ((pDistS <= 0) && (pDistE <= 0))
2149 sphi = pDistS / compS;
2150 xi = p.
x() + sphi * v.
x();
2151 yi = p.
y() + sphi * v.
y();
2157 vphi = std::atan2(v.
y(), v.
x());
2159 if (((
fSPhi - halfAngTolerance) <= vphi)
2160 && ((
ePhi + halfAngTolerance) >= vphi))
2172 if (pDistS > -halfCarTolerance)
2185 sphi2 = pDistE / compE;
2188 xi = p.
x() + sphi2 * v.
x();
2189 yi = p.
y() + sphi2 * v.
y();
2197 vphi = std::atan2(v.
y(), v.
x());
2199 if (!((
fSPhi - halfAngTolerance <= vphi)
2200 && (
fSPhi +
fDPhi + halfAngTolerance >= vphi)))
2203 if (pDistE <= -halfCarTolerance)
2216 if (pDistE <= -halfCarTolerance)
2228 else if ((pDistS >= 0) && (pDistE >= 0))
2230 if (pDistS <= pDistE)
2240 if ((compS < 0) && (compE < 0))
2254 if ((compS >= 0) && (compE >= 0))
2264 else if ((pDistS > 0) && (pDistE < 0))
2272 sphi = pDistE / compE;
2273 xi = p.
x() + sphi * v.
x();
2274 yi = p.
y() + sphi * v.
y();
2281 vphi = std::atan2(v.
y(), v.
x());
2283 if (((
fSPhi - halfAngTolerance) <= vphi)
2284 && ((
ePhi + halfAngTolerance) >= vphi))
2296 if (pDistE > -halfCarTolerance)
2313 sphi = pDistE / compE;
2314 xi = p.
x() + sphi * v.
x();
2315 yi = p.
y() + sphi * v.
y();
2322 vphi = std::atan2(v.
y(), v.
x());
2324 if (((
fSPhi - halfAngTolerance) <= vphi)
2325 && ((
ePhi + halfAngTolerance) >= vphi))
2357 sphi = pDistS / compS;
2358 xi = p.
x() + sphi * v.
x();
2359 yi = p.
y() + sphi * v.
y();
2366 vphi = std::atan2(v.
y(), v.
x());
2368 if (((
fSPhi - halfAngTolerance) <= vphi)
2369 && ((
ePhi + halfAngTolerance) >= vphi))
2381 if (pDistS > -halfCarTolerance)
2398 sphi = pDistS / compS;
2399 xi = p.
x() + sphi * v.
x();
2400 yi = p.
y() + sphi * v.
y();
2407 vphi = std::atan2(v.
y(), v.
x());
2409 if (((
fSPhi - halfAngTolerance) <= vphi)
2410 && ((
ePhi + halfAngTolerance) >= vphi))
2444 vphi = std::atan2(v.
y(), v.
x());
2445 if ((
fSPhi - halfAngTolerance < vphi) && (vphi <
ePhi + halfAngTolerance))
2475 xi = p.
x() + snxt * v.
x();
2476 yi = p.
y() + snxt * v.
y();
2477 zi = p.
z() + snxt * v.
z();
2483 xi = p.
x() + snxt * v.
x();
2484 yi = p.
y() + snxt * v.
y();
2485 zi = p.
z() + snxt * v.
z();
2524 xi = p.
x() + snxt * v.
x();
2525 yi = p.
y() + snxt * v.
y();
2526 rho2 = xi * xi + yi * yi;
2529 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
2530 n =
UVector3(xi / rhoSecTheta, yi / rhoSecTheta,
2541 xi = p.
x() + snxt * v.
x();
2542 yi = p.
y() + snxt * v.
y();
2543 rho2 = xi * xi + yi * yi;
2546 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
2547 n =
UVector3(xi / rhoSecTheta, yi / rhoSecTheta,
2567 xi = p.
x() + snxt * v.
x();
2568 yi = p.
y() + snxt * v.
y();
2569 rho2 = xi * xi + yi * yi;
2572 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2573 n =
UVector3(xi / rhoSecTheta, yi / rhoSecTheta,
2584 xi = p.
x() + snxt * v.
x();
2585 yi = p.
y() + snxt * v.
y();
2586 rho2 = xi * xi + yi * yi;
2589 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2590 n = -
UVector3(xi / rhoSecTheta, yi / rhoSecTheta,
2604 std::ostringstream message;
2605 int oldprc = message.precision(16);
2606 message <<
"Undefined side for valid surface normal to solid."
2608 <<
"Position:" << std::endl << std::endl
2609 <<
"p.x = " << p.
x() <<
" mm" << std::endl
2610 <<
"p.y = " << p.
y() <<
" mm" << std::endl
2611 <<
"p.z = " << p.
z() <<
" mm" << std::endl << std::endl
2612 <<
"Direction:" << std::endl << std::endl
2613 <<
"v.x = " << v.
x() << std::endl
2614 <<
"v.y = " << v.
y() << std::endl
2615 <<
"v.z = " << v.
z() << std::endl << std::endl
2616 <<
"Proposed distance :" << std::endl << std::endl
2617 <<
"snxt = " << snxt <<
" mm" << std::endl;
2618 message.precision(oldprc);
2620 "GeomSolids1002",
UWarning, 1, message.str().c_str());
2627 std::ostringstream message;
2628 int oldprc = message.precision(16);
2629 message <<
"Logic error: snxt = UUtils::Infinity() ???" << std::endl
2630 <<
"Position:" << std::endl << std::endl
2631 <<
"p.x = " << p.
x() <<
" mm" << std::endl
2632 <<
"p.y = " << p.
y() <<
" mm" << std::endl
2633 <<
"p.z = " << p.
z() <<
" mm" << std::endl << std::endl
2634 <<
"Rp = " << std::sqrt(p.
x() * p.
x() + p.
y() * p.
y() + p.
z() * p.
z())
2635 <<
" mm" << std::endl << std::endl
2636 <<
"Direction:" << std::endl << std::endl
2637 <<
"v.x = " << v.
x() << std::endl
2638 <<
"v.y = " << v.
y() << std::endl
2639 <<
"v.z = " << v.
z() << std::endl << std::endl
2640 <<
"Proposed distance :" << std::endl << std::endl
2641 <<
"snxt = " << snxt <<
" mm" << std::endl;
2642 message.precision(oldprc);
2644 "GeomSolids1002",
UWarning, 1, message.str().c_str());
2656 double safe = 0.0, safeRMin, safeRMax, safePhi, safeTheta;
2657 double rho2, rds, rho;
2659 rho2 = p.
x() * p.
x() + p.
y() * p.
y();
2660 rds = std::sqrt(rho2 + p.
z() * p.
z());
2661 rho = std::sqrt(rho2);
2666 int old_prc = cout.precision(16);
2669 cout <<
"Position:" << std::endl << std::endl;
2670 cout <<
"p.x = " << p.
x() <<
" mm" << std::endl;
2671 cout <<
"p.y = " << p.
y() <<
" mm" << std::endl;
2672 cout <<
"p.z = " << p.
z() <<
" mm" << std::endl << std::endl;
2673 cout.precision(old_prc);
2675 "GeomSolids1002",
UWarning, 1,
"Point p is outside !?");
2681 safeRMax =
fRmax-rds;
2685 safeRMin = rds-
fRmin;
2686 safe =
std::min( safeRMin, safeRMax );
2720 pTheta=std::acos(p.
z()/rds);
2725 { dTheta2=
eTheta-pTheta;}
2727 safeTheta=rds*std::sin(
std::min(dTheta1, dTheta2) );
2734 safe =
std::min( safe, safeTheta );
2737 if (safe<0.0) { safe=0; }
2886 return std::string(
"Sphere");
2904 int oldprc = os.precision(16);
2905 os <<
"-----------------------------------------------------------\n"
2906 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
2907 <<
" ===================================================\n"
2908 <<
" Solid type: USphere\n"
2909 <<
" Parameters: \n"
2910 <<
" inner radius: " <<
fRmin <<
" mm \n"
2911 <<
" outer radius: " <<
fRmax <<
" mm \n"
2912 <<
" starting phi of segment : " <<
fSPhi / (
UUtils::kPi / 180.0) <<
" degrees \n"
2913 <<
" delta phi of segment : " <<
fDPhi / (
UUtils::kPi / 180.0) <<
" degrees \n"
2914 <<
" starting theta of segment: " <<
fSTheta / (
UUtils::kPi / 180.0) <<
" degrees \n"
2916 <<
"-----------------------------------------------------------\n";
2917 os.precision(oldprc);
2928 double zRand, aOne, aTwo, aThr, aFou, aFiv, chose, phi, sinphi, cosphi;
2929 double height1, height2, slant1, slant2, costheta, sintheta, rRand;
2944 cosphi = std::cos(phi);
2945 sinphi = std::sin(phi);
2971 if ((chose >= 0.) && (chose < aOne))
2974 fRmax * sintheta * sinphi,
fRmax * costheta);
2976 else if ((chose >= aOne) && (chose < aOne + aTwo))
2979 fRmin * sintheta * sinphi,
fRmin * costheta);
2981 else if ((chose >= aOne + aTwo) && (chose < aOne + aTwo + aThr))
2991 return UVector3(rRand * cosphi, rRand * sinphi, 0.);
2994 else if ((chose >= aOne + aTwo + aThr) && (chose < aOne + aTwo + aThr + aFou))
3004 return UVector3(rRand * cosphi, rRand * sinphi, 0.);
3007 else if ((chose >= aOne + aTwo + aThr + aFou) && (chose < aOne + aTwo + aThr + aFou + aFiv))
3010 rRand * sintheta *
sinSPhi, rRand * costheta);
3015 rRand * sintheta *
sinEPhi, rRand * costheta);
3041 double acos1 = std::acos(std::pow(
sinSTheta, 2) * std::cos(
fDPhi)
3054 double acos2 = std::acos(std::pow(
sinETheta, 2) * std::cos(
fDPhi)
static double frTolerance
double GetInnerRadius() const
const std::string & GetName() const
VUSolid::EnumInside Inside(const UVector3 &p) const
void Extent(UVector3 &aMin, UVector3 &aMax) const
double DistanceToOut(const UVector3 &p, const UVector3 &v, UVector3 &n, bool &validNorm, double aPstep=UUtils::kInfinity) const
UVector3 ApproxSurfaceNormal(const UVector3 &p) const
void CheckThetaAngles(double sTheta, double dTheta)
double GetDeltaThetaAngle() const
USphere & operator=(const USphere &rhs)
double GetOuterRadius() const
double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const
static double Tolerance()
UVector3 GetPointOnSurface() const
double SafetyFromOutside(const UVector3 &p, bool aAccurate=false) const
UGeometryType GetEntityType() const
static double faTolerance
double GetRadiusInRing(double rmin, double rmax)
USphere(const std::string &pName, double pRmin, double pRmax, double pSPhi, double pDPhi, double pSTheta, double pDTheta)
void Exception(const char *originOfException, const char *exceptionCode, UExceptionSeverity severity, int level, const char *description)
void Set(double xx, double yy, double zz)
void GetParametersList(int, double *) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
double GetStartThetaAngle() const
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
std::ostream & StreamInfo(std::ostream &os) const
std::string UGeometryType
void CheckPhiAngles(double sPhi, double dPhi)
bool Normal(const UVector3 &p, UVector3 &n) const
double GetStartPhiAngle() const
double Random(double min=0.0, double max=1.0)
double GetDeltaPhiAngle() const
double SafetyFromInside(const UVector3 &p, bool aAccurate=false) const