50#define G4MT_pcphix ((subInstanceManager.offset[instanceID]).fPhix)
51#define G4MT_pcphiy ((subInstanceManager.offset[instanceID]).fPhiy)
52#define G4MT_pcphiz ((subInstanceManager.offset[instanceID]).fPhiz)
53#define G4MT_pcphik ((subInstanceManager.offset[instanceID]).fPhik)
59 return subInstanceManager;
84 r[0] = tail->
r; z[0] = tail->
z;
85 r[1] = head->
r; z[1] = head->
z;
87 phiIsOpen = thePhiIsOpen;
90 deltaPhi = theDeltaPhi;
91 startPhi = thePhiStart;
96 while (deltaPhi < 0.0)
100 while (startPhi < 0.0)
112 tail->
r*std::sin(startPhi), tail->
z );
114 head->
r*std::sin(startPhi), head->
z );
116 tail->
r*std::sin(startPhi+deltaPhi), tail->
z );
118 head->
r*std::sin(startPhi+deltaPhi), head->
z );
126 allBehind = isAllBehind;
136 rS = r[1]-r[0]; zS = z[1]-z[0];
137 length = std::sqrt( rS*rS + zS*zS);
138 rS /= length; zS /= length;
145 prevRS = r[0]-prevRZ->
r;
146 prevZS = z[0]-prevRZ->
z;
147 lAdj = std::sqrt( prevRS*prevRS + prevZS*prevZS );
151 rNormEdge[0] = rNorm + prevZS;
152 zNormEdge[0] = zNorm - prevRS;
153 lAdj = std::sqrt( rNormEdge[0]*rNormEdge[0] + zNormEdge[0]*zNormEdge[0] );
154 rNormEdge[0] /= lAdj;
155 zNormEdge[0] /= lAdj;
157 nextRS = nextRZ->
r-r[1];
158 nextZS = nextRZ->
z-z[1];
159 lAdj = std::sqrt( nextRS*nextRS + nextZS*nextZS );
163 rNormEdge[1] = rNorm + nextZS;
164 zNormEdge[1] = zNorm - nextRS;
165 lAdj = std::sqrt( rNormEdge[1]*rNormEdge[1] + zNormEdge[1]*zNormEdge[1] );
166 rNormEdge[1] /= lAdj;
167 zNormEdge[1] /= lAdj;
174 : startPhi(0.), deltaPhi(0.),
175 rNorm(0.), zNorm(0.), rS(0.), zS(0.), length(0.),
176 prevRS(0.), prevZS(0.), nextRS(0.), nextZS(0.),
177 kCarTolerance(0.), instanceID(0)
181 rNormEdge[0]= rNormEdge[1] = 0.;
182 zNormEdge[0]= zNormEdge[1] = 0.;
190 if (phiIsOpen) {
delete [] corners; }
197 instanceID = subInstanceManager.CreateSubInstance();
206 if (
this == &source) {
return *
this; }
209 if (phiIsOpen) {
delete [] corners; }
225 startPhi = source.startPhi;
226 deltaPhi = source.deltaPhi;
227 phiIsOpen = source.phiIsOpen;
228 allBehind = source.allBehind;
231 fSurfaceArea = source.fSurfaceArea;
235 rNorm = source.rNorm;
236 zNorm = source.zNorm;
239 length = source.length;
240 prevRS = source.prevRS;
241 prevZS = source.prevZS;
242 nextRS = source.nextRS;
243 nextZS = source.nextZS;
245 rNormEdge[0] = source.rNormEdge[0];
246 rNormEdge[1] = source.rNormEdge[1];
247 zNormEdge[0] = source.zNormEdge[0];
248 zNormEdge[1] = source.zNormEdge[1];
255 corners[0] = source.corners[0];
256 corners[1] = source.corners[1];
257 corners[2] = source.corners[2];
258 corners[3] = source.corners[3];
274 G4double normSign = outgoing ? +1 : -1;
276 isAllBehind = allBehind;
281 G4int nside = cone->LineHitsCone( p, v, &s1, &s2 );
282 if (nside == 0) {
return false; }
289 if (PointOnCone( hit, normSign, p, v, normal ))
294 if (normSign*v.
dot(normal) > 0)
311 if (normSign*v.
dot(pNormal) > 0)
317 distFromSurface = -normSign*DistanceAway( p,
false, distOutside2 );
318 if (distOutside2 < surfTolerance*surfTolerance)
320 if (distFromSurface > -surfTolerance)
333 distFromSurface = s1;
347 if (nside==1) {
return false;
355 if (PointOnCone( hit, normSign, p, v, normal ))
360 if (normSign*v.
dot(normal) > 0)
365 if (normSign*v.
dot(pNormal) > 0)
368 distFromSurface = -normSign*DistanceAway( p,
false, distOutside2 );
369 if (distOutside2 < surfTolerance*surfTolerance)
371 if (distFromSurface > -surfTolerance)
380 distFromSurface = s2;
401 G4double normSign = outgoing ? -1 : +1;
407 distFrom = normSign*DistanceAway( p,
false, distOut2 );
408 if (distFrom > -0.5*kCarTolerance )
415 return std::sqrt( distFrom*distFrom + distOut2 );
417 return std::fabs(distFrom);
423 distFrom = normSign*DistanceAway( p,
true, distOut2 );
424 if (distFrom > -0.5*kCarTolerance)
428 return std::sqrt( distFrom*distFrom + distOut2 );
430 return std::fabs(distFrom);
445 distFrom = DistanceAway( p, distOut2, &edgeRZnorm );
446 dist2 = distFrom*distFrom + distOut2;
448 *bestDistance = std::sqrt( dist2);
452 if ( (std::fabs(edgeRZnorm) < tolerance)
453 && (distOut2< tolerance*tolerance) )
474 dFrom = DistanceAway( p,
false, dOut2 );
476 *bestDistance = std::sqrt( dFrom*dFrom + dOut2 );
479 if (rds!=0.) {
return {rNorm*p.
x()/rds,rNorm*p.
y()/rds,zNorm}; }
492 return axis.z() < 0 ? -cone->ZLo() : cone->ZHi();
501 while( phi < startPhi )
506 if (phi > deltaPhi+startPhi)
512 G4double cosP = std::cos(startPhi), sinP = std::sin(startPhi);
515 cosP = std::cos(startPhi+deltaPhi); sinP = std::sin(startPhi+deltaPhi);
524 if (bd > ad) { ad = bd; }
525 if (cd > ad) { ad = cd; }
526 if (dd > ad) { ad = dd; }
540 if (b > a) { a = b; }
568 G4int numPhi = (
G4int)(deltaPhi/kMeshAngleDefault) + 1;
583 G4double rFudge = 1.0/std::cos(0.5*sigPhi);
621 if ( prevRS*zS - prevZS*rS > 0 )
626 if (r[0] >
DBL_MIN) { r2 = r[0]*rFudge; }
633 FindLineIntersect( z0, r0, zS, rS,
634 z0, r0*rFudge, prevZS, prevRS*rFudge, z0, r0 );
638 if ( nextZS >
DBL_MIN && (rS*nextZS - zS*nextRS < 0) )
644 FindLineIntersect( z1, r1, zS, rS,
645 z1, r1*rFudge, nextZS, nextRS*rFudge, z1, r1 );
664 if ( prevRS*zS - prevZS*rS > 0 )
669 if (r[0] >
DBL_MIN) { r2 = r[0]; }
676 FindLineIntersect( z0, r0, zS, rS*rFudge,
677 z0, r[0], prevZS, prevRS, z0, r0 );
681 if ( nextZS < -
DBL_MIN && (rS*nextZS - zS*nextRS < 0) )
687 FindLineIntersect( z1, r1, zS, rS*rFudge,
688 z1, r[1], nextZS, nextRS, z1, r1 );
705 if (prevZS >
DBL_MIN) { r0 *= rFudge; }
706 if (nextZS >
DBL_MIN) { r1 *= rFudge; }
713 cosPhi = std::cos(phi),
714 sinPhi = std::sin(phi);
717 v1( r1*cosPhi, r1*sinPhi, z1 ),
731 if (numPhi == 1) { phi = startPhi+deltaPhi; }
732 cosPhi = std::cos(phi),
733 sinPhi = std::sin(phi);
796 }
while( --numPhi > 0 );
804 if (phiIsOpen && rNorm >
DBL_MIN)
806 cosPhi = std::cos(startPhi);
807 sinPhi = std::sin(startPhi);
810 a1( r[1]*cosPhi, r[1]*sinPhi, z[1] ),
811 b0( r0*cosPhi, r0*sinPhi, z[0] ),
812 b1( r1*cosPhi, r1*sinPhi, z[1] );
834 cosPhi = std::cos(startPhi+deltaPhi);
835 sinPhi = std::sin(startPhi+deltaPhi);
919 if (opposite) { rx = -rx; }
924 G4double deltaR = rx - r[0], deltaZ = zx - z[0];
925 G4double answer = deltaR*rNorm + deltaZ*zNorm;
934 if (edgeRZnorm !=
nullptr)
936 *edgeRZnorm = deltaR*rNormEdge[0] + deltaZ*zNormEdge[0];
941 distOutside2 =
sqr( q-length );
942 if (edgeRZnorm !=
nullptr)
946 *edgeRZnorm = deltaR*rNormEdge[1] + deltaZ*zNormEdge[1];
952 if (edgeRZnorm !=
nullptr) { *edgeRZnorm = answer; }
961 while( phi < startPhi )
966 if (phi > startPhi+deltaPhi)
971 G4double d1 = phi-startPhi-deltaPhi;
972 while( phi > startPhi )
978 if (d2 < d1) { d1 = d2; }
985 distOutside2 += dist*dist;
986 if (edgeRZnorm !=
nullptr)
988 *edgeRZnorm = std::max(std::fabs(*edgeRZnorm),std::fabs(dist));
1014 if (rx < 0) { part = -1; }
1019 G4double deltaR = rx - r[0]*part, deltaZ = zx - z[0];
1020 G4double answer = deltaR*rNorm*part + deltaZ*zNorm;
1025 G4double q = deltaR*rS*part + deltaZ*zS;
1029 if (edgeRZnorm !=
nullptr)
1031 *edgeRZnorm = deltaR*rNormEdge[0]*part + deltaZ*zNormEdge[0];
1034 else if (q > length)
1036 distOutside2 =
sqr( q-length );
1037 if (edgeRZnorm !=
nullptr)
1039 deltaR = rx - r[1]*part;
1041 *edgeRZnorm = deltaR*rNormEdge[1]*part + deltaZ*zNormEdge[1];
1047 if (edgeRZnorm !=
nullptr) { *edgeRZnorm = answer; }
1056 while( phi < startPhi )
1061 if (phi > startPhi+deltaPhi)
1066 G4double d1 = phi-startPhi-deltaPhi;
1067 while( phi > startPhi )
1073 if (d2 < d1) { d1 = d2; }
1080 distOutside2 += dist*dist;
1081 if (edgeRZnorm !=
nullptr)
1083 *edgeRZnorm = std::max(std::fabs(*edgeRZnorm),std::fabs(dist));
1105 if (!cone->HitOn( rx, hit.
z() )) {
return false; }
1109 G4double phiTolerant = 2.0*kCarTolerance/(rx+kCarTolerance);
1116 while( phi < startPhi-phiTolerant )
1121 if (phi > startPhi+deltaPhi+phiTolerant) {
return false; }
1123 if (phi > startPhi+deltaPhi-phiTolerant)
1130 qb = qx - corners[3];
1133 if (normSign*qacb.
dot(v) < 0) {
return false; }
1135 else if (phi < phiTolerant)
1139 qb = qx - corners[0];
1142 if (normSign*qacb.
dot(v) < 0) {
return false; }
1178 G4double deter = tx1*ty2 - tx2*ty1;
1180 G4double s1 = ((x2-x1)*ty2 - tx2*(y2-y1))/deter;
1181 G4double s2 = ((x2-x1)*ty1 - tx1*(y2-y1))/deter;
1187 x = 0.5*( x1+s1*tx1 + x2+s2*tx2 );
1188 y = 0.5*( y1+s1*ty1 + y2+s2*ty2 );
1195 if(fSurfaceArea==0.)
1197 fSurfaceArea = (r[0]+r[1])* std::sqrt(
sqr(r[0]-r[1])+
sqr(z[0]-z[1]));
1198 fSurfaceArea *= 0.5*(deltaPhi);
1200 return fSurfaceArea;
1209 dr=r[1]-r[0];dz=z[1]-z[0];
1230 zz = z[0]+(rr-r[0])*dz/dr;
const G4double kCarTolerance
G4GeomSplitter< G4PlSideData > G4PlSideManager
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 ...
G4PolyconeSide is a utility class implementing a face that represents one conical side of a polycone.
void CalculateExtent(const EAxis axis, const G4VoxelLimits &voxelLimit, const G4AffineTransform &tranform, G4SolidExtentList &extentList) override
~G4PolyconeSide() override
G4ThreeVector GetPointOnFace() override
G4PolyconeSide(const G4PolyconeSideRZ *prevRZ, const G4PolyconeSideRZ *tail, const G4PolyconeSideRZ *head, const G4PolyconeSideRZ *nextRZ, G4double phiStart, G4double deltaPhi, G4bool phiIsOpen, G4bool isAllBehind=false)
G4ThreeVector Normal(const G4ThreeVector &p, G4double *bestDistance) override
G4double SurfaceArea() override
EInside Inside(const G4ThreeVector &p, G4double tolerance, G4double *bestDistance) override
G4double Distance(const G4ThreeVector &p, G4bool outgoing) override
G4bool Intersect(const G4ThreeVector &p, const G4ThreeVector &v, G4bool outgoing, G4double surfTolerance, G4double &distance, G4double &distFromSurface, G4ThreeVector &normal, G4bool &isAllBehind) override
static const G4PlSideManager & GetSubInstanceManager()
G4double Extent(const G4ThreeVector axis) override
G4PolyconeSide & operator=(const G4PolyconeSide &source)
G4SolidExtentList is utility class designed for calculating the extent of a CSG-like solid for a voxe...
void AddSurface(const G4ClippablePolygon &surface)
G4VoxelLimits represents limitation/restrictions of space, where restrictions are only made perpendic...
const G4int kMaxMeshSections
const G4int kMinMeshSections
const axis_t axis_to_type< N >::axis