79 for (i=0; i<numZPlanes; i++)
81 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
83 if( (rInner[i] > rOuter[i+1])
84 ||(rInner[i+1] > rOuter[i]) )
87 std::ostringstream message;
88 message <<
"Cannot create a Polycone with no contiguous segments."
90 <<
" Segments are not contiguous !" <<
G4endl
91 <<
" rMin[" << i <<
"] = " << rInner[i]
92 <<
" -- rMax[" << i+1 <<
"] = " << rOuter[i+1] <<
G4endl
93 <<
" rMin[" << i+1 <<
"] = " << rInner[i+1]
94 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
95 G4Exception(
"G4Polycone::G4Polycone()",
"GeomSolids0002",
113 Create( phiStart, phiTotal, rz );
132 Create( phiStart, phiTotal, rz );
155 if (rz->
Amin() < 0.0)
157 std::ostringstream message;
158 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
159 <<
" All R values must be >= 0 !";
160 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
170 std::ostringstream message;
171 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
172 <<
" R/Z cross section is zero or near zero: " << rzArea;
173 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
180 std::ostringstream message;
181 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
182 <<
" Too few unique R/Z values !";
183 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
189 std::ostringstream message;
190 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
191 <<
" R/Z segments cross !";
192 G4Exception(
"G4Polycone::Create()",
"GeomSolids0002",
202 if (phiTotal <= 0 || phiTotal > twopi-1E-10)
218 endPhi = phiStart+phiTotal;
236 next->
r = iterRZ.
GetA();
237 next->
z = iterRZ.
GetB();
238 }
while( ++next, iterRZ.
Next() );
262 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
270 if (corner->
z > next->
z)
287 }
while( prev=corner, corner=next, corner >
corners );
316 :
G4VCSGfaceted(a), startPhi(0.), endPhi(0.), phiIsOpen(false),
317 genericPcon(false), numCorner(0), corners(0),
318 original_parameters(0), enclosingCylinder(0)
349 if (
this == &source)
return *
this;
413 std::ostringstream message;
414 message <<
"Solid " <<
GetName() <<
" built using generic construct."
415 <<
G4endl <<
"Not applicable to the generic construct !";
416 G4Exception(
"G4Polycone::Reset()",
"GeomSolids1001",
526 G4int oldprc = os.precision(16);
527 os <<
"-----------------------------------------------------------\n"
528 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
529 <<
" ===================================================\n"
530 <<
" Solid type: G4Polycone\n"
532 <<
" starting phi angle : " <<
startPhi/degree <<
" degrees \n"
533 <<
" ending phi angle : " <<
endPhi/degree <<
" degrees \n";
538 os <<
" number of Z planes: " << numPlanes <<
"\n"
540 for (i=0; i<numPlanes; i++)
542 os <<
" Z plane " << i <<
": "
545 os <<
" Tangent distances to inner surface (Rmin): \n";
546 for (i=0; i<numPlanes; i++)
548 os <<
" Z plane " << i <<
": "
551 os <<
" Tangent distances to outer surface (Rmax): \n";
552 for (i=0; i<numPlanes; i++)
554 os <<
" Z plane " << i <<
": "
558 os <<
" number of RZ points: " <<
numCorner <<
"\n"
559 <<
" RZ values (corners): \n";
565 os <<
"-----------------------------------------------------------\n";
566 os.precision(oldprc);
584 G4double Aone, Atwo, Afive, phi, zRand, fDPhi, cosu, sinu;
585 G4double rRand1, rmin, rmax, chose, rone, rtwo, qone, qtwo,
586 fDz = std::fabs((zTwo-zOne)/2.);
590 rone = (fRmax1-fRmax2)/(2.*fDz);
591 rtwo = (fRmin1-fRmin2)/(2.*fDz);
592 if(fRmax1==fRmax2){qone=0.;}
594 qone = fDz*(fRmax1+fRmax2)/(fRmax1-fRmax2);
596 if(fRmin1==fRmin2){qtwo=0.;}
598 qtwo = fDz*(fRmin1+fRmin2)/(fRmin1-fRmin2);
600 Aone = 0.5*fDPhi*(fRmax2 + fRmax1)*(
sqr(fRmin1-fRmin2)+
sqr(zTwo-zOne));
601 Atwo = 0.5*fDPhi*(fRmin2 + fRmin1)*(
sqr(fRmax1-fRmax2)+
sqr(zTwo-zOne));
602 Afive = fDz*(fRmax1-fRmin1+fRmax2-fRmin2);
603 totArea = Aone+Atwo+2.*Afive;
606 cosu = std::cos(phi);
607 sinu = std::sin(phi);
612 if( (chose >= 0) && (chose < Aone) )
618 rone*sinu*(qone-zRand), zRand);
629 else if(chose >= Aone && chose < Aone + Atwo)
635 rtwo*sinu*(qtwo-zRand), zRand);
645 else if( (chose >= Aone + Atwo + Afive) && (chose < Aone + Atwo + 2.*Afive) )
648 rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
649 rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
657 rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
658 rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
661 rRand1*std::sin(
endPhi), zRand);
677 G4double xRand,yRand,zRand,phi,cosphi,sinphi,chose,
678 aOne,aTwo,aFou,rRand,fDz,fSPhi,fDPhi;
679 fDz = std::fabs(0.5*(zTwo-zOne));
683 aOne = 2.*fDz*fDPhi*fRMax;
684 aTwo = 2.*fDz*fDPhi*fRMin;
685 aFou = 2.*fDz*(fRMax-fRMin);
686 totArea = aOne+aTwo+2.*aFou;
688 cosphi = std::cos(phi);
689 sinphi = std::sin(phi);
696 if( (chose >= 0) && (chose < aOne) )
698 xRand = fRMax*cosphi;
699 yRand = fRMax*sinphi;
703 else if( (chose >= aOne) && (chose < aOne + aTwo) )
705 xRand = fRMin*cosphi;
706 yRand = fRMin*sinphi;
710 else if( (chose >= aOne+aTwo) && (chose <aOne+aTwo+aFou) )
712 xRand = rRand*std::cos(fSPhi+fDPhi);
713 yRand = rRand*std::sin(fSPhi+fDPhi);
720 xRand = rRand*std::cos(fSPhi+fDPhi);
721 yRand = rRand*std::sin(fSPhi+fDPhi);
736 G4double xRand,yRand,phi,cosphi,sinphi,rRand1,rRand2,A1,Atot,rCh;
739 cosphi = std::cos(phi);
740 sinphi = std::sin(phi);
744 rRand1 = fRMin1; A1=0.;
749 A1=std::fabs(fRMin2*fRMin2-fRMin1*fRMin1);
753 rRand2=fRMax1; Atot=A1;
758 Atot = A1+std::fabs(fRMax2*fRMax2-fRMax1*fRMax1);
762 if(rCh>A1) { rRand1=rRand2; }
764 xRand = rRand1*cosphi;
765 yRand = rRand1*sinphi;
784 if( (fRMin1 == fRMin2) && (fRMax1 == fRMax2) )
788 return GetPointOnCone(fRMin1,fRMax1,fRMin2,fRMax2,zOne,zTwo,totArea);
799 G4double Area=0,totArea=0,Achose1=0,Achose2=0,phi,cosphi,sinphi,rRand;
804 cosphi = std::cos(phi);
805 sinphi = std::sin(phi);
811 std::vector<G4double> areas;
812 std::vector<G4ThreeVector> points;
817 for(i=0; i<numPlanes-1; i++)
842 areas.push_back(Area);
849 totArea += (areas[0]+areas[numPlanes]);
852 if( (chose>=0.) && (chose<areas[0]) )
858 for (i=0; i<numPlanes-1; i++)
861 Achose2 = (Achose1+areas[i+1]);
862 if(chose>=Achose1 && chose<Achose2)
929 const G4int numSide =
936 typedef G4int int4[4];
943 std::vector<G4bool> chopped(
numCorner,
false);
944 std::vector<G4int*> triQuads;
947 while (remaining >= 3)
951 G4int A = -1, B = -1, C = -1;
952 G4int iStepper = iStarter;
955 if (A < 0) { A = iStepper; }
956 else if (B < 0) { B = iStepper; }
957 else if (C < 0) { C = iStepper; }
960 if (++iStepper >=
numCorner) { iStepper = 0; }
962 while (chopped[iStepper]);
964 while (C < 0 && iStepper != iStarter);
979 triQuads.push_back(tq);
987 if (++iStarter >=
numCorner) { iStarter = 0; }
989 while (chopped[iStarter]);
995 nFaces = numSide *
numCorner + 2 * triQuads.size();
996 faces_vec =
new int4[nFaces];
1000 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
1002 for (
size_t i = 0; i < triQuads.size(); ++i)
1015 a = triQuads[i][0] + addition;
1016 b = triQuads[i][2] + addition;
1017 c = triQuads[i][1] + addition;
1019 G4int ab = std::abs(b - a);
1020 G4int bc = std::abs(c - b);
1021 G4int ca = std::abs(a - c);
1022 faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
1023 faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
1024 faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
1025 faces_vec[iface][3] = 0;
1032 xyz =
new double3[nNodes];
1036 for (
G4int iSide = 0; iSide < numSide; ++iSide)
1040 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1041 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1047 faces_vec[iface][0] = ixyz + 1;
1048 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1049 faces_vec[iface][2] = ixyz +
numCorner + 2;
1050 faces_vec[iface][3] = ixyz + 2;
1054 faces_vec[iface][0] = ixyz + 1;
1055 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1056 faces_vec[iface][2] = ixyz + 2;
1057 faces_vec[iface][3] = ixyz -
numCorner + 2;
1060 else if (iSide == numSide - 1)
1064 faces_vec[iface][0] = ixyz + 1;
1065 faces_vec[iface][1] = ixyz +
numCorner + 1;
1066 faces_vec[iface][2] = ixyz +
numCorner + 2;
1067 faces_vec[iface][3] = -(ixyz + 2);
1071 faces_vec[iface][0] = ixyz + 1;
1072 faces_vec[iface][1] = ixyz +
numCorner + 1;
1073 faces_vec[iface][2] = ixyz + 2;
1074 faces_vec[iface][3] = -(ixyz -
numCorner + 2);
1081 faces_vec[iface][0] = ixyz + 1;
1082 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1083 faces_vec[iface][2] = ixyz +
numCorner + 2;
1084 faces_vec[iface][3] = -(ixyz + 2);
1088 faces_vec[iface][0] = ixyz + 1;
1089 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1090 faces_vec[iface][2] = ixyz + 2;
1091 faces_vec[iface][3] = -(ixyz -
numCorner + 2);
1104 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1105 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1114 xyz =
new double3[nNodes];
1115 faces_vec =
new int4[nFaces];
1118 G4int ixyz = 0, iface = 0;
1119 for (
G4int iSide = 0; iSide < numSide; ++iSide)
1123 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1124 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1127 if (iSide < numSide - 1)
1131 faces_vec[iface][0] = ixyz + 1;
1132 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1133 faces_vec[iface][2] = ixyz +
numCorner + 2;
1134 faces_vec[iface][3] = -(ixyz + 2);
1138 faces_vec[iface][0] = ixyz + 1;
1139 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1140 faces_vec[iface][2] = ixyz + 2;
1141 faces_vec[iface][3] = -(ixyz -
numCorner + 2);
1148 faces_vec[iface][0] = ixyz + 1;
1149 faces_vec[iface][1] = -(ixyz +
numCorner - nFaces + 1);
1150 faces_vec[iface][2] = ixyz +
numCorner - nFaces + 2;
1151 faces_vec[iface][3] = -(ixyz + 2);
1155 faces_vec[iface][0] = ixyz + 1;
1156 faces_vec[iface][1] = -(ixyz - nFaces +
numCorner + 1);
1157 faces_vec[iface][2] = ixyz - nFaces + 2;
1158 faces_vec[iface][3] = -(ixyz -
numCorner + 2);
1169 delete [] faces_vec;
1173 std::ostringstream message;
1174 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
1175 G4Exception(
"G4Polycone::CreatePolyhedron()",
"GeomSolids1002",
1202 : Start_angle(0.), Opening_angle(0.), Num_z_planes(0),
1203 Z_values(0), Rmin(0), Rmax(0)
1236 if ( &right ==
this )
return *
this;
CLHEP::Hep3Vector G4ThreeVector
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool MustBeOutside(const G4ThreeVector &p) const
G4PolyconeHistorical & operator=(const G4PolyconeHistorical &right)
G4EnclosingCylinder * enclosingCylinder
G4NURBS * CreateNURBS() const
G4ThreeVector GetPointOnSurface() const
void SetOriginalParameters()
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[])
G4ThreeVector GetPointOnTubs(G4double fRMin, G4double fRMax, G4double zOne, G4double zTwo, G4double &totArea) const
G4ThreeVector GetPointOnCone(G4double fRmin1, G4double fRmax1, G4double fRmin2, G4double fRmax2, G4double zOne, G4double zTwo, G4double &totArea) const
const G4Polycone & operator=(const G4Polycone &source)
G4Polyhedron * CreatePolyhedron() const
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
EInside Inside(const G4ThreeVector &p) const
void CopyStuff(const G4Polycone &source)
G4PolyconeSideRZ * corners
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4PolyconeHistorical * original_parameters
G4ThreeVector GetPointOnRing(G4double fRMin, G4double fRMax, G4double fRMin2, G4double fRMax2, G4double zOne) const
std::ostream & StreamInfo(std::ostream &os) const
G4ThreeVector GetPointOnCut(G4double fRMin1, G4double fRMax1, G4double fRMin2, G4double fRMax2, G4double zOne, G4double zTwo, G4double &totArea) 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)
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
virtual EInside Inside(const G4ThreeVector &p) const
const G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
G4ThreeVector GetPointOnSurfaceGeneric() const
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
static G4int GetNumberOfRotationSteps()
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)