64 using namespace CLHEP;
 
   75   : 
G4VSolid(pName), fRebuildPolyhedron(false), fpPolyhedron(0),
 
   76     fCubicVolume(0.), fSurfaceArea(0.), zTopCut(0.)
 
   81   halfRadTol = 0.5*kRadTolerance;
 
   86   if ( (pxSemiAxis <= 0.) || (pySemiAxis <= 0.) || (pzMax <= 0.) )
 
   88      std::ostringstream message;
 
   89      message << 
"Invalid semi-axis or height - " << 
GetName();
 
   90      G4Exception(
"G4EllipticalCone::G4EllipticalCone()", 
"GeomSolids0002",
 
   95      std::ostringstream message;
 
   96      message << 
"Invalid z-coordinate for cutting plane - " << 
GetName();
 
   97      G4Exception(
"G4EllipticalCone::G4EllipticalCone()", 
"InvalidSetup",
 
  111   : 
G4VSolid(a), fRebuildPolyhedron(false), fpPolyhedron(0),
 
  112     kRadTolerance(0.), halfRadTol(0.), halfCarTol(0.), fCubicVolume(0.),
 
  113     fSurfaceArea(0.), xSemiAxis(0.), ySemiAxis(0.), zheight(0.),
 
  114     semiAxisMax(0.), zTopCut(0.)
 
  133     fRebuildPolyhedron(false), fpPolyhedron(0),
 
  134     kRadTolerance(rhs.kRadTolerance),
 
  135     halfRadTol(rhs.halfRadTol), halfCarTol(rhs.halfCarTol), 
 
  136     fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
 
  137     xSemiAxis(rhs.xSemiAxis), ySemiAxis(rhs.ySemiAxis), zheight(rhs.zheight),
 
  138     semiAxisMax(rhs.semiAxisMax), zTopCut(rhs.zTopCut)
 
  150    if (
this == &rhs)  { 
return *
this; }
 
  158    kRadTolerance = rhs.kRadTolerance;
 
  159    halfRadTol = rhs.halfRadTol; halfCarTol = rhs.halfCarTol;
 
  160    fCubicVolume = rhs.fCubicVolume; fSurfaceArea = rhs.fSurfaceArea;
 
  161    xSemiAxis = rhs.xSemiAxis; ySemiAxis = rhs.ySemiAxis;
 
  162    zheight = rhs.zheight; semiAxisMax = rhs.semiAxisMax; zTopCut = rhs.zTopCut;
 
  179   pMin.
set(-xmax,-ymax,-zcut);
 
  180   pMax.
set( xmax, ymax, zcut);
 
  184   if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
 
  186     std::ostringstream message;
 
  187     message << 
"Bad bounding box (min >= max) for solid: " 
  189             << 
"\npMin = " << pMin
 
  190             << 
"\npMax = " << pMax;
 
  191     G4Exception(
"G4EllipticalCone::Extent()", 
"GeomMgt0001",
 
  215   if (
true) 
return bbox.
CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
 
  219     return exist = (pMin < pMax) ? 
true : 
false;
 
  224   static const G4int NSTEPS = 48; 
 
  226   static const G4double sinHalf = std::sin(0.5*ang);
 
  227   static const G4double cosHalf = std::cos(0.5*ang);
 
  228   static const G4double sinStep = 2.*sinHalf*cosHalf;
 
  229   static const G4double cosStep = 1. - 2.*sinHalf*sinHalf;
 
  240   for (
G4int k=0; k<NSTEPS; ++k)
 
  242     baseA[k].set(sxmax*cosCur,symax*sinCur,-zcut);
 
  243     baseB[k].set(sxmin*cosCur,symin*sinCur, zcut);
 
  246     sinCur = sinCur*cosStep + cosCur*sinStep;
 
  247     cosCur = cosCur*cosStep - sinTmp*sinStep;
 
  250   std::vector<const G4ThreeVectorList *> polygons(2);
 
  251   polygons[0] = &baseA;
 
  252   polygons[1] = &baseB;
 
  274   if ( (p.
z() < -zTopCut - halfCarTol)
 
  275     || (p.
z() > zTopCut + halfCarTol ) )
 
  280   rad2oo= 
sqr(p.
x()/( xSemiAxis + halfRadTol ))
 
  281         + 
sqr(p.
y()/( ySemiAxis + halfRadTol ));
 
  283   if ( rad2oo > 
sqr( zheight-p.
z() ) )
 
  290   rad2oi = 
sqr(p.
x()/( xSemiAxis - halfRadTol ))
 
  291         + 
sqr(p.
y()/( ySemiAxis - halfRadTol ));
 
  293   if (rad2oi < 
sqr( zheight-p.
z() ) )
 
  295     in = ( ( p.
z() < -zTopCut + halfRadTol )
 
  314            ry = 
sqr(p.
y()/ySemiAxis);
 
  320   if( (p.
z() < -zTopCut) && ((rx+ry) < 
sqr(zTopCut + zheight)) )
 
  325   if( (p.
z() > (zheight > zTopCut ? zheight : zTopCut)) &&
 
  326       ((rx+ry) < 
sqr(zheight-zTopCut)) )
 
  331   if( p.
z() > rds + 2.*zTopCut - zheight ) 
 
  333     if ( p.
z() > zTopCut )
 
  338         return norm /= norm.
mag();
 
  343         return norm /= norm.
mag();
 
  356                             - ( zheight - zTopCut ) );
 
  359       return norm /= norm.
mag();      
 
  365   if( p.
z() < rds - 2.*zTopCut - zheight )
 
  370       return norm /= norm.
mag();
 
  375       return norm /= norm.
mag();
 
  388                           - ( zheight - zTopCut ) );
 
  391     return norm /= norm.
mag();      
 
  397   G4double c = -zTopCut - k*(zTopCut + zheight);
 
  399   if( p.
z() < -k*rds + c )
 
  402   return norm /= norm.
mag();
 
  423   if (sigz < halfCarTol)
 
  442       if ( 
sqr(p.
x()/( xSemiAxis - halfCarTol ))
 
  443          + 
sqr(p.
y()/( ySemiAxis - halfCarTol )) <= 
sqr( zheight+zTopCut ) )
 
  458                yi = p.
y() + q*v.
y();
 
  463       if ( 
sqr(xi/xSemiAxis) + 
sqr(yi/ySemiAxis) <= 
sqr( zheight + zTopCut ) )
 
  468         return (sigz < -halfCarTol) ? q : 0;
 
  470       else if (xi/(xSemiAxis*xSemiAxis)*v.
x()
 
  471              + yi/(ySemiAxis*ySemiAxis)*v.
y() >= 0)
 
  485   sigz = p.
z() - zTopCut;
 
  487   if (sigz > -halfCarTol)
 
  494       if ( 
sqr(p.
x()/( xSemiAxis - halfCarTol ))
 
  495          + 
sqr(p.
y()/( ySemiAxis - halfCarTol )) <= 
sqr( zheight-zTopCut ) )
 
  503                yi = p.
y() + q*v.
y();
 
  505       if ( 
sqr(xi/xSemiAxis) + 
sqr(yi/ySemiAxis) <= 
sqr( zheight - zTopCut ) )
 
  507         return (sigz > -halfCarTol) ? q : 0;
 
  509       else if (xi/(xSemiAxis*xSemiAxis)*v.
x()
 
  510              + yi/(ySemiAxis*ySemiAxis)*v.
y() >= 0)
 
  529     if ( 
sqr((lambda*v.
x()+p.
x())/xSemiAxis) + 
 
  530          sqr((lambda*v.
y()+p.
y())/ySemiAxis) <=
 
  531          sqr(zTopCut + zheight + 0.5*kRadTolerance) ) 
 
  533       return distMin = std::fabs(lambda);    
 
  544     if ( 
sqr((lambda*v.
x() + p.
x())/xSemiAxis) + 
 
  545          sqr((lambda*v.
y() + p.
y())/ySemiAxis) <=
 
  546          sqr(zheight - zTopCut + 0.5*kRadTolerance) )
 
  548         return distMin = std::fabs(lambda);
 
  552   if (p.
z() > zTopCut - halfCarTol
 
  553    && p.
z() < zTopCut + halfCarTol )
 
  561   if (p.
z() < -zTopCut + halfCarTol
 
  562    && p.
z() > -zTopCut - halfCarTol)
 
  577                   v.
y()*p.
y()/
sqr(ySemiAxis) + v.
z()*(zheight-p.
z()));
 
  579                sqr(zheight - p.
z());
 
  585   if ( discr < -halfCarTol )
 
  590   if ( (discr >= - halfCarTol ) && (discr < halfCarTol ) )
 
  592     return distMin = std::fabs(-B/(2.*A)); 
 
  595   G4double plus  = (-B+std::sqrt(discr))/(2.*A);
 
  596   G4double minus = (-B-std::sqrt(discr))/(2.*A);
 
  600   if ( ( std::fabs(plus) < halfCarTol )||( std::fabs(minus) < halfCarTol ) )
 
  603                            p.
y()/(ySemiAxis*ySemiAxis),
 
  604                            -( p.
z() - zheight ));
 
  605     if ( truenorm*v >= 0)  
 
  618   if ( minus > halfCarTol && minus < distMin ) 
 
  626                              pin.
y()/(ySemiAxis*ySemiAxis),
 
  627                              - ( pin.
z() - zheight ));
 
  634   if ( plus > halfCarTol  && plus < distMin )
 
  642                              pin.
y()/(ySemiAxis*ySemiAxis),
 
  643                              - ( pin.
z() - zheight ) );
 
  650   if (distMin < halfCarTol) distMin=0.;
 
  661   G4double distR, distR2, distZ, maxDim;
 
  667   if( (p.
z() <= -zTopCut) && (
sqr(p.
x()/xSemiAxis) + 
sqr(p.
y()/ySemiAxis)
 
  671      return distZ = std::fabs(zTopCut + p.
z());
 
  674   if( (p.
z() >= zTopCut) && (
sqr(p.
x()/xSemiAxis)+
sqr(p.
y()/ySemiAxis)
 
  677     return distZ = std::fabs(p.
z() - zTopCut);
 
  684   maxDim = xSemiAxis >= ySemiAxis ? xSemiAxis:ySemiAxis;
 
  685   distRad = std::sqrt(p.
x()*p.
x()+p.
y()*p.
y());
 
  687   if( p.
z() > maxDim*distRad + zTopCut*(1.+maxDim)-
sqr(maxDim)*zheight )
 
  689     distR2 = 
sqr(p.
z() - zTopCut) + 
sqr(distRad - maxDim*(zheight - zTopCut));
 
  690     return std::sqrt( distR2 );
 
  693   if( distRad > maxDim*( zheight - p.
z() ) )
 
  695     if( p.
z() > maxDim*distRad - (zTopCut*(1.+maxDim)+
sqr(maxDim)*zheight) )
 
  697       G4double zVal = (p.
z()-maxDim*(distRad-maxDim*zheight))/(1.+
sqr(maxDim));
 
  698       G4double rVal = maxDim*(zheight - zVal);
 
  699       return distR  = std::sqrt(
sqr(p.
z() - zVal) + 
sqr(distRad - rVal));
 
  703   if( distRad <= maxDim*(zheight - p.
z()) )
 
  705     distR2 = 
sqr(distRad - maxDim*(zheight + zTopCut)) + 
sqr(p.
z() + zTopCut);
 
  706     return std::sqrt( distR2 );    
 
  724   enum surface_e {kPlaneSurf, kCurvedSurf, kNoSurf} surface;
 
  731     lambda = (-p.
z() - zTopCut)/v.
z();
 
  733     if ( (
sqr((p.
x() + lambda*v.
x())/xSemiAxis) + 
 
  734           sqr((p.
y() + lambda*v.
y())/ySemiAxis)) < 
 
  737       distMin = std::fabs(lambda);
 
  739       if (!calcNorm) { 
return distMin; }
 
  741     distMin = std::fabs(lambda);
 
  742     surface = kPlaneSurf;
 
  747     lambda = (zTopCut - p.
z()) / v.
z();
 
  749     if ( (
sqr((p.
x() + lambda*v.
x())/xSemiAxis)
 
  750         + 
sqr((p.
y() + lambda*v.
y())/ySemiAxis) )
 
  753       distMin = std::fabs(lambda);
 
  754       if (!calcNorm) { 
return distMin; }
 
  756     distMin = std::fabs(lambda);
 
  757     surface = kPlaneSurf;
 
  765                    v.
y()*p.
y()/
sqr(ySemiAxis) + v.
z()*(zheight-p.
z()));
 
  767              - 
sqr(zheight - p.
z());
 
  773     if(!calcNorm) { 
return distMin = std::fabs(-B/(2.*A)); }
 
  778     G4double plus  = (-B+std::sqrt(discr))/(2.*A);
 
  779     G4double minus = (-B-std::sqrt(discr))/(2.*A);
 
  785       lambda   = std::fabs(plus) < std::fabs(minus) ? plus : minus;
 
  795     if ( std::fabs(lambda) < distMin )
 
  799         distMin  = std::fabs(lambda);
 
  800         surface  = kCurvedSurf;
 
  805                                p.
y()/(ySemiAxis*ySemiAxis),
 
  806                                -( p.
z() - zheight ));
 
  807         if( truenorm.
dot(v) > 0 )
 
  810           surface  = kCurvedSurf;
 
  820     if (surface == kNoSurf)
 
  839                                   pexit.
y()/(ySemiAxis*ySemiAxis),
 
  840                                   -( pexit.
z() - zheight ) );
 
  841           truenorm /= truenorm.
mag();
 
  848           std::ostringstream message;
 
  849           G4int oldprc = message.precision(16);
 
  850           message << 
"Undefined side for valid surface normal to solid." 
  853                   << 
"   p.x() = "   << p.
x()/
mm << 
" mm" << 
G4endl 
  854                   << 
"   p.y() = "   << p.
y()/
mm << 
" mm" << 
G4endl 
  855                   << 
"   p.z() = "   << p.
z()/
mm << 
" mm" << 
G4endl 
  857                   << 
"   v.x() = "   << v.
x() << 
G4endl 
  858                   << 
"   v.y() = "   << v.
y() << 
G4endl 
  859                   << 
"   v.z() = "   << v.
z() << 
G4endl 
  860                   << 
"Proposed distance :" << 
G4endl 
  861                   << 
"   distMin = "    << distMin/
mm << 
" mm";
 
  862           message.precision(oldprc);
 
  863           G4Exception(
"G4EllipticalCone::DistanceToOut(p,v,..)",
 
  885      std::ostringstream message;
 
  886      G4int oldprc = message.precision(16);
 
  887      message << 
"Point p is outside !?" << 
G4endl 
  889              << 
"   p.x() = "   << p.
x()/
mm << 
" mm" << 
G4endl 
  890              << 
"   p.y() = "   << p.
y()/
mm << 
" mm" << 
G4endl 
  891              << 
"   p.z() = "   << p.
z()/
mm << 
" mm";
 
  892      message.precision(oldprc) ;
 
  893      G4Exception(
"G4Ellipsoid::DistanceToOut(p)", 
"GeomSolids1002",
 
  902   if (xSemiAxis < ySemiAxis)
 
  905     py  *= xSemiAxis/ySemiAxis; 
 
  910     px  *= ySemiAxis/xSemiAxis; 
 
  913   G4double distZ = zTopCut - std::abs(pz) ;
 
  914   if (distZ <= 0) 
return 0; 
 
  917   G4double pr  = std::sqrt(px*px+py*py);
 
  918   if (pr >= rho)  
return 0; 
 
  920   G4double distR = (rho-pr)/std::sqrt(1+axis*axis);
 
  930   return G4String(
"G4EllipticalCone");
 
  948   G4int oldprc = os.precision(16);
 
  949   os << 
"-----------------------------------------------------------\n" 
  950      << 
"    *** Dump for solid - " << 
GetName() << 
" ***\n" 
  951      << 
"    ===================================================\n" 
  952      << 
" Solid type: G4EllipticalCone\n" 
  955      << 
"    semi-axis x: " << xSemiAxis/
mm << 
" mm \n" 
  956      << 
"    semi-axis y: " << ySemiAxis/
mm << 
" mm \n" 
  957      << 
"    height    z: " << zheight/
mm << 
" mm \n" 
  958      << 
"    half length in  z: " << zTopCut/
mm << 
" mm \n" 
  959      << 
"-----------------------------------------------------------\n";
 
  960   os.precision(oldprc);
 
  974   G4double phi, sinphi, cosphi, aOne, aTwo, aThree,
 
  975            chose, zRand, rRand1, rRand2;
 
  978                 + 
sqr(ySemiAxis))*(zheight - zTopCut);
 
  980                 + 
sqr(ySemiAxis))*(zheight + zTopCut);
 
  984   aOne   = 
pi*(rOne + rTwo)*std::sqrt(
sqr(rOne - rTwo)+
sqr(2.*zTopCut));
 
  985   aTwo   = 
pi*xSemiAxis*ySemiAxis*
sqr(zheight+zTopCut);
 
  986   aThree = 
pi*xSemiAxis*ySemiAxis*
sqr(zheight-zTopCut);  
 
  989   cosphi = std::cos(phi);
 
  990   sinphi = std::sin(phi);
 
  992   if(zTopCut >= zheight) aThree = 0.;
 
  995   if((chose>=0.) && (chose<aOne))
 
  999                          ySemiAxis*(zheight-zRand)*sinphi,zRand);    
 
 1001   else if((chose>=aOne) && (chose<aOne+aTwo))
 
 1007     } 
while (( rRand2 >= rRand1  ) && (++it1 < 1000)) ;
 
 1009     return G4ThreeVector(rRand1*xSemiAxis*(zheight+zTopCut)*cosphi,
 
 1010                          rRand1*ySemiAxis*(zheight+zTopCut)*sinphi, -zTopCut);
 
 1020   } 
while (( rRand2 >= rRand1  ) && (++it2 < 1000));
 
 1022   return G4ThreeVector(rRand1*xSemiAxis*(zheight-zTopCut)*cosphi,
 
 1023                        rRand1*ySemiAxis*(zheight-zTopCut)*sinphi, zTopCut);
 
void set(double x, double y, double z)
 
ThreeVector shoot(const G4int Ap, const G4int Af)
 
static constexpr double mm
 
G4EllipticalCone & operator=(const G4EllipticalCone &rhs)
 
static const G4double kInfinity
 
G4double GetSemiAxisX() const 
 
CLHEP::Hep3Vector G4ThreeVector
 
double dot(const Hep3Vector &) const 
 
EInside Inside(const G4ThreeVector &p) const 
 
double B(double temperature)
 
virtual void AddSolid(const G4Box &)=0
 
G4Polyhedron * CreatePolyhedron() const 
 
#define G4MUTEX_INITIALIZER
 
static constexpr double twopi
 
std::ostream & StreamInfo(std::ostream &os) const 
 
G4bool fRebuildPolyhedron
 
G4ThreeVector GetPointOnSurface() const 
 
double A(double temperature)
 
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const 
 
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const 
 
G4Polyhedron * fpPolyhedron
 
G4double GetRadialTolerance() const 
 
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const 
 
G4EllipticalCone(const G4String &pName, G4double pxSemiAxis, G4double pySemiAxis, G4double zMax, G4double pzTopCut)
 
void Extent(G4ThreeVector &pMin, G4ThreeVector &pMax) const 
 
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const 
 
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const 
 
std::vector< G4ThreeVector > G4ThreeVectorList
 
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
 
void DescribeYourselfTo(G4VGraphicsScene &scene) const 
 
G4double GetSemiAxisY() const 
 
void SetSemiAxis(G4double x, G4double y, G4double z)
 
static G4int GetNumberOfRotationSteps()
 
void SetZCut(G4double newzTopCut)
 
T min(const T t1, const T t2)
brief Return the smallest of the two arguments 
 
G4double GetZTopCut() const 
 
G4VSolid & operator=(const G4VSolid &rhs)
 
G4int GetNumberOfRotationStepsAtTimeOfCreation() const 
 
static constexpr double pi
 
G4Polyhedron * GetPolyhedron() const 
 
G4GeometryType GetEntityType() const 
 
G4VisExtent GetExtent() const 
 
virtual ~G4EllipticalCone()
 
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const 
 
static G4GeometryTolerance * GetInstance()