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",
230 if ( (phiTotal <= 0) || (phiTotal > twopi*(1-
DBL_EPSILON)) )
256 next->
r = iterRZ.
GetA();
257 next->
z = iterRZ.
GetB();
258 }
while( ++next, iterRZ.
Next() );
282 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
290 if (corner->
z > next->
z)
307 }
while( prev=corner, corner=next, corner >
corners );
368 if (
this == &source)
return *
this;
514 G4double rmin = kInfinity, rmax = -kInfinity;
515 G4double zmin = kInfinity, zmax = -kInfinity;
520 if (corner.
r < rmin) rmin = corner.
r;
521 if (corner.
r > rmax) rmax = corner.
r;
522 if (corner.
z < zmin) zmin = corner.
z;
523 if (corner.
z > zmax) zmax = corner.
z;
533 pMin.
set(vmin.
x(),vmin.
y(),zmin);
534 pMax.
set(vmax.
x(),vmax.
y(),zmax);
538 pMin.
set(-rmax,-rmax, zmin);
539 pMax.
set( rmax, rmax, zmax);
544 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
546 std::ostringstream message;
547 message <<
"Bad bounding box (min >= max) for solid: "
549 <<
"\npMin = " << pMin
550 <<
"\npMax = " << pMax;
551 G4Exception(
"G4Polycone::BoundingLimits()",
"GeomMgt0001",
576 return exist = (pMin < pMax) ?
true :
false;
585 std::vector<G4int> iout;
597 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
602 std::ostringstream message;
603 message <<
"Triangulation of RZ contour has failed for solid: "
605 <<
"\nExtent has been calculated using boundary box";
612 const G4int NSTEPS = 24;
618 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-deg)/astep) + 1;
621 G4double sinHalf = std::sin(0.5*ang);
622 G4double cosHalf = std::cos(0.5*ang);
623 G4double sinStep = 2.*sinHalf*cosHalf;
624 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
632 std::vector<const G4ThreeVectorList *> polygons;
633 polygons.resize(ksteps+2);
635 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
636 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
644 for (
G4int i=0; i<ntria; ++i)
647 for (
G4int k=0; k<3; ++k)
649 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
652 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
653 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
657 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
663 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
664 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
665 for (
G4int j=0; j<6; ++j) pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
666 for (
G4int k=1; k<ksteps+1; ++k)
668 for (
G4int j=0; j<6; ++j) pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
670 sinCur = sinCur*cosStep + cosCur*sinStep;
671 cosCur = cosCur*cosStep - sinTmp*sinStep;
673 for (
G4int j=0; j<6; ++j) pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
678 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
679 if (emin < pMin) pMin = emin;
680 if (emax > pMax) pMax = emax;
681 if (eminlim > pMin && emaxlim < pMax)
return true;
683 return (pMin < pMax);
714 G4long oldprc = os.precision(16);
715 os <<
"-----------------------------------------------------------\n"
716 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
717 <<
" ===================================================\n"
718 <<
" Solid type: G4Polycone\n"
720 <<
" starting phi angle : " <<
startPhi/degree <<
" degrees \n"
721 <<
" ending phi angle : " <<
endPhi/degree <<
" degrees \n";
725 os <<
" number of Z planes: " << numPlanes <<
"\n"
727 for (i=0; i<numPlanes; ++i)
729 os <<
" Z plane " << i <<
": "
732 os <<
" Tangent distances to inner surface (Rmin): \n";
733 for (i=0; i<numPlanes; ++i)
735 os <<
" Z plane " << i <<
": "
738 os <<
" Tangent distances to outer surface (Rmax): \n";
739 for (i=0; i<numPlanes; ++i)
741 os <<
" Z plane " << i <<
": "
745 os <<
" number of RZ points: " <<
numCorner <<
"\n"
746 <<
" RZ values (corners): \n";
752 os <<
"-----------------------------------------------------------\n";
753 os.precision(oldprc);
769 for (
G4int i=0; i<nrz; ++i)
772 total += (b.
r*b.
r + b.
r*a.
r + a.
r*a.
r)*(b.
z - a.
z);
794 for (
G4int i=0; i<nrz; ++i)
797 scut += a.
r*b.
z - a.
z*b.
r;
800 scut = std::abs(scut);
805 for (
G4int i=0; i<nrz; ++i)
809 slat += (b.
r + a.
r)*h;
825 fElements =
new std::vector<G4Polycone::surface_element>;
832 for (
G4int ib=0; ib<nrz; ++ib)
841 if (a.
r == 0. && b.
r == 0.)
continue;
843 total += 0.5*dphi*(b.
r + a.
r)*h;
852 std::vector<G4int> triangles;
853 for (
G4int i=0; i<nrz; ++i)
860 for (
G4int i=0; i<ntria; i+=3)
863 selem.
i0 = triangles[i];
864 selem.
i1 = triangles[i+1];
865 selem.
i2 = triangles[i+2];
902 ->
G4bool { return x.area < val; });
922 r = (p1.
r - p0.
r)*u + p0.
r;
923 z = (p1.
z - p0.
z)*u + p0.
z;
927 r = std::sqrt(p1.
r*p1.
r*u + p0.
r*p0.
r*(1. - u));
928 z = p0.
z + (p1.
z - p0.
z)*(r - p0.
r)/(p1.
r - p0.
r);
936 if (i0 >= nrz) { i0 -= nrz; }
940 if (u + v > 1.) { u = 1. - u; v = 1. - v; }
941 r = (p1.
r - p0.
r)*u + (p2.
r - p0.
r)*v + p0.
r;
942 z = (p1.
z - p0.
z)*u + (p2.
z - p0.
z)*v + p0.
z;
964 G4bool isConvertible =
true;
970 std::vector<G4double>
Z;
971 std::vector<G4double> Rmin;
972 std::vector<G4double> Rmax;
985 Rmax.push_back (
corners[1].r);icurr=1;
987 else if (Zprev ==
corners[numPlanes-1].z)
989 Rmin.push_back(
corners[numPlanes-1].r);
1001 G4int inextr=0, inextl=0;
1002 for (
G4int i=0; i < numPlanes-2; ++i)
1005 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1007 if((
corners[inextr].z >= Zmax) & (
corners[inextl].
z >= Zmax)) {
break; }
1022 Rmin.push_back(
corners[inextl].r);
1023 Rmax.push_back(
corners[icurr].r);
1027 Rmin.push_back(
corners[inextl].r);
1036 Rmin.push_back(
corners[icurl].r);
1037 Rmax.push_back(
corners[icurr].r);
1041 Rmin.push_back(
corners[icurl].r);
1048 isConvertible=
false;
break;
1050 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1058 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1060 Rmin.push_back(
corners[inextl].r);
1061 Rmax.push_back(
corners[inextr].r);
1065 Z.push_back(Zright);
1074 Rmax.push_back(
corners[inextr].r);
1075 Rmin.push_back(
corners[icurr].r);
1079 Rmin.push_back(
corners[icurl].r + (Zright-
corners[icurl].z)/difZl
1081 Rmax.push_back(
corners[inextr].r);
1089 Rmax.push_back(
corners[inextr].r);
1090 Rmin.push_back (
corners[icurr].r);
1094 Rmax.push_back(
corners[inextr].r);
1102 isConvertible=
false;
break;
1112 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1114 Rmax.push_back(
corners[inextr].r);
1115 Rmin.push_back(
corners[inextl].r);
1126 for(
G4int j=0; j < countPlanes; ++j)
1140 std::ostringstream message;
1142 <<
"cannot be converted to Polycone with (Rmin,Rmaz,Z) parameters!";
1143 G4Exception(
"G4Polycone::SetOriginalParameters()",
"GeomSolids0002",
1151 for(
G4int j=0; j < numPlanes; ++j)
1161 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