71 using namespace CLHEP;
80 :
G4VSolid(pName), fCubicVolume(0.), fSurfaceArea(0.),
81 fRebuildPolyhedron(false), fpPolyhedron(0)
89 std::ostringstream message;
91 <<
" Invalid Z half-length: "
92 << newHalfLenZ/
mm <<
" mm";
100 if (newInnerRadius<0 || newOuterRadius<0)
102 std::ostringstream message;
104 <<
" Invalid radii ! Inner radius: "
105 << newInnerRadius/
mm <<
" mm" <<
G4endl
107 << newOuterRadius/
mm <<
" mm";
111 if (newInnerRadius >= newOuterRadius)
113 std::ostringstream message;
115 <<
" Invalid radii ! Inner radius: "
116 << newInnerRadius/
mm <<
" mm" <<
G4endl
118 << newOuterRadius/
mm <<
" mm";
139 :
G4VSolid(a), innerRadius(0.), outerRadius(0.), halfLenZ(0.), innerStereo(0.),
140 outerStereo(0.), tanInnerStereo(0.), tanOuterStereo(0.), tanInnerStereo2(0.),
141 tanOuterStereo2(0.), innerRadius2(0.), outerRadius2(0.), endInnerRadius2(0.),
142 endOuterRadius2(0.), endInnerRadius(0.), endOuterRadius(0.),
143 fCubicVolume(0.), fSurfaceArea(0.), fHalfTol(0.),
144 fRebuildPolyhedron(false), fpPolyhedron(0)
154 delete fpPolyhedron; fpPolyhedron = 0;
162 :
G4VSolid(rhs), innerRadius(rhs.innerRadius),
163 outerRadius(rhs.outerRadius), halfLenZ(rhs.halfLenZ),
164 innerStereo(rhs.innerStereo), outerStereo(rhs.outerStereo),
165 tanInnerStereo(rhs.tanInnerStereo), tanOuterStereo(rhs.tanOuterStereo),
166 tanInnerStereo2(rhs.tanInnerStereo2), tanOuterStereo2(rhs.tanOuterStereo2),
167 innerRadius2(rhs.innerRadius2), outerRadius2(rhs.outerRadius2),
168 endInnerRadius2(rhs.endInnerRadius2), endOuterRadius2(rhs.endOuterRadius2),
169 endInnerRadius(rhs.endInnerRadius), endOuterRadius(rhs.endOuterRadius),
170 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
171 fHalfTol(rhs.fHalfTol), fRebuildPolyhedron(false), fpPolyhedron(0)
183 if (
this == &rhs) {
return *
this; }
199 fCubicVolume = rhs.fCubicVolume; fSurfaceArea = rhs.fSurfaceArea;
200 fHalfTol = rhs.fHalfTol;
201 fRebuildPolyhedron =
false;
202 delete fpPolyhedron; fpPolyhedron = 0;
230 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
232 std::ostringstream message;
233 message <<
"Bad bounding box (min >= max) for solid: "
235 <<
"\npMin = " << pMin
236 <<
"\npMax = " << pMax;
327 if (dist2Inner < dist2Z && dist2Inner < dist2Outer)
334 if (dist2Z < dist2Outer)
387 G4bool couldMissOuter(
true),
388 couldMissInner(
true),
389 cantMissInnerCylinder(
false);
396 if (sigz > -fHalfTol)
439 yi = p.
y() + q*v.
y();
467 cantMissInnerCylinder =
true;
472 return (sigz < fHalfTol) ? 0 : q;
515 if (pz < halfLenZ+fHalfTol)
545 if (zi < -halfLenZ)
continue;
546 if (zi > +halfLenZ && couldMissOuter)
continue;
552 yi = p.
y() + q[i]*v.
y();
570 if (cantMissInnerCylinder)
return (sigz < fHalfTol) ? 0 : -sigz/vz;
578 if (pz < halfLenZ+fHalfTol)
598 if (q[i] > best)
break;
608 if (zi < -halfLenZ)
continue;
609 if (zi > +halfLenZ && couldMissInner)
continue;
615 yi = p.
y() + q[i]*v.
y();
664 if (sigz > -fHalfTol)
669 return sigz < fHalfTol ? 0 : sigz;
677 G4double answer = std::sqrt( dr*dr + sigz*sigz );
678 return answer < fHalfTol ? 0 : answer;
686 return sigz < fHalfTol ? 0 : sigz;
698 G4double answer = std::sqrt( dr*dr + sigz*sigz );
699 return answer < fHalfTol ? 0 : answer;
711 return answer < fHalfTol ? 0 : answer;
719 return answer < fHalfTol ? 0 : answer;
766 if (calcNorm) { *norm = *nBest; *validNorm =
true; }
798 if (normHere.dot(v) > 0)
800 if (calcNorm) { *norm = normHere.
unit(); *validNorm =
false; }
811 if (q[i] > sBest)
break;
820 if (norm1.
dot(v) > 0)
846 if (normHere.dot(v) > 0)
850 *norm = normHere.
unit();
863 if (q[i] > sBest)
break;
868 if (norm2.
dot(v) > 0)
887 if (nBest == &norm1 || nBest == &norm2)
888 *norm = nBest->
unit();
913 if (tryOuter < sBest)
919 if (tryInner < sBest) sBest = tryInner;
971 G4double a = tx*tx + ty*ty - tz*tz*tan2Phi;
981 if (std::fabs(b) <
DBL_MIN)
return 0;
991 if (radical < -
DBL_MIN)
return 0;
1002 radical = std::sqrt(radical);
1004 G4double q = -0.5*( b + (b < 0 ? -radical : +radical) );
1007 if (sa < sb) { ss[0] = sa; ss[1] = sb; }
else { ss[0] = sb; ss[1] = sa; }
1036 if (tanPhi <
DBL_MIN)
return pr-r0;
1044 G4double r1 = std::sqrt( r0*r0 + z1*z1*tan2Phi );
1049 G4double z2 = (pr*tanPhi + pz)/(1 + tan2Phi);
1050 G4double r2 = std::sqrt( r0*r0 + z2*z2*tan2Phi );
1067 return std::sqrt( dr*dr + dz*dz );
1073 return std::fabs((pr-r1)*dz - (pz-z1)*dr)/
len;
1099 G4double rh = std::sqrt( r0*r0 + pz*pz*tan2Phi );
1108 return std::fabs((pr-rh)*dr)/
len;
1126 return new G4Hype(*
this);
1135 if(fCubicVolume != 0.) {;}
1137 return fCubicVolume;
1146 if(fSurfaceArea != 0.) {;}
1148 return fSurfaceArea;
1157 G4int oldprc = os.precision(16);
1158 os <<
"-----------------------------------------------------------\n"
1159 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1160 <<
" ===================================================\n"
1161 <<
" Solid type: G4Hype\n"
1162 <<
" Parameters: \n"
1163 <<
" half length Z: " <<
halfLenZ/
mm <<
" mm \n"
1168 <<
"-----------------------------------------------------------\n";
1169 os.precision(oldprc);
1181 G4double xRand, yRand, zRand, r2 , aOne, aTwo, aThree, chose, sinhu;
1182 G4double phi, cosphi, sinphi, rBar2Out, rBar2In,
alpha, t, rOut, rIn2, rOut2;
1191 t = std::log(t+std::sqrt(
sqr(t)+1));
1192 aOne = std::fabs(2.*alpha*(std::sinh(2.*t)/4.+t/2.));
1198 t = std::log(t+std::sqrt(
sqr(t)+1));
1199 aTwo = std::fabs(2.*alpha*(std::sinh(2.*t)/4.+t/2.));
1208 cosphi = std::cos(phi);
1209 sinphi = std::sin(phi);
1214 if(chose>=0. && chose < aOne)
1229 else if(chose>=aOne && chose<aOne+aTwo)
1246 else if(chose>=aOne+aTwo && chose<aOne+aTwo+aThree)
1250 rOut = std::sqrt(rOut2) ;
1256 r2 = xRand*xRand + yRand*yRand ;
1257 }
while ( ! ( r2 >= rIn2 && r2 <= rOut2 ) ) ;
1266 rOut = std::sqrt(rOut2) ;
1272 r2 = xRand*xRand + yRand*yRand ;
1273 }
while ( ! ( r2 >= rIn2 && r2 <= rOut2 ) ) ;
1318 if (!fpPolyhedron ||
1319 fRebuildPolyhedron ||
1324 delete fpPolyhedron;
1326 fRebuildPolyhedron =
false;
1329 return fpPolyhedron;
1338 return std::log(arg+std::sqrt(
sqr(arg)+1));
void set(double x, double y, double z)
G4double GetCubicVolume()
ThreeVector shoot(const G4int Ap, const G4int Af)
G4Hype(const G4String &pName, G4double newInnerRadius, G4double newOuterRadius, G4double newInnerStereo, G4double newOuterStereo, G4double newHalfLenZ)
static constexpr double mm
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
static const G4double kInfinity
CLHEP::Hep3Vector G4ThreeVector
G4double GetSurfaceArea()
double dot(const Hep3Vector &) const
std::vector< ExP01TrackerHit * > a
G4GeometryType GetEntityType() const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
static G4double ApproxDistInside(G4double pr, G4double pz, G4double r0, G4double tan2Phi)
void Extent(G4ThreeVector &pMin, G4ThreeVector &pMax) const
virtual G4double GetCubicVolume()
G4Polyhedron * CreatePolyhedron() const
void DescribeYourselfTo(G4VGraphicsScene &scene) const
virtual void AddSolid(const G4Box &)=0
G4bool InnerSurfaceExists() const
#define G4MUTEX_INITIALIZER
G4double HypeOuterRadius2(G4double zVal) const
static G4double ApproxDistOutside(G4double pr, G4double pz, G4double r0, G4double tanPhi)
G4double HypeInnerRadius2(G4double zVal) const
static constexpr double degree
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
G4Hype & operator=(const G4Hype &rhs)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4ThreeVector GetPointOnSurface() const
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4VisExtent GetExtent() const
static G4int IntersectHype(const G4ThreeVector &p, const G4ThreeVector &v, G4double r2, G4double tan2Phi, G4double s[2])
static G4int GetNumberOfRotationSteps()
EInside Inside(const G4ThreeVector &p) const
G4VSolid & operator=(const G4VSolid &rhs)
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
void SetOuterStereo(G4double newOSte)
static constexpr double pi
static const G4double alpha
virtual G4double GetSurfaceArea()
std::ostream & StreamInfo(std::ostream &os) const
G4Polyhedron * GetPolyhedron() const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
void SetInnerStereo(G4double newISte)
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const