Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PolyhedraSide Class Reference

G4PolyhedraSide is a utility class implementing a face that represents one segmented side of a polyhedra. More...

#include <G4PolyhedraSide.hh>

Inheritance diagram for G4PolyhedraSide:

Public Member Functions

 G4PolyhedraSide (const G4PolyhedraSideRZ *prevRZ, const G4PolyhedraSideRZ *tail, const G4PolyhedraSideRZ *head, const G4PolyhedraSideRZ *nextRZ, G4int numSide, G4double phiStart, G4double phiTotal, G4bool phiIsOpen, G4bool isAllBehind=false)
 ~G4PolyhedraSide () override
 G4PolyhedraSide (const G4PolyhedraSide &source)
G4PolyhedraSideoperator= (const G4PolyhedraSide &source)
G4bool Intersect (const G4ThreeVector &p, const G4ThreeVector &v, G4bool outgoing, G4double surfTolerance, G4double &distance, G4double &distFromSurface, G4ThreeVector &normal, G4bool &allBehind) override
G4double Distance (const G4ThreeVector &p, G4bool outgoing) override
EInside Inside (const G4ThreeVector &p, G4double tolerance, G4double *bestDistance) override
G4ThreeVector Normal (const G4ThreeVector &p, G4double *bestDistance) override
G4double Extent (const G4ThreeVector axis) override
void CalculateExtent (const EAxis axis, const G4VoxelLimits &voxelLimit, const G4AffineTransform &tranform, G4SolidExtentList &extentList) override
G4VCSGfaceClone () override
G4double SurfaceArea () override
 G4PolyhedraSide (__void__ &)
G4int GetInstanceID () const
Public Member Functions inherited from G4VCSGface
 G4VCSGface ()=default
virtual ~G4VCSGface ()=default

Static Public Member Functions

static const G4PhSideManagerGetSubInstanceManager ()

Friends

struct sG4PolyhedraSideVec

Detailed Description

G4PolyhedraSide is a utility class implementing a face that represents one segmented side of a polyhedra.

Definition at line 90 of file G4PolyhedraSide.hh.

Constructor & Destructor Documentation

◆ G4PolyhedraSide() [1/3]

G4PolyhedraSide::G4PolyhedraSide ( const G4PolyhedraSideRZ * prevRZ,
const G4PolyhedraSideRZ * tail,
const G4PolyhedraSideRZ * head,
const G4PolyhedraSideRZ * nextRZ,
G4int numSide,
G4double phiStart,
G4double phiTotal,
G4bool phiIsOpen,
G4bool isAllBehind = false )

Constructor for the segmented side of a polyhedra.

Parameters
[in]prevRZPointer to previous r,Z section.
[in]tailPointer to r,Z tail of section.
[in]headPointer to r,Z head of section.
[in]nextRZPointer to next r,Z section.
[in]numSideThe number od sides.
[in]phiStartInitial Phi starting angle.
[in]phiTotalTotal Phi angle.
[in]phiIsOpenFlag indicating if it is a Phi section.
[in]isAllBehindIndicating if entire surface is behind normal.

Definition at line 66 of file G4PolyhedraSide.cc.

75{
76 instanceID = subInstanceManager.CreateSubInstance();
77
79 G4MT_phphix = 0.0; G4MT_phphiy = 0.0; G4MT_phphiz = 0.0;
80 G4MT_phphik = 0.0;
81
82 //
83 // Record values
84 //
85 r[0] = tail->r; z[0] = tail->z;
86 r[1] = head->r; z[1] = head->z;
87
88 G4double phiTotal;
89
90 //
91 // Set phi to our convention
92 //
93 startPhi = thePhiStart;
94 while (startPhi < 0.0) // Loop checking, 13.08.2015, G.Cosmo
95 {
96 startPhi += twopi;
97 }
98
99 phiIsOpen = thePhiIsOpen;
100 phiTotal = (phiIsOpen) ? thePhiTotal : twopi;
101
102 allBehind = isAllBehind;
103
104 //
105 // Make our intersecting cone
106 //
107 cone = new G4IntersectingCone( r, z );
108
109 //
110 // Construct side plane vector set
111 //
112 numSide = theNumSide>0 ? theNumSide : 1;
113 deltaPhi = phiTotal/numSide;
114 endPhi = startPhi+phiTotal;
115
116 const std::size_t maxSides = numSide;
117 vecs = new G4PolyhedraSideVec[maxSides];
118 edges = new G4PolyhedraSideEdge[phiIsOpen ? maxSides+1 : maxSides];
119
120 //
121 // ...this is where we start
122 //
123 G4double phi = startPhi;
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 ),
128 a2, b2, c2, d2;
129 G4PolyhedraSideEdge *edge = edges;
130
131 G4PolyhedraSideVec *vec = vecs;
132 do // Loop checking, 13.08.2015, G.Cosmo
133 {
134 //
135 // ...this is where we are going
136 //
137 phi += deltaPhi;
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 );
142
143 G4ThreeVector tt;
144
145 //
146 // ...build some relevant vectors.
147 // the point is to sacrifice a little memory with precalcs
148 // to gain speed
149 //
150 vec->center = 0.25*( a1 + a2 + b1 + b2 );
151
152 tt = b2 + b1 - a2 - a1;
153 vec->surfRZ = tt.unit();
154 if (vec==vecs) { lenRZ = 0.25*tt.mag(); }
155
156 tt = b2 - b1 + a2 - a1;
157 vec->surfPhi = tt.unit();
158 if (vec==vecs)
159 {
160 lenPhi[0] = 0.25*tt.mag();
161 tt = b2 - b1;
162 lenPhi[1] = (0.5*tt.mag()-lenPhi[0])/lenRZ;
163 }
164
165 tt = vec->surfPhi.cross(vec->surfRZ);
166 vec->normal = tt.unit();
167
168 //
169 // ...edge normals are the average of the normals of
170 // the two faces they connect.
171 //
172 // ...edge normals are necessary if we are to accurately
173 // decide if a point is "inside" a face. For non-convex
174 // shapes, it is absolutely necessary to know information
175 // on adjacent faces to accurate determine this.
176 //
177 // ...we don't need them for the phi edges, since that
178 // information is taken care of internally. The r/z edges,
179 // however, depend on the adjacent G4PolyhedraSide.
180 //
181 G4ThreeVector a12, adj;
182
183 a12 = a2-a1;
184
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();
189
190 a12 = b1-b2;
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();
195
196 //
197 // ...the corners are crucial. It is important that
198 // they are calculated consistently for adjacent
199 // G4PolyhedraSides, to avoid gaps caused by roundoff.
200 //
201 vec->edges[0] = edge;
202 edge->corner[0] = a1;
203 edge->corner[1] = b1;
204 edge++;
205 vec->edges[1] = edge;
206
207 a1 = a2;
208 b1 = b2;
209 c1 = c2;
210 d1 = d2;
211 } while( ++vec < vecs+maxSides );
212
213 //
214 // Clean up hanging edge
215 //
216 if (phiIsOpen)
217 {
218 edge->corner[0] = a2;
219 edge->corner[1] = b2;
220 }
221 else
222 {
223 vecs[maxSides-1].edges[1] = edges;
224 }
225
226 //
227 // Go back and fill in remaining fields in edges
228 //
229 vec = vecs;
230 G4PolyhedraSideVec *prev = vecs+maxSides-1;
231 do // Loop checking, 13.08.2015, G.Cosmo
232 {
233 edge = vec->edges[0]; // The edge between prev and vec
234
235 //
236 // Okay: edge normal is average of normals of adjacent faces
237 //
238 G4ThreeVector eNorm = vec->normal + prev->normal;
239 edge->normal = eNorm.unit();
240
241 //
242 // Vertex normal is average of norms of adjacent surfaces (all four)
243 // However, vec->edgeNorm is unit vector in some direction
244 // as the sum of normals of adjacent PolyhedraSide with vec.
245 // The normalization used for this vector should be the same
246 // for vec and prev.
247 //
248 eNorm = vec->edgeNorm[0] + prev->edgeNorm[0];
249 edge->cornNorm[0] = eNorm.unit();
250
251 eNorm = vec->edgeNorm[1] + prev->edgeNorm[1];
252 edge->cornNorm[1] = eNorm.unit();
253 } while( prev=vec, ++vec < vecs + maxSides );
254
255 if (phiIsOpen)
256 {
257 // G4double rFact = std::cos(0.5*deltaPhi);
258 //
259 // If phi is open, we need to patch up normals of the
260 // first and last edges and their corresponding
261 // vertices.
262 //
263 // We use vectors that are in the plane of the
264 // face. This should be safe.
265 //
266 vec = vecs;
267
268 G4ThreeVector normvec = vec->edges[0]->corner[0]
269 - vec->edges[0]->corner[1];
270 normvec = normvec.cross(vec->normal);
271 if (normvec.dot(vec->surfPhi) > 0) { normvec = -normvec; }
272
273 vec->edges[0]->normal = normvec.unit();
274
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();
279
280 //
281 // Repeat for ending phi
282 //
283 vec = vecs + maxSides - 1;
284
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; }
288
289 vec->edges[1]->normal = normvec.unit();
290
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();
295 }
296
297 //
298 // edgeNorm is the factor one multiplies the distance along vector phi
299 // on the surface of one of our sides in order to calculate the distance
300 // from the edge. (see routine DistanceAway)
301 //
302 edgeNorm = 1.0/std::sqrt( 1.0 + lenPhi[1]*lenPhi[1] );
303}
#define G4MT_phphix
#define G4MT_phphiz
#define G4MT_phphiy
#define G4MT_phphik
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
Hep3Vector unit() const
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
double mag() const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()

Referenced by Clone(), G4PolyhedraSide(), and operator=().

◆ ~G4PolyhedraSide()

G4PolyhedraSide::~G4PolyhedraSide ( )
override

Destructor.

Definition at line 320 of file G4PolyhedraSide.cc.

321{
322 delete cone;
323 delete [] vecs;
324 delete [] edges;
325}

◆ G4PolyhedraSide() [2/3]

G4PolyhedraSide::G4PolyhedraSide ( const G4PolyhedraSide & source)

Copy constructor and assignment operator.

Definition at line 329 of file G4PolyhedraSide.cc.

330{
331 instanceID = subInstanceManager.CreateSubInstance();
332
333 CopyStuff( source );
334}

◆ G4PolyhedraSide() [3/3]

G4PolyhedraSide::G4PolyhedraSide ( __void__ & )

Fake default constructor for usage restricted to direct object persistency for clients requiring preallocation of memory for persistifiable objects.

Definition at line 308 of file G4PolyhedraSide.cc.

309 : startPhi(0.), deltaPhi(0.), endPhi(0.),
310 lenRZ(0.), edgeNorm(0.), kCarTolerance(0.), instanceID(0)
311{
312 r[0] = r[1] = 0.;
313 z[0] = z[1] = 0.;
314 lenPhi[0] = lenPhi[1] = 0.;
315}
const G4double kCarTolerance

Member Function Documentation

◆ CalculateExtent()

void G4PolyhedraSide::CalculateExtent ( const EAxis axis,
const G4VoxelLimits & voxelLimit,
const G4AffineTransform & tranform,
G4SolidExtentList & extentList )
overridevirtual

Calculates the extent of the face for the voxel navigator.

Parameters
[in]axisThe axis in which to check the shapes 3D extent against.
[in]voxelLimitLimits along x, y, and/or z axes.
[in]tranformA coordinate transformation on which to apply to the shape before testing.
[out]extentListThe list of (voxel) extents along the axis.

Implements G4VCSGface.

Definition at line 706 of file G4PolyhedraSide.cc.

710{
711 //
712 // Loop over all sides
713 //
714 G4PolyhedraSideVec *vec = vecs;
715 do // Loop checking, 13.08.2015, G.Cosmo
716 {
717 //
718 // Fill our polygon with the four corners of
719 // this side, after the specified transformation
720 //
721 G4ClippablePolygon polygon;
722
723 polygon.AddVertexInOrder(transform.
724 TransformPoint(vec->edges[0]->corner[0]));
725 polygon.AddVertexInOrder(transform.
726 TransformPoint(vec->edges[0]->corner[1]));
727 polygon.AddVertexInOrder(transform.
728 TransformPoint(vec->edges[1]->corner[1]));
729 polygon.AddVertexInOrder(transform.
730 TransformPoint(vec->edges[1]->corner[0]));
731
732 //
733 // Get extent
734 //
735 if (polygon.PartialClip( voxelLimit, axis ))
736 {
737 //
738 // Get dot product of normal along target axis
739 //
740 polygon.SetNormal( transform.TransformAxis(vec->normal) );
741
742 extentList.AddSurface( polygon );
743 }
744 } while( ++vec < vecs+numSide );
745
746 return;
747}
G4bool PartialClip(const G4VoxelLimits &voxelLimit, const EAxis IgnoreMe)
void AddVertexInOrder(const G4ThreeVector &vertex)
void SetNormal(const G4ThreeVector &newNormal)
void AddSurface(const G4ClippablePolygon &surface)
const axis_t axis_to_type< N >::axis
Definition pugixml.cc:9668

◆ Clone()

G4VCSGface * G4PolyhedraSide::Clone ( )
inlineoverridevirtual

Method invoked by the copy constructor or the assignment operator. Its purpose is to return a pointer to a duplicate copy of the face.

Implements G4VCSGface.

Definition at line 203 of file G4PolyhedraSide.hh.

203{ return new G4PolyhedraSide( *this ); }
G4PolyhedraSide(const G4PolyhedraSideRZ *prevRZ, const G4PolyhedraSideRZ *tail, const G4PolyhedraSideRZ *head, const G4PolyhedraSideRZ *nextRZ, G4int numSide, G4double phiStart, G4double phiTotal, G4bool phiIsOpen, G4bool isAllBehind=false)

◆ Distance()

G4double G4PolyhedraSide::Distance ( const G4ThreeVector & p,
G4bool outgoing )
overridevirtual

Determines the distance of a point from either the inside or outside surfaces of the face.

Parameters
[in]pPosition.
[in]outgoingFlag, true, to consider only inside surfaces or false, to consider only outside surfaces.
Returns
The distance to the closest surface satisfying requirements or kInfinity if no such surface exists.

Implements G4VCSGface.

Definition at line 570 of file G4PolyhedraSide.cc.

571{
572 G4double normSign = outgoing ? -1 : +1;
573
574 //
575 // Try the closest phi segment first
576 //
577 G4int iPhi = ClosestPhiSegment( GetPhi(p) );
578
579 G4ThreeVector pdotc = p - vecs[iPhi].center;
580 G4double normDist = pdotc.dot(vecs[iPhi].normal);
581
582 if (normSign*normDist > -0.5*kCarTolerance)
583 {
584 return DistanceAway( p, vecs[iPhi], &normDist );
585 }
586
587 //
588 // Now we have an interesting problem... do we try to find the
589 // closest facing side??
590 //
591 // Considered carefully, the answer is no. We know that if we
592 // are asking for the distance out, we are supposed to be inside,
593 // and vice versa.
594 //
595
596 return kInfinity;
597}
int G4int
Definition G4Types.hh:85

◆ Extent()

G4double G4PolyhedraSide::Extent ( const G4ThreeVector axis)
overridevirtual

Returns the face extent along the axis.

Parameters
[in]axisUnit vector defining the direction.
Returns
The largest point along the given axis of the face's extent.

Implements G4VCSGface.

Definition at line 648 of file G4PolyhedraSide.cc.

649{
650 if (axis.perp2() < DBL_MIN)
651 {
652 //
653 // Special case
654 //
655 return axis.z() < 0 ? -cone->ZLo() : cone->ZHi();
656 }
657
658 G4int iPhi, i1, i2;
659 G4double best;
660 G4ThreeVector* list[4];
661
662 //
663 // Which phi segment, if any, does the axis belong to
664 //
665 iPhi = PhiSegment( GetPhi(axis) );
666
667 if (iPhi < 0)
668 {
669 //
670 // No phi segment? Check front edge of first side and
671 // last edge of second side
672 //
673 i1 = 0; i2 = numSide-1;
674 }
675 else
676 {
677 //
678 // Check all corners of matching phi side
679 //
680 i1 = iPhi; i2 = iPhi;
681 }
682
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;
687
688 //
689 // Who's biggest?
690 //
691 best = -kInfinity;
692 G4ThreeVector** vec = list;
693 do // Loop checking, 13.08.2015, G.Cosmo
694 {
695 G4double answer = (*vec)->dot(axis);
696 if (answer > best) { best = answer; }
697 } while( ++vec < list+4 );
698
699 return best;
700}
#define DBL_MIN
Definition templates.hh:54

◆ GetInstanceID()

G4int G4PolyhedraSide::GetInstanceID ( ) const
inline

Returns the instance ID.

Definition at line 220 of file G4PolyhedraSide.hh.

220{ return instanceID; }

◆ GetSubInstanceManager()

const G4PhSideManager & G4PolyhedraSide::GetSubInstanceManager ( )
static

Returns the private data instance manager.

Definition at line 56 of file G4PolyhedraSide.cc.

57{
58 return subInstanceManager;
59}

Referenced by G4SolidsWorkspace::G4SolidsWorkspace().

◆ Inside()

EInside G4PolyhedraSide::Inside ( const G4ThreeVector & p,
G4double tolerance,
G4double * bestDistance )
overridevirtual

Determines whether a point is inside, outside, or on the surface of the face.

Parameters
[in]pPosition.
[in]toleranceTolerance defining the bounds of the "kSurface", nominally equal to kCarTolerance/2.
[out]bestDistanceDistance to the closest surface (in or out).
Returns
kInside if the point is closest to the inside surface; kOutside if the point is closest to the outside surface; kSurface if the point is withing tolerance of the surface.

Implements G4VCSGface.

Definition at line 601 of file G4PolyhedraSide.cc.

604{
605 //
606 // Which phi segment is closest to this point?
607 //
608 G4int iPhi = ClosestPhiSegment( GetPhi(p) );
609
610 G4double norm;
611
612 //
613 // Get distance to this segment
614 //
615 *bestDistance = DistanceToOneSide( p, vecs[iPhi], &norm );
616
617 //
618 // Use distance along normal to decide return value
619 //
620 if ( (std::fabs(norm) > tolerance) || (*bestDistance > 2.0*tolerance) )
621 {
622 return (norm < 0) ? kInside : kOutside;
623 }
624 return kSurface;
625}
@ kInside
Definition geomdefs.hh:70
@ kOutside
Definition geomdefs.hh:68
@ kSurface
Definition geomdefs.hh:69

◆ Intersect()

G4bool G4PolyhedraSide::Intersect ( const G4ThreeVector & p,
const G4ThreeVector & v,
G4bool outgoing,
G4double surfTolerance,
G4double & distance,
G4double & distFromSurface,
G4ThreeVector & normal,
G4bool & allBehind )
overridevirtual

Determines the distance along a line to the face.

Parameters
[in]pPosition.
[in]vDirection (assumed to be a unit vector).
[in]outgoingFlag true, to consider only inside surfaces; false, to consider only outside surfaces.
[in]surfToleranceMinimum distance from the surface.
[out]distanceDistance to intersection.
[out]distFromSurfaceDistance from surface (along surface normal), < 0 if the point is in front of the surface.
[out]normalNormal of surface at intersection point.
[out]allBehindFlag, true, if entire surface is behind normal.
Returns
true if there is an intersection, false otherwise.

Implements G4VCSGface.

Definition at line 450 of file G4PolyhedraSide.cc.

458{
459 G4double normSign = outgoing ? +1 : -1;
460
461 //
462 // ------------------TO BE IMPLEMENTED---------------------
463 // Testing the intersection of individual phi faces is
464 // pretty straight forward. The simple thing therefore is to
465 // form a loop and check them all in sequence.
466 //
467 // But, I worry about one day someone making
468 // a polygon with a thousands sides. A linear search
469 // would not be ideal in such a case.
470 //
471 // So, it would be nice to be able to quickly decide
472 // which face would be intersected. One can make a very
473 // good guess by using the intersection with a cone.
474 // However, this is only reliable in 99% of the cases.
475 //
476 // My solution: make a decent guess as to the one or
477 // two potential faces might get intersected, and then
478 // test them. If we have the wrong face, use the test
479 // to make a better guess.
480 //
481 // Since we might have two guesses, form a queue of
482 // potential intersecting faces. Keep an array of
483 // already tested faces to avoid doing one more than
484 // once.
485 //
486 // Result: at worst, an iterative search. On average,
487 // a little more than two tests would be required.
488 //
489 G4ThreeVector q = p + v;
490
491 G4int face = 0;
492 G4PolyhedraSideVec* vec = vecs;
493 do // Loop checking, 13.08.2015, G.Cosmo
494 {
495 //
496 // Correct normal?
497 //
498 G4double dotProd = normSign*v.dot(vec->normal);
499 if (dotProd <= 0) { continue; }
500
501 //
502 // Is this face in front of the point along the trajectory?
503 //
504 G4ThreeVector delta = p - vec->center;
505 distFromSurface = -normSign*delta.dot(vec->normal);
506
507 if (distFromSurface < -surfTolerance) { continue; }
508
509 //
510 // phi
511 // c -------- d ^
512 // | | |
513 // a -------- b +---> r/z
514 //
515 //
516 // Do we remain on this particular segment?
517 //
518 G4ThreeVector qc = q - vec->edges[1]->corner[0];
519 G4ThreeVector qd = q - vec->edges[1]->corner[1];
520
521 if (normSign*qc.cross(qd).dot(v) < 0) { continue; }
522
523 G4ThreeVector qa = q - vec->edges[0]->corner[0];
524 G4ThreeVector qb = q - vec->edges[0]->corner[1];
525
526 if (normSign*qa.cross(qb).dot(v) > 0) { continue; }
527
528 //
529 // We found the one and only segment we might be intersecting.
530 // Do we remain within r/z bounds?
531 //
532
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; }
535
536 //
537 // We allow the face to be slightly behind the trajectory
538 // (surface tolerance) only if the point p is within
539 // the vicinity of the face
540 //
541 if (distFromSurface < 0)
542 {
543 G4ThreeVector ps = p - vec->center;
544
545 G4double rz = ps.dot(vec->surfRZ);
546 if (std::fabs(rz) > lenRZ+surfTolerance) { return false; }
547
548 G4double pp = ps.dot(vec->surfPhi);
549 if (std::fabs(pp) > lenPhi[0]+lenPhi[1]*rz+surfTolerance) { return false; }
550 }
551
552
553 //
554 // Intersection found. Return answer.
555 //
556 distance = distFromSurface/dotProd;
557 normal = vec->normal;
558 isAllBehind = allBehind;
559 return true;
560 } while( ++vec, ++face < numSide );
561
562 //
563 // Oh well. Better luck next time.
564 //
565 return false;
566}

◆ Normal()

G4ThreeVector G4PolyhedraSide::Normal ( const G4ThreeVector & p,
G4double * bestDistance )
overridevirtual

Returns the normal of surface closest to the point.

Parameters
[in]pPosition.
[out]bestDistanceDistance to the closest surface (in or out).
Returns
The normal of the surface nearest the point.

Implements G4VCSGface.

Definition at line 629 of file G4PolyhedraSide.cc.

631{
632 //
633 // Which phi segment is closest to this point?
634 //
635 G4int iPhi = ClosestPhiSegment( GetPhi(p) );
636
637 //
638 // Get distance to this segment
639 //
640 G4double norm;
641 *bestDistance = DistanceToOneSide( p, vecs[iPhi], &norm );
642
643 return vecs[iPhi].normal;
644}

◆ operator=()

G4PolyhedraSide & G4PolyhedraSide::operator= ( const G4PolyhedraSide & source)

Definition at line 340 of file G4PolyhedraSide.cc.

341{
342 if (this == &source) { return *this; }
343
344 delete cone;
345 delete [] vecs;
346 delete [] edges;
347
348 CopyStuff( source );
349
350 return *this;
351}

◆ SurfaceArea()

G4double G4PolyhedraSide::SurfaceArea ( )
overridevirtual

Returning an estimation of the face surface area, in internal units.

Implements G4VCSGface.

Definition at line 1217 of file G4PolyhedraSide.cc.

1218{
1219 if( fSurfaceArea==0. )
1220 {
1221 // Define the variables
1222 //
1223 G4double area,areas;
1224 G4ThreeVector point1;
1225 G4ThreeVector v1,v2,v3,v4;
1226 G4PolyhedraSideVec* vec = vecs;
1227 areas=0.;
1228
1229 // Do a loop on all SideEdge
1230 //
1231 do // Loop checking, 13.08.2015, G.Cosmo
1232 {
1233 // Define 4points for a Plane or Triangle
1234 //
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);
1240 areas+=area;
1241 } while( ++vec < vecs + numSide);
1242
1243 fSurfaceArea=areas;
1244 }
1245 return fSurfaceArea;
1246}

◆ sG4PolyhedraSideVec

friend struct sG4PolyhedraSideVec
friend

Definition at line 233 of file G4PolyhedraSide.hh.

Referenced by sG4PolyhedraSideVec.


The documentation for this class was generated from the following files: