47 #if !defined(G4GEOM_USE_UCONS)
62 using namespace CLHEP;
84 :
G4CSGSolid(pName), fRmin1(pRmin1), fRmin2(pRmin2),
85 fRmax1(pRmax1), fRmax2(pRmax2), fDz(pDz), fSPhi(0.), fDPhi(0.)
98 std::ostringstream message;
99 message <<
"Invalid Z half-length for Solid: " <<
GetName() <<
G4endl
107 if (((pRmin1>=pRmax1) || (pRmin2>=pRmax2) || (pRmin1<0)) && (pRmin2<0))
109 std::ostringstream message;
110 message <<
"Invalid values of radii for Solid: " <<
GetName() <<
G4endl
111 <<
" pRmin1 = " << pRmin1 <<
", pRmin2 = " << pRmin2
112 <<
", pRmax1 = " << pRmax1 <<
", pRmax2 = " << pRmax2;
130 :
G4CSGSolid(a), kRadTolerance(0.), kAngTolerance(0.),
131 fRmin1(0.), fRmin2(0.), fRmax1(0.), fRmax2(0.), fDz(0.),
132 fSPhi(0.), fDPhi(0.), sinCPhi(0.), cosCPhi(0.), cosHDPhiOT(0.),
133 cosHDPhiIT(0.), sinSPhi(0.), cosSPhi(0.), sinEPhi(0.), cosEPhi(0.),
134 fPhiFullCone(false), halfCarTolerance(0.), halfRadTolerance(0.),
153 :
G4CSGSolid(rhs), kRadTolerance(rhs.kRadTolerance),
154 kAngTolerance(rhs.kAngTolerance), fRmin1(rhs.fRmin1), fRmin2(rhs.fRmin2),
155 fRmax1(rhs.fRmax1), fRmax2(rhs.fRmax2), fDz(rhs.fDz), fSPhi(rhs.fSPhi),
156 fDPhi(rhs.fDPhi), sinCPhi(rhs.sinCPhi), cosCPhi(rhs.cosCPhi),
157 cosHDPhiOT(rhs.cosHDPhiOT), cosHDPhiIT(rhs.cosHDPhiIT),
158 sinSPhi(rhs.sinSPhi), cosSPhi(rhs.cosSPhi), sinEPhi(rhs.sinEPhi),
159 cosEPhi(rhs.cosEPhi), fPhiFullCone(rhs.fPhiFullCone),
160 halfCarTolerance(rhs.halfCarTolerance),
161 halfRadTolerance(rhs.halfRadTolerance),
162 halfAngTolerance(rhs.halfAngTolerance)
174 if (
this == &rhs) {
return *
this; }
205 G4double r2, rl, rh, pPhi, tolRMin, tolRMax;
212 r2 = p.x()*p.x() + p.y()*p.y() ;
219 if ( tolRMin < 0 ) { tolRMin = 0; }
222 if ( (r2<tolRMin*tolRMin) || (r2>tolRMax*tolRMax) ) {
return in =
kOutside; }
225 else { tolRMin = 0.0; }
230 if ( (r2 < tolRMin*tolRMin) || (r2 >= tolRMax*tolRMax) ) { in =
kSurface; }
232 if ( !
fPhiFullCone && ((p.x() != 0.0) || (p.y() != 0.0)) )
234 pPhi = std::atan2(p.y(),p.x()) ;
288 G4double diff1, diff2, delta, maxDiff, newMin, newMax, RMax ;
289 G4double xoff1, xoff2, yoff1, yoff2 ;
292 zMin = zoffset -
fDz ;
293 zMax = zoffset +
fDz ;
318 xMin = 2*xoffset-xMax ;
342 yMin = 2*yoffset-yMax ;
343 RMax = yMax - yoffset ;
367 yoff1 = yoffset - yMin ;
368 yoff2 = yMax - yoffset ;
370 if ((yoff1 >= 0) && (yoff2 >= 0))
379 delta=RMax*RMax-yoff1*yoff1;
380 diff1=(delta>0.) ? std::sqrt(delta) : 0.;
381 delta=RMax*RMax-yoff2*yoff2;
382 diff2=(delta>0.) ? std::sqrt(delta) : 0.;
383 maxDiff = (diff1>diff2) ? diff1:diff2 ;
384 newMin = xoffset - maxDiff ;
385 newMax = xoffset + maxDiff ;
386 pMin = ( newMin < xMin ) ? xMin : newMin ;
387 pMax = ( newMax > xMax) ? xMax : newMax ;
392 xoff1 = xoffset - xMin ;
393 xoff2 = xMax - xoffset ;
395 if ((xoff1 >= 0) && (xoff2 >= 0) )
404 delta=RMax*RMax-xoff1*xoff1;
405 diff1=(delta>0.) ? std::sqrt(delta) : 0.;
406 delta=RMax*RMax-xoff2*xoff2;
407 diff2=(delta>0.) ? std::sqrt(delta) : 0.;
408 maxDiff = (diff1 > diff2) ? diff1:diff2 ;
409 newMin = yoffset - maxDiff ;
410 newMax = yoffset + maxDiff ;
411 pMin = (newMin < yMin) ? yMin : newMin ;
412 pMax = (newMax > yMax) ? yMax : newMax ;
431 G4int i, noEntries, noBetweenSections4 ;
432 G4bool existsAfterClip = false ;
438 noEntries = vertices->size() ;
439 noBetweenSections4 = noEntries-4 ;
441 for ( i = 0 ; i < noEntries ; i += 4 )
445 for ( i = 0 ; i < noBetweenSections4 ; i += 4 )
451 existsAfterClip = true ;
472 existsAfterClip = true ;
478 return existsAfterClip ;
490 G4int noSurfaces = 0;
494 G4double tanRMin, secRMin, pRMin, widRMin;
495 G4double tanRMax, secRMax, pRMax, widRMax;
500 distZ = std::fabs(std::fabs(p.z()) -
fDz);
501 rho = std::sqrt(p.x()*p.x() + p.y()*p.y());
504 secRMin = std::sqrt(1 + tanRMin*tanRMin);
505 pRMin = rho - p.z()*tanRMin;
507 distRMin = std::fabs(pRMin - widRMin)/secRMin;
510 secRMax = std::sqrt(1+tanRMax*tanRMax);
511 pRMax = rho - p.z()*tanRMax;
513 distRMax = std::fabs(pRMax - widRMax)/secRMax;
519 pPhi = std::atan2(p.y(),p.x());
524 distSPhi = std::fabs( pPhi -
fSPhi );
537 nR =
G4ThreeVector(p.x()/rho/secRMax, p.y()/rho/secRMax, -tanRMax/secRMax);
540 nr =
G4ThreeVector(-p.x()/rho/secRMin,-p.y()/rho/secRMin,tanRMin/secRMin);
570 if ( p.z() >= 0.) { sumnorm += nZ; }
571 else { sumnorm -= nZ; }
573 if ( noSurfaces == 0 )
576 G4Exception(
"G4Cons::SurfaceNormal(p)",
"GeomSolids1002",
581 else if ( noSurfaces == 1 ) { norm = sumnorm; }
582 else { norm = sumnorm.unit(); }
597 G4double distZ, distRMin, distRMax, distSPhi, distEPhi, distMin ;
598 G4double tanRMin, secRMin, pRMin, widRMin ;
599 G4double tanRMax, secRMax, pRMax, widRMax ;
601 distZ = std::fabs(std::fabs(p.z()) -
fDz) ;
602 rho = std::sqrt(p.x()*p.x() + p.y()*p.y()) ;
605 secRMin = std::sqrt(1 + tanRMin*tanRMin) ;
606 pRMin = rho - p.z()*tanRMin ;
608 distRMin = std::fabs(pRMin - widRMin)/secRMin ;
611 secRMax = std::sqrt(1+tanRMax*tanRMax) ;
612 pRMax = rho - p.z()*tanRMax ;
614 distRMax = std::fabs(pRMax - widRMax)/secRMax ;
616 if (distRMin < distRMax)
618 if (distZ < distRMin)
631 if (distZ < distRMax)
644 phi = std::atan2(p.y(),p.x()) ;
646 if (phi < 0) { phi += twopi; }
648 if (
fSPhi < 0) { distSPhi = std::fabs(phi - (
fSPhi + twopi))*rho; }
649 else { distSPhi = std::fabs(phi -
fSPhi)*rho; }
651 distEPhi = std::fabs(phi -
fSPhi -
fDPhi)*rho ;
655 if (distSPhi < distEPhi)
657 if (distSPhi < distMin) { side =
kNSPhi; }
661 if (distEPhi < distMin) { side =
kNEPhi; }
668 norm =
G4ThreeVector(-p.x()/rho, -p.y()/rho, tanRMin/secRMin) ;
672 norm =
G4ThreeVector(p.x()/rho, p.y()/rho, -tanRMax/secRMax) ;
688 "Undefined side for valid surface normal to solid.");
724 G4double tanRMax,secRMax,rMaxAv,rMaxOAv ;
725 G4double tanRMin,secRMin,rMinAv,rMinOAv ;
728 G4double tolORMin,tolORMin2,tolIRMin,tolIRMin2 ;
729 G4double tolORMax2,tolIRMax,tolIRMax2 ;
732 G4double Dist,sd,xi,yi,zi,ri=0.,risec,rhoi2,cosPsi ;
743 secRMin = std::sqrt(1.0 + tanRMin*tanRMin) ;
755 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
764 if (std::fabs(p.z()) >= tolIDz)
766 if ( p.z()*v.z() < 0 )
768 sd = (std::fabs(p.z()) -
fDz)/std::fabs(v.z()) ;
770 if( sd < 0.0 ) { sd = 0.0; }
772 xi = p.x() + sd*v.x() ;
773 yi = p.y() + sd*v.y() ;
774 rhoi2 = xi*xi + yi*yi ;
781 tolORMin =
fRmin1 - halfRadTolerance*secRMin ;
782 tolIRMin =
fRmin1 + halfRadTolerance*secRMin ;
783 tolIRMax =
fRmax1 - halfRadTolerance*secRMin ;
784 tolORMax2 = (
fRmax1 + halfRadTolerance*secRMax)*
785 (
fRmax1 + halfRadTolerance*secRMax) ;
789 tolORMin =
fRmin2 - halfRadTolerance*secRMin ;
790 tolIRMin =
fRmin2 + halfRadTolerance*secRMin ;
791 tolIRMax =
fRmax2 - halfRadTolerance*secRMin ;
792 tolORMax2 = (
fRmax2 + halfRadTolerance*secRMax)*
793 (
fRmax2 + halfRadTolerance*secRMax) ;
797 tolORMin2 = tolORMin*tolORMin ;
798 tolIRMin2 = tolIRMin*tolIRMin ;
805 if ( tolIRMax > 0 ) { tolIRMax2 = tolIRMax*tolIRMax; }
806 else { tolIRMax2 = 0.0; }
808 if ( (tolIRMin2 <= rhoi2) && (rhoi2 <= tolIRMax2) )
849 t1 = 1.0 - v.z()*v.z() ;
850 t2 = p.x()*v.x() + p.y()*v.y() ;
851 t3 = p.x()*p.x() + p.y()*p.y() ;
852 rin = tanRMin*p.z() + rMinAv ;
853 rout = tanRMax*p.z() + rMaxAv ;
858 nt1 = t1 - (tanRMax*v.z())*(tanRMax*v.z()) ;
859 nt2 = t2 - tanRMax*v.z()*rout ;
860 nt3 = t3 - rout*rout ;
876 if ((rout < 0) && (nt3 <= 0))
881 if (b>0) { sd = c/(-b-std::sqrt(d)); }
882 else { sd = -b + std::sqrt(d); }
886 if ((b <= 0) && (c >= 0))
888 sd=c/(-b+std::sqrt(d));
894 sd = -b + std::sqrt(d) ;
895 if((sd<0) & (sd>-halfRadTolerance)) sd=0;
907 G4double fTerm = sd-std::fmod(sd,dRmax);
910 zi = p.z() + sd*v.z() ;
912 if (std::fabs(zi) <= tolODz)
919 xi = p.x() + sd*v.x() ;
920 yi = p.y() + sd*v.y() ;
921 ri = rMaxAv + zi*tanRMax ;
935 if ( ( t3 > (rin + halfRadTolerance*secRMin)*
936 (rin + halfRadTolerance*secRMin) )
937 && (nt2 < 0) && (d >= 0) && (std::fabs(p.z()) <= tolIDz) )
944 risec = std::sqrt(xi*xi + yi*yi)*secRMax ;
951 if ( Normal.dot(v) <= 0 ) {
return 0.0; }
956 if ( Normal.dot(v) <= 0 ) {
return 0.0; }
970 zi = p.z() + sd*v.z() ;
972 if ((std::fabs(zi) <= tolODz) && (nt2 < 0))
979 xi = p.x() + sd*v.x() ;
980 yi = p.y() + sd*v.y() ;
981 ri = rMaxAv + zi*tanRMax ;
1006 nt1 = t1 - (tanRMin*v.z())*(tanRMin*v.z()) ;
1007 nt2 = t2 - tanRMin*v.z()*rin ;
1008 nt3 = t3 - rin*rin ;
1022 if(b>0){sd = c/( -b-std::sqrt(d));}
1023 else {sd = -b + std::sqrt(d) ;}
1029 G4double fTerm = sd-std::fmod(sd,dRmax);
1032 zi = p.z() + sd*v.z() ;
1034 if ( std::fabs(zi) <= tolODz )
1038 xi = p.x() + sd*v.x() ;
1039 yi = p.y() + sd*v.y() ;
1040 ri = rMinAv + zi*tanRMin ;
1045 if ( sd > halfRadTolerance ) { snxt=sd; }
1050 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1051 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin);
1052 if ( Normal.dot(v) <= 0 ) { snxt = sd; }
1058 if ( sd > halfRadTolerance ) {
return sd; }
1063 xi = p.x() + sd*v.x() ;
1064 yi = p.y() + sd*v.y() ;
1065 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1066 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
1067 if ( Normal.dot(v) <= 0 ) {
return sd; }
1087 if (b>0) { sd = c/(-b-std::sqrt(d)); }
1088 else { sd = -b + std::sqrt(d); }
1089 zi = p.z() + sd*v.z() ;
1090 ri = rMinAv + zi*tanRMin ;
1094 if ( (sd >= 0) && (std::fabs(zi) <= tolODz) )
1098 G4double fTerm = sd-std::fmod(sd,dRmax);
1103 xi = p.x() + sd*v.x() ;
1104 yi = p.y() + sd*v.y() ;
1109 if ( sd > halfRadTolerance ) { snxt=sd; }
1114 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1115 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin);
1116 if ( Normal.dot(v) <= 0 ) { snxt = sd; }
1122 if( sd > halfRadTolerance ) {
return sd; }
1127 xi = p.x() + sd*v.x() ;
1128 yi = p.y() + sd*v.y() ;
1129 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1130 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
1131 if ( Normal.dot(v) <= 0 ) {
return sd; }
1138 if (b>0) { sd = -b - std::sqrt(d); }
1139 else { sd = c/(-b+std::sqrt(d)); }
1140 zi = p.z() + sd*v.z() ;
1141 ri = rMinAv + zi*tanRMin ;
1143 if ( (sd >= 0) && (ri > 0) && (std::fabs(zi) <= tolODz) )
1147 G4double fTerm = sd-std::fmod(sd,dRmax);
1152 xi = p.x() + sd*v.x() ;
1153 yi = p.y() + sd*v.y() ;
1158 if ( sd > halfRadTolerance ) { snxt=sd; }
1163 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1164 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin);
1165 if ( Normal.dot(v) <= 0 ) { snxt = sd; }
1171 if ( sd > halfRadTolerance ) {
return sd; }
1176 xi = p.x() + sd*v.x() ;
1177 yi = p.y() + sd*v.y() ;
1178 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1179 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
1180 if ( Normal.dot(v) <= 0 ) {
return sd; }
1194 if ( std::fabs(p.z()) <= tolODz )
1206 else {
return 0.0; }
1219 if (b>0) { sd = -b - std::sqrt(d); }
1220 else { sd = c/(-b+std::sqrt(d)); }
1221 zi = p.z() + sd*v.z() ;
1222 ri = rMinAv + zi*tanRMin ;
1226 if (b>0) { sd = c/(-b-std::sqrt(d)); }
1227 else { sd = -b + std::sqrt(d); }
1229 zi = p.z() + sd*v.z() ;
1231 if ( (sd >= 0) && (std::fabs(zi) <= tolODz) )
1235 G4double fTerm = sd-std::fmod(sd,dRmax);
1240 xi = p.x() + sd*v.x() ;
1241 yi = p.y() + sd*v.y() ;
1242 ri = rMinAv + zi*tanRMin ;
1262 if (b>0) { sd = c/(-b-std::sqrt(d)); }
1263 else { sd = -b + std::sqrt(d) ; }
1264 zi = p.z() + sd*v.z() ;
1266 if ( (sd >= 0) && (std::fabs(zi) <= tolODz) )
1270 G4double fTerm = sd-std::fmod(sd,dRmax);
1275 xi = p.x() + sd*v.x();
1276 yi = p.y() + sd*v.y();
1277 ri = rMinAv + zi*tanRMin ;
1309 if (Dist < halfCarTolerance)
1315 if ( sd < 0 ) { sd = 0.0; }
1317 zi = p.z() + sd*v.z() ;
1319 if ( std::fabs(zi) <= tolODz )
1321 xi = p.x() + sd*v.x() ;
1322 yi = p.y() + sd*v.y() ;
1323 rhoi2 = xi*xi + yi*yi ;
1324 tolORMin2 = (rMinOAv + zi*tanRMin)*(rMinOAv + zi*tanRMin) ;
1325 tolORMax2 = (rMaxOAv + zi*tanRMax)*(rMaxOAv + zi*tanRMax) ;
1327 if ( (rhoi2 >= tolORMin2) && (rhoi2 <= tolORMax2) )
1346 if (Dist < halfCarTolerance)
1352 if ( sd < 0 ) { sd = 0.0; }
1354 zi = p.z() + sd*v.z() ;
1356 if (std::fabs(zi) <= tolODz)
1358 xi = p.x() + sd*v.x() ;
1359 yi = p.y() + sd*v.y() ;
1360 rhoi2 = xi*xi + yi*yi ;
1361 tolORMin2 = (rMinOAv + zi*tanRMin)*(rMinOAv + zi*tanRMin) ;
1362 tolORMax2 = (rMaxOAv + zi*tanRMax)*(rMaxOAv + zi*tanRMax) ;
1364 if ( (rhoi2 >= tolORMin2) && (rhoi2 <= tolORMax2) )
1376 if (snxt < halfCarTolerance) { snxt = 0.; }
1390 G4double safe=0.0, rho, safeR1, safeR2, safeZ, safePhi, cosPsi ;
1394 rho = std::sqrt(p.x()*p.x() + p.y()*p.y()) ;
1395 safeZ = std::fabs(p.z()) -
fDz ;
1400 secRMin = std::sqrt(1.0 + tanRMin*tanRMin) ;
1402 safeR1 = (pRMin - rho)/secRMin ;
1405 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
1407 safeR2 = (rho - pRMax)/secRMax ;
1409 if ( safeR1 > safeR2) { safe = safeR1; }
1410 else { safe = safeR2; }
1415 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
1417 safe = (rho - pRMax)/secRMax ;
1419 if ( safeZ > safe ) { safe = safeZ; }
1427 if ( cosPsi < std::cos(
fDPhi*0.5) )
1431 safePhi = std::fabs(p.x()*std::sin(
fSPhi)-p.y()*std::cos(
fSPhi));
1437 if ( safePhi > safe ) { safe = safePhi; }
1440 if ( safe < 0.0 ) { safe = 0.0; }
1460 G4double tanRMax, secRMax, rMaxAv ;
1461 G4double tanRMin, secRMin, rMinAv ;
1463 G4double t1, t2, t3, rout, rin, nt1, nt2, nt3 ;
1473 G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, risec, vphi ;
1480 pdist =
fDz - p.z() ;
1484 snxt = pdist/v.z() ;
1497 else if ( v.z() < 0.0 )
1499 pdist =
fDz + p.z() ;
1503 snxt = -pdist/v.z() ;
1540 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
1544 t1 = 1.0 - v.z()*v.z() ;
1545 t2 = p.x()*v.x() + p.y()*v.y() ;
1546 t3 = p.x()*p.x() + p.y()*p.y() ;
1547 rout = tanRMax*p.z() + rMaxAv ;
1549 nt1 = t1 - (tanRMax*v.z())*(tanRMax*v.z()) ;
1550 nt2 = t2 - tanRMax*v.z()*rout ;
1551 nt3 = t3 - rout*rout ;
1555 deltaRoi2 = snxt*snxt*t1 + 2*snxt*t2 + t3
1558 else if ( v.z() < 0.0 )
1560 deltaRoi2 = snxt*snxt*t1 + 2*snxt*t2 + t3
1568 if ( nt1 && (deltaRoi2 > 0.0) )
1585 risec = std::sqrt(t3)*secRMax ;
1587 *n =
G4ThreeVector(p.x()/risec,p.y()/risec,-tanRMax/secRMax);
1594 if (b>0) { srd = -b - std::sqrt(d); }
1595 else { srd = c/(-b+std::sqrt(d)) ; }
1597 zi = p.z() + srd*v.z() ;
1598 ri = tanRMax*zi + rMaxAv ;
1613 if (b>0) { sr2 = c/(-b-std::sqrt(d)); }
1614 else { sr2 = -b + std::sqrt(d); }
1615 zi = p.z() + sr2*v.z() ;
1616 ri = tanRMax*zi + rMaxAv ;
1645 risec = std::sqrt(t3)*secRMax;
1647 *n =
G4ThreeVector(p.x()/risec,p.y()/risec,-tanRMax/secRMax);
1652 else if ( nt2 && (deltaRoi2 > 0.0) )
1658 risec = std::sqrt(t3)*secRMax;
1660 *n =
G4ThreeVector(p.x()/risec,p.y()/risec,-tanRMax/secRMax);
1685 xi = p.x() + slentol*v.x();
1686 yi = p.y() + slentol*v.y();
1687 risec = std::sqrt(xi*xi + yi*yi)*secRMax;
1690 if ( Normal.dot(v) > 0 )
1694 *n = Normal.unit() ;
1710 nt1 = t1 - (tanRMin*v.z())*(tanRMin*v.z()) ;
1714 secRMin = std::sqrt(1.0 + tanRMin*tanRMin) ;
1716 rin = tanRMin*p.z() + rMinAv ;
1717 nt2 = t2 - tanRMin*v.z()*rin ;
1718 nt3 = t3 - rin*rin ;
1735 if (calcNorm) { *validNorm =
false; }
1741 if (b>0) { sr2 = -b - std::sqrt(d); }
1742 else { sr2 = c/(-b+std::sqrt(d)); }
1743 zi = p.z() + sr2*v.z() ;
1744 ri = tanRMin*zi + rMinAv ;
1756 if (b>0) { sr3 = c/(-b-std::sqrt(d)); }
1757 else { sr3 = -b + std::sqrt(d) ; }
1766 zi = p.z() + sr3*v.z() ;
1767 ri = tanRMin*zi + rMinAv ;
1805 xi = p.x() + slentol*v.x() ;
1806 yi = p.y() + slentol*v.y() ;
1807 if( sidetol==
kRMax )
1809 risec = std::sqrt(xi*xi + yi*yi)*secRMax ;
1810 Normal =
G4ThreeVector(xi/risec,yi/risec,-tanRMax/secRMax) ;
1814 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1815 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
1817 if( Normal.dot(v) > 0 )
1823 *n = Normal.unit() ;
1850 vphi = std::atan2(v.y(),v.x()) ;
1855 if ( p.x() || p.y() )
1877 sphi = pDistS/compS ;
1880 xi = p.x() + sphi*v.x() ;
1881 yi = p.y() + sphi*v.y() ;
1922 sphi2 = pDistE/compE ;
1928 xi = p.x() + sphi2*v.x() ;
1929 yi = p.y() + sphi2*v.y() ;
1943 else { sphi = 0.0; }
1953 else { sphi = 0.0; }
1995 xi = p.x() + snxt*v.x() ;
1996 yi = p.y() + snxt*v.y() ;
1997 risec = std::sqrt(xi*xi + yi*yi)*secRMax ;
2002 *validNorm = false ;
2012 *validNorm = false ;
2023 *validNorm = false ;
2037 std::ostringstream message;
2038 G4int oldprc = message.precision(16) ;
2039 message <<
"Undefined side for valid surface normal to solid."
2041 <<
"Position:" << G4endl << G4endl
2042 <<
"p.x() = " << p.x()/
mm <<
" mm" << G4endl
2043 <<
"p.y() = " << p.y()/
mm <<
" mm" << G4endl
2044 <<
"p.z() = " << p.z()/
mm <<
" mm" << G4endl << G4endl
2045 <<
"pho at z = " << std::sqrt( p.x()*p.x()+p.y()*p.y() )/
mm
2046 <<
" mm" << G4endl << G4endl ;
2047 if( p.x() != 0. || p.y() != 0.)
2049 message <<
"point phi = " << std::atan2(p.y(),p.x())/
degree
2050 <<
" degree" << G4endl << G4endl ;
2052 message <<
"Direction:" << G4endl << G4endl
2053 <<
"v.x() = " << v.x() << G4endl
2054 <<
"v.y() = " << v.y() << G4endl
2055 <<
"v.z() = " << v.z() << G4endl<< G4endl
2056 <<
"Proposed distance :" << G4endl<< G4endl
2057 <<
"snxt = " << snxt/
mm <<
" mm" <<
G4endl ;
2058 message.precision(oldprc) ;
2059 G4Exception(
"G4Cons::DistanceToOut(p,v,..)",
"GeomSolids1002",
2075 G4double safe=0.0, rho, safeR1, safeR2, safeZ, safePhi;
2089 G4cout <<
"pho at z = " << std::sqrt( p.x()*p.x()+p.y()*p.y() )/
mm
2090 <<
" mm" << G4endl << G4endl ;
2091 if( (p.x() != 0.) || (p.x() != 0.) )
2093 G4cout <<
"point phi = " << std::atan2(p.y(),p.x())/
degree
2094 <<
" degree" << G4endl << G4endl ;
2096 G4cout.precision(oldprc) ;
2097 G4Exception(
"G4Cons::DistanceToOut(p)",
"GeomSolids1002",
2102 rho = std::sqrt(p.x()*p.x() + p.y()*p.y()) ;
2103 safeZ =
fDz - std::fabs(p.z()) ;
2108 secRMin = std::sqrt(1.0 + tanRMin*tanRMin) ;
2110 safeR1 = (rho - pRMin)/secRMin ;
2118 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
2120 safeR2 = (pRMax - rho)/secRMax ;
2122 if (safeR1 < safeR2) { safe = safeR1; }
2123 else { safe = safeR2; }
2124 if (safeZ < safe) { safe = safeZ ; }
2140 if (safePhi < safe) { safe = safePhi; }
2142 if ( safe < 0 ) { safe = 0; }
2163 G4double meshAngle, meshRMax1, meshRMax2, crossAngle;
2164 G4double cosCrossAngle, sinCrossAngle, sAngle ;
2165 G4double rMaxX1, rMaxX2, rMaxY1, rMaxY2, rMinX1, rMinX2, rMinY1, rMinY2 ;
2166 G4int crossSection, noCrossSections ;
2180 meshAngle =
fDPhi/(noCrossSections - 1) ;
2182 meshRMax1 =
fRmax1/std::cos(meshAngle*0.5) ;
2183 meshRMax2 =
fRmax2/std::cos(meshAngle*0.5) ;
2190 sAngle = -meshAngle*0.5 ;
2200 vertices->reserve(noCrossSections*4) ;
2201 for (crossSection = 0 ; crossSection < noCrossSections ; crossSection++)
2205 crossAngle = sAngle + crossSection*meshAngle ;
2206 cosCrossAngle = std::cos(crossAngle) ;
2207 sinCrossAngle = std::sin(crossAngle) ;
2209 rMaxX1 = meshRMax1*cosCrossAngle ;
2210 rMaxY1 = meshRMax1*sinCrossAngle ;
2211 rMaxX2 = meshRMax2*cosCrossAngle ;
2212 rMaxY2 = meshRMax2*sinCrossAngle ;
2214 rMinX1 =
fRmin1*cosCrossAngle ;
2215 rMinY1 =
fRmin1*sinCrossAngle ;
2216 rMinX2 =
fRmin2*cosCrossAngle ;
2217 rMinY2 =
fRmin2*sinCrossAngle ;
2235 "Error in allocation of vertices. Out of memory !");
2256 return new G4Cons(*
this);
2265 G4int oldprc = os.precision(16);
2266 os <<
"-----------------------------------------------------------\n"
2267 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
2268 <<
" ===================================================\n"
2269 <<
" Solid type: G4Cons\n"
2270 <<
" Parameters: \n"
2271 <<
" inside -fDz radius: " <<
fRmin1/
mm <<
" mm \n"
2272 <<
" outside -fDz radius: " <<
fRmax1/
mm <<
" mm \n"
2273 <<
" inside +fDz radius: " <<
fRmin2/
mm <<
" mm \n"
2274 <<
" outside +fDz radius: " <<
fRmax2/
mm <<
" mm \n"
2275 <<
" half length in Z : " <<
fDz/
mm <<
" mm \n"
2276 <<
" starting angle of segment: " <<
fSPhi/
degree <<
" degrees \n"
2277 <<
" delta angle of segment : " <<
fDPhi/
degree <<
" degrees \n"
2278 <<
"-----------------------------------------------------------\n";
2279 os.precision(oldprc);
2294 G4double Aone, Atwo, Athree, Afour, Afive, slin, slout, phi;
2295 G4double zRand, cosu, sinu, rRand1, rRand2, chose, rone, rtwo, qone, qtwo;
2310 cosu = std::cos(phi); sinu = std::sin(phi);
2317 if( (chose >= 0.) && (chose < Aone) )
2323 rtwo*sinu*(qtwo-zRand), zRand);
2331 else if( (chose >= Aone) && (chose <= Aone + Atwo) )
2337 rone*sinu*(qone-zRand), zRand);
2345 else if( (chose >= Aone + Atwo) && (chose < Aone + Atwo + Athree) )
2349 else if( (chose >= Aone + Atwo + Athree)
2350 && (chose < Aone + Atwo + Athree + Afour) )
2354 else if( (chose >= Aone + Atwo + Athree + Afour)
2355 && (chose < Aone + Atwo + Athree + Afour + Afive) )
2361 rRand1*std::sin(
fSPhi), zRand);
G4Cons(const G4String &pName, G4double pRmin1, G4double pRmax1, G4double pRmin2, G4double pRmax2, G4double pDz, G4double pSPhi, G4double pDPhi)
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
ThreeVector shoot(const G4int Ap, const G4int Af)
G4double halfRadTolerance
static const G4double kInfinity
G4double GetMinYExtent() const
CLHEP::Hep3Vector G4ThreeVector
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform) const
G4Cons & operator=(const G4Cons &rhs)
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool IsYLimited() const
G4double GetRadiusInRing(G4double rmin, G4double rmax) const
EInside Inside(const G4ThreeVector &p) const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
G4ThreeVector ApproxSurfaceNormal(const G4ThreeVector &p) const
std::ostream & StreamInfo(std::ostream &os) const
G4bool IsXLimited() const
const G4int kMinMeshSections
virtual void AddSolid(const G4Box &)=0
G4GeometryType GetEntityType() const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
void CheckPhiAngles(G4double sPhi, G4double dPhi)
G4double GetMaxXExtent() const
G4double GetMinZExtent() const
G4GLOB_DLL std::ostream G4cout
G4double GetRadialTolerance() const
G4double halfCarTolerance
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinXExtent() const
G4double GetMaxZExtent() const
G4double halfAngTolerance
G4Polyhedron * CreatePolyhedron() const
static const double degree
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4double GetMaxYExtent() const
G4ThreeVector GetPointOnSurface() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4double GetMaxExtent(const EAxis pAxis) const
G4CSGSolid & operator=(const G4CSGSolid &rhs)
G4bool IsZLimited() const
G4double GetAngularTolerance() const
void ClipBetweenSections(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
G4double GetMinExtent(const EAxis pAxis) const
const G4double kMeshAngleDefault
static G4GeometryTolerance * GetInstance()
const G4int kMaxMeshSections