33 #if !defined(G4GEOM_USE_UPOLYCONE)
49 using namespace CLHEP;
74 for (
G4int i=0; i<numZPlanes; ++i)
76 if(rInner[i]>rOuter[i])
80 message <<
"Cannot create a Polycone with rInner > rOuter for the same Z"
82 <<
" rInner > rOuter for the same Z !" <<
G4endl
83 <<
" rMin[" << i <<
"] = " << rInner[i]
84 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
85 G4Exception(
"G4Polycone::G4Polycone()",
"GeomSolids0002",
88 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
90 if( (rInner[i] > rOuter[i+1])
91 ||(rInner[i+1] > rOuter[i]) )
95 message <<
"Cannot create a Polycone with no contiguous segments."
97 <<
" Segments are not contiguous !" <<
G4endl
98 <<
" rMin[" << i <<
"] = " << rInner[i]
99 <<
" -- rMax[" << i+1 <<
"] = " << rOuter[i+1] <<
G4endl
100 <<
" rMin[" << i+1 <<
"] = " << rInner[i+1]
101 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
102 G4Exception(
"G4Polycone::G4Polycone()",
"GeomSolids0002",
120 Create( phiStart, phiTotal, rz );
138 Create( phiStart, phiTotal, rz );
148 message <<
"Polycone " <<
GetName() <<
"cannot be converted" <<
G4endl
149 <<
"to Polycone with (Rmin,Rmaz,Z) parameters!";
150 G4Exception(
"G4Polycone::G4Polycone()",
"GeomSolids0002",
156 <<
"to optimized polycone with (Rmin,Rmaz,Z) parameters !"
174 if (rz->
Amin() < 0.0)
177 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
178 <<
" All R values must be >= 0 !";
179 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
191 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
192 <<
" R/Z cross section is zero or near zero: " << rzArea;
193 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
201 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
202 <<
" Too few unique R/Z values !";
203 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
210 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
211 <<
" R/Z segments cross !";
212 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
222 if (phiTotal <= 0 || phiTotal >
twopi-1
E-10)
239 endPhi = phiStart+phiTotal;
258 next->
r = iterRZ.
GetA();
259 next->
z = iterRZ.
GetB();
260 }
while( ++next, iterRZ.
Next() );
292 if (corner->
z > next->
z)
309 }
while( prev=corner, corner=next, corner >
corners );
363 if (
this == &source)
return *
this;
501 if (corner.
r < rmin) rmin = corner.
r;
502 if (corner.
r > rmax) rmax = corner.
r;
503 if (corner.
z < zmin) zmin = corner.
z;
504 if (corner.
z > zmax) zmax = corner.
z;
514 pMin.
set(vmin.
x(),vmin.
y(),zmin);
515 pMax.
set(vmax.
x(),vmax.
y(),zmax);
519 pMin.
set(-rmax,-rmax, zmin);
520 pMax.
set( rmax, rmax, zmax);
525 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
528 message <<
"Bad bounding box (min >= max) for solid: "
530 <<
"\npMin = " << pMin
531 <<
"\npMax = " <<
pMax;
532 G4Exception(
"G4Polycone::BoundingLimits()",
"GeomMgt0001",
557 return exist = (pMin <
pMax) ?
true :
false;
566 std::vector<G4int> iout;
578 if (area < 0.)
std::reverse(contourRZ.begin(),contourRZ.end());
584 message <<
"Triangulation of RZ contour has failed for solid: "
586 <<
"\nExtent has been calculated using boundary box";
593 const G4int NSTEPS = 24;
599 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-
deg)/astep) + 1;
602 G4double sinHalf = std::sin(0.5*ang);
603 G4double cosHalf = std::cos(0.5*ang);
604 G4double sinStep = 2.*sinHalf*cosHalf;
605 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
613 std::vector<const G4ThreeVectorList *> polygons;
614 polygons.resize(ksteps+2);
616 for (
G4int k=0;
k<ksteps+2; ++
k) pols[
k].resize(6);
617 for (
G4int k=0;
k<ksteps+2; ++
k) polygons[
k] = &pols[
k];
624 G4int ntria = triangles.size()/3;
625 for (
G4int i=0; i<ntria; ++i)
630 G4int e0 = i3+
k,
e1 = (k<2) ? e0+1 : i3;
633 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
634 r0[k2+1] = triangles[
e1].x(); z0[k2+1] = triangles[
e1].y();
638 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
644 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
645 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
646 for (
G4int j=0; j<6; ++j) pols[0][j].
set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
649 for (
G4int j=0; j<6; ++j) pols[
k][j].
set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
651 sinCur = sinCur*cosStep + cosCur*sinStep;
652 cosCur = cosCur*cosStep - sinTmp*sinStep;
654 for (
G4int j=0; j<6; ++j) pols[ksteps+1][j].
set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
659 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
660 if (emin < pMin) pMin =
emin;
661 if (emax > pMax) pMax =
emax;
662 if (eminlim > pMin && emaxlim < pMax)
return true;
664 return (pMin < pMax);
695 G4int oldprc = os.precision(16);
696 os <<
"-----------------------------------------------------------\n"
697 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
698 <<
" ===================================================\n"
699 <<
" Solid type: G4Polycone\n"
702 <<
" ending phi angle : " <<
endPhi/
degree <<
" degrees \n";
706 os <<
" number of Z planes: " << numPlanes <<
"\n"
708 for (i=0; i<numPlanes; ++i)
710 os <<
" Z plane " << i <<
": "
713 os <<
" Tangent distances to inner surface (Rmin): \n";
714 for (i=0; i<numPlanes; ++i)
716 os <<
" Z plane " << i <<
": "
719 os <<
" Tangent distances to outer surface (Rmax): \n";
720 for (i=0; i<numPlanes; ++i)
722 os <<
" Z plane " << i <<
": "
726 os <<
" number of RZ points: " <<
numCorner <<
"\n"
727 <<
" RZ values (corners): \n";
733 os <<
"-----------------------------------------------------------\n";
734 os.precision(oldprc);
750 G4double Aone, Atwo, Afive,
phi, zRand, fDPhi, cosu, sinu;
751 G4double rRand1, rmin,
rmax, chose, rone, rtwo, qone, qtwo;
752 G4double fDz=(zTwo-zOne)/2., afDz=std::fabs(fDz);
755 rone = (fRmax1-fRmax2)/(2.*fDz);
756 rtwo = (fRmin1-fRmin2)/(2.*fDz);
757 if(fRmax1==fRmax2){qone=0.;}
760 qone = fDz*(fRmax1+fRmax2)/(fRmax1-fRmax2);
762 if(fRmin1==fRmin2){qtwo=0.;}
765 qtwo = fDz*(fRmin1+fRmin2)/(fRmin1-fRmin2);
767 Aone = 0.5*fDPhi*(fRmax2 + fRmax1)*(
sqr(fRmin1-fRmin2)+
sqr(zTwo-zOne));
768 Atwo = 0.5*fDPhi*(fRmin2 + fRmin1)*(
sqr(fRmax1-fRmax2)+
sqr(zTwo-zOne));
769 Afive = fDz*(fRmax1-fRmin1+fRmax2-fRmin2);
770 totArea = Aone+Atwo+2.*Afive;
773 cosu = std::cos(phi);
774 sinu = std::sin(phi);
777 if( (startPhi == 0.) && (
endPhi ==
twopi) ) { Afive = 0.; }
779 if( (chose >= 0.) && (chose < Aone) )
785 rone*sinu*(qone-zRand), zRand);
794 else if(chose >= Aone && chose < Aone + Atwo)
800 rtwo*sinu*(qtwo-zRand), zRand);
809 else if( (chose >= Aone + Atwo + Afive) && (chose < Aone + Atwo + 2.*Afive) )
812 rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
813 rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
816 rRand1*std::sin(startPhi), zRand);
821 rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
822 rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
825 rRand1*std::sin(
endPhi), zRand);
840 G4double xRand,yRand,zRand,
phi,cosphi,sinphi,chose,
841 aOne,aTwo,aFou,rRand,fDz,fSPhi,fDPhi;
842 fDz = std::fabs(0.5*(zTwo-zOne));
846 aOne = 2.*fDz*fDPhi*fRMax;
847 aTwo = 2.*fDz*fDPhi*fRMin;
848 aFou = 2.*fDz*(fRMax-fRMin);
849 totArea = aOne+aTwo+2.*aFou;
851 cosphi = std::cos(phi);
852 sinphi = std::sin(phi);
859 if( (chose >= 0.) && (chose < aOne) )
861 xRand = fRMax*cosphi;
862 yRand = fRMax*sinphi;
866 else if( (chose >= aOne) && (chose < aOne + aTwo) )
868 xRand = fRMin*cosphi;
869 yRand = fRMin*sinphi;
873 else if( (chose >= aOne+aTwo) && (chose <aOne+aTwo+aFou) )
875 xRand = rRand*std::cos(fSPhi+fDPhi);
876 yRand = rRand*std::sin(fSPhi+fDPhi);
883 xRand = rRand*std::cos(fSPhi+fDPhi);
884 yRand = rRand*std::sin(fSPhi+fDPhi);
897 G4double xRand,yRand,
phi,cosphi,sinphi,rRand1,rRand2,A1,Atot,rCh;
899 cosphi = std::cos(phi);
900 sinphi = std::sin(phi);
904 rRand1 = fRMin1; A1=0.;
909 A1=std::fabs(fRMin2*fRMin2-fRMin1*fRMin1);
913 rRand2=fRMax1; Atot=A1;
918 Atot = A1+std::fabs(fRMax2*fRMax2-fRMax1*fRMax1);
922 if(rCh>A1) { rRand1=rRand2; }
924 xRand = rRand1*cosphi;
925 yRand = rRand1*sinphi;
942 if( (fRMin1 == fRMin2) && (fRMax1 == fRMax2) )
946 return GetPointOnCone(fRMin1,fRMax1,fRMin2,fRMax2,zOne,zTwo,totArea);
953 G4double Area=0.,totArea=0.,Achose1=0.,Achose2=0.,
phi,cosphi,sinphi,rRand;
958 cosphi = std::cos(
phi);
959 sinphi = std::sin(
phi);
965 std::vector<G4double> areas;
966 std::vector<G4ThreeVector> points;
971 for(i=0; i<numPlanes-1; ++i)
996 areas.push_back(Area);
1003 totArea += (areas[0]+areas[numPlanes]);
1006 if( (chose>=0.) && (chose<areas[0]) )
1012 for (i=0; i<numPlanes-1; ++i)
1014 Achose1 += areas[i];
1015 Achose2 = (Achose1+areas[i+1]);
1016 if(chose>=Achose1 && chose<Achose2)
1057 G4bool isConvertible =
true;
1063 std::vector<G4double>
Z;
1064 std::vector<G4double> Rmin;
1065 std::vector<G4double> Rmax;
1067 G4int countPlanes=1;
1078 Rmax.push_back (
corners[1].r);icurr=1;
1080 else if (Zprev ==
corners[numPlanes-1].z)
1082 Rmin.push_back(
corners[numPlanes-1].
r);
1089 Rmax.push_back (
corners[0].r);
1094 G4int inextr=0, inextl=0;
1095 for (
G4int i=0; i < numPlanes-2; ++i)
1098 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1116 Rmax.push_back(
corners[icurr].r);
1130 Rmax.push_back(
corners[icurr].r);
1141 isConvertible=
false;
break;
1143 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1151 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1154 Rmax.push_back(
corners[inextr].r);
1158 Z.push_back(Zright);
1168 Rmin.push_back(
corners[icurr].r);
1174 Rmax.push_back(
corners[inextr].r);
1183 Rmin.push_back (
corners[icurr].r);
1195 isConvertible=
false;
break;
1205 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1208 Rmin.push_back(
corners[inextl].r);
1219 for(
G4int j=0; j < countPlanes; ++j)
1235 <<
"cannot be converted to Polycone with (Rmin,Rmaz,Z) parameters!";
1236 G4Exception(
"G4Polycone::SetOriginalParameters()",
"GeomSolids0002",
1244 for(
G4int j=0; j < numPlanes; ++j)
1254 return isConvertible;