42 #if !defined(G4GEOM_USE_UPOLYCONE) 
   58 using namespace CLHEP;
 
   85   for (i=0; i<numZPlanes; i++)
 
   87     if(rInner[i]>rOuter[i])
 
   90       std::ostringstream message;
 
   91       message << 
"Cannot create a Polycone with rInner > rOuter for the same Z" 
   93               << 
"        rInner > rOuter for the same Z !" << 
G4endl 
   94               << 
"        rMin[" << i << 
"] = " << rInner[i]
 
   95               << 
" -- rMax[" << i << 
"] = " << rOuter[i];
 
   96       G4Exception(
"G4Polycone::G4Polycone()", 
"GeomSolids0002",
 
   99     if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
 
  101       if( (rInner[i]   > rOuter[i+1])
 
  102         ||(rInner[i+1] > rOuter[i])   )
 
  105         std::ostringstream message;
 
  106         message << 
"Cannot create a Polycone with no contiguous segments." 
  108                 << 
"        Segments are not contiguous !" << 
G4endl 
  109                 << 
"        rMin[" << i << 
"] = " << rInner[i]
 
  110                 << 
" -- rMax[" << i+1 << 
"] = " << rOuter[i+1] << 
G4endl 
  111                 << 
"        rMin[" << i+1 << 
"] = " << rInner[i+1]
 
  112                 << 
" -- rMax[" << i << 
"] = " << rOuter[i];
 
  113         G4Exception(
"G4Polycone::G4Polycone()", 
"GeomSolids0002",
 
  131   Create( phiStart, phiTotal, rz );
 
  151   Create( phiStart, phiTotal, rz );
 
  160     std::ostringstream message;
 
  161     message << 
"Polycone " << 
GetName() << 
"cannot be converted" << 
G4endl 
  162             << 
"to Polycone with (Rmin,Rmaz,Z) parameters!";
 
  163     G4Exception(
"G4Polycone::G4Polycone()", 
"GeomSolids0002",
 
  169            << 
"to optimized polycone with (Rmin,Rmaz,Z) parameters !" 
  188   if (rz->
Amin() < 0.0)
 
  190     std::ostringstream message;
 
  191     message << 
"Illegal input parameters - " << 
GetName() << 
G4endl 
  192             << 
"        All R values must be >= 0 !";
 
  193     G4Exception(
"G4Polycone::Create()", 
"GeomSolids0002",
 
  204     std::ostringstream message;
 
  205     message << 
"Illegal input parameters - " << 
GetName() << 
G4endl 
  206             << 
"        R/Z cross section is zero or near zero: " << rzArea;
 
  207     G4Exception(
"G4Polycone::Create()", 
"GeomSolids0002",
 
  214     std::ostringstream message;
 
  215     message << 
"Illegal input parameters - " << 
GetName() << 
G4endl 
  216             << 
"        Too few unique R/Z values !";
 
  217     G4Exception(
"G4Polycone::Create()", 
"GeomSolids0002",
 
  223     std::ostringstream message;
 
  224     message << 
"Illegal input parameters - " << 
GetName() << 
G4endl 
  225             << 
"        R/Z segments cross !";
 
  226     G4Exception(
"G4Polycone::Create()", 
"GeomSolids0002",
 
  236   if (phiTotal <= 0 || phiTotal > 
twopi-1E-10)
 
  253     endPhi = phiStart+phiTotal;
 
  272     next->
r = iterRZ.
GetA();
 
  273     next->
z = iterRZ.
GetB();
 
  274   } 
while( ++next, iterRZ.
Next() );
 
  306     if (corner->
z > next->
z)
 
  323   } 
while( prev=corner, corner=next, corner > 
corners );
 
  352   : 
G4VCSGfaceted(a), startPhi(0.),  endPhi(0.), phiIsOpen(false),
 
  353     numCorner(0), corners(0),original_parameters(0), 
 
  385   if (
this == &source) 
return *
this;
 
  534     if (corner.
r < rmin) rmin = corner.
r;
 
  535     if (corner.
r > rmax) rmax = corner.
r;
 
  536     if (corner.
z < zmin) zmin = corner.
z;
 
  537     if (corner.
z > zmax) zmax = corner.
z;
 
  547     pMin.
set(vmin.
x(),vmin.
y(),zmin);
 
  548     pMax.
set(vmax.
x(),vmax.
y(),zmax);
 
  552     pMin.
set(-rmax,-rmax, zmin);
 
  553     pMax.
set( rmax, rmax, zmax);
 
  558   if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
 
  560     std::ostringstream message;
 
  561     message << 
"Bad bounding box (min >= max) for solid: " 
  563             << 
"\npMin = " << pMin
 
  564             << 
"\npMax = " << pMax;
 
  587   if (
true) 
return bbox.
CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
 
  591     return exist = (pMin < pMax) ? 
true : 
false;
 
  600   std::vector<G4int> iout;
 
  612   if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
 
  617     std::ostringstream message;
 
  618     message << 
"Triangulation of RZ contour has failed for solid: " 
  620             << 
"\nExtent has been calculated using boundary box";
 
  627   const G4int NSTEPS = 24;            
 
  633   G4int    ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-
deg)/astep) + 1;
 
  636   G4double sinHalf = std::sin(0.5*ang);
 
  637   G4double cosHalf = std::cos(0.5*ang);
 
  638   G4double sinStep = 2.*sinHalf*cosHalf;
 
  639   G4double cosStep = 1. - 2.*sinHalf*sinHalf;
 
  647   std::vector<const G4ThreeVectorList *> polygons;
 
  648   polygons.resize(ksteps+2);
 
  650   for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
 
  651   for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
 
  658   G4int ntria = triangles.size()/3;
 
  659   for (
G4int i=0; i<ntria; ++i)
 
  662     for (
G4int k=0; k<3; ++k)
 
  664       G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
 
  667       r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
 
  668       r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
 
  672       if (z0[k2+1] - z0[k2+0] <= 0) 
continue;
 
  678     G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
 
  679     G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
 
  680     for (
G4int j=0; j<6; ++j) pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
 
  681     for (
G4int k=1; k<ksteps+1; ++k)
 
  683       for (
G4int j=0; j<6; ++j) pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
 
  685       sinCur = sinCur*cosStep + cosCur*sinStep;
 
  686       cosCur = cosCur*cosStep - sinTmp*sinStep;
 
  688     for (
G4int j=0; j<6; ++j) pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
 
  693     if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) 
continue;
 
  694     if (emin < pMin) pMin = emin;
 
  695     if (emax > pMax) pMax = 
emax;
 
  696     if (eminlim > pMin && emaxlim < pMax) 
return true; 
 
  698   return (pMin < pMax);
 
  732   G4int oldprc = os.precision(16);
 
  733   os << 
"-----------------------------------------------------------\n" 
  734      << 
"    *** Dump for solid - " << 
GetName() << 
" ***\n" 
  735      << 
"    ===================================================\n" 
  736      << 
" Solid type: G4Polycone\n" 
  739      << 
"    ending phi angle   : " << 
endPhi/
degree << 
" degrees \n";
 
  743     os << 
"    number of Z planes: " << numPlanes << 
"\n" 
  745     for (i=0; i<numPlanes; i++)
 
  747       os << 
"              Z plane " << i << 
": " 
  750     os << 
"              Tangent distances to inner surface (Rmin): \n";
 
  751     for (i=0; i<numPlanes; i++)
 
  753       os << 
"              Z plane " << i << 
": " 
  756     os << 
"              Tangent distances to outer surface (Rmax): \n";
 
  757     for (i=0; i<numPlanes; i++)
 
  759       os << 
"              Z plane " << i << 
": " 
  763   os << 
"    number of RZ points: " << 
numCorner << 
"\n" 
  764      << 
"              RZ values (corners): \n";
 
  770   os << 
"-----------------------------------------------------------\n";
 
  771   os.precision(oldprc);
 
  789   G4double Aone, Atwo, Afive, phi, zRand, fDPhi, cosu, sinu;
 
  790   G4double rRand1, rmin, rmax, chose, rone, rtwo, qone, qtwo;
 
  791   G4double fDz=(zTwo-zOne)/2., afDz=std::fabs(fDz);
 
  794   rone = (fRmax1-fRmax2)/(2.*fDz); 
 
  795   rtwo = (fRmin1-fRmin2)/(2.*fDz);
 
  796   if(fRmax1==fRmax2){qone=0.;}
 
  799     qone = fDz*(fRmax1+fRmax2)/(fRmax1-fRmax2);
 
  801   if(fRmin1==fRmin2){qtwo=0.;}
 
  804     qtwo = fDz*(fRmin1+fRmin2)/(fRmin1-fRmin2);
 
  806   Aone   = 0.5*fDPhi*(fRmax2 + fRmax1)*(
sqr(fRmin1-fRmin2)+
sqr(zTwo-zOne));       
 
  807   Atwo   = 0.5*fDPhi*(fRmin2 + fRmin1)*(
sqr(fRmax1-fRmax2)+
sqr(zTwo-zOne));
 
  808   Afive  = fDz*(fRmax1-fRmin1+fRmax2-fRmin2);
 
  809   totArea = Aone+Atwo+2.*Afive;
 
  812   cosu = std::cos(phi);
 
  813   sinu = std::sin(phi);
 
  816   if( (startPhi == 0) && (
endPhi == 
twopi) ) { Afive = 0; }
 
  818   if( (chose >= 0) && (chose < Aone) )
 
  824                              rone*sinu*(qone-zRand), zRand);
 
  833   else if(chose >= Aone && chose < Aone + Atwo)
 
  839                              rtwo*sinu*(qtwo-zRand), zRand);
 
  848   else if( (chose >= Aone + Atwo + Afive) && (chose < Aone + Atwo + 2.*Afive) )
 
  851     rmin   = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
 
  852     rmax   = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
 
  855                             rRand1*std::sin(startPhi), zRand);
 
  860     rmin   = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
 
  861     rmax   = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
 
  864                             rRand1*std::sin(
endPhi), zRand);
 
  881   G4double xRand,yRand,zRand,phi,cosphi,sinphi,chose,
 
  882            aOne,aTwo,aFou,rRand,fDz,fSPhi,fDPhi;
 
  883   fDz = std::fabs(0.5*(zTwo-zOne));
 
  887   aOne = 2.*fDz*fDPhi*fRMax;
 
  888   aTwo = 2.*fDz*fDPhi*fRMin;
 
  889   aFou = 2.*fDz*(fRMax-fRMin);
 
  890   totArea = aOne+aTwo+2.*aFou;
 
  892   cosphi = std::cos(phi);
 
  893   sinphi = std::sin(phi);
 
  900   if( (chose >= 0) && (chose < aOne) )
 
  902     xRand = fRMax*cosphi;
 
  903     yRand = fRMax*sinphi;
 
  907   else if( (chose >= aOne) && (chose < aOne + aTwo) )
 
  909     xRand = fRMin*cosphi;
 
  910     yRand = fRMin*sinphi;
 
  914   else if( (chose >= aOne+aTwo) && (chose <aOne+aTwo+aFou) )
 
  916     xRand = rRand*std::cos(fSPhi+fDPhi);
 
  917     yRand = rRand*std::sin(fSPhi+fDPhi);
 
  924   xRand = rRand*std::cos(fSPhi+fDPhi);
 
  925   yRand = rRand*std::sin(fSPhi+fDPhi);
 
  940   G4double xRand,yRand,phi,cosphi,sinphi,rRand1,rRand2,A1,Atot,rCh;
 
  942   cosphi = std::cos(phi);
 
  943   sinphi = std::sin(phi);
 
  947     rRand1 = fRMin1; A1=0.;
 
  952     A1=std::fabs(fRMin2*fRMin2-fRMin1*fRMin1);
 
  956     rRand2=fRMax1; Atot=A1;
 
  961     Atot   = A1+std::fabs(fRMax2*fRMax2-fRMax1*fRMax1);
 
  965   if(rCh>A1) { rRand1=rRand2; }
 
  967   xRand = rRand1*cosphi;
 
  968   yRand = rRand1*sinphi;
 
  987     if( (fRMin1 == fRMin2) && (fRMax1 == fRMax2) )
 
  991     return GetPointOnCone(fRMin1,fRMax1,fRMin2,fRMax2,zOne,zTwo,totArea);
 
 1000     G4double Area=0,totArea=0,Achose1=0,Achose2=0,phi,cosphi,sinphi,rRand;
 
 1005     cosphi = std::cos(phi);
 
 1006     sinphi = std::sin(phi);
 
 1012     std::vector<G4double> areas;       
 
 1013     std::vector<G4ThreeVector> points; 
 
 1018     for(i=0; i<numPlanes-1; i++)
 
 1043       areas.push_back(Area);
 
 1050     totArea += (areas[0]+areas[numPlanes]);
 
 1053     if( (chose>=0.) && (chose<areas[0]) )
 
 1059     for (i=0; i<numPlanes-1; i++)
 
 1061       Achose1 += areas[i];
 
 1062       Achose2 = (Achose1+areas[i+1]);
 
 1063       if(chose>=Achose1 && chose<Achose2)
 
 1103   G4bool isConvertible=
true;
 
 1109   std::vector<G4double> 
Z;
 
 1110   std::vector<G4double> Rmin;
 
 1111   std::vector<G4double> Rmax;
 
 1113   G4int countPlanes=1;
 
 1124     Rmax.push_back (
corners[1].r);icurr=1; 
 
 1126   else if (Zprev == 
corners[numPlanes-1].z)
 
 1128     Rmin.push_back(
corners[numPlanes-1].r);  
 
 1129     Rmax.push_back (
corners[0].r);
 
 1135     Rmax.push_back (
corners[0].r);
 
 1140   G4int inextr=0, inextl=0; 
 
 1141   for (
G4int i=0; i < numPlanes-2; i++)
 
 1144     inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
 
 1146     if((
corners[inextr].z >= Zmax) & (
corners[inextl].
z >= Zmax))  { 
break; }
 
 1161           Rmin.push_back(
corners[inextl].r);
 
 1162           Rmax.push_back(
corners[icurr].r);
 
 1166           Rmin.push_back(
corners[inextl].r);
 
 1175           Rmin.push_back(
corners[icurl].r);
 
 1176           Rmax.push_back(
corners[icurr].r);
 
 1180           Rmin.push_back(
corners[icurl].r);
 
 1187         isConvertible=
false; 
break;
 
 1189       icurl=(icurl == 0)? numPlanes-1 : icurl-1;
 
 1197       icurl=(icurl == 0)? numPlanes-1 : icurl-1;
 
 1199       Rmin.push_back(
corners[inextl].r);  
 
 1200       Rmax.push_back(
corners[inextr].r);
 
 1204       Z.push_back(Zright);  
 
 1213           Rmax.push_back(
corners[inextr].r);
 
 1214           Rmin.push_back(
corners[icurr].r); 
 
 1218           Rmin.push_back(
corners[icurl].r + (Zright-
corners[icurl].z)/difZl
 
 1220           Rmax.push_back(
corners[inextr].r);
 
 1228           Rmax.push_back(
corners[inextr].r);
 
 1229           Rmin.push_back (
corners[icurr].r); 
 
 1233           Rmax.push_back(
corners[inextr].r);
 
 1241         isConvertible=
false; 
break;
 
 1251   inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
 
 1253   Rmax.push_back(
corners[inextr].r);
 
 1254   Rmin.push_back(
corners[inextl].r);
 
 1265    for(
G4int j=0; j < countPlanes; j++)
 
 1279     std::ostringstream message;
 
 1281             << 
"cannot be converted to Polycone with (Rmin,Rmaz,Z) parameters!";
 
 1282     G4Exception(
"G4Polycone::SetOriginalParameters()", 
"GeomSolids0002",
 
 1290     for(
G4int j=0; j < numPlanes; j++)
 
 1300   return isConvertible;
 
void set(double x, double y, double z)
 
G4bool CrossesItself(G4double tolerance)
 
G4Polyhedron * CreatePolyhedron() const 
 
ThreeVector shoot(const G4int Ap, const G4int Af)
 
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
 
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
 
G4bool fRebuildPolyhedron
 
G4Polyhedron * fpPolyhedron
 
static const G4double kInfinity
 
CLHEP::Hep3Vector G4ThreeVector
 
G4ThreeVector GetPointOnSurface() const 
 
G4ThreeVector GetPointOnRing(G4double fRMin, G4double fRMax, G4double fRMin2, G4double fRMax2, G4double zOne) const 
 
G4int GetNumRZCorner() const 
 
G4double GetSinStartPhi() const 
 
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const 
 
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const 
 
G4bool MustBeOutside(const G4ThreeVector &p) const 
 
G4PolyconeSideRZ * corners
 
G4double GetEndPhi() const 
 
std::ostream & StreamInfo(std::ostream &os) const 
 
static constexpr double twopi
 
G4ThreeVector GetPointOnCone(G4double fRmin1, G4double fRmax1, G4double fRmin2, G4double fRmax2, G4double zOne, G4double zTwo, G4double &totArea) const 
 
G4GeometryType GetEntityType() const 
 
G4ThreeVector GetPointOnCut(G4double fRMin1, G4double fRMax1, G4double fRMin2, G4double fRMax2, G4double zOne, G4double zTwo, G4double &totArea) const 
 
G4bool RemoveDuplicateVertices(G4double tolerance)
 
G4bool RemoveRedundantVertices(G4double tolerance)
 
G4Polycone & operator=(const G4Polycone &source)
 
G4GLOB_DLL std::ostream G4cout
 
G4int NumVertices() const 
 
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const 
 
static constexpr double degree
 
void SetOriginalParameters(G4PolyconeHistorical *pars)
 
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 
 
EInside Inside(const G4ThreeVector &p) const 
 
G4double GetCosStartPhi() const 
 
G4double GetStartPhi() const 
 
std::vector< G4ThreeVector > G4ThreeVectorList
 
G4double GetCosEndPhi() const 
 
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
 
static const G4double emax
 
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const 
 
void CopyStuff(const G4Polycone &source)
 
G4EnclosingCylinder * enclosingCylinder
 
G4double GetSinEndPhi() const 
 
G4ThreeVector GetPointOnTubs(G4double fRMin, G4double fRMax, G4double zOne, G4double zTwo, G4double &totArea) const 
 
G4bool BisectedBy(G4double a1, G4double b1, G4double a2, G4double b2, G4double tolerance)
 
CLHEP::Hep2Vector G4TwoVector
 
static constexpr double pi
 
G4Polycone(const G4String &name, G4double phiStart, G4double phiTotal, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
 
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
 
static constexpr double deg
 
G4double GetMaxExtent(const EAxis pAxis) const 
 
G4PolyconeHistorical * original_parameters
 
virtual EInside Inside(const G4ThreeVector &p) const 
 
G4PolyconeSideRZ GetCorner(G4int index) const 
 
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const 
 
G4double GetMinExtent(const EAxis pAxis) const