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