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;
183 if ((rad2 <= rMaxMinus * rMaxMinus) && (rad2 >= rMinPlus * rMinPlus))
189 tolRMax =
fRmax + halfTolerance;
191 if ((rad2 <= tolRMax * tolRMax) && (rad2 >= tolRMin * tolRMin))
205 pPhi = std::atan2(p.
y, p.
x);
207 if (pPhi <
fSPhi - halfAngTolerance)
211 else if (pPhi >
ePhi + halfAngTolerance)
216 if ((pPhi <
fSPhi - halfAngTolerance)
217 || (pPhi >
ePhi + halfAngTolerance))
224 if ((pPhi <
fSPhi + halfAngTolerance)
225 || (pPhi >
ePhi - halfAngTolerance))
236 rho = std::sqrt(rho2);
237 pTheta = std::atan2(rho, p.
z);
241 if ((pTheta <
fSTheta + halfAngTolerance)
242 || (pTheta >
eTheta - halfAngTolerance))
244 if ((pTheta >=
fSTheta - halfAngTolerance)
245 && (pTheta <=
eTheta + halfAngTolerance))
257 if ((pTheta <
fSTheta - halfAngTolerance)
258 || (pTheta >
eTheta + halfAngTolerance))
276 double rho, rho2, radius, pTheta, pPhi = 0.;
280 UVector3 nR, nPs, nPe, nTs, nTe, nZ(0., 0., 1.);
286 rho2 = p.
x * p.
x + p.
y * p.
y;
287 radius = std::sqrt(rho2 + p.
z * p.
z);
288 rho = std::sqrt(rho2);
290 double distRMax = std::fabs(radius -
fRmax);
291 if (
fRmin) distRMin = std::fabs(radius -
fRmin);
295 pPhi = std::atan2(p.
y, p.
x);
297 if (pPhi <
fSPhi - halfAngTolerance)
301 else if (pPhi >
ePhi + halfAngTolerance)
310 distSPhi = std::fabs(pPhi -
fSPhi);
311 distEPhi = std::fabs(pPhi -
ePhi);
325 pTheta = std::atan2(rho, p.
z);
326 distSTheta = std::fabs(pTheta -
fSTheta);
327 distETheta = std::fabs(pTheta -
eTheta);
353 nR =
UVector3(p.
x / radius, p.
y / radius, p.
z / radius);
356 if (distRMax <= halfCarTolerance)
361 if (
fRmin && (distRMin <= halfCarTolerance))
368 if (distSPhi <= halfAngTolerance)
373 if (distEPhi <= halfAngTolerance)
381 if ((distSTheta <= halfAngTolerance) && (
fSTheta > 0.))
414 Warning, 1,
"Point p is not on surface !?");
418 else if (noSurfaces == 1)
424 norm = sumnorm.
Unit();
427 return (noSurfaces > 0);
440 double rho, rho2, radius, pPhi, pTheta;
441 double distRMin, distRMax, distSPhi, distEPhi,
442 distSTheta, distETheta, distMin;
444 rho2 = p.
x * p.
x + p.
y * p.
y;
445 radius = std::sqrt(rho2 + p.
z * p.
z);
446 rho = std::sqrt(rho2);
452 distRMax = std::fabs(radius -
fRmax);
455 distRMin = std::fabs(radius -
fRmin);
457 if (distRMin < distRMax)
478 pPhi = std::atan2(p.
y, p.
x);
492 distSPhi = std::fabs(pPhi -
fSPhi) * rho;
495 distEPhi = std::fabs(pPhi -
fSPhi -
fDPhi) * rho;
499 if (distSPhi < distEPhi)
501 if (distSPhi < distMin)
509 if (distEPhi < distMin)
523 pTheta = std::atan2(rho, p.
z);
524 distSTheta = std::fabs(pTheta -
fSTheta) * radius;
529 if (distSTheta < distETheta)
531 if (distSTheta < distMin)
533 distMin = distSTheta;
539 if (distETheta < distMin)
541 distMin = distETheta;
550 norm =
UVector3(-p.
x / radius, -p.
y / radius, -p.
z / radius);
553 norm =
UVector3(p.
x / radius, p.
y / radius, p.
z / radius);
575 "Undefined side for valid surface normal to solid.");
614 double rho2, rad2, pDotV2d, pDotV3d, pTheta;
615 double tolSTheta = 0., tolETheta = 0.;
616 const double dRmax = 100.*
fRmax;
620 const double halfTolerance =
kTolerance * 0.5;
622 const double tolORMin2 = (
fRmin > halfRminTolerance)
623 ? (
fRmin - halfRminTolerance) * (
fRmin - halfRminTolerance) : 0;
624 const double tolIRMin2 =
625 (
fRmin + halfRminTolerance) * (
fRmin + halfRminTolerance);
626 const double tolORMax2 =
627 (
fRmax + halfTolerance) * (
fRmax + halfTolerance);
628 const double tolIRMax2 =
629 (
fRmax - halfTolerance) * (
fRmax - halfTolerance);
633 double xi, yi, zi, rhoi, rhoi2, radi2, iTheta;
645 double dist2STheta, dist2ETheta;
650 rho2 = p.
x * p.
x + p.
y * p.
y;
651 rad2 = rho2 + p.
z * p.
z;
652 pTheta = std::atan2(std::sqrt(rho2), p.
z);
654 pDotV2d = p.
x * v.
x + p.
y * v.
y;
655 pDotV3d = pDotV2d + p.
z * v.
z;
661 tolSTheta =
fSTheta - halfAngTolerance;
662 tolETheta =
eTheta + halfAngTolerance;
686 d2 = pDotV3d * pDotV3d - c;
690 sd = -pDotV3d - std::sqrt(d2);
697 double fTerm = sd - std::fmod(sd, dRmax);
702 rhoi = std::sqrt(xi * xi + yi * yi);
717 iTheta = std::atan2(rhoi, zi);
718 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
738 iTheta = std::atan2(rhoi, zi);
739 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
761 d2 = pDotV3d * pDotV3d - c;
763 if ((rad2 > tolIRMax2)
764 && ((d2 >=
kTolerance * fRmax) && (pDotV3d < 0)))
817 d2 = pDotV3d * pDotV3d - c;
822 if ((c > -halfRminTolerance) && (rad2 < tolIRMin2)
869 sd = -pDotV3d + std::sqrt(d2);
870 if (sd >= halfRminTolerance)
874 rhoi = std::sqrt(xi * xi + yi * yi);
889 iTheta = std::atan2(rhoi, zi);
890 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
910 iTheta = std::atan2(rhoi, zi);
911 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
946 if (Dist < halfCarTolerance)
957 rhoi2 = xi * xi + yi * yi ;
958 radi2 = rhoi2 + zi * zi ;
969 if ((radi2 <= tolORMax2)
970 && (radi2 >= tolORMin2)
979 iTheta = std::atan2(std::sqrt(rhoi2), zi);
980 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
985 if ((yi *
cosCPhi - xi * sinCPhi) <= 0)
1008 if (Dist < halfCarTolerance)
1016 xi = p.
x + sd * v.
x;
1017 yi = p.
y + sd * v.
y;
1018 zi = p.
z + sd * v.
z;
1019 rhoi2 = xi * xi + yi * yi ;
1020 radi2 = rhoi2 + zi * zi ;
1031 if ((radi2 <= tolORMax2)
1032 && (radi2 >= tolORMin2)
1041 iTheta = std::atan2(std::sqrt(rhoi2), zi);
1042 if ((iTheta >= tolSTheta) && (iTheta <= tolETheta))
1047 if ((yi *
cosCPhi - xi * sinCPhi) >= 0)
1103 if (pTheta < tolSTheta)
1113 c = dist2STheta / t1;
1120 zi = p.
z + sd * v.
z;
1126 if ((sd >= 0) && (sd < snxt))
1128 xi = p.
x + sd * v.
x;
1129 yi = p.
y + sd * v.
y;
1130 zi = p.
z + sd * v.
z;
1131 rhoi2 = xi * xi + yi * yi;
1132 radi2 = rhoi2 + zi * zi;
1133 if ((radi2 <= tolORMax2)
1134 && (radi2 >= tolORMin2)
1164 c = dist2ETheta / t1;
1172 if ((sd >= 0) && (sd < snxt))
1174 xi = p.
x + sd * v.
x;
1175 yi = p.
y + sd * v.
y;
1176 zi = p.
z + sd * v.
z;
1177 rhoi2 = xi * xi + yi * yi;
1178 radi2 = rhoi2 + zi * zi;
1180 if ((radi2 <= tolORMax2)
1181 && (radi2 >= tolORMin2)
1202 else if (pTheta > tolETheta)
1213 c = dist2ETheta / t1;
1220 zi = p.
z + sd * v.
z;
1226 if ((sd >= 0) && (sd < snxt))
1228 xi = p.
x + sd * v.
x;
1229 yi = p.
y + sd * v.
y;
1230 zi = p.
z + sd * v.
z;
1231 rhoi2 = xi * xi + yi * yi;
1232 radi2 = rhoi2 + zi * zi;
1234 if ((radi2 <= tolORMax2)
1235 && (radi2 >= tolORMin2)
1265 c = dist2STheta / t1;
1273 if ((sd >= 0) && (sd < snxt))
1275 xi = p.
x + sd * v.
x;
1276 yi = p.
y + sd * v.
y;
1277 zi = p.
z + sd * v.
z;
1278 rhoi2 = xi * xi + yi * yi;
1279 radi2 = rhoi2 + zi * zi;
1281 if ((radi2 <= tolORMax2)
1282 && (radi2 >= tolORMin2)
1304 && (
fSTheta > halfAngTolerance))
1312 || (t2 < 0 && tolIRMin2 < rad2 && rad2 < tolIRMax2 && fSTheta >
UUtils::kPi / 2)
1335 c = dist2STheta / t1;
1345 xi = p.
x + sd * v.
x;
1346 yi = p.
y + sd * v.
y;
1347 zi = p.
z + sd * v.
z;
1348 rhoi2 = xi * xi + yi * yi;
1349 radi2 = rhoi2 + zi * zi;
1351 if ((radi2 <= tolORMax2)
1352 && (radi2 >= tolORMin2)
1382 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2))
1384 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2))
1386 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2)))
1408 c = dist2ETheta / t1;
1416 if ((sd >= halfCarTolerance)
1419 xi = p.
x + sd * v.
x;
1420 yi = p.
y + sd * v.
y;
1421 zi = p.
z + sd * v.
z;
1422 rhoi2 = xi * xi + yi * yi;
1423 radi2 = rhoi2 + zi * zi;
1425 if ((radi2 <= tolORMax2)
1426 && (radi2 >= tolORMin2)
1456 c = dist2STheta / t1;
1464 if ((sd >= 0) && (sd < snxt))
1466 xi = p.
x + sd * v.
x;
1467 yi = p.
y + sd * v.
y;
1468 zi = p.
z + sd * v.
z;
1469 rhoi2 = xi * xi + yi * yi;
1470 radi2 = rhoi2 + zi * zi;
1472 if ((radi2 <= tolORMax2)
1473 && (radi2 >= tolORMin2)
1497 c = dist2ETheta / t1;
1505 if ((sd >= 0) && (sd < snxt))
1507 xi = p.
x + sd * v.
x;
1508 yi = p.
y + sd * v.
y;
1509 zi = p.
z + sd * v.
z;
1510 rhoi2 = xi * xi + yi * yi;
1511 radi2 = rhoi2 + zi * zi;
1513 if ((radi2 <= tolORMax2)
1514 && (radi2 >= tolORMin2)
1548 double safe = 0.0, safeRMin, safeRMax, safePhi, safeTheta;
1549 double rho2, rds, rho;
1551 double pTheta, dTheta1, dTheta2;
1552 rho2 = p.
x * p.
x + p.
y * p.
y;
1553 rds = std::sqrt(rho2 + p.
z * p.
z);
1554 rho = std::sqrt(rho2);
1561 safeRMin =
fRmin - rds;
1562 safeRMax = rds -
fRmax;
1563 if (safeRMin > safeRMax)
1585 if (cosPsi < std::cos(
hDPhi))
1608 pTheta = std::acos(p.
z / rds);
1614 dTheta2 = pTheta -
eTheta;
1615 if (dTheta1 > dTheta2)
1619 safeTheta = rds * std::sin(dTheta1);
1620 if (safe <= safeTheta)
1630 safeTheta = rds * std::sin(dTheta2);
1631 if (safe <= safeTheta)
1659 const double halfTolerance =
kTolerance * 0.5;
1661 const double rMaxPlus =
fRmax + halfTolerance;
1662 const double Rmin_minus = (
fRmin) ?
fRmin - halfRminTolerance : 0;
1668 double pDistS, compS, pDistE, compE, sphi2, vphi;
1670 double rho2, rad2, pDotV2d, pDotV3d;
1677 double dist2STheta, dist2ETheta, distTheta;
1682 rho2 = p.
x * p.
x + p.
y * p.
y;
1683 rad2 = rho2 + p.
z * p.
z;
1685 pDotV2d = p.
x * v.
x + p.
y * v.
y;
1686 pDotV3d = pDotV2d + p.
z * v.
z;
1704 if ((rad2 <= rMaxPlus * rMaxPlus) && (rad2 >= Rmin_minus * Rmin_minus))
1719 d2 = pDotV3d * pDotV3d - c;
1722 && ((pDotV3d >= 0) || (d2 < 0)))
1726 n =
UVector3(p.
x / fRmax, p.
y / fRmax, p.
z / fRmax);
1731 snxt = -pDotV3d + std::sqrt(d2);
1743 d2 = pDotV3d * pDotV3d - c;
1751 n =
UVector3(-p.
x / fRmin, -p.
y / fRmin, -p.
z / fRmin);
1758 sd = -pDotV3d - std::sqrt(d2);
1803 if (std::fabs(p.
z) <= halfTolerance)
1809 stheta = -p.
z / v.
z;
1819 distTheta = std::sqrt(rho2) - p.
z *
tanSTheta;
1821 if (std::fabs(t1) < halfAngTolerance)
1826 if (std::fabs(distTheta) < halfTolerance)
1833 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
1850 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
1860 stheta = -0.5 * dist2STheta / t2;
1866 if (std::fabs(distTheta) < halfTolerance)
1873 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
1890 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
1905 c = dist2STheta / t1;
1916 if (((std::fabs(sd) < halfTolerance) && (t2 < 0.))
1917 || (sd < 0.) || ((sd > 0.) && (p.
z + sd * v.
z > 0.)))
1921 if ((sd > halfTolerance) && (p.
z + sd * v.
z <= 0.))
1931 if (((std::fabs(sd) < halfTolerance) && (t2 >= 0.))
1932 || (sd < 0.) || ((sd > 0.) && (p.
z + sd * v.
z < 0.)))
1936 if ((sd > halfTolerance) && (p.
z + sd * v.
z >= 0.))
1952 if (std::fabs(p.
z) <= halfTolerance)
1973 distTheta = std::sqrt(rho2) - p.
z *
tanETheta;
1975 if (std::fabs(t1) < halfAngTolerance)
1980 if (std::fabs(distTheta) < halfTolerance)
1987 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2003 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2015 sd = -0.5 * dist2ETheta / t2;
2026 if (std::fabs(distTheta) < halfTolerance)
2033 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2042 && (t2 < 0.) && (p.
z <= 0.))
2047 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2058 c = dist2ETheta / t1;
2069 if (((std::fabs(sd) < halfTolerance) && (t2 < 0.))
2074 if (sd > halfTolerance)
2087 if (((std::fabs(sd) < halfTolerance) && (t2 >= 0.))
2088 || (sd < 0.) || ((sd > 0.) && (p.
z + sd * v.
z > 0.)))
2092 if ((sd > halfTolerance) && (p.
z + sd * v.
z <= 0.))
2125 if ((pDistS <= 0) && (pDistE <= 0))
2131 sphi = pDistS / compS;
2132 xi = p.
x + sphi * v.
x;
2133 yi = p.
y + sphi * v.
y;
2139 vphi = std::atan2(v.
y, v.
x);
2141 if (((
fSPhi - halfAngTolerance) <= vphi)
2142 && ((
ePhi + halfAngTolerance) >= vphi))
2154 if (pDistS > -halfCarTolerance)
2167 sphi2 = pDistE / compE;
2170 xi = p.
x + sphi2 * v.
x;
2171 yi = p.
y + sphi2 * v.
y;
2179 vphi = std::atan2(v.
y, v.
x);
2181 if (!((
fSPhi - halfAngTolerance <= vphi)
2182 && (
fSPhi +
fDPhi + halfAngTolerance >= vphi)))
2185 if (pDistE <= -halfCarTolerance)
2198 if (pDistE <= -halfCarTolerance)
2210 else if ((pDistS >= 0) && (pDistE >= 0))
2212 if (pDistS <= pDistE)
2222 if ((compS < 0) && (compE < 0))
2236 if ((compS >= 0) && (compE >= 0))
2246 else if ((pDistS > 0) && (pDistE < 0))
2254 sphi = pDistE / compE;
2255 xi = p.
x + sphi * v.
x;
2256 yi = p.
y + sphi * v.
y;
2263 vphi = std::atan2(v.
y, v.
x);
2265 if (((
fSPhi - halfAngTolerance) <= vphi)
2266 && ((
ePhi + halfAngTolerance) >= vphi))
2278 if (pDistE > -halfCarTolerance)
2295 sphi = pDistE / compE;
2296 xi = p.
x + sphi * v.
x;
2297 yi = p.
y + sphi * v.
y;
2304 vphi = std::atan2(v.
y, v.
x);
2306 if (((
fSPhi - halfAngTolerance) <= vphi)
2307 && ((
ePhi + halfAngTolerance) >= vphi))
2339 sphi = pDistS / compS;
2340 xi = p.
x + sphi * v.
x;
2341 yi = p.
y + sphi * v.
y;
2348 vphi = std::atan2(v.
y, v.
x);
2350 if (((
fSPhi - halfAngTolerance) <= vphi)
2351 && ((
ePhi + halfAngTolerance) >= vphi))
2363 if (pDistS > -halfCarTolerance)
2380 sphi = pDistS / compS;
2381 xi = p.
x + sphi * v.
x;
2382 yi = p.
y + sphi * v.
y;
2389 vphi = std::atan2(v.
y, v.
x);
2391 if (((
fSPhi - halfAngTolerance) <= vphi)
2392 && ((
ePhi + halfAngTolerance) >= vphi))
2426 vphi = std::atan2(v.
y, v.
x);
2427 if ((
fSPhi - halfAngTolerance < vphi) && (vphi <
ePhi + halfAngTolerance))
2457 xi = p.
x + snxt * v.
x;
2458 yi = p.
y + snxt * v.
y;
2459 zi = p.
z + snxt * v.
z;
2465 xi = p.
x + snxt * v.
x;
2466 yi = p.
y + snxt * v.
y;
2467 zi = p.
z + snxt * v.
z;
2506 xi = p.
x + snxt * v.
x;
2507 yi = p.
y + snxt * v.
y;
2508 rho2 = xi * xi + yi * yi;
2511 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
2512 n =
UVector3(xi / rhoSecTheta, yi / rhoSecTheta,
2523 xi = p.
x + snxt * v.
x;
2524 yi = p.
y + snxt * v.
y;
2525 rho2 = xi * xi + yi * yi;
2528 rhoSecTheta = std::sqrt(rho2 * (1 +
tanSTheta2));
2529 n =
UVector3(xi / rhoSecTheta, yi / rhoSecTheta,
2549 xi = p.
x + snxt * v.
x;
2550 yi = p.
y + snxt * v.
y;
2551 rho2 = xi * xi + yi * yi;
2554 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2555 n =
UVector3(xi / rhoSecTheta, yi / rhoSecTheta,
2566 xi = p.
x + snxt * v.
x;
2567 yi = p.
y + snxt * v.
y;
2568 rho2 = xi * xi + yi * yi;
2571 rhoSecTheta = std::sqrt(rho2 * (1 +
tanETheta2));
2572 n = -
UVector3(xi / rhoSecTheta, yi / rhoSecTheta,
2586 std::ostringstream message;
2587 int oldprc = message.precision(16);
2588 message <<
"Undefined side for valid surface normal to solid."
2590 <<
"Position:" << std::endl << std::endl
2591 <<
"p.x = " << p.
x <<
" mm" << std::endl
2592 <<
"p.y = " << p.
y <<
" mm" << std::endl
2593 <<
"p.z = " << p.
z <<
" mm" << std::endl << std::endl
2594 <<
"Direction:" << std::endl << std::endl
2595 <<
"v.x = " << v.
x << std::endl
2596 <<
"v.y = " << v.
y << std::endl
2597 <<
"v.z = " << v.
z << std::endl << std::endl
2598 <<
"Proposed distance :" << std::endl << std::endl
2599 <<
"snxt = " << snxt <<
" mm" << std::endl;
2600 message.precision(oldprc);
2602 "GeomSolids1002",
Warning, 1, message.str().c_str());
2609 std::ostringstream message;
2610 int oldprc = message.precision(16);
2611 message <<
"Logic error: snxt = UUtils::Infinity() ???" << std::endl
2612 <<
"Position:" << std::endl << std::endl
2613 <<
"p.x = " << p.
x <<
" mm" << std::endl
2614 <<
"p.y = " << p.
y <<
" mm" << std::endl
2615 <<
"p.z = " << p.
z <<
" mm" << std::endl << std::endl
2616 <<
"Rp = " << std::sqrt(p.
x * p.
x + p.
y * p.
y + p.
z * p.
z)
2617 <<
" mm" << std::endl << std::endl
2618 <<
"Direction:" << std::endl << std::endl
2619 <<
"v.x = " << v.
x << std::endl
2620 <<
"v.y = " << v.
y << std::endl
2621 <<
"v.z = " << v.
z << std::endl << std::endl
2622 <<
"Proposed distance :" << std::endl << std::endl
2623 <<
"snxt = " << snxt <<
" mm" << std::endl;
2624 message.precision(oldprc);
2626 "GeomSolids1002",
Warning, 1, message.str().c_str());
2638 double safe = 0.0, safeRMin, safeRMax, safePhi, safeTheta;
2639 double rho2, rds, rho;
2640 double pTheta, dTheta1, dTheta2;
2641 rho2 = p.
x * p.
x + p.
y * p.
y;
2642 rds = std::sqrt(rho2 + p.
z * p.
z);
2643 rho = std::sqrt(rho2);
2648 int old_prc = cout.precision(16);
2651 cout <<
"Position:" << std::endl << std::endl;
2652 cout <<
"p.x = " << p.
x <<
" mm" << std::endl;
2653 cout <<
"p.y = " << p.
y <<
" mm" << std::endl;
2654 cout <<
"p.z = " << p.
z <<
" mm" << std::endl << std::endl;
2655 cout.precision(old_prc);
2657 "GeomSolids1002",
Warning, 1,
"Point p is outside !?");
2666 safeRMin = rds -
fRmin;
2667 safeRMax =
fRmax - rds;
2668 if (safeRMin < safeRMax)
2706 pTheta = std::acos(p.
z / rds);
2712 dTheta2 =
eTheta - pTheta;
2713 if (dTheta1 < dTheta2)
2715 safeTheta = rds * std::sin(dTheta1);
2719 safeTheta = rds * std::sin(dTheta2);
2721 if (safe > safeTheta)
2877 return std::string(
"Sphere");
2895 int oldprc = os.precision(16);
2896 os <<
"-----------------------------------------------------------\n"
2897 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
2898 <<
" ===================================================\n"
2899 <<
" Solid type: USphere\n"
2900 <<
" Parameters: \n"
2901 <<
" inner radius: " <<
fRmin <<
" mm \n"
2902 <<
" outer radius: " <<
fRmax <<
" mm \n"
2903 <<
" starting phi of segment : " <<
fSPhi / (
UUtils::kPi / 180.0) <<
" degrees \n"
2904 <<
" delta phi of segment : " <<
fDPhi / (
UUtils::kPi / 180.0) <<
" degrees \n"
2905 <<
" starting theta of segment: " <<
fSTheta / (
UUtils::kPi / 180.0) <<
" degrees \n"
2907 <<
"-----------------------------------------------------------\n";
2908 os.precision(oldprc);
2919 double zRand, aOne, aTwo, aThr, aFou, aFiv, chose, phi, sinphi, cosphi;
2920 double height1, height2, slant1, slant2, costheta, sintheta, rRand;
2935 cosphi = std::cos(phi);
2936 sinphi = std::sin(phi);
2962 if ((chose >= 0.) && (chose < aOne))
2965 fRmax * sintheta * sinphi,
fRmax * costheta);
2967 else if ((chose >= aOne) && (chose < aOne + aTwo))
2970 fRmin * sintheta * sinphi,
fRmin * costheta);
2972 else if ((chose >= aOne + aTwo) && (chose < aOne + aTwo + aThr))
2982 return UVector3(rRand * cosphi, rRand * sinphi, 0.);
2985 else if ((chose >= aOne + aTwo + aThr) && (chose < aOne + aTwo + aThr + aFou))
2995 return UVector3(rRand * cosphi, rRand * sinphi, 0.);
2998 else if ((chose >= aOne + aTwo + aThr + aFou) && (chose < aOne + aTwo + aThr + aFou + aFiv))
3001 rRand * sintheta *
sinSPhi, rRand * costheta);
3006 rRand * sintheta *
sinEPhi, rRand * costheta);
3032 double acos1 = std::acos(std::pow(
sinSTheta, 2) * std::cos(
fDPhi)
3045 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 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
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
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
double Random(double min=0.0, double max=1.0)
double GetDeltaPhiAngle() const
double SafetyFromInside(const UVector3 &p, bool aAccurate=false) const