52 using namespace CLHEP;
79 for (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 );
145 Create( phiStart, phiTotal, rz );
168 if (rz->
Amin() < 0.0)
170 std::ostringstream message;
171 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
172 <<
" All R values must be >= 0 !";
173 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
183 std::ostringstream message;
184 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
185 <<
" R/Z cross section is zero or near zero: " << rzArea;
186 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
193 std::ostringstream message;
194 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
195 <<
" Too few unique R/Z values !";
196 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
202 std::ostringstream message;
203 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
204 <<
" R/Z segments cross !";
205 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
215 if (phiTotal <= 0 || phiTotal >
twopi-1E-10)
231 endPhi = phiStart+phiTotal;
249 next->
r = iterRZ.
GetA();
250 next->
z = iterRZ.
GetB();
251 }
while( ++next, iterRZ.
Next() );
275 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
283 if (corner->
z > next->
z)
300 }
while( prev=corner, corner=next, corner >
corners );
329 :
G4VCSGfaceted(a), startPhi(0.), endPhi(0.), phiIsOpen(false),
330 genericPcon(false), numCorner(0), corners(0),
331 original_parameters(0), enclosingCylinder(0)
362 if (
this == &source)
return *
this;
426 std::ostringstream message;
427 message <<
"Solid " <<
GetName() <<
" built using generic construct."
428 <<
G4endl <<
"Not applicable to the generic construct !";
429 G4Exception(
"G4Polycone::Reset()",
"GeomSolids1001",
539 G4int oldprc = os.precision(16);
540 os <<
"-----------------------------------------------------------\n"
541 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
542 <<
" ===================================================\n"
543 <<
" Solid type: G4Polycone\n"
546 <<
" ending phi angle : " <<
endPhi/
degree <<
" degrees \n";
551 os <<
" number of Z planes: " << numPlanes <<
"\n"
553 for (i=0; i<numPlanes; i++)
555 os <<
" Z plane " << i <<
": "
558 os <<
" Tangent distances to inner surface (Rmin): \n";
559 for (i=0; i<numPlanes; i++)
561 os <<
" Z plane " << i <<
": "
564 os <<
" Tangent distances to outer surface (Rmax): \n";
565 for (i=0; i<numPlanes; i++)
567 os <<
" Z plane " << i <<
": "
571 os <<
" number of RZ points: " <<
numCorner <<
"\n"
572 <<
" RZ values (corners): \n";
578 os <<
"-----------------------------------------------------------\n";
579 os.precision(oldprc);
597 G4double Aone, Atwo, Afive, phi, zRand, fDPhi, cosu, sinu;
598 G4double rRand1, rmin, rmax, chose, rone, rtwo, qone, qtwo;
599 G4double fDz=(zTwo-zOne)/2., afDz=std::fabs(fDz);
602 rone = (fRmax1-fRmax2)/(2.*fDz);
603 rtwo = (fRmin1-fRmin2)/(2.*fDz);
604 if(fRmax1==fRmax2){qone=0.;}
606 qone = fDz*(fRmax1+fRmax2)/(fRmax1-fRmax2);
608 if(fRmin1==fRmin2){qtwo=0.;}
610 qtwo = fDz*(fRmin1+fRmin2)/(fRmin1-fRmin2);
612 Aone = 0.5*fDPhi*(fRmax2 + fRmax1)*(
sqr(fRmin1-fRmin2)+
sqr(zTwo-zOne));
613 Atwo = 0.5*fDPhi*(fRmin2 + fRmin1)*(
sqr(fRmax1-fRmax2)+
sqr(zTwo-zOne));
614 Afive = fDz*(fRmax1-fRmin1+fRmax2-fRmin2);
615 totArea = Aone+Atwo+2.*Afive;
617 phi = RandFlat::shoot(startPhi,
endPhi);
618 cosu = std::cos(phi);
619 sinu = std::sin(phi);
622 if( (startPhi == 0) && (
endPhi ==
twopi) ) { Afive = 0; }
623 chose = RandFlat::shoot(0.,Aone+Atwo+2.*Afive);
624 if( (chose >= 0) && (chose < Aone) )
628 zRand = RandFlat::shoot(-1.*afDz,afDz);
630 rone*sinu*(qone-zRand), zRand);
635 RandFlat::shoot(-1.*afDz,afDz));
639 else if(chose >= Aone && chose < Aone + Atwo)
643 zRand = RandFlat::shoot(-1.*afDz,afDz);
645 rtwo*sinu*(qtwo-zRand), zRand);
651 RandFlat::shoot(-1.*afDz,afDz));
654 else if( (chose >= Aone + Atwo + Afive) && (chose < Aone + Atwo + 2.*Afive) )
656 zRand = RandFlat::shoot(-1.*afDz,afDz);
657 rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
658 rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
659 rRand1 = std::sqrt(RandFlat::shoot()*(
sqr(rmax)-
sqr(rmin))+
sqr(rmin));
661 rRand1*std::sin(startPhi), zRand);
665 zRand = RandFlat::shoot(-1.*afDz,afDz);
666 rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
667 rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
668 rRand1 = std::sqrt(RandFlat::shoot()*(
sqr(rmax)-
sqr(rmin))+
sqr(rmin));
670 rRand1*std::sin(
endPhi), zRand);
687 G4double xRand,yRand,zRand,phi,cosphi,sinphi,chose,
688 aOne,aTwo,aFou,rRand,fDz,fSPhi,fDPhi;
689 fDz = std::fabs(0.5*(zTwo-zOne));
693 aOne = 2.*fDz*fDPhi*fRMax;
694 aTwo = 2.*fDz*fDPhi*fRMin;
695 aFou = 2.*fDz*(fRMax-fRMin);
696 totArea = aOne+aTwo+2.*aFou;
697 phi = RandFlat::shoot(startPhi,
endPhi);
698 cosphi = std::cos(phi);
699 sinphi = std::sin(phi);
700 rRand = fRMin + (fRMax-fRMin)*std::sqrt(RandFlat::shoot());
705 chose = RandFlat::shoot(0.,aOne+aTwo+2.*aFou);
706 if( (chose >= 0) && (chose < aOne) )
708 xRand = fRMax*cosphi;
709 yRand = fRMax*sinphi;
710 zRand = RandFlat::shoot(-1.*fDz,fDz);
713 else if( (chose >= aOne) && (chose < aOne + aTwo) )
715 xRand = fRMin*cosphi;
716 yRand = fRMin*sinphi;
717 zRand = RandFlat::shoot(-1.*fDz,fDz);
720 else if( (chose >= aOne+aTwo) && (chose <aOne+aTwo+aFou) )
722 xRand = rRand*std::cos(fSPhi+fDPhi);
723 yRand = rRand*std::sin(fSPhi+fDPhi);
724 zRand = RandFlat::shoot(-1.*fDz,fDz);
730 xRand = rRand*std::cos(fSPhi+fDPhi);
731 yRand = rRand*std::sin(fSPhi+fDPhi);
732 zRand = RandFlat::shoot(-1.*fDz,fDz);
746 G4double xRand,yRand,phi,cosphi,sinphi,rRand1,rRand2,A1,Atot,rCh;
748 cosphi = std::cos(phi);
749 sinphi = std::sin(phi);
753 rRand1 = fRMin1; A1=0.;
757 rRand1 = RandFlat::shoot(fRMin1,fRMin2);
758 A1=std::fabs(fRMin2*fRMin2-fRMin1*fRMin1);
762 rRand2=fRMax1; Atot=A1;
766 rRand2 = RandFlat::shoot(fRMax1,fRMax2);
767 Atot = A1+std::fabs(fRMax2*fRMax2-fRMax1*fRMax1);
769 rCh = RandFlat::shoot(0.,Atot);
771 if(rCh>A1) { rRand1=rRand2; }
773 xRand = rRand1*cosphi;
774 yRand = rRand1*sinphi;
793 if( (fRMin1 == fRMin2) && (fRMax1 == fRMax2) )
797 return GetPointOnCone(fRMin1,fRMax1,fRMin2,fRMax2,zOne,zTwo,totArea);
808 G4double Area=0,totArea=0,Achose1=0,Achose2=0,phi,cosphi,sinphi,rRand;
813 cosphi = std::cos(phi);
814 sinphi = std::sin(phi);
818 * std::sqrt(RandFlat::shoot()) );
820 std::vector<G4double> areas;
821 std::vector<G4ThreeVector> points;
826 for(i=0; i<numPlanes-1; i++)
851 areas.push_back(Area);
858 totArea += (areas[0]+areas[numPlanes]);
859 G4double chose = RandFlat::shoot(0.,totArea);
861 if( (chose>=0.) && (chose<areas[0]) )
867 for (i=0; i<numPlanes-1; i++)
870 Achose2 = (Achose1+areas[i+1]);
871 if(chose>=Achose1 && chose<Achose2)
884 * std::sqrt(RandFlat::shoot()) );
936 const G4int numSide =
943 typedef G4int int4[4];
950 std::vector<G4bool> chopped(
numCorner,
false);
951 std::vector<G4int*> triQuads;
954 while (remaining >= 3)
958 G4int A = -1, B = -1, C = -1;
959 G4int iStepper = iStarter;
962 if (A < 0) { A = iStepper; }
963 else if (B < 0) { B = iStepper; }
964 else if (C < 0) { C = iStepper; }
967 if (++iStepper >=
numCorner) { iStepper = 0; }
969 while (chopped[iStepper]);
971 while (C < 0 && iStepper != iStarter);
986 triQuads.push_back(tq);
994 if (++iStarter >=
numCorner) { iStarter = 0; }
996 while (chopped[iStarter]);
1002 nFaces = numSide *
numCorner + 2 * triQuads.size();
1003 faces_vec =
new int4[nFaces];
1007 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
1009 for (
size_t i = 0; i < triQuads.size(); ++i)
1022 a = triQuads[i][0] + addition;
1023 b = triQuads[i][2] + addition;
1024 c = triQuads[i][1] + addition;
1026 G4int ab = std::abs(b - a);
1027 G4int bc = std::abs(c - b);
1028 G4int ca = std::abs(a - c);
1029 faces_vec[iface][0] = (ab == 1 || ab ==
d)? a: -a;
1030 faces_vec[iface][1] = (bc == 1 || bc ==
d)? b: -b;
1031 faces_vec[iface][2] = (ca == 1 || ca ==
d)? c: -c;
1032 faces_vec[iface][3] = 0;
1039 xyz =
new double3[nNodes];
1043 for (
G4int iSide = 0; iSide < numSide; ++iSide)
1047 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1048 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1052 if (iCorner < numCorner - 1)
1054 faces_vec[iface][0] = ixyz + 1;
1055 faces_vec[iface][1] = -(ixyz + numCorner + 1);
1056 faces_vec[iface][2] = ixyz + numCorner + 2;
1057 faces_vec[iface][3] = ixyz + 2;
1061 faces_vec[iface][0] = ixyz + 1;
1062 faces_vec[iface][1] = -(ixyz + numCorner + 1);
1063 faces_vec[iface][2] = ixyz + 2;
1064 faces_vec[iface][3] = ixyz - numCorner + 2;
1067 else if (iSide == numSide - 1)
1069 if (iCorner < numCorner - 1)
1071 faces_vec[iface][0] = ixyz + 1;
1072 faces_vec[iface][1] = ixyz + numCorner + 1;
1073 faces_vec[iface][2] = ixyz + numCorner + 2;
1074 faces_vec[iface][3] = -(ixyz + 2);
1078 faces_vec[iface][0] = ixyz + 1;
1079 faces_vec[iface][1] = ixyz + numCorner + 1;
1080 faces_vec[iface][2] = ixyz + 2;
1081 faces_vec[iface][3] = -(ixyz - numCorner + 2);
1086 if (iCorner < numCorner - 1)
1088 faces_vec[iface][0] = ixyz + 1;
1089 faces_vec[iface][1] = -(ixyz + numCorner + 1);
1090 faces_vec[iface][2] = ixyz + numCorner + 2;
1091 faces_vec[iface][3] = -(ixyz + 2);
1095 faces_vec[iface][0] = ixyz + 1;
1096 faces_vec[iface][1] = -(ixyz + numCorner + 1);
1097 faces_vec[iface][2] = ixyz + 2;
1098 faces_vec[iface][3] = -(ixyz - numCorner + 2);
1111 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1112 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1121 xyz =
new double3[nNodes];
1122 faces_vec =
new int4[nFaces];
1125 G4int ixyz = 0, iface = 0;
1126 for (
G4int iSide = 0; iSide < numSide; ++iSide)
1130 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1131 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1134 if (iSide < numSide - 1)
1136 if (iCorner < numCorner - 1)
1138 faces_vec[iface][0] = ixyz + 1;
1139 faces_vec[iface][1] = -(ixyz + numCorner + 1);
1140 faces_vec[iface][2] = ixyz + numCorner + 2;
1141 faces_vec[iface][3] = -(ixyz + 2);
1145 faces_vec[iface][0] = ixyz + 1;
1146 faces_vec[iface][1] = -(ixyz + numCorner + 1);
1147 faces_vec[iface][2] = ixyz + 2;
1148 faces_vec[iface][3] = -(ixyz - numCorner + 2);
1153 if (iCorner < numCorner - 1)
1155 faces_vec[iface][0] = ixyz + 1;
1156 faces_vec[iface][1] = -(ixyz + numCorner - nFaces + 1);
1157 faces_vec[iface][2] = ixyz + numCorner - nFaces + 2;
1158 faces_vec[iface][3] = -(ixyz + 2);
1162 faces_vec[iface][0] = ixyz + 1;
1163 faces_vec[iface][1] = -(ixyz - nFaces + numCorner + 1);
1164 faces_vec[iface][2] = ixyz - nFaces + 2;
1165 faces_vec[iface][3] = -(ixyz - numCorner + 2);
1176 delete [] faces_vec;
1180 std::ostringstream message;
1181 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
1182 G4Exception(
"G4Polycone::CreatePolyhedron()",
"GeomSolids1002",
1207 : Start_angle(0.), Opening_angle(0.), Num_z_planes(0),
1208 Z_values(0), Rmin(0), Rmax(0)
1241 if ( &right ==
this )
return *
this;