51 using namespace CLHEP;
 
   61  : 
G4VSolid(pName), fpPolyhedron(0), fSurfaceArea(0.), fCubicVolume(0.) 
 
   64   if( (pDz <= 0.) || (pR2 <= pR1) || (pR1 < 0.) )
 
   66     std::ostringstream message;
 
   67     message << 
"Invalid dimensions. Negative Input Values or R1>=R2 - " 
   69     G4Exception(
"G4Paraboloid::G4Paraboloid()", 
"GeomSolids0002", 
 
   71                 "Z half-length must be larger than zero or R1>=R2.");
 
   93   : 
G4VSolid(a), fpPolyhedron(0), fSurfaceArea(0.), fCubicVolume(0.),
 
   94     dz(0.), r1(0.), r2(0.), k1(0.), k2(0.)
 
  112     fSurfaceArea(rhs.fSurfaceArea), fCubicVolume(rhs.fCubicVolume),
 
  113     dz(rhs.dz), r1(rhs.r1), r2(rhs.r2), k1(rhs.k1), k2(rhs.k2)
 
  126    if (
this == &rhs)  { 
return *
this; }
 
  253     G4bool existsAfterClip=
true;
 
  257     G4int noPolygonVertices=0;
 
  267       for(G4ThreeVectorList::iterator it = vertices->begin();
 
  268           it < vertices->end(); it++)
 
  270         if(pMin > (*it)[pAxis]) pMin = (*it)[pAxis];
 
  275         if(pMax < (*it)[pAxis])
 
  286       || pMax < pVoxelLimit.
GetMinExtent(pAxis)) { existsAfterClip = 
false; }
 
  292       existsAfterClip = 
false;
 
  295     return existsAfterClip;
 
  314   if(
A < 0 && 
sqr(
A) > rhoSurfTimesTol2)
 
  319     if(std::fabs(p.z()) > 
dz - 0.5 * kCarTolerance)
 
  331   else if(
A <= 0 || 
sqr(
A) < rhoSurfTimesTol2)
 
  404     if(A < 0 && 
sqr(A) > rhoSurfTimesTol2)
 
  409       if(p.mag2() != 0) { n = p.unit(); }
 
  411     else if(A <= 0 || 
sqr(A) < rhoSurfTimesTol2)
 
  425     std::ostringstream message;
 
  426     message << 
"No normal defined for this point p." << 
G4endl 
  427             << 
"          p = " << 1 / 
mm * p << 
" mm";
 
  428     G4Exception(
"G4Paraboloid::SurfaceNormal(p)", 
"GeomSolids1002",
 
  443   G4double rho2 = p.perp2(), paraRho2 = std::fabs(
k1 * p.z() + 
k2);
 
  447   if(
r2 && p.z() > - tolh + 
dz) 
 
  454       if(
sqr(p.x() + v.x()*intersection)
 
  455        + 
sqr(p.y() + v.y()*intersection) < 
sqr(
r2 + 0.5 * kCarTolerance))
 
  457         if(p.z() < tolh + 
dz)
 
  460           { 
return intersection; }
 
  468   else if(
r1 && p.z() < tolh - 
dz)
 
  474       G4double intersection = (-
dz - p.z()) / v.z(); 
 
  475       if(
sqr(p.x() + v.x()*intersection)
 
  476        + 
sqr(p.y() + v.y()*intersection) < 
sqr(
r1 + 0.5 * kCarTolerance))
 
  478         if(p.z() > -tolh - 
dz)
 
  494   G4double A = 
k1 / 2 * v.z() - p.x() * v.x() - p.y() * v.y(),
 
  495            vRho2 = v.perp2(), intersection,
 
  496            B = (
k1 * p.z() + 
k2 - rho2) * vRho2;
 
  498   if ( ( (rho2 > paraRho2) && (
sqr(rho2-paraRho2-0.25*tol2) > tol2*paraRho2) )
 
  506       intersection = ((rho2 - 
k2)/
k1 - p.z())/v.z();
 
  507       if(intersection < 0) { 
return kInfinity; }
 
  508       else if(std::fabs(p.z() + v.z() * intersection) <= 
dz)
 
  523       intersection = (A - std::sqrt(B + 
sqr(A))) / vRho2;
 
  528       else if(std::fabs(p.z() + intersection * v.z()) < 
dz + tolh)
 
  538   else if(
sqr(rho2 - paraRho2 - .25 * tol2) <= tol2 * paraRho2)
 
  550     std::ostringstream message;
 
  557       message << 
"Likely a problem in this function, for solid: " << 
GetName()
 
  560     message << 
"          p = " << p * (1/
mm) << 
" mm" << 
G4endl 
  561             << 
"          v = " << v * (1/
mm) << 
" mm";
 
  562     G4Exception(
"G4Paraboloid::DistanceToIn(p,v)", 
"GeomSolids1002",
 
  576   if(safz<0) { safz=0; }
 
  579   G4double rho = p.x()*p.x()+p.y()*p.y();
 
  586     if(safr>safz) { safz=safr; }
 
  590   G4double sqprho = std::sqrt(paraRho);
 
  592   if(dRho<0) { 
return safz; }
 
  596   if(tmp<0.) { 
return safz; }
 
  598   G4double salf = talf/std::sqrt(tmp);
 
  599   safr = std::fabs(dRho*salf);
 
  600   if(safr>safz) { safz=safr; }
 
  615   G4double rho2 = p.perp2(), paraRho2 = std::fabs(
k1 * p.z() + 
k2);
 
  616   G4double vRho2 = v.perp2(), intersection;
 
  620   if(calcNorm) { *validNorm = 
false; }
 
  630   G4double A = 
k1 / 2 * v.z() - p.x() * v.x() - p.y() * v.y();
 
  634   G4double B = (-rho2 + paraRho2) * vRho2;
 
  636   if ( rho2 < paraRho2 && 
sqr(rho2 - paraRho2 - 0.25 * tol2) > tol2 * paraRho2
 
  637     && std::fabs(p.z()) < 
dz - kCarTolerance)
 
  648       intersection = (
dz - p.z()) / v.z();
 
  651       if(ip.perp2() < 
sqr(
r2 + kCarTolerance))
 
  656           if(
r2 < tolh || ip.perp2() > 
sqr(
r2 - tolh))
 
  673       intersection = (-
dz - p.z()) / v.z();
 
  676       if(ip.perp2() < 
sqr(
r1 + tolh))
 
  681           if(
r1 < tolh || ip.perp2() > 
sqr(
r1 - tolh))
 
  696       intersection = ((rho2 - 
k2)/
k1 - p.z())/v.z();
 
  707     else if( ((A <= 0) && (B >= 
sqr(A) * (
sqr(vRho2) - 1))) || (A >= 0))
 
  714       B = (
k1 * p.z() + 
k2 - rho2)/vRho2;
 
  715       intersection = B/(-A + std::sqrt(B + 
sqr(A)));
 
  725     std::ostringstream message;
 
  726     message << 
"There is no intersection between given line and solid!" 
  730     G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)", 
"GeomSolids1002",
 
  735   else if ( (rho2 < paraRho2 + kCarTolerance
 
  736          || 
sqr(rho2 - paraRho2 - 0.25 * tol2) < tol2 * paraRho2 )
 
  737          && std::fabs(p.z()) < 
dz + tolh) 
 
  743     if(std::fabs(p.z()) > 
dz - tolh)
 
  747       if( ((v.z() > 0) && (p.z() > 0)) || ((v.z() < 0) && (p.z() < 0)) )
 
  768         A = vRho2 * ( 
sqr(r) - 
sqr(p.x()) - 
sqr(p.y()));
 
  769         intersection = (-pDotV + std::sqrt(A + 
sqr(pDotV))) / vRho2;
 
  777               * intersection, -
k1/2).unit()).unit();
 
  807       intersection = (
dz - p.z()) / v.z();
 
  810       if(ip.perp2() < 
sqr(
r2 - tolh))
 
  819       else if(ip.perp2() < 
sqr(
r2 + tolh))
 
  835       intersection = (-
dz - p.z()) / v.z();
 
  838       if(ip.perp2() < 
sqr(
r1 - tolh))
 
  847       else if(ip.perp2() < 
sqr(
r1 + tolh))
 
  862     if(std::fabs(vRho2) > tol2) 
 
  865       B = (
k1 * p.z() + 
k2 - rho2);
 
  869         intersection = B/(-A + std::sqrt(B + 
sqr(A)));
 
  873         if(normal.dot(v) >= 0)
 
  887       intersection = ((rho2 - 
k2) / 
k1 - p.z()) / v.z();
 
  894          + intersection * v.y(), - 
k1 / 2);
 
  904       G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)", 
"GeomSolids1002",
 
  908       G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)", 
"GeomSolids1002",
 
  909                   JustWarning, 
"There's an error in this functions code.");
 
  930      std::ostringstream message;
 
  931      G4int oldprc = message.precision(16);
 
  932      message << 
"Point p is outside !?" << G4endl
 
  933              << 
"Position:" << G4endl
 
  934              << 
"   p.x() = "   << p.x()/
mm << 
" mm" << G4endl
 
  935              << 
"   p.y() = "   << p.y()/
mm << 
" mm" << G4endl
 
  936              << 
"   p.z() = "   << p.z()/
mm << 
" mm";
 
  937      message.precision(oldprc) ;
 
  938      G4Exception(
"G4Paraboloid::DistanceToOut(p)", 
"GeomSolids1002",
 
  944   safeZ = 
dz - std::fabs(p.z()) ;
 
  946   tanRMax = (
r2 - 
r1)*0.5/
dz ;
 
  947   secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
 
  948   pRMax   = tanRMax*p.z() + (
r1+
r2)*0.5 ;
 
  949   safeR  = (pRMax - rho)/secRMax ;
 
  951   if (safeZ < safeR) { safe = safeZ; }
 
  952   else { safe = safeR; }
 
  981   G4int oldprc = os.precision(16);
 
  982   os << 
"-----------------------------------------------------------\n" 
  983      << 
"    *** Dump for solid - " << 
GetName() << 
" ***\n" 
  984      << 
"    ===================================================\n" 
  985      << 
" Solid type: G4Paraboloid\n" 
  987      << 
"    z half-axis:   " << 
dz/
mm << 
" mm \n" 
  988      << 
"    radius at -dz: " << 
r1/
mm << 
" mm \n" 
  989      << 
"    radius at dz:  " << 
r2/
mm << 
" mm \n" 
  990      << 
"-----------------------------------------------------------\n";
 
  991   os.precision(oldprc);
 
 1023                          std::sqrt(z*
k1 + 
k2)*std::sin(phi), z);
 
 1029                                           G4int& noPolygonVertices)
 const 
 1033   G4double meshAnglePhi, cosMeshAnglePhiPer2,
 
 1034            crossAnglePhi, coscrossAnglePhi, sincrossAnglePhi, sAnglePhi,
 
 1035            sRho, dRho, rho, lastRho = 0., swapRho;
 
 1037   G4int crossSectionPhi, noPhiCrossSections, noRhoSections;
 
 1052   meshAnglePhi=twopi/(noPhiCrossSections-1);
 
 1054   sAnglePhi = -meshAnglePhi*0.5*0;
 
 1055   cosMeshAnglePhiPer2 = std::cos(meshAnglePhi / 2.);
 
 1071   dRho = (
r2 - 
r1) / 
double(noRhoSections - 1);
 
 1077     for (crossSectionPhi=0; crossSectionPhi<noPhiCrossSections;
 
 1080       crossAnglePhi=sAnglePhi+crossSectionPhi*meshAnglePhi;
 
 1081       coscrossAnglePhi=std::cos(crossAnglePhi);
 
 1082       sincrossAnglePhi=std::sin(crossAnglePhi);
 
 1084       for (
int iRho=0; iRho < noRhoSections;
 
 1089         if(iRho == noRhoSections - 1)
 
 1095           rho = iRho * dRho + sRho;
 
 1100           k3 = 
k1 / (2*rho + dRho);
 
 1101           k4 = rho - k3 * (
sqr(rho) - 
k2) / 
k1;
 
 1103           rho += std::sqrt(
k1 * zm + 
k2) - zm * k3 - k4;
 
 1106         rho += (1 / cosMeshAnglePhiPer2 - 1) * (iRho * dRho + sRho);
 
 1111           lastRho = rho + dRho;
 
 1116           lastRho = rho + dRho;
 
 1119         rx = coscrossAnglePhi*rho;
 
 1120         ry = sincrossAnglePhi*rho;
 
 1121         rz = (
sqr(iRho * dRho + sRho) - 
k2) / 
k1;
 
 1126     noPolygonVertices = noRhoSections ;
 
 1131     G4Exception(
"G4Paraboloid::CreateRotatedVertices()",
 
 1133                 "Error in allocation of vertices. Out of memory !");
 
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 
 
virtual void AddSolid(const G4Box &)=0
 
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
 
void DescribeYourselfTo(G4VGraphicsScene &scene) const 
 
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 
 
static const G4double A[nN]
 
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