40 #if !(defined(G4GEOM_USE_UPARABOLOID) && defined(G4GEOM_USE_SYS_USOLIDS))
59 using namespace CLHEP;
69 :
G4VSolid(pName), fRebuildPolyhedron(false), fpPolyhedron(0),
70 fSurfaceArea(0.), fCubicVolume(0.)
73 if( (pDz <= 0.) || (pR2 <= pR1) || (pR1 < 0.) )
75 std::ostringstream message;
76 message <<
"Invalid dimensions. Negative Input Values or R1>=R2 - "
78 G4Exception(
"G4Paraboloid::G4Paraboloid()",
"GeomSolids0002",
80 "Z half-length must be larger than zero or R1>=R2.");
102 :
G4VSolid(a), fRebuildPolyhedron(false), fpPolyhedron(0),
103 fSurfaceArea(0.), fCubicVolume(0.),
104 dz(0.), r1(0.), r2(0.), k1(0.), k2(0.)
122 :
G4VSolid(rhs), fRebuildPolyhedron(false), fpPolyhedron(0),
123 fSurfaceArea(rhs.fSurfaceArea), fCubicVolume(rhs.fCubicVolume),
124 dz(rhs.dz), r1(rhs.r1), r2(rhs.r2), k1(rhs.k1), k2(rhs.k2)
137 if (
this == &rhs) {
return *
this; }
265 G4bool existsAfterClip=
true;
269 G4int noPolygonVertices=0;
279 for(G4ThreeVectorList::iterator it = vertices->begin();
280 it < vertices->end(); it++)
282 if(pMin > (*it)[pAxis]) pMin = (*it)[pAxis];
287 if(pMax < (*it)[pAxis])
298 || pMax < pVoxelLimit.
GetMinExtent(pAxis)) { existsAfterClip =
false; }
304 existsAfterClip =
false;
307 return existsAfterClip;
326 if(
A < 0 &&
sqr(
A) > rhoSurfTimesTol2)
331 if(std::fabs(p.z()) >
dz - 0.5 * kCarTolerance)
343 else if(
A <= 0 ||
sqr(
A) < rhoSurfTimesTol2)
416 if(A < 0 &&
sqr(A) > rhoSurfTimesTol2)
421 if(p.mag2() != 0) { n = p.unit(); }
423 else if(A <= 0 ||
sqr(A) < rhoSurfTimesTol2)
437 std::ostringstream message;
438 message <<
"No normal defined for this point p." <<
G4endl
439 <<
" p = " << 1 /
mm * p <<
" mm";
440 G4Exception(
"G4Paraboloid::SurfaceNormal(p)",
"GeomSolids1002",
455 G4double rho2 = p.perp2(), paraRho2 = std::fabs(
k1 * p.z() +
k2);
459 if(
r2 && p.z() > - tolh +
dz)
466 if(
sqr(p.x() + v.x()*intersection)
467 +
sqr(p.y() + v.y()*intersection) <
sqr(
r2 + 0.5 * kCarTolerance))
469 if(p.z() < tolh +
dz)
472 {
return intersection; }
480 else if(
r1 && p.z() < tolh -
dz)
486 G4double intersection = (-
dz - p.z()) / v.z();
487 if(
sqr(p.x() + v.x()*intersection)
488 +
sqr(p.y() + v.y()*intersection) <
sqr(
r1 + 0.5 * kCarTolerance))
490 if(p.z() > -tolh -
dz)
506 G4double A =
k1 / 2 * v.z() - p.x() * v.x() - p.y() * v.y(),
507 vRho2 = v.perp2(), intersection,
508 B = (
k1 * p.z() +
k2 - rho2) * vRho2;
510 if ( ( (rho2 > paraRho2) && (
sqr(rho2-paraRho2-0.25*tol2) > tol2*paraRho2) )
518 intersection = ((rho2 -
k2)/
k1 - p.z())/v.z();
519 if(intersection < 0) {
return kInfinity; }
520 else if(std::fabs(p.z() + v.z() * intersection) <=
dz)
535 intersection = (A - std::sqrt(B +
sqr(A))) / vRho2;
540 else if(std::fabs(p.z() + intersection * v.z()) <
dz + tolh)
550 else if(
sqr(rho2 - paraRho2 - .25 * tol2) <= tol2 * paraRho2)
562 std::ostringstream message;
569 message <<
"Likely a problem in this function, for solid: " <<
GetName()
572 message <<
" p = " << p * (1/
mm) <<
" mm" <<
G4endl
573 <<
" v = " << v * (1/
mm) <<
" mm";
574 G4Exception(
"G4Paraboloid::DistanceToIn(p,v)",
"GeomSolids1002",
588 if(safz<0) { safz=0; }
591 G4double rho = p.x()*p.x()+p.y()*p.y();
598 if(safr>safz) { safz=safr; }
602 G4double sqprho = std::sqrt(paraRho);
604 if(dRho<0) {
return safz; }
608 if(tmp<0.) {
return safz; }
610 G4double salf = talf/std::sqrt(tmp);
611 safr = std::fabs(dRho*salf);
612 if(safr>safz) { safz=safr; }
627 G4double rho2 = p.perp2(), paraRho2 = std::fabs(
k1 * p.z() +
k2);
628 G4double vRho2 = v.perp2(), intersection;
632 if(calcNorm) { *validNorm =
false; }
642 G4double A =
k1 / 2 * v.z() - p.x() * v.x() - p.y() * v.y();
648 if ( rho2 < paraRho2 &&
sqr(rho2 - paraRho2 - 0.25 * tol2) > tol2 * paraRho2
649 && std::fabs(p.z()) <
dz - kCarTolerance)
660 intersection = (
dz - p.z()) / v.z();
663 if(ip.perp2() <
sqr(
r2 + kCarTolerance))
668 if(
r2 < tolh || ip.perp2() >
sqr(
r2 - tolh))
685 intersection = (-
dz - p.z()) / v.z();
688 if(ip.perp2() <
sqr(
r1 + tolh))
693 if(
r1 < tolh || ip.perp2() >
sqr(
r1 - tolh))
708 intersection = ((rho2 -
k2)/
k1 - p.z())/v.z();
719 else if( ((A <= 0) && (B >=
sqr(A) * (
sqr(vRho2) - 1))) || (A >= 0))
726 B = (
k1 * p.z() +
k2 - rho2)/vRho2;
727 intersection = B/(-A + std::sqrt(B +
sqr(A)));
737 std::ostringstream message;
738 message <<
"There is no intersection between given line and solid!"
742 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
747 else if ( (rho2 < paraRho2 + kCarTolerance
748 ||
sqr(rho2 - paraRho2 - 0.25 * tol2) < tol2 * paraRho2 )
749 && std::fabs(p.z()) <
dz + tolh)
755 if(std::fabs(p.z()) >
dz - tolh)
759 if( ((v.z() > 0) && (p.z() > 0)) || ((v.z() < 0) && (p.z() < 0)) )
780 A = vRho2 * (
sqr(r) -
sqr(p.x()) -
sqr(p.y()));
781 intersection = (-pDotV + std::sqrt(A +
sqr(pDotV))) / vRho2;
789 * intersection, -
k1/2).unit()).unit();
819 intersection = (
dz - p.z()) / v.z();
822 if(ip.perp2() <
sqr(
r2 - tolh))
831 else if(ip.perp2() <
sqr(
r2 + tolh))
847 intersection = (-
dz - p.z()) / v.z();
850 if(ip.perp2() <
sqr(
r1 - tolh))
859 else if(ip.perp2() <
sqr(
r1 + tolh))
874 if(std::fabs(vRho2) > tol2)
877 B = (
k1 * p.z() +
k2 - rho2);
881 intersection = B/(-A + std::sqrt(B +
sqr(A)));
885 if(normal.dot(v) >= 0)
899 intersection = ((rho2 -
k2) /
k1 - p.z()) / v.z();
906 + intersection * v.y(), -
k1 / 2);
916 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
920 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
921 JustWarning,
"There's an error in this functions code.");
942 std::ostringstream message;
943 G4int oldprc = message.precision(16);
944 message <<
"Point p is outside !?" << G4endl
945 <<
"Position:" << G4endl
946 <<
" p.x() = " << p.x()/
mm <<
" mm" << G4endl
947 <<
" p.y() = " << p.y()/
mm <<
" mm" << G4endl
948 <<
" p.z() = " << p.z()/
mm <<
" mm";
949 message.precision(oldprc) ;
950 G4Exception(
"G4Paraboloid::DistanceToOut(p)",
"GeomSolids1002",
956 safeZ =
dz - std::fabs(p.z()) ;
958 tanRMax = (
r2 -
r1)*0.5/
dz ;
959 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
960 pRMax = tanRMax*p.z() + (
r1+
r2)*0.5 ;
961 safeR = (pRMax - rho)/secRMax ;
963 if (safeZ < safeR) { safe = safeZ; }
964 else { safe = safeR; }
993 G4int oldprc = os.precision(16);
994 os <<
"-----------------------------------------------------------\n"
995 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
996 <<
" ===================================================\n"
997 <<
" Solid type: G4Paraboloid\n"
999 <<
" z half-axis: " <<
dz/
mm <<
" mm \n"
1000 <<
" radius at -dz: " <<
r1/
mm <<
" mm \n"
1001 <<
" radius at dz: " <<
r2/
mm <<
" mm \n"
1002 <<
"-----------------------------------------------------------\n";
1003 os.precision(oldprc);
1035 std::sqrt(z*
k1 +
k2)*std::sin(phi), z);
1041 G4int& noPolygonVertices)
const
1045 G4double meshAnglePhi, cosMeshAnglePhiPer2,
1046 crossAnglePhi, coscrossAnglePhi, sincrossAnglePhi, sAnglePhi,
1047 sRho, dRho, rho, lastRho = 0., swapRho;
1049 G4int crossSectionPhi, noPhiCrossSections, noRhoSections;
1064 meshAnglePhi=
twopi/(noPhiCrossSections-1);
1066 sAnglePhi = -meshAnglePhi*0.5*0;
1067 cosMeshAnglePhiPer2 = std::cos(meshAnglePhi / 2.);
1083 dRho = (
r2 -
r1) /
double(noRhoSections - 1);
1089 for (crossSectionPhi=0; crossSectionPhi<noPhiCrossSections;
1092 crossAnglePhi=sAnglePhi+crossSectionPhi*meshAnglePhi;
1093 coscrossAnglePhi=std::cos(crossAnglePhi);
1094 sincrossAnglePhi=std::sin(crossAnglePhi);
1096 for (
int iRho=0; iRho < noRhoSections;
1101 if(iRho == noRhoSections - 1)
1107 rho = iRho * dRho + sRho;
1112 k3 =
k1 / (2*rho + dRho);
1113 k4 = rho - k3 * (
sqr(rho) -
k2) /
k1;
1115 rho += std::sqrt(
k1 * zm +
k2) - zm * k3 - k4;
1118 rho += (1 / cosMeshAnglePhiPer2 - 1) * (iRho * dRho + sRho);
1123 lastRho = rho + dRho;
1128 lastRho = rho + dRho;
1131 rx = coscrossAnglePhi*rho;
1132 ry = sincrossAnglePhi*rho;
1133 rz = (
sqr(iRho * dRho + sRho) -
k2) /
k1;
1138 noPolygonVertices = noRhoSections ;
1143 G4Exception(
"G4Paraboloid::CreateRotatedVertices()",
1145 "Error in allocation of vertices. Out of memory !");
1181 #endif // !defined(G4GEOM_USE_UPARABOLOID) || !defined(G4GEOM_USE_SYS_USOLIDS)
ThreeVector shoot(const G4int Ap, const G4int Af)
static const G4double kInfinity
G4double GetMinYExtent() const
CLHEP::Hep3Vector G4ThreeVector
G4Polyhedron * fpPolyhedron
G4bool IsYLimited() const
G4Paraboloid & operator=(const G4Paraboloid &rhs)
G4bool IsXLimited() const
G4GeometryType GetEntityType() const
double B(double temperature)
virtual void AddSolid(const G4Box &)=0
#define G4MUTEX_INITIALIZER
G4double CalculateSurfaceArea() const
static double normal(HepRandomEngine *eptr)
G4double GetMaxXExtent() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4double GetMinZExtent() const
G4GLOB_DLL std::ostream G4cout
double A(double temperature)
void DescribeYourselfTo(G4VGraphicsScene &scene) const
static const double twopi
std::vector< G4ThreeVector > G4ThreeVectorList
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, 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
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
EInside Inside(const G4ThreeVector &p) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
std::ostream & StreamInfo(std::ostream &os) const
G4double GetMinXExtent() const
G4double GetMaxZExtent() const
G4ThreeVector GetPointOnSurface() const
G4double GetMaxYExtent() const
G4VSolid & operator=(const G4VSolid &rhs)
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform, G4int &noPolygonVertices) const
G4double GetMaxExtent(const EAxis pAxis) const
G4bool IsZLimited() const
G4Polyhedron * GetPolyhedron() const
G4Paraboloid(const G4String &pName, G4double pDz, G4double pR1, G4double pR2)
G4double GetMinExtent(const EAxis pAxis) const
const G4double kMeshAngleDefault
G4Polyhedron * CreatePolyhedron() const
G4bool fRebuildPolyhedron