49#define G4MT_phphix ((subInstanceManager.offset[instanceID]).fPhix)
50#define G4MT_phphiy ((subInstanceManager.offset[instanceID]).fPhiy)
51#define G4MT_phphiz ((subInstanceManager.offset[instanceID]).fPhiz)
52#define G4MT_phphik ((subInstanceManager.offset[instanceID]).fPhik)
58 return subInstanceManager;
85 r[0] = tail->
r; z[0] = tail->
z;
86 r[1] = head->
r; z[1] = head->
z;
93 startPhi = thePhiStart;
94 while (startPhi < 0.0)
99 phiIsOpen = thePhiIsOpen;
100 phiTotal = (phiIsOpen) ? thePhiTotal : twopi;
102 allBehind = isAllBehind;
112 numSide = theNumSide>0 ? theNumSide : 1;
113 deltaPhi = phiTotal/numSide;
114 endPhi = startPhi+phiTotal;
116 const std::size_t maxSides = numSide;
117 vecs =
new G4PolyhedraSideVec[maxSides];
118 edges =
new G4PolyhedraSideEdge[phiIsOpen ? maxSides+1 : maxSides];
124 G4ThreeVector a1( r[0]*std::cos(phi), r[0]*std::sin(phi), z[0] ),
125 b1( r[1]*std::cos(phi), r[1]*std::sin(phi), z[1] ),
126 c1( prevRZ->
r*std::cos(phi), prevRZ->
r*std::sin(phi), prevRZ->
z ),
127 d1( nextRZ->
r*std::cos(phi), nextRZ->
r*std::sin(phi), nextRZ->
z ),
129 G4PolyhedraSideEdge *edge = edges;
131 G4PolyhedraSideVec *vec = vecs;
138 a2 =
G4ThreeVector( r[0]*std::cos(phi), r[0]*std::sin(phi), z[0] );
139 b2 =
G4ThreeVector( r[1]*std::cos(phi), r[1]*std::sin(phi), z[1] );
140 c2 =
G4ThreeVector( prevRZ->
r*std::cos(phi), prevRZ->
r*std::sin(phi), prevRZ->
z );
141 d2 =
G4ThreeVector( nextRZ->
r*std::cos(phi), nextRZ->
r*std::sin(phi), nextRZ->
z );
150 vec->center = 0.25*( a1 + a2 + b1 + b2 );
152 tt = b2 + b1 - a2 - a1;
153 vec->surfRZ = tt.
unit();
154 if (vec==vecs) { lenRZ = 0.25*tt.
mag(); }
156 tt = b2 - b1 + a2 - a1;
157 vec->surfPhi = tt.
unit();
160 lenPhi[0] = 0.25*tt.
mag();
162 lenPhi[1] = (0.5*tt.
mag()-lenPhi[0])/lenRZ;
165 tt = vec->surfPhi.
cross(vec->surfRZ);
166 vec->normal = tt.
unit();
185 adj = 0.5*(c1+c2-a1-a2);
186 adj = adj.
cross(a12);
187 adj = adj.
unit() + vec->normal;
188 vec->edgeNorm[0] = adj.
unit();
191 adj = 0.5*(d1+d2-b1-b2);
192 adj = adj.
cross(a12);
193 adj = adj.
unit() + vec->normal;
194 vec->edgeNorm[1] = adj.
unit();
201 vec->edges[0] = edge;
202 edge->corner[0] = a1;
203 edge->corner[1] = b1;
205 vec->edges[1] = edge;
211 }
while( ++vec < vecs+maxSides );
218 edge->corner[0] = a2;
219 edge->corner[1] = b2;
223 vecs[maxSides-1].edges[1] = edges;
230 G4PolyhedraSideVec *prev = vecs+maxSides-1;
233 edge = vec->edges[0];
239 edge->normal = eNorm.
unit();
248 eNorm = vec->edgeNorm[0] + prev->edgeNorm[0];
249 edge->cornNorm[0] = eNorm.
unit();
251 eNorm = vec->edgeNorm[1] + prev->edgeNorm[1];
252 edge->cornNorm[1] = eNorm.
unit();
253 }
while( prev=vec, ++vec < vecs + maxSides );
269 - vec->edges[0]->corner[1];
270 normvec = normvec.
cross(vec->normal);
271 if (normvec.
dot(vec->surfPhi) > 0) { normvec = -normvec; }
273 vec->edges[0]->normal = normvec.
unit();
275 vec->edges[0]->cornNorm[0] = (vec->edges[0]->corner[0]
276 - vec->center).unit();
277 vec->edges[0]->cornNorm[1] = (vec->edges[0]->corner[1]
278 - vec->center).unit();
283 vec = vecs + maxSides - 1;
285 normvec = vec->edges[1]->corner[0] - vec->edges[1]->corner[1];
286 normvec = normvec.
cross(vec->normal);
287 if (normvec.
dot(vec->surfPhi) < 0) { normvec = -normvec; }
289 vec->edges[1]->normal = normvec.
unit();
291 vec->edges[1]->cornNorm[0] = (vec->edges[1]->corner[0]
292 - vec->center).unit();
293 vec->edges[1]->cornNorm[1] = (vec->edges[1]->corner[1]
294 - vec->center).unit();
302 edgeNorm = 1.0/std::sqrt( 1.0 + lenPhi[1]*lenPhi[1] );
309 : startPhi(0.), deltaPhi(0.), endPhi(0.),
310 lenRZ(0.), edgeNorm(0.), kCarTolerance(0.), instanceID(0)
314 lenPhi[0] = lenPhi[1] = 0.;
331 instanceID = subInstanceManager.CreateSubInstance();
342 if (
this == &source) {
return *
this; }
364 numSide = source.numSide;
365 startPhi = source.startPhi;
366 deltaPhi = source.deltaPhi;
367 endPhi = source.endPhi;
368 phiIsOpen = source.phiIsOpen;
369 allBehind = source.allBehind;
371 lenRZ = source.lenRZ;
372 lenPhi[0] = source.lenPhi[0];
373 lenPhi[1] = source.lenPhi[1];
374 edgeNorm = source.edgeNorm;
377 fSurfaceArea = source.fSurfaceArea;
384 const std::size_t numSides = (numSide > 0) ? numSide : 1;
385 const std::size_t numEdges = phiIsOpen ? numSides+1 : numSides;
386 edges =
new G4PolyhedraSideEdge[numEdges];
388 G4PolyhedraSideEdge *edge = edges,
389 *sourceEdge = source.edges;
393 }
while( ++sourceEdge, ++edge < edges + numEdges);
398 vecs =
new G4PolyhedraSideVec[numSides];
400 G4PolyhedraSideVec *vec = vecs,
401 *sourceVec = source.vecs;
405 vec->edges[0] = edges + (sourceVec->edges[0] - source.edges);
406 vec->edges[1] = edges + (sourceVec->edges[1] - source.edges);
407 }
while( ++sourceVec, ++vec < vecs + numSides );
459 G4double normSign = outgoing ? +1 : -1;
492 G4PolyhedraSideVec* vec = vecs;
499 if (dotProd <= 0) {
continue; }
505 distFromSurface = -normSign*delta.
dot(vec->normal);
507 if (distFromSurface < -surfTolerance) {
continue; }
521 if (normSign*qc.
cross(qd).
dot(v) < 0) {
continue; }
526 if (normSign*qa.
cross(qb).
dot(v) > 0) {
continue; }
533 if (r[0] > 1/kInfinity && normSign*qa.
cross(qc).
dot(v) < 0) {
return false; }
534 if (r[1] > 1/kInfinity && normSign*qb.
cross(qd).
dot(v) > 0) {
return false; }
541 if (distFromSurface < 0)
546 if (std::fabs(rz) > lenRZ+surfTolerance) {
return false; }
549 if (std::fabs(pp) > lenPhi[0]+lenPhi[1]*rz+surfTolerance) {
return false; }
556 distance = distFromSurface/dotProd;
557 normal = vec->normal;
558 isAllBehind = allBehind;
560 }
while( ++vec, ++face < numSide );
572 G4double normSign = outgoing ? -1 : +1;
577 G4int iPhi = ClosestPhiSegment( GetPhi(p) );
582 if (normSign*normDist > -0.5*kCarTolerance)
584 return DistanceAway( p, vecs[iPhi], &normDist );
608 G4int iPhi = ClosestPhiSegment( GetPhi(p) );
615 *bestDistance = DistanceToOneSide( p, vecs[iPhi], &norm );
620 if ( (std::fabs(norm) > tolerance) || (*bestDistance > 2.0*tolerance) )
635 G4int iPhi = ClosestPhiSegment( GetPhi(p) );
641 *bestDistance = DistanceToOneSide( p, vecs[iPhi], &norm );
643 return vecs[iPhi].normal;
655 return axis.z() < 0 ? -cone->ZLo() : cone->ZHi();
665 iPhi = PhiSegment( GetPhi(
axis) );
673 i1 = 0; i2 = numSide-1;
680 i1 = iPhi; i2 = iPhi;
683 list[0] = vecs[i1].edges[0]->corner;
684 list[1] = vecs[i1].edges[0]->corner+1;
685 list[2] = vecs[i2].edges[1]->corner;
686 list[3] = vecs[i2].edges[1]->corner+1;
696 if (answer > best) { best = answer; }
697 }
while( ++vec < list+4 );
714 G4PolyhedraSideVec *vec = vecs;
724 TransformPoint(vec->edges[0]->corner[0]));
726 TransformPoint(vec->edges[0]->corner[1]));
728 TransformPoint(vec->edges[1]->corner[1]));
730 TransformPoint(vec->edges[1]->corner[0]));
744 }
while( ++vec < vecs+numSide );
777 const G4PolyhedraSideVec& vec,
789 if (dotProd <= 0) {
return false; }
796 distFromSurface = -normSign*delta.
dot(vec.normal);
798 if (distFromSurface < -surfTolerance) {
return false; }
804 distance = distFromSurface/dotProd;
826 if (r[0]==0) {
return true; }
828 if (atRZ < -lenRZ*1.2) {
return false; }
832 qb = q - vec.edges[1]->corner[0];
834 if (normSign*qacb.
dot(v) < 0) {
return false; }
836 if (distFromSurface < 0)
838 if (atRZ < -lenRZ-surfTolerance) {
return false; }
843 if (r[1]==0) {
return true; }
845 if (atRZ > lenRZ*1.2) {
return false; }
849 qb = q - vec.edges[1]->corner[1];
851 if (normSign*qacb.
dot(v) >= 0) {
return false; }
853 if (distFromSurface < 0)
855 if (atRZ > lenRZ+surfTolerance) {
return false; }
876 G4int n = cone->LineHitsCone( p, v, &s1, &s2 );
878 if (n==0) {
return 0; }
883 *i1 = PhiSegment( std::atan2( p.
y() + s1*v.
y(), p.
x() + s1*v.
x() ) );
886 return (*i1 < 0) ? 0 : 1;
892 *i2 = PhiSegment( std::atan2( p.
y() + s2*v.
y(), p.
x() + s2*v.
x() ) );
893 if (*i1 == *i2) {
return 0; }
897 if (*i2 < 0) {
return 0; }
902 if (*i2 < 0) {
return 1;
933 auto answer = (
G4int)(phi/deltaPhi);
935 if (answer >= numSide)
954 G4int iPhi = PhiSegment( phi0 );
955 if (iPhi >= 0) {
return iPhi; }
963 while( phi < startPhi )
969 while( phi > startPhi )
975 return (d2 < d1) ? 0 : numSide-1;
1011 const G4PolyhedraSideVec& vec,
1019 *normDist = vec.normal.
dot(pct);
1024 return DistanceAway( p, vec, normDist );
1033 const G4PolyhedraSideVec& vec,
1062 if (pcDotRZ < -lenRZ)
1064 G4double lenPhiZ = lenPhi[0] - lenRZ*lenPhi[1];
1069 if (pcDotPhi < -lenPhiZ)
1074 G4double distOutPhi = pcDotPhi+lenPhiZ;
1075 distOut2 = distOutPhi*distOutPhi + distOutZ*distOutZ;
1077 *normDist = pa.
dot(vec.edges[0]->cornNorm[0]);
1079 else if (pcDotPhi > lenPhiZ)
1084 G4double distOutPhi = pcDotPhi-lenPhiZ;
1085 distOut2 = distOutPhi*distOutPhi + distOutZ*distOutZ;
1087 *normDist = pb.
dot(vec.edges[1]->cornNorm[0]);
1095 distOut2 = distOutZ*distOutZ;
1096 *normDist = pa.
dot(vec.edgeNorm[0]);
1099 else if (pcDotRZ > lenRZ)
1101 G4double lenPhiZ = lenPhi[0] + lenRZ*lenPhi[1];
1106 if (pcDotPhi < -lenPhiZ)
1111 G4double distOutPhi = pcDotPhi+lenPhiZ;
1112 distOut2 = distOutPhi*distOutPhi + distOutZ*distOutZ;
1114 *normDist = pd.
dot(vec.edges[0]->cornNorm[1]);
1116 else if (pcDotPhi > lenPhiZ)
1121 G4double distOutPhi = pcDotPhi-lenPhiZ;
1122 distOut2 = distOutPhi*distOutPhi + distOutZ*distOutZ;
1124 *normDist = pe.
dot(vec.edges[1]->cornNorm[1]);
1131 distOut2 = distOutZ*distOutZ;
1133 *normDist = pd.
dot(vec.edgeNorm[1]);
1138 G4double lenPhiZ = lenPhi[0] + pcDotRZ*lenPhi[1];
1142 if (pcDotPhi < -lenPhiZ)
1147 G4double distOut = edgeNorm*(pcDotPhi+lenPhiZ);
1148 distOut2 = distOut*distOut;
1150 *normDist = pd.
dot(vec.edges[0]->normal);
1152 else if (pcDotPhi > lenPhiZ)
1157 G4double distOut = edgeNorm*(pcDotPhi-lenPhiZ);
1158 distOut2 = distOut*distOut;
1160 *normDist = pe.
dot(vec.edges[1]->normal);
1167 return std::fabs(distFaceNorm);
1170 return std::sqrt( distFaceNorm*distFaceNorm + distOut2 );
1188 *p4=p2 + lambda1*w + lambda2*v;
1203 aOne = SurfaceTriangle(p0,p1,p2,&point1);
1204 aTwo = SurfaceTriangle(p2,p3,p0,&point2);
1208 if( (chose>=0.) && (chose < aOne) )
1219 if( fSurfaceArea==0. )
1226 G4PolyhedraSideVec* vec = vecs;
1235 v1=vec->edges[0]->corner[0];
1236 v2=vec->edges[0]->corner[1];
1237 v3=vec->edges[1]->corner[1];
1238 v4=vec->edges[1]->corner[0];
1239 point1=GetPointOnPlane(v1,v2,v3,v4,&area);
1241 }
while( ++vec < vecs + numSide);
1245 return fSurfaceArea;
1254 std::vector<G4double>areas;
1255 std::vector<G4ThreeVector>points;
1260 G4PolyhedraSideVec* vec = vecs;
1268 v1=vec->edges[0]->corner[0];
1269 v2=vec->edges[0]->corner[1];
1270 v3=vec->edges[1]->corner[1];
1271 v4=vec->edges[1]->corner[0];
1272 point1=GetPointOnPlane(v1,v2,v3,v4,&result1);
1273 points.push_back(point1);
1274 areas.push_back(result1);
1276 }
while( ++vec < vecs+numSide );
1286 if(chose>=Achose1 && chose<Achose2)
1288 point1=points[i] ;
break;
1290 ++i; Achose1=Achose2;
1291 }
while( i<numSide );
const G4double kCarTolerance
G4GeomSplitter< G4PhSideData > G4PhSideManager
G4double G4QuickRand(uint32_t seed=0)
CLHEP::Hep3Vector G4ThreeVector
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
G4ClippablePolygon in a utility class defining a polygon that can be clipped by a voxel.
G4bool PartialClip(const G4VoxelLimits &voxelLimit, const EAxis IgnoreMe)
void AddVertexInOrder(const G4ThreeVector &vertex)
void SetNormal(const G4ThreeVector &newNormal)
G4int CreateSubInstance()
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4IntersectingCone is a utility class used to calculate the intersection of an arbitrary line with a ...
G4PolyhedraSide is a utility class implementing a face that represents one segmented side of a polyhe...
G4ThreeVector Normal(const G4ThreeVector &p, G4double *bestDistance) override
static const G4PhSideManager & GetSubInstanceManager()
G4PolyhedraSide & operator=(const G4PolyhedraSide &source)
G4PolyhedraSide(const G4PolyhedraSideRZ *prevRZ, const G4PolyhedraSideRZ *tail, const G4PolyhedraSideRZ *head, const G4PolyhedraSideRZ *nextRZ, G4int numSide, G4double phiStart, G4double phiTotal, G4bool phiIsOpen, G4bool isAllBehind=false)
G4bool Intersect(const G4ThreeVector &p, const G4ThreeVector &v, G4bool outgoing, G4double surfTolerance, G4double &distance, G4double &distFromSurface, G4ThreeVector &normal, G4bool &allBehind) override
G4double SurfaceArea() override
EInside Inside(const G4ThreeVector &p, G4double tolerance, G4double *bestDistance) override
G4double Extent(const G4ThreeVector axis) override
G4double Distance(const G4ThreeVector &p, G4bool outgoing) override
void CalculateExtent(const EAxis axis, const G4VoxelLimits &voxelLimit, const G4AffineTransform &tranform, G4SolidExtentList &extentList) override
~G4PolyhedraSide() override
G4SolidExtentList is utility class designed for calculating the extent of a CSG-like solid for a voxe...
void AddSurface(const G4ClippablePolygon &surface)
virtual G4ThreeVector GetPointOnFace()=0
G4VoxelLimits represents limitation/restrictions of space, where restrictions are only made perpendic...
const axis_t axis_to_type< N >::axis