69 using namespace CLHEP;
78 :
G4VSolid(pName), fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
84 std::ostringstream message;
86 <<
" Invalid Z half-length: "
87 << newHalfLenZ/
mm <<
" mm";
95 if (newInnerRadius<0 || newOuterRadius<0)
97 std::ostringstream message;
99 <<
" Invalid radii ! Inner radius: "
100 << newInnerRadius/
mm <<
" mm" <<
G4endl
102 << newOuterRadius/
mm <<
" mm";
106 if (newInnerRadius >= newOuterRadius)
108 std::ostringstream message;
110 <<
" Invalid radii ! Inner radius: "
111 << newInnerRadius/
mm <<
" mm" <<
G4endl
113 << newOuterRadius/
mm <<
" mm";
134 :
G4VSolid(a), innerRadius(0.), outerRadius(0.), halfLenZ(0.), innerStereo(0.),
135 outerStereo(0.), tanInnerStereo(0.), tanOuterStereo(0.), tanInnerStereo2(0.),
136 tanOuterStereo2(0.), innerRadius2(0.), outerRadius2(0.), endInnerRadius2(0.),
137 endOuterRadius2(0.), endInnerRadius(0.), endOuterRadius(0.),
138 fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
156 :
G4VSolid(rhs), innerRadius(rhs.innerRadius),
157 outerRadius(rhs.outerRadius), halfLenZ(rhs.halfLenZ),
158 innerStereo(rhs.innerStereo), outerStereo(rhs.outerStereo),
159 tanInnerStereo(rhs.tanInnerStereo), tanOuterStereo(rhs.tanOuterStereo),
160 tanInnerStereo2(rhs.tanInnerStereo2), tanOuterStereo2(rhs.tanOuterStereo2),
161 innerRadius2(rhs.innerRadius2), outerRadius2(rhs.outerRadius2),
162 endInnerRadius2(rhs.endInnerRadius2), endOuterRadius2(rhs.endOuterRadius2),
163 endInnerRadius(rhs.endInnerRadius), endOuterRadius(rhs.endOuterRadius),
164 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
177 if (
this == &rhs) {
return *
this; }
193 fCubicVolume = rhs.fCubicVolume; fSurfaceArea = rhs.fSurfaceArea;
228 G4double rFudge = 1.0/std::cos(0.5*sigPhi);
281 cosPhi = std::cos(phi),
282 sinPhi = std::sin(phi);
290 w0, w1, w2, w3, w4, w5, w6;
348 if (numPhi == 1) phi = 0;
349 cosPhi = std::cos(phi),
350 sinPhi = std::sin(phi);
441 if (splitOuter) v4 = w4;
443 }
while( --numPhi > 0 );
496 phiPoly.
SetNormal( (v1-v0).cross(w0-v0).unit() );
569 if (dist2Inner < dist2Z && dist2Inner < dist2Outer)
576 if (dist2Z < dist2Outer)
631 G4bool couldMissOuter(
true),
632 couldMissInner(
true),
633 cantMissInnerCylinder(
false);
652 if (sigz > 0)
return kInfinity;
683 yi = p.
y() + q*v.
y();
711 cantMissInnerCylinder =
true;
716 return (sigz < halfTol) ? 0 : q;
759 if (pz < halfLenZ+halfTol)
789 if (zi < -halfLenZ)
continue;
790 if (zi > +halfLenZ && couldMissOuter)
continue;
796 yi = p.
y() + q[i]*v.
y();
814 if (cantMissInnerCylinder)
return (sigz < halfTol) ? 0 : -sigz/vz;
822 if (pz < halfLenZ+halfTol)
842 if (q[i] > best)
break;
852 if (zi < -halfLenZ)
continue;
853 if (zi > +halfLenZ && couldMissInner)
continue;
859 yi = p.
y() + q[i]*v.
y();
915 return sigz < halfTol ? 0 : sigz;
923 G4double answer = std::sqrt( dr*dr + sigz*sigz );
924 return answer < halfTol ? 0 : answer;
932 return sigz < halfTol ? 0 : sigz;
944 G4double answer = std::sqrt( dr*dr + sigz*sigz );
945 return answer < halfTol ? 0 : answer;
957 return answer < halfTol ? 0 : answer;
965 return answer < halfTol ? 0 : answer;
1015 if (calcNorm) { *norm = *nBest; *validNorm =
true; }
1047 if (normHere.dot(v) > 0)
1049 if (calcNorm) { *norm = normHere.
unit(); *validNorm =
false; }
1058 for( i=0; i<
n; i++ )
1060 if (q[i] > sBest)
break;
1069 if (norm1.
dot(v) > 0)
1095 if (normHere.dot(v) > 0)
1099 *norm = normHere.
unit();
1110 for( i=0; i<
n; i++ )
1112 if (q[i] > sBest)
break;
1117 if (norm2.
dot(v) > 0)
1136 if (nBest == &norm1 || nBest == &norm2)
1137 *norm = nBest->
unit();
1162 if (tryOuter < sBest)
1168 if (tryInner < sBest) sBest = tryInner;
1220 G4double a = tx*tx + ty*ty - tz*tz*tan2Phi;
1221 G4double b = 2*( x0*tx + y0*ty - z0*tz*tan2Phi );
1222 G4double c = x0*x0 + y0*y0 - r2 - z0*z0*tan2Phi;
1230 if (std::fabs(b) <
DBL_MIN)
return 0;
1239 if (radical < -
DBL_MIN)
return 0;
1250 radical = std::sqrt(radical);
1252 G4double q = -0.5*( b + (b < 0 ? -radical : +radical) );
1255 if (sa < sb) { ss[0] = sa; ss[1] = sb; }
else { ss[0] = sb; ss[1] = sa; }
1284 if (tanPhi <
DBL_MIN)
return pr-r0;
1292 G4double r1 = std::sqrt( r0*r0 + z1*z1*tan2Phi );
1297 G4double z2 = (pr*tanPhi + pz)/(1 + tan2Phi);
1298 G4double r2 = std::sqrt( r0*r0 + z2*z2*tan2Phi );
1315 return std::sqrt( dr*dr + dz*dz );
1321 return std::fabs((pr-r1)*dz - (pz-z1)*dr)/
len;
1347 G4double rh = std::sqrt( r0*r0 + pz*pz*tan2Phi );
1356 return std::fabs((pr-rh)*dr)/
len;
1374 return new G4Hype(*
this);
1383 if(fCubicVolume != 0.) {;}
1385 return fCubicVolume;
1394 if(fSurfaceArea != 0.) {;}
1396 return fSurfaceArea;
1405 G4int oldprc = os.precision(16);
1406 os <<
"-----------------------------------------------------------\n"
1407 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1408 <<
" ===================================================\n"
1409 <<
" Solid type: G4Hype\n"
1410 <<
" Parameters: \n"
1411 <<
" half length Z: " <<
halfLenZ/
mm <<
" mm \n"
1416 <<
"-----------------------------------------------------------\n";
1417 os.precision(oldprc);
1429 G4double xRand, yRand, zRand, r2 , aOne, aTwo, aThree, chose, sinhu;
1430 G4double phi, cosphi, sinphi, rBar2Out, rBar2In,
alpha, t, rOut, rIn2, rOut2;
1439 t = std::log(t+std::sqrt(
sqr(t)+1));
1440 aOne = std::fabs(2.*alpha*(std::sinh(2.*t)/4.+t/2.));
1446 t = std::log(t+std::sqrt(
sqr(t)+1));
1447 aTwo = std::fabs(2.*alpha*(std::sinh(2.*t)/4.+t/2.));
1455 phi = RandFlat::shoot(0.,2.*
pi);
1456 cosphi = std::cos(phi);
1457 sinphi = std::sin(phi);
1461 chose = RandFlat::shoot(0.,aOne+aTwo+2.*aThree);
1462 if(chose>=0. && chose < aOne)
1477 else if(chose>=aOne && chose<aOne+aTwo)
1494 else if(chose>=aOne+aTwo && chose<aOne+aTwo+aThree)
1498 rOut = std::sqrt(rOut2) ;
1501 xRand = RandFlat::shoot(-rOut,rOut) ;
1502 yRand = RandFlat::shoot(-rOut,rOut) ;
1503 r2 = xRand*xRand + yRand*yRand ;
1504 }
while ( ! ( r2 >= rIn2 && r2 <= rOut2 ) ) ;
1513 rOut = std::sqrt(rOut2) ;
1516 xRand = RandFlat::shoot(-rOut,rOut) ;
1517 yRand = RandFlat::shoot(-rOut,rOut) ;
1518 r2 = xRand*xRand + yRand*yRand ;
1519 }
while ( ! ( r2 >= rIn2 && r2 <= rOut2 ) ) ;
1564 if (!fpPolyhedron ||
1568 delete fpPolyhedron;
1571 return fpPolyhedron;
1591 return std::log(arg+std::sqrt(
sqr(arg)+1));