90 std::ostringstream message;
91 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
92 <<
" No sides specified !";
93 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
101 if ( (phiTotal <=0) || (phiTotal >= twopi*(1-
DBL_EPSILON)) )
102 { phiTotal = twopi; }
103 G4double convertRad = std::cos(0.5*phiTotal/theNumSide);
119 for (i=0; i<numZPlanes; i++)
121 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
123 if( (rInner[i] > rOuter[i+1])
124 ||(rInner[i+1] > rOuter[i]) )
127 std::ostringstream message;
128 message <<
"Cannot create a Polyhedra with no contiguous segments."
130 <<
" Segments are not contiguous !" <<
G4endl
131 <<
" rMin[" << i <<
"] = " << rInner[i]
132 <<
" -- rMax[" << i+1 <<
"] = " << rOuter[i+1] <<
G4endl
133 <<
" rMin[" << i+1 <<
"] = " << rInner[i+1]
134 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
135 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
150 rz->
ScaleA( 1/convertRad );
155 Create( phiStart, phiTotal, theNumSide, rz );
175 Create( phiStart, phiTotal, theNumSide, rz );
199 if (rz->
Amin() < 0.0)
201 std::ostringstream message;
202 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
203 <<
" All R values must be >= 0 !";
204 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
214 std::ostringstream message;
215 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
216 <<
" R/Z cross section is zero or near zero: " << rzArea;
217 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
224 std::ostringstream message;
225 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
226 <<
" Too few unique R/Z values !";
227 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
233 std::ostringstream message;
234 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
235 <<
" R/Z segments cross !";
236 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
249 if ( (phiTotal <= 0) || (phiTotal > twopi*(1-
DBL_EPSILON)) )
261 endPhi = phiStart+phiTotal;
284 next->
r = iterRZ.
GetA();
285 next->
z = iterRZ.
GetB();
286 }
while( ++next, iterRZ.
Next() );
313 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
338 }
while( prev=corner, corner=next, corner >
corners );
368 phiIsOpen(false), genericPgon(false), numCorner(0), corners(0),
369 original_parameters(0), enclosingCylinder(0)
401 if (
this == &source)
return *
this;
469 std::ostringstream message;
470 message <<
"Solid " <<
GetName() <<
" built using generic construct."
471 <<
G4endl <<
"Not applicable to the generic construct !";
472 G4Exception(
"G4Polyhedra::Reset()",
"GeomSolids1001",
586 G4int oldprc = os.precision(16);
587 os <<
"-----------------------------------------------------------\n"
588 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
589 <<
" ===================================================\n"
590 <<
" Solid type: G4Polyhedra\n"
592 <<
" starting phi angle : " <<
startPhi/degree <<
" degrees \n"
593 <<
" ending phi angle : " <<
endPhi/degree <<
" degrees \n";
598 os <<
" number of Z planes: " << numPlanes <<
"\n"
600 for (i=0; i<numPlanes; i++)
602 os <<
" Z plane " << i <<
": "
605 os <<
" Tangent distances to inner surface (Rmin): \n";
606 for (i=0; i<numPlanes; i++)
608 os <<
" Z plane " << i <<
": "
611 os <<
" Tangent distances to outer surface (Rmax): \n";
612 for (i=0; i<numPlanes; i++)
614 os <<
" Z plane " << i <<
": "
618 os <<
" number of RZ points: " <<
numCorner <<
"\n"
619 <<
" RZ values (corners): \n";
625 os <<
"-----------------------------------------------------------\n";
626 os.precision(oldprc);
640 G4double lambda1, lambda2, chose,aOne,aTwo;
651 if( (chose>=0.) && (chose < aOne) )
655 return (p2+lambda1*v+lambda2*w);
660 return (p0+lambda1*t+lambda2*u);
679 return (p2 + lambda1*w + lambda2*v);
691 G4double chose, totArea=0., Achose1, Achose2,
692 rad1, rad2, sinphi1, sinphi2, cosphi1, cosphi2;
693 G4double a, b, l2, rang, totalPhi, ksi,
694 area, aTop=0., aBottom=0., zVal=0.;
697 std::vector<G4double> aVector1;
698 std::vector<G4double> aVector2;
699 std::vector<G4double> aVector3;
707 for(j=0; j<numPlanes-1; j++)
713 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
714 aVector1.push_back(area);
717 for(j=0; j<numPlanes-1; j++)
723 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
724 aVector2.push_back(area);
727 for(j=0; j<numPlanes-1; j++)
738 else { aVector3.push_back(0.); }
741 for(j=0; j<numPlanes-1; j++)
743 totArea +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
753 aTop = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
761 aBottom = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
765 Achose2 =
numSide*(aVector1[0]+aVector2[0])+2.*aVector3[0];
768 if( (chose >= 0.) && (chose < aTop + aBottom) )
771 rang = std::floor((chose-
startPhi)/ksi-0.01);
772 if(rang<0) { rang=0; }
773 rang = std::fabs(rang);
774 sinphi1 = std::sin(
startPhi+rang*ksi);
775 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
776 cosphi1 = std::cos(
startPhi+rang*ksi);
777 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
779 if(chose>=0. && chose<aTop)
799 for (j=0; j<numPlanes-1; j++)
801 if( ((chose >= Achose1) && (chose < Achose2)) || (j == numPlanes-2) )
805 Achose1 +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
806 Achose2 = Achose1 +
numSide*(aVector1[j+1]+aVector2[j+1])
816 totArea =
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
819 if( (chose>=0.) && (chose<
numSide*aVector1[j]) )
822 rang = std::floor((chose-
startPhi)/ksi-0.01);
823 if(rang<0) { rang=0; }
824 rang = std::fabs(rang);
827 sinphi1 = std::sin(
startPhi+rang*ksi);
828 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
829 cosphi1 = std::cos(
startPhi+rang*ksi);
830 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
842 else if ( (chose >=
numSide*aVector1[j])
843 && (chose <=
numSide*(aVector1[j]+aVector2[j])) )
846 rang = std::floor((chose-
startPhi)/ksi-0.01);
847 if(rang<0) { rang=0; }
848 rang = std::fabs(rang);
851 sinphi1 = std::sin(
startPhi+rang*ksi);
852 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
853 cosphi1 = std::cos(
startPhi+rang*ksi);
854 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
868 if( (chose>=0.) && (chose < 1.) )
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]);
1004 faces_vec =
new int4[nFaces];
1008 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
1010 for (
size_t i = 0; i < triQuads.size(); ++i)
1023 a = triQuads[i][0] + addition;
1024 b = triQuads[i][2] + addition;
1025 c = triQuads[i][1] + addition;
1027 G4int ab = std::abs(b - a);
1028 G4int bc = std::abs(c - b);
1029 G4int ca = std::abs(a - c);
1030 faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
1031 faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
1032 faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
1033 faces_vec[iface][3] = 0;
1040 xyz =
new double3[nNodes];
1048 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1049 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1053 faces_vec[iface][0] = ixyz + 1;
1054 faces_vec[iface][1] = ixyz +
numCorner + 1;
1055 faces_vec[iface][2] = ixyz +
numCorner + 2;
1056 faces_vec[iface][3] = ixyz + 2;
1060 faces_vec[iface][0] = ixyz + 1;
1061 faces_vec[iface][1] = ixyz +
numCorner + 1;
1062 faces_vec[iface][2] = ixyz + 2;
1063 faces_vec[iface][3] = ixyz -
numCorner + 2;
1075 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1076 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1085 xyz =
new double3[nNodes];
1086 faces_vec =
new int4[nFaces];
1090 G4int ixyz = 0, iface = 0;
1095 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1096 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1102 faces_vec[iface][0] = ixyz + 1;
1103 faces_vec[iface][1] = ixyz +
numCorner + 1;
1104 faces_vec[iface][2] = ixyz +
numCorner + 2;
1105 faces_vec[iface][3] = ixyz + 2;
1109 faces_vec[iface][0] = ixyz + 1;
1110 faces_vec[iface][1] = ixyz +
numCorner + 1;
1111 faces_vec[iface][2] = ixyz + 2;
1112 faces_vec[iface][3] = ixyz -
numCorner + 2;
1119 faces_vec[iface][0] = ixyz + 1;
1120 faces_vec[iface][1] = ixyz +
numCorner - nFaces + 1;
1121 faces_vec[iface][2] = ixyz +
numCorner - nFaces + 2;
1122 faces_vec[iface][3] = ixyz + 2;
1126 faces_vec[iface][0] = ixyz + 1;
1127 faces_vec[iface][1] = ixyz - nFaces +
numCorner + 1;
1128 faces_vec[iface][2] = ixyz - nFaces + 2;
1129 faces_vec[iface][3] = ixyz -
numCorner + 2;
1140 delete [] faces_vec;
1144 std::ostringstream message;
1145 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
1146 G4Exception(
"G4Polyhedra::CreatePolyhedron()",
"GeomSolids1002",
1171 : Start_angle(0.), Opening_angle(0.), numSide(0), Num_z_planes(0),
1172 Z_values(0), Rmin(0), Rmax(0)
1206 if ( &right ==
this )
return *
this;
CLHEP::Hep3Vector G4ThreeVector
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool MustBeOutside(const G4ThreeVector &p) const
G4PolyhedraHistorical & operator=(const G4PolyhedraHistorical &right)
G4ThreeVector GetPointOnSurface() const
std::ostream & StreamInfo(std::ostream &os) const
G4PolyhedraHistorical * original_parameters
const G4Polyhedra & operator=(const G4Polyhedra &source)
G4PolyhedraSideRZ * corners
G4Polyhedra(const G4String &name, G4double phiStart, G4double phiTotal, G4int numSide, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
void CopyStuff(const G4Polyhedra &source)
void Create(G4double phiStart, G4double phiTotal, G4int numSide, G4ReduciblePolygon *rz)
G4GeometryType GetEntityType() const
G4ThreeVector GetPointOnPlane(G4ThreeVector p0, G4ThreeVector p1, G4ThreeVector p2, G4ThreeVector p3) const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4NURBS * CreateNURBS() const
void SetOriginalParameters()
G4EnclosingCylinder * enclosingCylinder
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
EInside Inside(const G4ThreeVector &p) const
G4Polyhedron * CreatePolyhedron() const
G4ThreeVector GetPointOnTriangle(G4ThreeVector p0, G4ThreeVector p1, G4ThreeVector p2) const
G4bool RemoveDuplicateVertices(G4double tolerance)
G4int NumVertices() const
G4bool RemoveRedundantVertices(G4double tolerance)
G4bool CrossesItself(G4double tolerance)
void ScaleA(G4double scale)
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
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)