59 #if !defined(G4GEOM_USE_UPOLYHEDRA)
72 using namespace CLHEP;
91 std::ostringstream message;
92 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
93 <<
" No sides specified !";
94 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
102 if ( (phiTotal <=0) || (phiTotal >= twopi*(1-
DBL_EPSILON)) )
103 { phiTotal = twopi; }
104 G4double convertRad = std::cos(0.5*phiTotal/theNumSide);
120 for (i=0; i<numZPlanes; i++)
122 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
124 if( (rInner[i] > rOuter[i+1])
125 ||(rInner[i+1] > rOuter[i]) )
128 std::ostringstream message;
129 message <<
"Cannot create a Polyhedra with no contiguous segments."
131 <<
" Segments are not contiguous !" <<
G4endl
132 <<
" rMin[" << i <<
"] = " << rInner[i]
133 <<
" -- rMax[" << i+1 <<
"] = " << rOuter[i+1] <<
G4endl
134 <<
" rMin[" << i+1 <<
"] = " << rInner[i+1]
135 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
136 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
151 rz->
ScaleA( 1/convertRad );
156 Create( phiStart, phiTotal, theNumSide, rz );
176 std::ostringstream message;
177 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
178 <<
" No sides specified !";
179 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
185 Create( phiStart, phiTotal, theNumSide, rz );
209 if (rz->
Amin() < 0.0)
211 std::ostringstream message;
212 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
213 <<
" All R values must be >= 0 !";
214 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
224 std::ostringstream message;
225 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
226 <<
" R/Z cross section is zero or near zero: " << rzArea;
227 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
234 std::ostringstream message;
235 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
236 <<
" Too few unique R/Z values !";
237 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
243 std::ostringstream message;
244 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
245 <<
" R/Z segments cross !";
246 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
259 if ( (phiTotal <= 0) || (phiTotal > twopi*(1-
DBL_EPSILON)) )
271 endPhi = phiStart+phiTotal;
294 next->
r = iterRZ.
GetA();
295 next->
z = iterRZ.
GetB();
296 }
while( ++next, iterRZ.
Next() );
348 }
while( prev=corner, corner=next, corner >
corners );
378 phiIsOpen(false), genericPgon(false), numCorner(0), corners(0),
379 original_parameters(0), enclosingCylinder(0)
411 if (
this == &source)
return *
this;
481 std::ostringstream message;
482 message <<
"Solid " <<
GetName() <<
" built using generic construct."
483 <<
G4endl <<
"Not applicable to the generic construct !";
484 G4Exception(
"G4Polyhedra::Reset()",
"GeomSolids1001",
598 G4int oldprc = os.precision(16);
599 os <<
"-----------------------------------------------------------\n"
600 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
601 <<
" ===================================================\n"
602 <<
" Solid type: G4Polyhedra\n"
605 <<
" ending phi angle : " <<
endPhi/
degree <<
" degrees \n";
610 os <<
" number of Z planes: " << numPlanes <<
"\n"
612 for (i=0; i<numPlanes; i++)
614 os <<
" Z plane " << i <<
": "
617 os <<
" Tangent distances to inner surface (Rmin): \n";
618 for (i=0; i<numPlanes; i++)
620 os <<
" Z plane " << i <<
": "
623 os <<
" Tangent distances to outer surface (Rmax): \n";
624 for (i=0; i<numPlanes; i++)
626 os <<
" Z plane " << i <<
": "
630 os <<
" number of RZ points: " <<
numCorner <<
"\n"
631 <<
" RZ values (corners): \n";
637 os <<
"-----------------------------------------------------------\n";
638 os.precision(oldprc);
652 G4double lambda1, lambda2, chose,aOne,aTwo;
663 if( (chose>=0.) && (chose < aOne) )
667 return (p2+lambda1*v+lambda2*w);
672 return (p0+lambda1*t+lambda2*u);
691 return (p2 + lambda1*w + lambda2*v);
703 G4double chose, totArea=0., Achose1, Achose2,
704 rad1, rad2, sinphi1, sinphi2, cosphi1, cosphi2;
706 area, aTop=0., aBottom=0., zVal=0.;
709 std::vector<G4double> aVector1;
710 std::vector<G4double> aVector2;
711 std::vector<G4double> aVector3;
719 for(j=0; j<numPlanes-1; j++)
725 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
726 aVector1.push_back(area);
729 for(j=0; j<numPlanes-1; j++)
735 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
736 aVector2.push_back(area);
739 for(j=0; j<numPlanes-1; j++)
750 else { aVector3.push_back(0.); }
753 for(j=0; j<numPlanes-1; j++)
755 totArea +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
765 aTop = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
773 aBottom = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
777 Achose2 =
numSide*(aVector1[0]+aVector2[0])+2.*aVector3[0];
780 if( (chose >= 0.) && (chose < aTop + aBottom) )
783 rang = std::floor((chose-
startPhi)/ksi-0.01);
784 if(rang<0) { rang=0; }
785 rang = std::fabs(rang);
786 sinphi1 = std::sin(
startPhi+rang*ksi);
787 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
788 cosphi1 = std::cos(
startPhi+rang*ksi);
789 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
791 if(chose>=0. && chose<aTop)
811 for (j=0; j<numPlanes-1; j++)
813 if( ((chose >= Achose1) && (chose < Achose2)) || (j == numPlanes-2) )
817 Achose1 +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
818 Achose2 = Achose1 +
numSide*(aVector1[j+1]+aVector2[j+1])
828 totArea =
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
831 if( (chose>=0.) && (chose<
numSide*aVector1[j]) )
834 rang = std::floor((chose-
startPhi)/ksi-0.01);
835 if(rang<0) { rang=0; }
836 rang = std::fabs(rang);
839 sinphi1 = std::sin(
startPhi+rang*ksi);
840 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
841 cosphi1 = std::cos(
startPhi+rang*ksi);
842 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
854 else if ( (chose >=
numSide*aVector1[j])
855 && (chose <=
numSide*(aVector1[j]+aVector2[j])) )
858 rang = std::floor((chose-
startPhi)/ksi-0.01);
859 if(rang<0) { rang=0; }
860 rang = std::fabs(rang);
863 sinphi1 = std::sin(
startPhi+rang*ksi);
864 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
865 cosphi1 = std::cos(
startPhi+rang*ksi);
866 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
880 if( (chose>=0.) && (chose < 1.) )
955 typedef G4int int4[4];
962 std::vector<G4bool> chopped(
numCorner,
false);
963 std::vector<G4int*> triQuads;
966 while (remaining >= 3)
970 G4int A = -1, B = -1, C = -1;
971 G4int iStepper = iStarter;
974 if (A < 0) { A = iStepper; }
975 else if (B < 0) { B = iStepper; }
976 else if (C < 0) { C = iStepper; }
979 if (++iStepper >=
numCorner) iStepper = 0;
981 while (chopped[iStepper]);
983 while (C < 0 && iStepper != iStarter);
998 triQuads.push_back(tq);
1006 if (++iStarter >=
numCorner) { iStarter = 0; }
1008 while (chopped[iStarter]);
1016 faces_vec =
new int4[nFaces];
1020 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
1022 for (
size_t i = 0; i < triQuads.size(); ++i)
1035 a = triQuads[i][0] + addition;
1036 b = triQuads[i][2] + addition;
1037 c = triQuads[i][1] + addition;
1040 G4int bc = std::abs(c - b);
1041 G4int ca = std::abs(a - c);
1042 faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
1043 faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
1044 faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
1045 faces_vec[iface][3] = 0;
1052 xyz =
new double3[nNodes];
1060 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1061 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1063 if (iCorner < numCorner - 1)
1065 faces_vec[iface][0] = ixyz + 1;
1066 faces_vec[iface][1] = ixyz + numCorner + 1;
1067 faces_vec[iface][2] = ixyz + numCorner + 2;
1068 faces_vec[iface][3] = ixyz + 2;
1072 faces_vec[iface][0] = ixyz + 1;
1073 faces_vec[iface][1] = ixyz + numCorner + 1;
1074 faces_vec[iface][2] = ixyz + 2;
1075 faces_vec[iface][3] = ixyz - numCorner + 2;
1087 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1088 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1097 xyz =
new double3[nNodes];
1098 faces_vec =
new int4[nFaces];
1102 G4int ixyz = 0, iface = 0;
1107 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1108 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1110 if (iSide < numSide - 1)
1112 if (iCorner < numCorner - 1)
1114 faces_vec[iface][0] = ixyz + 1;
1115 faces_vec[iface][1] = ixyz + numCorner + 1;
1116 faces_vec[iface][2] = ixyz + numCorner + 2;
1117 faces_vec[iface][3] = ixyz + 2;
1121 faces_vec[iface][0] = ixyz + 1;
1122 faces_vec[iface][1] = ixyz + numCorner + 1;
1123 faces_vec[iface][2] = ixyz + 2;
1124 faces_vec[iface][3] = ixyz - numCorner + 2;
1129 if (iCorner < numCorner - 1)
1131 faces_vec[iface][0] = ixyz + 1;
1132 faces_vec[iface][1] = ixyz + numCorner - nFaces + 1;
1133 faces_vec[iface][2] = ixyz + numCorner - nFaces + 2;
1134 faces_vec[iface][3] = ixyz + 2;
1138 faces_vec[iface][0] = ixyz + 1;
1139 faces_vec[iface][1] = ixyz - nFaces + numCorner + 1;
1140 faces_vec[iface][2] = ixyz - nFaces + 2;
1141 faces_vec[iface][3] = ixyz - numCorner + 2;
1151 G4int problem = polyhedron->createPolyhedron(nNodes, nFaces, xyz, faces_vec);
1152 delete [] faces_vec;
1156 std::ostringstream message;
1157 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
1158 G4Exception(
"G4Polyhedra::CreatePolyhedron()",
"GeomSolids1002",
1174 G4bool isConvertible=
true;
1180 std::vector<G4double> Z;
1181 std::vector<G4double> Rmin;
1182 std::vector<G4double> Rmax;
1184 G4int countPlanes=1;
1195 Rmax.push_back (
corners[1].r);icurr=1;
1197 else if (Zprev ==
corners[numPlanes-1].z)
1199 Rmin.push_back(
corners[numPlanes-1].r);
1200 Rmax.push_back (
corners[0].r);
1206 Rmax.push_back (
corners[0].r);
1211 G4int inextr=0, inextl=0;
1212 for (
G4int i=0; i < numPlanes-2; i++)
1215 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1217 if((
corners[inextr].z >= Zmax) & (
corners[inextl].
z >= Zmax)) {
break; }
1232 Rmin.push_back(
corners[icurl].r);
1233 Rmax.push_back(Rmax[countPlanes-2]);
1234 Rmax[countPlanes-2]=
corners[icurl].
r;
1238 Rmin.push_back(
corners[inextl].r);
1239 Rmax.push_back(
corners[icurl].r);
1244 Rmin.push_back(
corners[inextl].r);
1245 Rmax.push_back (
corners[icurr].r + (Zleft-
corners[icurr].z)/difZr
1250 isConvertible=
false;
break;
1252 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1260 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1262 Rmin.push_back(
corners[inextl].r);
1263 Rmax.push_back (
corners[inextr].r);
1267 Z.push_back(Zright);
1276 Rmin.push_back(
corners[icurr].r);
1277 Rmax.push_back(
corners[inextr].r);
1281 Rmin.push_back(
corners[inextr].r);
1282 Rmax.push_back(
corners[icurr].r);
1283 Rmax[countPlanes-2]=
corners[inextr].
r;
1291 Rmax.push_back(
corners[inextr].r);
1292 Rmin.push_back (
corners[icurr].r);
1296 Rmax.push_back(
corners[inextr].r);
1304 isConvertible=
false;
break;
1314 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1318 Rmax.push_back(
corners[inextr].r);
1319 Rmin.push_back(
corners[inextl].r);
1323 Rmax.push_back(
corners[inextr].r);
1324 Rmin.push_back(
corners[inextl].r);
1337 for(
G4int j=0; j < countPlanes; j++)
1351 std::ostringstream message;
1353 <<
"cannot be converted to Polyhedra with (Rmin,Rmaz,Z) parameters!";
1354 G4Exception(
"G4Polyhedra::SetOriginalParameters()",
1363 for(
G4int j=0; j < numPlanes; j++)
void CopyStuff(const G4Polyhedra &source)
G4bool CrossesItself(G4double tolerance)
ThreeVector shoot(const G4int Ap, const G4int Af)
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
G4Polyhedron * fpPolyhedron
static const G4double kInfinity
CLHEP::Hep3Vector G4ThreeVector
G4GeometryType GetEntityType() const
G4PolyhedraHistorical * original_parameters
G4ThreeVector GetPointOnPlane(G4ThreeVector p0, G4ThreeVector p1, G4ThreeVector p2, G4ThreeVector p3) const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4PolyhedraSideRZ * corners
G4bool MustBeOutside(const G4ThreeVector &p) const
void Create(G4double phiStart, G4double phiTotal, G4int numSide, G4ReduciblePolygon *rz)
G4ThreeVector GetPointOnSurface() const
static double normal(HepRandomEngine *eptr)
G4bool RemoveDuplicateVertices(G4double tolerance)
G4EnclosingCylinder * enclosingCylinder
G4bool RemoveRedundantVertices(G4double tolerance)
G4ThreeVector GetPointOnSurfaceGeneric() const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4int NumVertices() const
void ScaleA(G4double scale)
static const G4double A[nN]
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
EInside Inside(const G4ThreeVector &p) const
G4Polyhedron * CreatePolyhedron() const
static const double degree
G4Polyhedra & operator=(const G4Polyhedra &source)
void SetOriginalParameters(G4PolyhedraHistorical *pars)
G4ThreeVector GetPointOnTriangle(G4ThreeVector p0, G4ThreeVector p1, G4ThreeVector p2) const
virtual EInside Inside(const G4ThreeVector &p) const
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
std::ostream & StreamInfo(std::ostream &os) const
G4Polyhedra(const G4String &name, G4double phiStart, G4double phiTotal, G4int numSide, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
virtual G4Polyhedron * GetPolyhedron() const