63 :
G4VSolid(pName), fpPolyhedron(0), fSurfaceArea(0.), fCubicVolume(0.)
66 if( (pDz <= 0.) || (pR2 <= pR1) || (pR1 < 0.) )
68 std::ostringstream message;
69 message <<
"Invalid dimensions. Negative Input Values or R1>=R2 - "
71 G4Exception(
"G4Paraboloid::G4Paraboloid()",
"GeomSolids0002",
73 "Z half-length must be larger than zero or R1>=R2.");
85 k1 = (r2 * r2 - r1 * r1) / 2 / dz;
86 k2 = (r2 * r2 + r1 * r1) / 2;
95 :
G4VSolid(a), fpPolyhedron(0), fSurfaceArea(0.), fCubicVolume(0.),
96 dz(0.), r1(0.), r2(0.), k1(0.), k2(0.)
114 fSurfaceArea(rhs.fSurfaceArea), fCubicVolume(rhs.fCubicVolume),
115 dz(rhs.dz), r1(rhs.r1), r2(rhs.r2), k1(rhs.k1), k2(rhs.k2)
128 if (
this == &rhs) {
return *
this; }
137 fSurfaceArea = rhs.fSurfaceArea; fCubicVolume = rhs.fCubicVolume;
138 dz = rhs.dz; r1 = rhs.r1; r2 = rhs.r2; k1 = rhs.k1; k2 = rhs.k2;
255 G4bool existsAfterClip=
true;
259 G4int noPolygonVertices=0;
261 = CreateRotatedVertices(pTransform,noPolygonVertices);
269 for(G4ThreeVectorList::iterator it = vertices->begin();
270 it < vertices->end(); it++)
272 if(pMin > (*it)[pAxis]) pMin = (*it)[pAxis];
277 if(pMax < (*it)[pAxis])
288 || pMax < pVoxelLimit.
GetMinExtent(pAxis)) { existsAfterClip =
false; }
294 existsAfterClip =
false;
297 return existsAfterClip;
316 if(A < 0 &&
sqr(A) > rhoSurfTimesTol2)
333 else if(A <= 0 ||
sqr(A) < rhoSurfTimesTol2)
406 if(A < 0 &&
sqr(A) > rhoSurfTimesTol2)
413 else if(A <= 0 ||
sqr(A) < rhoSurfTimesTol2)
427 std::ostringstream message;
428 message <<
"No normal defined for this point p." <<
G4endl
429 <<
" p = " << 1 / mm * p <<
" mm";
430 G4Exception(
"G4Paraboloid::SurfaceNormal(p)",
"GeomSolids1002",
449 if(r2 && p.
z() > - tolh + dz)
456 if(
sqr(p.
x() + v.
x()*intersection)
459 if(p.
z() < tolh + dz)
462 {
return intersection; }
470 else if(r1 && p.
z() < tolh - dz)
476 G4double intersection = (-dz - p.
z()) / v.
z();
477 if(
sqr(p.
x() + v.
x()*intersection)
480 if(p.
z() > -tolh - dz)
497 vRho2 = v.
perp2(), intersection,
498 B = (k1 * p.
z() + k2 - rho2) * vRho2;
500 if ( ( (rho2 > paraRho2) && (
sqr(rho2-paraRho2-0.25*tol2) > tol2*paraRho2) )
508 intersection = ((rho2 - k2)/k1 - p.
z())/v.
z();
509 if(intersection < 0) {
return kInfinity; }
510 else if(std::fabs(p.
z() + v.
z() * intersection) <= dz)
525 intersection = (A - std::sqrt(B +
sqr(A))) / vRho2;
530 else if(std::fabs(p.
z() + intersection * v.
z()) < dz + tolh)
540 else if(
sqr(rho2 - paraRho2 - .25 * tol2) <= tol2 * paraRho2)
545 if(normal.
dot(v) <= 0)
548 {
return kInfinity; }
552 std::ostringstream message;
559 message <<
"Likely a problem in this function, for solid: " <<
GetName()
562 message <<
" p = " << p * (1/mm) <<
" mm" <<
G4endl
563 <<
" v = " << v * (1/mm) <<
" mm";
564 G4Exception(
"G4Paraboloid::DistanceToIn(p,v)",
"GeomSolids1002",
578 if(safz<0) { safz=0; }
588 if(safr>safz) { safz=safr; }
592 G4double sqprho = std::sqrt(paraRho);
594 if(dRho<0) {
return safz; }
598 if(tmp<0.) {
return safz; }
600 G4double salf = talf/std::sqrt(tmp);
601 safr = std::fabs(dRho*salf);
602 if(safr>safz) { safz=safr; }
622 if(calcNorm) { *validNorm =
false; }
636 G4double B = (-rho2 + paraRho2) * vRho2;
638 if ( rho2 < paraRho2 &&
sqr(rho2 - paraRho2 - 0.25 * tol2) > tol2 * paraRho2
650 intersection = (dz - p.
z()) / v.
z();
658 if(r2 < tolh || ip.
perp2() >
sqr(r2 - tolh))
675 intersection = (-dz - p.
z()) / v.
z();
683 if(r1 < tolh || ip.
perp2() >
sqr(r1 - tolh))
698 intersection = ((rho2 - k2)/k1 - p.
z())/v.
z();
709 else if( ((A <= 0) && (B >=
sqr(A) * (
sqr(vRho2) - 1))) || (A >= 0))
716 B = (k1 * p.
z() + k2 - rho2)/vRho2;
717 intersection = B/(-A + std::sqrt(B +
sqr(A)));
727 std::ostringstream message;
728 message <<
"There is no intersection between given line and solid!"
732 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
738 ||
sqr(rho2 - paraRho2 - 0.25 * tol2) < tol2 * paraRho2 )
739 && std::fabs(p.
z()) < dz + tolh)
745 if(std::fabs(p.
z()) > dz - tolh)
749 if( ((v.
z() > 0) && (p.
z() > 0)) || ((v.
z() < 0) && (p.
z() < 0)) )
771 intersection = (-pDotV + std::sqrt(A +
sqr(pDotV))) / vRho2;
779 * intersection, -k1/2).
unit()).unit();
809 intersection = (dz - p.
z()) / v.
z();
821 else if(ip.
perp2() <
sqr(r2 + tolh))
837 intersection = (-dz - p.
z()) / v.
z();
849 else if(ip.
perp2() <
sqr(r1 + tolh))
864 if(std::fabs(vRho2) > tol2)
867 B = (k1 * p.
z() + k2 - rho2);
871 intersection = B/(-A + std::sqrt(B +
sqr(A)));
875 if(normal.
dot(v) >= 0)
889 intersection = ((rho2 - k2) / k1 - p.
z()) / v.
z();
896 + intersection * v.
y(), - k1 / 2);
906 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
910 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
911 JustWarning,
"There's an error in this functions code.");
932 std::ostringstream message;
933 G4int oldprc = message.precision(16);
934 message <<
"Point p is outside !?" <<
G4endl
936 <<
" p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
937 <<
" p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
938 <<
" p.z() = " << p.
z()/mm <<
" mm";
939 message.precision(oldprc) ;
940 G4Exception(
"G4Paraboloid::DistanceToOut(p)",
"GeomSolids1002",
946 safeZ = dz - std::fabs(p.
z()) ;
948 tanRMax = (r2 - r1)*0.5/dz ;
949 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
950 pRMax = tanRMax*p.
z() + (r1+r2)*0.5 ;
951 safeR = (pRMax - rho)/secRMax ;
953 if (safeZ < safeR) { safe = safeZ; }
954 else { safe = safeR; }
983 G4int oldprc = os.precision(16);
984 os <<
"-----------------------------------------------------------\n"
985 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
986 <<
" ===================================================\n"
987 <<
" Solid type: G4Paraboloid\n"
989 <<
" z half-axis: " << dz/mm <<
" mm \n"
990 <<
" radius at -dz: " << r1/mm <<
" mm \n"
991 <<
" radius at dz: " << r2/mm <<
" mm \n"
992 <<
"-----------------------------------------------------------\n";
993 os.precision(oldprc);
1007 if(pi*(
sqr(r1) +
sqr(r2))/A >= z)
1010 if(pi *
sqr(r1) / A > z)
1013 return G4ThreeVector(rho * std::cos(phi), rho * std::sin(phi), -dz);
1018 return G4ThreeVector(rho * std::cos(phi), rho * std::sin(phi), dz);
1025 std::sqrt(z*k1 + k2)*std::sin(phi), z);
1031 G4int& noPolygonVertices)
const
1035 G4double meshAnglePhi, cosMeshAnglePhiPer2,
1036 crossAnglePhi, coscrossAnglePhi, sincrossAnglePhi, sAnglePhi,
1037 sRho, dRho, rho, lastRho = 0., swapRho;
1039 G4int crossSectionPhi, noPhiCrossSections, noRhoSections;
1054 meshAnglePhi=twopi/(noPhiCrossSections-1);
1056 sAnglePhi = -meshAnglePhi*0.5*0;
1057 cosMeshAnglePhiPer2 = std::cos(meshAnglePhi / 2.);
1073 dRho = (r2 - r1) /
double(noRhoSections - 1);
1079 for (crossSectionPhi=0; crossSectionPhi<noPhiCrossSections;
1082 crossAnglePhi=sAnglePhi+crossSectionPhi*meshAnglePhi;
1083 coscrossAnglePhi=std::cos(crossAnglePhi);
1084 sincrossAnglePhi=std::sin(crossAnglePhi);
1086 for (
int iRho=0; iRho < noRhoSections;
1091 if(iRho == noRhoSections - 1)
1097 rho = iRho * dRho + sRho;
1102 k3 = k1 / (2*rho + dRho);
1103 k4 = rho - k3 * (
sqr(rho) - k2) / k1;
1104 zm = (
sqr(k1 / (2 * k3)) - k2) / k1;
1105 rho += std::sqrt(k1 * zm + k2) - zm * k3 - k4;
1108 rho += (1 / cosMeshAnglePhiPer2 - 1) * (iRho * dRho + sRho);
1113 lastRho = rho + dRho;
1118 lastRho = rho + dRho;
1121 rx = coscrossAnglePhi*rho;
1122 ry = sincrossAnglePhi*rho;
1123 rz = (
sqr(iRho * dRho + sRho) - k2) / k1;
1128 noPolygonVertices = noRhoSections ;
1133 G4Exception(
"G4Paraboloid::CreateRotatedVertices()",
1135 "Error in allocation of vertices. Out of memory !");
CLHEP::Hep3Vector G4ThreeVector
std::vector< G4ThreeVector > G4ThreeVectorList
G4DLLIMPORT std::ostream G4cout
double dot(const Hep3Vector &) const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
EInside Inside(const G4ThreeVector &p) const
G4Polyhedron * CreatePolyhedron() const
G4double CalculateSurfaceArea() const
G4ThreeVector GetPointOnSurface() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4Paraboloid(const G4String &pName, G4double pDz, G4double pR1, G4double pR2)
G4NURBS * CreateNURBS() const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4Polyhedron * fpPolyhedron
G4GeometryType GetEntityType() const
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
std::ostream & StreamInfo(std::ostream &os) const
G4Polyhedron * GetPolyhedron() const
G4Paraboloid & operator=(const G4Paraboloid &rhs)
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
G4double GetMinExtent(const EAxis pAxis) const
G4bool IsYLimited() const
G4double GetMinZExtent() const
G4bool IsXLimited() const
G4double GetMaxExtent(const EAxis pAxis) const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMinYExtent() const
G4double GetMinXExtent() const
G4bool IsZLimited() const
G4double GetMaxXExtent() const
static G4int GetNumberOfRotationSteps()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
const G4double kMeshAngleDefault