33#if !defined(G4GEOM_USE_UPOLYCONE)
79 for (
G4int i=0; i<numZPlanes; ++i)
81 if(rInner[i]>rOuter[i])
84 std::ostringstream message;
85 message <<
"Cannot create a Polycone with rInner > rOuter for the same Z"
87 <<
" rInner > rOuter for the same Z !" <<
G4endl
88 <<
" rMin[" << i <<
"] = " << rInner[i]
89 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
90 G4Exception(
"G4Polycone::G4Polycone()",
"GeomSolids0002",
93 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
95 if( (rInner[i] > rOuter[i+1])
96 ||(rInner[i+1] > rOuter[i]) )
99 std::ostringstream message;
100 message <<
"Cannot create a Polycone with no contiguous segments."
102 <<
" Segments are not contiguous !" <<
G4endl
103 <<
" rMin[" << i <<
"] = " << rInner[i]
104 <<
" -- rMax[" << i+1 <<
"] = " << rOuter[i+1] <<
G4endl
105 <<
" rMin[" << i+1 <<
"] = " << rInner[i+1]
106 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
107 G4Exception(
"G4Polycone::G4Polycone()",
"GeomSolids0002",
124 Create( phiStart, phiTotal, rz );
142 Create( phiStart, phiTotal, rz );
151 std::ostringstream message;
152 message <<
"Polycone " <<
GetName() <<
"cannot be converted" <<
G4endl
153 <<
"to Polycone with (Rmin,Rmaz,Z) parameters!";
154 G4Exception(
"G4Polycone::G4Polycone()",
"GeomSolids0002",
160 <<
"to optimized polycone with (Rmin,Rmaz,Z) parameters !"
178 if (rz->
Amin() < 0.0)
180 std::ostringstream message;
181 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
182 <<
" All R values must be >= 0 !";
183 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
194 std::ostringstream message;
195 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
196 <<
" R/Z cross section is zero or near zero: " << rzArea;
197 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
204 std::ostringstream message;
205 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
206 <<
" Too few unique R/Z values !";
207 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
213 std::ostringstream message;
214 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
215 <<
" R/Z segments cross !";
216 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
229 if ( (phiTotal <= 0) || (phiTotal > twopi*(1-
DBL_EPSILON)) )
255 next->
r = iterRZ.
GetA();
256 next->
z = iterRZ.
GetB();
257 }
while( ++next, iterRZ.
Next() );
281 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
289 if (corner->
z > next->
z)
306 }
while( prev=corner, corner=next, corner >
corners );
367 if (
this == &source)
return *
this;
512 G4double rmin = kInfinity, rmax = -kInfinity;
513 G4double zmin = kInfinity, zmax = -kInfinity;
518 if (corner.
r < rmin) rmin = corner.
r;
519 if (corner.
r > rmax) rmax = corner.
r;
520 if (corner.
z < zmin) zmin = corner.
z;
521 if (corner.
z > zmax) zmax = corner.
z;
531 pMin.
set(vmin.
x(),vmin.
y(),zmin);
532 pMax.
set(vmax.
x(),vmax.
y(),zmax);
536 pMin.
set(-rmax,-rmax, zmin);
537 pMax.
set( rmax, rmax, zmax);
542 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
544 std::ostringstream message;
545 message <<
"Bad bounding box (min >= max) for solid: "
547 <<
"\npMin = " << pMin
548 <<
"\npMax = " << pMax;
549 G4Exception(
"G4Polycone::BoundingLimits()",
"GeomMgt0001",
574 return exist = pMin < pMax;
583 std::vector<G4int> iout;
591 contourRZ.emplace_back(corner.
r,corner.
z);
595 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
600 std::ostringstream message;
601 message <<
"Triangulation of RZ contour has failed for solid: "
603 <<
"\nExtent has been calculated using boundary box";
610 const G4int NSTEPS = 24;
616 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-deg)/astep) + 1;
619 G4double sinHalf = std::sin(0.5*ang);
620 G4double cosHalf = std::cos(0.5*ang);
621 G4double sinStep = 2.*sinHalf*cosHalf;
622 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
630 std::vector<const G4ThreeVectorList *> polygons;
631 polygons.resize(ksteps+2);
633 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
634 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
642 for (
G4int i=0; i<ntria; ++i)
645 for (
G4int k=0; k<3; ++k)
647 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
650 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
651 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
655 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
661 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
662 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
663 for (
G4int j=0; j<6; ++j) pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
664 for (
G4int k=1; k<ksteps+1; ++k)
666 for (
G4int j=0; j<6; ++j) pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
668 sinCur = sinCur*cosStep + cosCur*sinStep;
669 cosCur = cosCur*cosStep - sinTmp*sinStep;
671 for (
G4int j=0; j<6; ++j) pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
676 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
677 if (emin < pMin) pMin = emin;
678 if (emax > pMax) pMax = emax;
679 if (eminlim > pMin && emaxlim < pMax)
return true;
681 return (pMin < pMax);
697 return {
"G4Polycone"};
712 G4long oldprc = os.precision(16);
713 os <<
"-----------------------------------------------------------\n"
714 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
715 <<
" ===================================================\n"
716 <<
" Solid type: G4Polycone\n"
718 <<
" starting phi angle : " <<
startPhi/degree <<
" degrees \n"
719 <<
" ending phi angle : " <<
endPhi/degree <<
" degrees \n";
723 os <<
" number of Z planes: " << numPlanes <<
"\n"
725 for (i=0; i<numPlanes; ++i)
727 os <<
" Z plane " << i <<
": "
730 os <<
" Tangent distances to inner surface (Rmin): \n";
731 for (i=0; i<numPlanes; ++i)
733 os <<
" Z plane " << i <<
": "
736 os <<
" Tangent distances to outer surface (Rmax): \n";
737 for (i=0; i<numPlanes; ++i)
739 os <<
" Z plane " << i <<
": "
743 os <<
" number of RZ points: " <<
numCorner <<
"\n"
744 <<
" RZ values (corners): \n";
750 os <<
"-----------------------------------------------------------\n";
751 os.precision(oldprc);
767 for (
G4int i=0; i<nrz; ++i)
770 total += (b.
r*b.
r + b.
r*a.
r + a.
r*a.
r)*(b.
z - a.
z);
792 for (
G4int i=0; i<nrz; ++i)
795 scut += a.
r*b.
z - a.
z*b.
r;
798 scut = std::abs(scut);
803 for (
G4int i=0; i<nrz; ++i)
807 slat += (b.
r + a.
r)*h;
823 fElements =
new std::vector<G4Polycone::surface_element>;
830 for (
G4int ib=0; ib<nrz; ++ib)
839 if (a.
r == 0. && b.
r == 0.)
continue;
841 total += 0.5*dphi*(b.
r + a.
r)*h;
850 std::vector<G4int> triangles;
851 for (
G4int i=0; i<nrz; ++i)
854 contourRZ.emplace_back(corner.
r, corner.
z);
857 auto ntria = (
G4int)triangles.size();
858 for (
G4int i=0; i<ntria; i+=3)
861 selem.
i0 = triangles[i];
862 selem.
i1 = triangles[i+1];
863 selem.
i2 = triangles[i+2];
900 ->
G4bool { return x.area < val; });
920 r = (p1.
r - p0.
r)*u + p0.
r;
921 z = (p1.
z - p0.
z)*u + p0.
z;
925 r = std::sqrt(p1.
r*p1.
r*u + p0.
r*p0.
r*(1. - u));
926 z = p0.
z + (p1.
z - p0.
z)*(r - p0.
r)/(p1.
r - p0.
r);
934 if (i0 >= nrz) { i0 -= nrz; }
938 if (u + v > 1.) { u = 1. - u; v = 1. - v; }
939 r = (p1.
r - p0.
r)*u + (p2.
r - p0.
r)*v + p0.
r;
940 z = (p1.
z - p0.
z)*u + (p2.
z - p0.
z)*v + p0.
z;
942 return { r*std::cos(phi), r*std::sin(phi), z };
962 G4bool isConvertible =
true;
968 std::vector<G4double> Z;
969 std::vector<G4double> Rmin;
970 std::vector<G4double> Rmax;
983 Rmax.push_back (
corners[1].r);icurr=1;
985 else if (Zprev ==
corners[numPlanes-1].z)
987 Rmin.push_back(
corners[numPlanes-1].r);
999 G4int inextr=0, inextl=0;
1000 for (
G4int i=0; i < numPlanes-2; ++i)
1003 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1005 if((
corners[inextr].z >= Zmax) & (
corners[inextl].z >= Zmax)) {
break; }
1020 Rmin.push_back(
corners[inextl].r);
1021 Rmax.push_back(
corners[icurr].r);
1025 Rmin.push_back(
corners[inextl].r);
1034 Rmin.push_back(
corners[icurl].r);
1035 Rmax.push_back(
corners[icurr].r);
1039 Rmin.push_back(
corners[icurl].r);
1046 isConvertible=
false;
break;
1048 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1056 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1058 Rmin.push_back(
corners[inextl].r);
1059 Rmax.push_back(
corners[inextr].r);
1063 Z.push_back(Zright);
1072 Rmax.push_back(
corners[inextr].r);
1073 Rmin.push_back(
corners[icurr].r);
1077 Rmin.push_back(
corners[icurl].r + (Zright-
corners[icurl].z)/difZl
1079 Rmax.push_back(
corners[inextr].r);
1087 Rmax.push_back(
corners[inextr].r);
1088 Rmin.push_back (
corners[icurr].r);
1092 Rmax.push_back(
corners[inextr].r);
1100 isConvertible=
false;
break;
1110 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1112 Rmax.push_back(
corners[inextr].r);
1113 Rmin.push_back(
corners[inextl].r);
1124 for(
G4int j=0; j < countPlanes; ++j)
1138 std::ostringstream message;
1140 <<
"cannot be converted to Polycone with (Rmin,Rmaz,Z) parameters!";
1141 G4Exception(
"G4Polycone::SetOriginalParameters()",
"GeomSolids0002",
1149 for(
G4int j=0; j < numPlanes; ++j)
1159 return isConvertible;
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool MustBeOutside(const G4ThreeVector &p) const
G4EnclosingCylinder * enclosingCylinder
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
G4double GetCosEndPhi() const
G4Polyhedron * CreatePolyhedron() const override
G4GeometryType GetEntityType() const override
G4Polycone(const G4String &name, G4double phiStart, G4double phiTotal, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
G4double GetSurfaceArea() override
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep) override
G4double GetEndPhi() const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const override
G4double GetSinEndPhi() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
EInside Inside(const G4ThreeVector &p) const override
void SetSurfaceElements() const
G4double GetCosStartPhi() const
void SetOriginalParameters(G4PolyconeHistorical *pars)
G4double GetCubicVolume() override
void CopyStuff(const G4Polycone &source)
G4double GetStartPhi() const
G4Polycone & operator=(const G4Polycone &source)
G4VSolid * Clone() const override
G4PolyconeSideRZ * corners
std::ostream & StreamInfo(std::ostream &os) const override
G4ThreeVector GetPointOnSurface() const override
G4double GetSinStartPhi() const
G4PolyconeHistorical * original_parameters
G4int GetNumRZCorner() const
std::vector< surface_element > * fElements
G4PolyconeSideRZ GetCorner(G4int index) const
G4bool BisectedBy(G4double a1, G4double b1, G4double a2, G4double b2, G4double tolerance)
G4bool RemoveDuplicateVertices(G4double tolerance)
G4int NumVertices() const
G4bool RemoveRedundantVertices(G4double tolerance)
G4bool CrossesItself(G4double tolerance)
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
EInside Inside(const G4ThreeVector &p) const override
G4Polyhedron * fpPolyhedron
G4bool fRebuildPolyhedron
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const