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",
125 Create( phiStart, phiTotal, rz );
143 Create( phiStart, phiTotal, rz );
152 std::ostringstream message;
153 message <<
"Polycone " <<
GetName() <<
"cannot be converted" <<
G4endl
154 <<
"to Polycone with (Rmin,Rmaz,Z) parameters!";
155 G4Exception(
"G4Polycone::G4Polycone()",
"GeomSolids0002",
161 <<
"to optimized polycone with (Rmin,Rmaz,Z) parameters !"
179 if (rz->
Amin() < 0.0)
181 std::ostringstream message;
182 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
183 <<
" All R values must be >= 0 !";
184 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
195 std::ostringstream message;
196 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
197 <<
" R/Z cross section is zero or near zero: " << rzArea;
198 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
205 std::ostringstream message;
206 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
207 <<
" Too few unique R/Z values !";
208 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
214 std::ostringstream message;
215 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
216 <<
" R/Z segments cross !";
217 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
227 if (phiTotal <= 0 || phiTotal > twopi-1E-10)
244 endPhi = phiStart+phiTotal;
263 next->
r = iterRZ.
GetA();
264 next->
z = iterRZ.
GetB();
265 }
while( ++next, iterRZ.
Next() );
289 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
297 if (corner->
z > next->
z)
314 }
while( prev=corner, corner=next, corner >
corners );
375 if (
this == &source)
return *
this;
521 G4double rmin = kInfinity, rmax = -kInfinity;
522 G4double zmin = kInfinity, zmax = -kInfinity;
527 if (corner.
r < rmin) rmin = corner.
r;
528 if (corner.
r > rmax) rmax = corner.
r;
529 if (corner.
z < zmin) zmin = corner.
z;
530 if (corner.
z > zmax) zmax = corner.
z;
540 pMin.
set(vmin.
x(),vmin.
y(),zmin);
541 pMax.
set(vmax.
x(),vmax.
y(),zmax);
545 pMin.
set(-rmax,-rmax, zmin);
546 pMax.
set( rmax, rmax, zmax);
551 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
553 std::ostringstream message;
554 message <<
"Bad bounding box (min >= max) for solid: "
556 <<
"\npMin = " << pMin
557 <<
"\npMax = " << pMax;
558 G4Exception(
"G4Polycone::BoundingLimits()",
"GeomMgt0001",
583 return exist = (pMin < pMax) ?
true :
false;
592 std::vector<G4int> iout;
604 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
609 std::ostringstream message;
610 message <<
"Triangulation of RZ contour has failed for solid: "
612 <<
"\nExtent has been calculated using boundary box";
619 const G4int NSTEPS = 24;
625 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-deg)/astep) + 1;
628 G4double sinHalf = std::sin(0.5*ang);
629 G4double cosHalf = std::cos(0.5*ang);
630 G4double sinStep = 2.*sinHalf*cosHalf;
631 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
639 std::vector<const G4ThreeVectorList *> polygons;
640 polygons.resize(ksteps+2);
642 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
643 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
650 G4int ntria = triangles.size()/3;
651 for (
G4int i=0; i<ntria; ++i)
654 for (
G4int k=0; k<3; ++k)
656 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
659 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
660 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
664 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
670 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
671 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
672 for (
G4int j=0; j<6; ++j) pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
673 for (
G4int k=1; k<ksteps+1; ++k)
675 for (
G4int j=0; j<6; ++j) pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
677 sinCur = sinCur*cosStep + cosCur*sinStep;
678 cosCur = cosCur*cosStep - sinTmp*sinStep;
680 for (
G4int j=0; j<6; ++j) pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
685 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
686 if (emin < pMin) pMin = emin;
687 if (emax > pMax) pMax = emax;
688 if (eminlim > pMin && emaxlim < pMax)
return true;
690 return (pMin < pMax);
721 G4int oldprc = os.precision(16);
722 os <<
"-----------------------------------------------------------\n"
723 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
724 <<
" ===================================================\n"
725 <<
" Solid type: G4Polycone\n"
727 <<
" starting phi angle : " <<
startPhi/degree <<
" degrees \n"
728 <<
" ending phi angle : " <<
endPhi/degree <<
" degrees \n";
732 os <<
" number of Z planes: " << numPlanes <<
"\n"
734 for (i=0; i<numPlanes; ++i)
736 os <<
" Z plane " << i <<
": "
739 os <<
" Tangent distances to inner surface (Rmin): \n";
740 for (i=0; i<numPlanes; ++i)
742 os <<
" Z plane " << i <<
": "
745 os <<
" Tangent distances to outer surface (Rmax): \n";
746 for (i=0; i<numPlanes; ++i)
748 os <<
" Z plane " << i <<
": "
752 os <<
" number of RZ points: " <<
numCorner <<
"\n"
753 <<
" RZ values (corners): \n";
759 os <<
"-----------------------------------------------------------\n";
760 os.precision(oldprc);
776 for (
G4int i=0; i<nrz; ++i)
779 total += (b.
r*b.
r + b.
r*a.
r + a.
r*a.
r)*(b.
z - a.
z);
801 for (
G4int i=0; i<nrz; ++i)
804 scut += a.
r*b.
z - a.
z*b.
r;
807 scut = std::abs(scut);
812 for (
G4int i=0; i<nrz; ++i)
816 slat += (b.
r + a.
r)*h;
832 fElements =
new std::vector<G4Polycone::surface_element>;
839 for (
G4int ib=0; ib<nrz; ++ib)
848 if (a.
r == 0. && b.
r == 0.)
continue;
850 total += 0.5*dphi*(b.
r + a.
r)*h;
859 std::vector<G4int> triangles;
860 for (
G4int i=0; i<nrz; ++i)
866 G4int ntria = triangles.size();
867 for (
G4int i=0; i<ntria; i+=3)
870 selem.
i0 = triangles[i];
871 selem.
i1 = triangles[i+1];
872 selem.
i2 = triangles[i+2];
909 ->
G4bool { return x.area < val; });
929 r = (p1.
r - p0.
r)*u + p0.
r;
930 z = (p1.
z - p0.
z)*u + p0.
z;
934 r = std::sqrt(p1.
r*p1.
r*u + p0.
r*p0.
r*(1. - u));
935 z = p0.
z + (p1.
z - p0.
z)*(r - p0.
r)/(p1.
r - p0.
r);
943 if (i0 >= nrz) { i0 -= nrz; }
947 if (u + v > 1.) { u = 1. - u; v = 1. - v; }
948 r = (p1.
r - p0.
r)*u + (p2.
r - p0.
r)*v + p0.
r;
949 z = (p1.
z - p0.
z)*u + (p2.
z - p0.
z)*v + p0.
z;
977 G4bool isConvertible =
true;
983 std::vector<G4double> Z;
984 std::vector<G4double> Rmin;
985 std::vector<G4double> Rmax;
998 Rmax.push_back (
corners[1].r);icurr=1;
1000 else if (Zprev ==
corners[numPlanes-1].z)
1002 Rmin.push_back(
corners[numPlanes-1].r);
1003 Rmax.push_back (
corners[0].r);
1009 Rmax.push_back (
corners[0].r);
1014 G4int inextr=0, inextl=0;
1015 for (
G4int i=0; i < numPlanes-2; ++i)
1018 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1020 if((
corners[inextr].z >= Zmax) & (
corners[inextl].
z >= Zmax)) {
break; }
1035 Rmin.push_back(
corners[inextl].r);
1036 Rmax.push_back(
corners[icurr].r);
1040 Rmin.push_back(
corners[inextl].r);
1049 Rmin.push_back(
corners[icurl].r);
1050 Rmax.push_back(
corners[icurr].r);
1054 Rmin.push_back(
corners[icurl].r);
1061 isConvertible=
false;
break;
1063 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1071 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1073 Rmin.push_back(
corners[inextl].r);
1074 Rmax.push_back(
corners[inextr].r);
1078 Z.push_back(Zright);
1087 Rmax.push_back(
corners[inextr].r);
1088 Rmin.push_back(
corners[icurr].r);
1092 Rmin.push_back(
corners[icurl].r + (Zright-
corners[icurl].z)/difZl
1094 Rmax.push_back(
corners[inextr].r);
1102 Rmax.push_back(
corners[inextr].r);
1103 Rmin.push_back (
corners[icurr].r);
1107 Rmax.push_back(
corners[inextr].r);
1115 isConvertible=
false;
break;
1125 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1127 Rmax.push_back(
corners[inextr].r);
1128 Rmin.push_back(
corners[inextl].r);
1139 for(
G4int j=0; j < countPlanes; ++j)
1153 std::ostringstream message;
1155 <<
"cannot be converted to Polycone with (Rmin,Rmaz,Z) parameters!";
1156 G4Exception(
"G4Polycone::SetOriginalParameters()",
"GeomSolids0002",
1164 for(
G4int j=0; j < numPlanes; ++j)
1174 return isConvertible;
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
CLHEP::Hep2Vector G4TwoVector
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
G4double GetCosEndPhi() const
G4ThreeVector GetPointOnSurface() const
G4GeometryType GetEntityType() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4Polycone(const G4String &name, G4double phiStart, G4double phiTotal, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
G4double GetEndPhi() const
G4Polyhedron * CreatePolyhedron() const
G4double GetSinEndPhi() const
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
EInside Inside(const G4ThreeVector &p) const
void SetSurfaceElements() const
G4double GetCosStartPhi() const
void SetOriginalParameters(G4PolyconeHistorical *pars)
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
void CopyStuff(const G4Polycone &source)
G4double GetStartPhi() const
G4Polycone & operator=(const G4Polycone &source)
G4double GetSurfaceArea()
G4PolyconeSideRZ * corners
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4double GetSinStartPhi() const
G4PolyconeHistorical * original_parameters
std::ostream & StreamInfo(std::ostream &os) const
G4int GetNumRZCorner() const
std::vector< surface_element > * fElements
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4PolyconeSideRZ GetCorner(G4int index) const
G4double GetCubicVolume()
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)
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
virtual EInside Inside(const G4ThreeVector &p) const
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