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

#include <G4PolyPhiFace.hh>

+ Inheritance diagram for G4PolyPhiFace:

Public Member Functions

 G4PolyPhiFace (const G4ReduciblePolygon *rz, G4double phi, G4double deltaPhi, G4double phiOther)
 
virtual ~G4PolyPhiFace ()
 
 G4PolyPhiFace (const G4PolyPhiFace &source)
 
G4PolyPhiFaceoperator= (const G4PolyPhiFace &source)
 
G4bool Intersect (const G4ThreeVector &p, const G4ThreeVector &v, G4bool outgoing, G4double surfTolerance, G4double &distance, G4double &distFromSurface, G4ThreeVector &normal, G4bool &allBehind)
 
G4double Distance (const G4ThreeVector &p, G4bool outgoing)
 
EInside Inside (const G4ThreeVector &p, G4double tolerance, G4double *bestDistance)
 
G4ThreeVector Normal (const G4ThreeVector &p, G4double *bestDistance)
 
G4double Extent (const G4ThreeVector axis)
 
void CalculateExtent (const EAxis axis, const G4VoxelLimits &voxelLimit, const G4AffineTransform &tranform, G4SolidExtentList &extentList)
 
G4VCSGfaceClone ()
 
G4double SurfaceArea ()
 
G4double SurfaceTriangle (G4ThreeVector p1, G4ThreeVector p2, G4ThreeVector p3, G4ThreeVector *p4)
 
G4ThreeVector GetPointOnFace ()
 
 G4PolyPhiFace (__void__ &)
 
void Diagnose (G4VSolid *solid)
 
- Public Member Functions inherited from G4VCSGface
 G4VCSGface ()
 
virtual ~G4VCSGface ()
 
virtual G4bool Intersect (const G4ThreeVector &p, const G4ThreeVector &v, G4bool outgoing, G4double surfTolerance, G4double &distance, G4double &distFromSurface, G4ThreeVector &normal, G4bool &allBehind)=0
 
virtual G4double Distance (const G4ThreeVector &p, G4bool outgoing)=0
 
virtual EInside Inside (const G4ThreeVector &p, G4double tolerance, G4double *bestDistance)=0
 
virtual G4ThreeVector Normal (const G4ThreeVector &p, G4double *bestDistance)=0
 
virtual G4double Extent (const G4ThreeVector axis)=0
 
virtual void CalculateExtent (const EAxis axis, const G4VoxelLimits &voxelLimit, const G4AffineTransform &tranform, G4SolidExtentList &extentList)=0
 
virtual G4VCSGfaceClone ()=0
 
virtual G4double SurfaceArea ()=0
 
virtual G4ThreeVector GetPointOnFace ()=0
 

Protected Member Functions

G4bool InsideEdgesExact (G4double r, G4double z, G4double normSign, const G4ThreeVector &p, const G4ThreeVector &v)
 
G4bool InsideEdges (G4double r, G4double z)
 
G4bool InsideEdges (G4double r, G4double z, G4double *distRZ2, G4PolyPhiFaceVertex **base3Dnorm=0, G4ThreeVector **head3Dnorm=0)
 
G4double ExactZOrder (G4double z, G4double qx, G4double qy, G4double qz, const G4ThreeVector &v, G4double normSign, const G4PolyPhiFaceVertex *vert) const
 
void CopyStuff (const G4PolyPhiFace &source)
 
G4double Area2 (G4TwoVector a, G4TwoVector b, G4TwoVector c)
 
G4bool Left (G4TwoVector a, G4TwoVector b, G4TwoVector c)
 
G4bool LeftOn (G4TwoVector a, G4TwoVector b, G4TwoVector c)
 
G4bool Collinear (G4TwoVector a, G4TwoVector b, G4TwoVector c)
 
G4bool IntersectProp (G4TwoVector a, G4TwoVector b, G4TwoVector c, G4TwoVector d)
 
G4bool Between (G4TwoVector a, G4TwoVector b, G4TwoVector c)
 
G4bool Intersect (G4TwoVector a, G4TwoVector b, G4TwoVector c, G4TwoVector d)
 
G4bool Diagonalie (G4PolyPhiFaceVertex *a, G4PolyPhiFaceVertex *b)
 
G4bool InCone (G4PolyPhiFaceVertex *a, G4PolyPhiFaceVertex *b)
 
G4bool Diagonal (G4PolyPhiFaceVertex *a, G4PolyPhiFaceVertex *b)
 
void EarInit ()
 
void Triangulate ()
 

Protected Attributes

G4int numEdges
 
G4PolyPhiFaceEdgeedges
 
G4PolyPhiFaceVertexcorners
 
G4ThreeVector normal
 
G4ThreeVector radial
 
G4ThreeVector surface
 
G4ThreeVector surface_point
 
G4double rMin
 
G4double rMax
 
G4double zMin
 
G4double zMax
 
G4bool allBehind
 
G4double kCarTolerance
 
G4double fSurfaceArea
 
G4PolyPhiFaceVertextriangles
 

Detailed Description

Definition at line 85 of file G4PolyPhiFace.hh.

Constructor & Destructor Documentation

◆ G4PolyPhiFace() [1/3]

G4PolyPhiFace::G4PolyPhiFace ( const G4ReduciblePolygon rz,
G4double  phi,
G4double  deltaPhi,
G4double  phiOther 
)

Definition at line 61 of file G4PolyPhiFace.cc.

65 : fSurfaceArea(0.), triangles(0)
66{
68
69 numEdges = rz->NumVertices();
70
71 rMin = rz->Amin();
72 rMax = rz->Amax();
73 zMin = rz->Bmin();
74 zMax = rz->Bmax();
75
76 //
77 // Is this the "starting" phi edge of the two?
78 //
79 G4bool start = (phiOther > phi);
80
81 //
82 // Build radial vector
83 //
84 radial = G4ThreeVector( std::cos(phi), std::sin(phi), 0.0 );
85
86 //
87 // Build normal
88 //
89 G4double zSign = start ? 1 : -1;
90 normal = G4ThreeVector( zSign*radial.y(), -zSign*radial.x(), 0 );
91
92 //
93 // Is allBehind?
94 //
95 allBehind = (zSign*(std::cos(phiOther)*radial.y() - std::sin(phiOther)*radial.x()) < 0);
96
97 //
98 // Adjacent edges
99 //
100 G4double midPhi = phi + (start ? +0.5 : -0.5)*deltaPhi;
101 G4double cosMid = std::cos(midPhi),
102 sinMid = std::sin(midPhi);
103
104 //
105 // Allocate corners
106 //
108 //
109 // Fill them
110 //
112
115
116 iterRZ.Begin();
117 do
118 {
119 corn->r = iterRZ.GetA();
120 corn->z = iterRZ.GetB();
121 corn->x = corn->r*radial.x();
122 corn->y = corn->r*radial.y();
123
124 // Add pointer on prev corner
125 //
126 if( corn == corners )
127 { corn->prev = corners+numEdges-1;}
128 else
129 { corn->prev = helper; }
130
131 // Add pointer on next corner
132 //
133 if( corn < corners+numEdges-1 )
134 { corn->next = corn+1;}
135 else
136 { corn->next = corners; }
137
138 helper = corn;
139 } while( ++corn, iterRZ.Next() );
140
141 //
142 // Allocate edges
143 //
145
146 //
147 // Fill them
148 //
149 G4double rFact = std::cos(0.5*deltaPhi);
150 G4double rFactNormalize = 1.0/std::sqrt(1.0+rFact*rFact);
151
153 *here = corners;
154 G4PolyPhiFaceEdge *edge = edges;
155 do
156 {
157 G4ThreeVector sideNorm;
158
159 edge->v0 = prev;
160 edge->v1 = here;
161
162 G4double dr = here->r - prev->r,
163 dz = here->z - prev->z;
164
165 edge->length = std::sqrt( dr*dr + dz*dz );
166
167 edge->tr = dr/edge->length;
168 edge->tz = dz/edge->length;
169
170 if ((here->r < DBL_MIN) && (prev->r < DBL_MIN))
171 {
172 //
173 // Sigh! Always exceptions!
174 // This edge runs at r==0, so its adjoing surface is not a
175 // PolyconeSide or PolyhedraSide, but the opposite PolyPhiFace.
176 //
177 G4double zSignOther = start ? -1 : 1;
178 sideNorm = G4ThreeVector( zSignOther*std::sin(phiOther),
179 -zSignOther*std::cos(phiOther), 0 );
180 }
181 else
182 {
183 sideNorm = G4ThreeVector( edge->tz*cosMid,
184 edge->tz*sinMid,
185 -edge->tr*rFact );
186 sideNorm *= rFactNormalize;
187 }
188 sideNorm += normal;
189
190 edge->norm3D = sideNorm.unit();
191 } while( edge++, prev=here, ++here < corners+numEdges );
192
193 //
194 // Go back and fill in corner "normals"
195 //
196 G4PolyPhiFaceEdge *prevEdge = edges+numEdges-1;
197 edge = edges;
198 do
199 {
200 //
201 // Calculate vertex 2D normals (on the phi surface)
202 //
203 G4double rPart = prevEdge->tr + edge->tr;
204 G4double zPart = prevEdge->tz + edge->tz;
205 G4double norm = std::sqrt( rPart*rPart + zPart*zPart );
206 G4double rNorm = +zPart/norm;
207 G4double zNorm = -rPart/norm;
208
209 edge->v0->rNorm = rNorm;
210 edge->v0->zNorm = zNorm;
211
212 //
213 // Calculate the 3D normals.
214 //
215 // Find the vector perpendicular to the z axis
216 // that defines the plane that contains the vertex normal
217 //
218 G4ThreeVector xyVector;
219
220 if (edge->v0->r < DBL_MIN)
221 {
222 //
223 // This is a vertex at r==0, which is a special
224 // case. The normal we will construct lays in the
225 // plane at the center of the phi opening.
226 //
227 // We also know that rNorm < 0
228 //
229 G4double zSignOther = start ? -1 : 1;
230 G4ThreeVector normalOther( zSignOther*std::sin(phiOther),
231 -zSignOther*std::cos(phiOther), 0 );
232
233 xyVector = - normal - normalOther;
234 }
235 else
236 {
237 //
238 // This is a vertex at r > 0. The plane
239 // is the average of the normal and the
240 // normal of the adjacent phi face
241 //
242 xyVector = G4ThreeVector( cosMid, sinMid, 0 );
243 if (rNorm < 0)
244 xyVector -= normal;
245 else
246 xyVector += normal;
247 }
248
249 //
250 // Combine it with the r/z direction from the face
251 //
252 edge->v0->norm3D = rNorm*xyVector.unit() + G4ThreeVector( 0, 0, zNorm );
253 } while( prevEdge=edge, ++edge < edges+numEdges );
254
255 //
256 // Build point on surface
257 //
258 G4double rAve = 0.5*(rMax-rMin),
259 zAve = 0.5*(zMax-zMin);
260 surface = G4ThreeVector( rAve*radial.x(), rAve*radial.y(), zAve );
261}
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:64
bool G4bool
Definition: G4Types.hh:67
Hep3Vector unit() const
double x() const
double y() const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4ThreeVector surface
G4double fSurfaceArea
G4PolyPhiFaceEdge * edges
G4ThreeVector radial
G4PolyPhiFaceVertex * corners
G4PolyPhiFaceVertex * triangles
G4ThreeVector normal
G4double kCarTolerance
G4double Amin() const
G4int NumVertices() const
G4double Bmin() const
G4double Bmax() const
G4double Amax() const
G4PolyPhiFaceVertex * v1
G4ThreeVector norm3D
G4PolyPhiFaceVertex * v0
G4ThreeVector norm3D
G4PolyPhiFaceVertex * next
G4PolyPhiFaceVertex * prev
#define DBL_MIN
Definition: templates.hh:75

◆ ~G4PolyPhiFace()

G4PolyPhiFace::~G4PolyPhiFace ( )
virtual

Definition at line 301 of file G4PolyPhiFace.cc.

302{
303 delete [] edges;
304 delete [] corners;
305}

◆ G4PolyPhiFace() [2/3]

G4PolyPhiFace::G4PolyPhiFace ( const G4PolyPhiFace source)

Definition at line 311 of file G4PolyPhiFace.cc.

312 : G4VCSGface()
313{
314 CopyStuff( source );
315}
void CopyStuff(const G4PolyPhiFace &source)

◆ G4PolyPhiFace() [3/3]

G4PolyPhiFace::G4PolyPhiFace ( __void__ &  )

Definition at line 291 of file G4PolyPhiFace.cc.

292 : numEdges(0), edges(0), corners(0), rMin(0.), rMax(0.), zMin(0.), zMax(0.),
293 allBehind(false), kCarTolerance(0.), fSurfaceArea(0.), triangles(0)
294{
295}

Member Function Documentation

◆ Area2()

G4double G4PolyPhiFace::Area2 ( G4TwoVector  a,
G4TwoVector  b,
G4TwoVector  c 
)
protected

Definition at line 966 of file G4PolyPhiFace.cc.

969{
970 return ((b.x()-a.x())*(c.y()-a.y())-
971 (c.x()-a.x())*(b.y()-a.y()));
972}
double x() const
double y() const

Referenced by Collinear(), Left(), and LeftOn().

◆ Between()

G4bool G4PolyPhiFace::Between ( G4TwoVector  a,
G4TwoVector  b,
G4TwoVector  c 
)
protected

Definition at line 1024 of file G4PolyPhiFace.cc.

1025{
1026 if( !Collinear(a,b,c) ) { return false; }
1027
1028 if(a.x()!=b.x())
1029 {
1030 return ((a.x()<=c.x())&&(c.x()<=b.x()))||
1031 ((a.x()>=c.x())&&(c.x()>=b.x()));
1032 }
1033 else
1034 {
1035 return ((a.y()<=c.y())&&(c.y()<=b.y()))||
1036 ((a.y()>=c.y())&&(c.y()>=b.y()));
1037 }
1038}
G4bool Collinear(G4TwoVector a, G4TwoVector b, G4TwoVector c)

Referenced by Intersect().

◆ CalculateExtent()

void G4PolyPhiFace::CalculateExtent ( const EAxis  axis,
const G4VoxelLimits voxelLimit,
const G4AffineTransform tranform,
G4SolidExtentList extentList 
)
virtual

Implements G4VCSGface.

Definition at line 628 of file G4PolyPhiFace.cc.

632{
633 //
634 // Construct a (sometimes big) clippable polygon,
635 //
636 // Perform the necessary transformations while doing so
637 //
638 G4ClippablePolygon polygon;
639
641 do
642 {
643 G4ThreeVector point( 0, 0, corner->z );
644 point += radial*corner->r;
645
646 polygon.AddVertexInOrder( transform.TransformPoint( point ) );
647 } while( ++corner < corners + numEdges );
648
649 //
650 // Clip away
651 //
652 if (polygon.PartialClip( voxelLimit, axis ))
653 {
654 //
655 // Add it to the list
656 //
657 polygon.SetNormal( transform.TransformAxis(normal) );
658 extentList.AddSurface( polygon );
659 }
660}
virtual G4bool PartialClip(const G4VoxelLimits &voxelLimit, const EAxis IgnoreMe)
virtual void AddVertexInOrder(const G4ThreeVector vertex)
void SetNormal(const G4ThreeVector &newNormal)
void AddSurface(const G4ClippablePolygon &surface)

◆ Clone()

G4VCSGface * G4PolyPhiFace::Clone ( )
inlinevirtual

Implements G4VCSGface.

◆ Collinear()

G4bool G4PolyPhiFace::Collinear ( G4TwoVector  a,
G4TwoVector  b,
G4TwoVector  c 
)
protected

Definition at line 997 of file G4PolyPhiFace.cc.

1000{
1001 return Area2(a,b,c)==0;
1002}
G4double Area2(G4TwoVector a, G4TwoVector b, G4TwoVector c)

Referenced by Between(), and IntersectProp().

◆ CopyStuff()

void G4PolyPhiFace::CopyStuff ( const G4PolyPhiFace source)
protected

Definition at line 337 of file G4PolyPhiFace.cc.

338{
339 //
340 // The simple stuff
341 //
342 numEdges = source.numEdges;
343 normal = source.normal;
344 radial = source.radial;
345 surface = source.surface;
346 rMin = source.rMin;
347 rMax = source.rMax;
348 zMin = source.zMin;
349 zMax = source.zMax;
350 allBehind = source.allBehind;
351 triangles = 0;
352
354 fSurfaceArea = source.fSurfaceArea;
355
356 //
357 // Corner dynamic array
358 //
361 *sourceCorn = source.corners;
362 do
363 {
364 *corn = *sourceCorn;
365 } while( ++sourceCorn, ++corn < corners+numEdges );
366
367 //
368 // Edge dynamic array
369 //
371
373 *here = corners;
374 G4PolyPhiFaceEdge *edge = edges,
375 *sourceEdge = source.edges;
376 do
377 {
378 *edge = *sourceEdge;
379 edge->v0 = prev;
380 edge->v1 = here;
381 } while( ++sourceEdge, ++edge, prev=here, ++here < corners+numEdges );
382}

Referenced by G4PolyPhiFace(), and operator=().

◆ Diagnose()

void G4PolyPhiFace::Diagnose ( G4VSolid solid)

Definition at line 272 of file G4PolyPhiFace.cc.

273{
275 do
276 {
277 G4ThreeVector test(corner->x, corner->y, corner->z);
278 test -= 1E-6*corner->norm3D;
279
280 if (owner->Inside(test) != kInside)
281 G4Exception( "G4PolyPhiFace::Diagnose()", "GeomSolids0002",
282 FatalException, "Bad vertex normal found." );
283 } while( ++corner < corners+numEdges );
284}
@ FatalException
@ kInside
Definition: geomdefs.hh:58
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41

◆ Diagonal()

G4bool G4PolyPhiFace::Diagonal ( G4PolyPhiFaceVertex a,
G4PolyPhiFaceVertex b 
)
protected

Definition at line 1124 of file G4PolyPhiFace.cc.

1125{
1126 return InCone(a,b) && InCone(b,a) && Diagonalie(a,b);
1127}
G4bool Diagonalie(G4PolyPhiFaceVertex *a, G4PolyPhiFaceVertex *b)
G4bool InCone(G4PolyPhiFaceVertex *a, G4PolyPhiFaceVertex *b)

Referenced by EarInit(), and Triangulate().

◆ Diagonalie()

G4bool G4PolyPhiFace::Diagonalie ( G4PolyPhiFaceVertex a,
G4PolyPhiFaceVertex b 
)
protected

Definition at line 1063 of file G4PolyPhiFace.cc.

1065{
1067 G4PolyPhiFaceVertex *corner_next=triangles;
1068
1069 // For each Edge (corner,corner_next)
1070 do
1071 {
1072 corner_next=corner->next;
1073
1074 // Skip edges incident to a of b
1075 //
1076 if( (corner!=a)&&(corner_next!=a)
1077 &&(corner!=b)&&(corner_next!=b) )
1078 {
1079 G4TwoVector rz1,rz2,rz3,rz4;
1080 rz1 = G4TwoVector(a->r,a->z);
1081 rz2 = G4TwoVector(b->r,b->z);
1082 rz3 = G4TwoVector(corner->r,corner->z);
1083 rz4 = G4TwoVector(corner_next->r,corner_next->z);
1084 if( Intersect(rz1,rz2,rz3,rz4) ) { return false; }
1085 }
1086 corner=corner->next;
1087
1088 } while( corner != triangles );
1089
1090 return true;
1091}
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:42
G4bool Intersect(const G4ThreeVector &p, const G4ThreeVector &v, G4bool outgoing, G4double surfTolerance, G4double &distance, G4double &distFromSurface, G4ThreeVector &normal, G4bool &allBehind)

Referenced by Diagonal().

◆ Distance()

G4double G4PolyPhiFace::Distance ( const G4ThreeVector p,
G4bool  outgoing 
)
virtual

Implements G4VCSGface.

Definition at line 445 of file G4PolyPhiFace.cc.

446{
447 G4double normSign = outgoing ? +1 : -1;
448 //
449 // Correct normal?
450 //
451 G4ThreeVector ps = p - surface;
452 G4double distPhi = -normSign*normal.dot(ps);
453
454 if (distPhi < -0.5*kCarTolerance)
455 return kInfinity;
456 else if (distPhi < 0)
457 distPhi = 0.0;
458
459 //
460 // Calculate projected point in r,z
461 //
462 G4double r = radial.dot(p);
463
464 //
465 // Are we inside the face?
466 //
467 G4double distRZ2;
468
469 if (InsideEdges( r, p.z(), &distRZ2, 0 ))
470 {
471 //
472 // Yup, answer is just distPhi
473 //
474 return distPhi;
475 }
476 else
477 {
478 //
479 // Nope. Penalize by distance out
480 //
481 return std::sqrt( distPhi*distPhi + distRZ2 );
482 }
483}
double z() const
double dot(const Hep3Vector &) const
G4bool InsideEdges(G4double r, G4double z)

◆ EarInit()

void G4PolyPhiFace::EarInit ( )
protected

Definition at line 1133 of file G4PolyPhiFace.cc.

1134{
1136 G4PolyPhiFaceVertex *c_prev,*c_next;
1137
1138 do
1139 {
1140 // We need to determine three consecutive vertices
1141 //
1142 c_next=corner->next;
1143 c_prev=corner->prev;
1144
1145 // Calculation of ears
1146 //
1147 corner->ear=Diagonal(c_prev,c_next);
1148 corner=corner->next;
1149
1150 } while( corner!=triangles );
1151}
G4bool Diagonal(G4PolyPhiFaceVertex *a, G4PolyPhiFaceVertex *b)

Referenced by Triangulate().

◆ ExactZOrder()

G4double G4PolyPhiFace::ExactZOrder ( G4double  z,
G4double  qx,
G4double  qy,
G4double  qz,
const G4ThreeVector v,
G4double  normSign,
const G4PolyPhiFaceVertex vert 
) const
inlineprotected

Referenced by InsideEdgesExact().

◆ Extent()

G4double G4PolyPhiFace::Extent ( const G4ThreeVector  axis)
virtual

Implements G4VCSGface.

Definition at line 606 of file G4PolyPhiFace.cc.

607{
608 G4double max = -kInfinity;
609
611 do
612 {
613 G4double here = axis.x()*corner->r*radial.x()
614 + axis.y()*corner->r*radial.y()
615 + axis.z()*corner->z;
616 if (here > max) max = here;
617 } while( ++corner < corners + numEdges );
618
619 return max;
620}

◆ GetPointOnFace()

G4ThreeVector G4PolyPhiFace::GetPointOnFace ( )
virtual

Implements G4VCSGface.

Definition at line 953 of file G4PolyPhiFace.cc.

954{
955 Triangulate();
956 return surface_point;
957}
G4ThreeVector surface_point

◆ InCone()

G4bool G4PolyPhiFace::InCone ( G4PolyPhiFaceVertex a,
G4PolyPhiFaceVertex b 
)
protected

Definition at line 1097 of file G4PolyPhiFace.cc.

1098{
1099 // a0,a and a1 are consecutive vertices
1100 //
1101 G4PolyPhiFaceVertex *a0,*a1;
1102 a1=a->next;
1103 a0=a->prev;
1104
1105 G4TwoVector arz,arz0,arz1,brz;
1106 arz=G4TwoVector(a->r,a->z);arz0=G4TwoVector(a0->r,a0->z);
1107 arz1=G4TwoVector(a1->r,a1->z);brz=G4TwoVector(b->r,b->z);
1108
1109
1110 if(LeftOn(arz,arz1,arz0)) // If a is convex vertex
1111 {
1112 return Left(arz,brz,arz0)&&Left(brz,arz,arz1);
1113 }
1114 else // Else a is reflex
1115 {
1116 return !( LeftOn(arz,brz,arz1)&&LeftOn(brz,arz,arz0));
1117 }
1118}
G4bool Left(G4TwoVector a, G4TwoVector b, G4TwoVector c)
G4bool LeftOn(G4TwoVector a, G4TwoVector b, G4TwoVector c)

Referenced by Diagonal().

◆ Inside()

EInside G4PolyPhiFace::Inside ( const G4ThreeVector p,
G4double  tolerance,
G4double bestDistance 
)
virtual

Implements G4VCSGface.

Definition at line 489 of file G4PolyPhiFace.cc.

492{
493 //
494 // Get distance along phi, which if negative means the point
495 // is nominally inside the shape.
496 //
497 G4ThreeVector ps = p - surface;
498 G4double distPhi = normal.dot(ps);
499
500 //
501 // Calculate projected point in r,z
502 //
503 G4double r = radial.dot(p);
504
505 //
506 // Are we inside the face?
507 //
508 G4double distRZ2;
509 G4PolyPhiFaceVertex *base3Dnorm;
510 G4ThreeVector *head3Dnorm;
511
512 if (InsideEdges( r, p.z(), &distRZ2, &base3Dnorm, &head3Dnorm ))
513 {
514 //
515 // Looks like we're inside. Distance is distance in phi.
516 //
517 *bestDistance = std::fabs(distPhi);
518
519 //
520 // Use distPhi to decide fate
521 //
522 if (distPhi < -tolerance) return kInside;
523 if (distPhi < tolerance) return kSurface;
524 return kOutside;
525 }
526 else
527 {
528 //
529 // We're outside the extent of the face,
530 // so the distance is penalized by distance from edges in RZ
531 //
532 *bestDistance = std::sqrt( distPhi*distPhi + distRZ2 );
533
534 //
535 // Use edge normal to decide fate
536 //
537 G4ThreeVector cc( base3Dnorm->r*radial.x(),
538 base3Dnorm->r*radial.y(),
539 base3Dnorm->z );
540 cc = p - cc;
541 G4double normDist = head3Dnorm->dot(cc);
542 if ( distRZ2 > tolerance*tolerance )
543 {
544 //
545 // We're far enough away that kSurface is not possible
546 //
547 return normDist < 0 ? kInside : kOutside;
548 }
549
550 if (normDist < -tolerance) return kInside;
551 if (normDist < tolerance) return kSurface;
552 return kOutside;
553 }
554}
@ kOutside
Definition: geomdefs.hh:58
@ kSurface
Definition: geomdefs.hh:58

◆ InsideEdges() [1/2]

G4bool G4PolyPhiFace::InsideEdges ( G4double  r,
G4double  z 
)
protected

Definition at line 822 of file G4PolyPhiFace.cc.

823{
824 //
825 // Quick check of extent
826 //
827 if ( r < rMin || r > rMax ) return false;
828 if ( z < zMin || z > zMax ) return false;
829
830 //
831 // More thorough check
832 //
833 G4double notUsed;
834
835 return InsideEdges( r, z, &notUsed, 0 );
836}

Referenced by Distance(), Inside(), InsideEdges(), and Normal().

◆ InsideEdges() [2/2]

G4bool G4PolyPhiFace::InsideEdges ( G4double  r,
G4double  z,
G4double distRZ2,
G4PolyPhiFaceVertex **  base3Dnorm = 0,
G4ThreeVector **  head3Dnorm = 0 
)
protected

Definition at line 844 of file G4PolyPhiFace.cc.

848{
849 G4double bestDistance2 = kInfinity;
850 G4bool answer = 0;
851
852 G4PolyPhiFaceEdge *edge = edges;
853 do
854 {
855 G4PolyPhiFaceVertex *testMe;
856 //
857 // Get distance perpendicular to the edge
858 //
859 G4double dr = (r-edge->v0->r), dz = (z-edge->v0->z);
860
861 G4double distOut = dr*edge->tz - dz*edge->tr;
862 G4double distance2 = distOut*distOut;
863 if (distance2 > bestDistance2) continue; // No hope!
864
865 //
866 // Check to see if normal intersects edge within the edge's boundary
867 //
868 G4double q = dr*edge->tr + dz*edge->tz;
869
870 //
871 // If it doesn't, penalize distance2 appropriately
872 //
873 if (q < 0)
874 {
875 distance2 += q*q;
876 testMe = edge->v0;
877 }
878 else if (q > edge->length)
879 {
880 G4double s2 = q-edge->length;
881 distance2 += s2*s2;
882 testMe = edge->v1;
883 }
884 else
885 {
886 testMe = 0;
887 }
888
889 //
890 // Closest edge so far?
891 //
892 if (distance2 < bestDistance2)
893 {
894 bestDistance2 = distance2;
895 if (testMe)
896 {
897 G4double distNorm = dr*testMe->rNorm + dz*testMe->zNorm;
898 answer = (distNorm <= 0);
899 if (base3Dnorm)
900 {
901 *base3Dnorm = testMe;
902 *head3Dnorm = &testMe->norm3D;
903 }
904 }
905 else
906 {
907 answer = (distOut <= 0);
908 if (base3Dnorm)
909 {
910 *base3Dnorm = edge->v0;
911 *head3Dnorm = &edge->norm3D;
912 }
913 }
914 }
915 } while( ++edge < edges + numEdges );
916
917 *bestDist2 = bestDistance2;
918 return answer;
919}

◆ InsideEdgesExact()

G4bool G4PolyPhiFace::InsideEdgesExact ( G4double  r,
G4double  z,
G4double  normSign,
const G4ThreeVector p,
const G4ThreeVector v 
)
protected

Definition at line 683 of file G4PolyPhiFace.cc.

687{
688 //
689 // Quick check of extent
690 //
691 if ( (r < rMin-kCarTolerance)
692 || (r > rMax+kCarTolerance) ) return false;
693
694 if ( (z < zMin-kCarTolerance)
695 || (z > zMax+kCarTolerance) ) return false;
696
697 //
698 // Exact check: loop over all vertices
699 //
700 G4double qx = p.x() + v.x(),
701 qy = p.y() + v.y(),
702 qz = p.z() + v.z();
703
704 G4int answer = 0;
706 *prev = corners+numEdges-1;
707
708 G4double cornZ, prevZ;
709
710 prevZ = ExactZOrder( z, qx, qy, qz, v, normSign, prev );
711 do
712 {
713 //
714 // Get z order of this vertex, and compare to previous vertex
715 //
716 cornZ = ExactZOrder( z, qx, qy, qz, v, normSign, corn );
717
718 if (cornZ < 0)
719 {
720 if (prevZ < 0) continue;
721 }
722 else if (cornZ > 0)
723 {
724 if (prevZ > 0) continue;
725 }
726 else
727 {
728 //
729 // By chance, we overlap exactly (within precision) with
730 // the current vertex. Continue if the same happened previously
731 // (e.g. the previous vertex had the same z value)
732 //
733 if (prevZ == 0) continue;
734
735 //
736 // Otherwise, to decide what to do, we need to know what is
737 // coming up next. Specifically, we need to find the next vertex
738 // with a non-zero z order.
739 //
740 // One might worry about infinite loops, but the above conditional
741 // should prevent it
742 //
743 G4PolyPhiFaceVertex *next = corn;
744 G4double nextZ;
745 do
746 {
747 next++;
748 if (next == corners+numEdges) next = corners;
749
750 nextZ = ExactZOrder( z, qx, qy, qz, v, normSign, next );
751 } while( nextZ == 0 );
752
753 //
754 // If we won't be changing direction, go to the next vertex
755 //
756 if (nextZ*prevZ < 0) continue;
757 }
758
759
760 //
761 // We overlap in z with the side of the face that stretches from
762 // vertex "prev" to "corn". On which side (left or right) do
763 // we lay with respect to this segment?
764 //
765 G4ThreeVector qa( qx - prev->x, qy - prev->y, qz - prev->z ),
766 qb( qx - corn->x, qy - corn->y, qz - corn->z );
767
768 G4double aboveOrBelow = normSign*qa.cross(qb).dot(v);
769
770 if (aboveOrBelow > 0)
771 answer++;
772 else if (aboveOrBelow < 0)
773 answer--;
774 else
775 {
776 //
777 // A precisely zero answer here means we exactly
778 // intersect (within roundoff) the edge of the face.
779 // Return true in this case.
780 //
781 return true;
782 }
783 } while( prevZ = cornZ, prev=corn, ++corn < corners+numEdges );
784
785// G4int fanswer = std::abs(answer);
786// if (fanswer==1 || fanswer>2) {
787// G4cerr << "G4PolyPhiFace::InsideEdgesExact: answer is "
788// << answer << G4endl;
789// }
790
791 return answer!=0;
792}
int G4int
Definition: G4Types.hh:66
G4double ExactZOrder(G4double z, G4double qx, G4double qy, G4double qz, const G4ThreeVector &v, G4double normSign, const G4PolyPhiFaceVertex *vert) const

Referenced by Intersect().

◆ Intersect() [1/2]

G4bool G4PolyPhiFace::Intersect ( const G4ThreeVector p,
const G4ThreeVector v,
G4bool  outgoing,
G4double  surfTolerance,
G4double distance,
G4double distFromSurface,
G4ThreeVector normal,
G4bool allBehind 
)
virtual

Implements G4VCSGface.

Definition at line 388 of file G4PolyPhiFace.cc.

396{
397 G4double normSign = outgoing ? +1 : -1;
398
399 //
400 // These don't change
401 //
402 isAllBehind = allBehind;
403 aNormal = normal;
404
405 //
406 // Correct normal? Here we have straight sides, and can safely ignore
407 // intersections where the dot product with the normal is zero.
408 //
409 G4double dotProd = normSign*normal.dot(v);
410
411 if (dotProd <= 0) return false;
412
413 //
414 // Calculate distance to surface. If the side is too far
415 // behind the point, we must reject it.
416 //
417 G4ThreeVector ps = p - surface;
418 distFromSurface = -normSign*ps.dot(normal);
419
420 if (distFromSurface < -surfTolerance) return false;
421
422 //
423 // Calculate precise distance to intersection with the side
424 // (along the trajectory, not normal to the surface)
425 //
426 distance = distFromSurface/dotProd;
427
428 //
429 // Calculate intersection point in r,z
430 //
431 G4ThreeVector ip = p + distance*v;
432
433 G4double r = radial.dot(ip);
434
435 //
436 // And is it inside the r/z extent?
437 //
438 return InsideEdgesExact( r, ip.z(), normSign, p, v );
439}
G4bool InsideEdgesExact(G4double r, G4double z, G4double normSign, const G4ThreeVector &p, const G4ThreeVector &v)

Referenced by Diagonalie().

◆ Intersect() [2/2]

G4bool G4PolyPhiFace::Intersect ( G4TwoVector  a,
G4TwoVector  b,
G4TwoVector  c,
G4TwoVector  d 
)
protected

Definition at line 1044 of file G4PolyPhiFace.cc.

1047{
1048 if( IntersectProp(a,b,c,d) )
1049 { return true; }
1050 else if( Between(a,b,c)||
1051 Between(a,b,d)||
1052 Between(c,d,a)||
1053 Between(c,d,b) )
1054 { return true; }
1055 else
1056 { return false; }
1057}
G4bool IntersectProp(G4TwoVector a, G4TwoVector b, G4TwoVector c, G4TwoVector d)
G4bool Between(G4TwoVector a, G4TwoVector b, G4TwoVector c)

◆ IntersectProp()

G4bool G4PolyPhiFace::IntersectProp ( G4TwoVector  a,
G4TwoVector  b,
G4TwoVector  c,
G4TwoVector  d 
)
protected

Definition at line 1008 of file G4PolyPhiFace.cc.

1011{
1012 if( Collinear(a,b,c) || Collinear(a,b,d)||
1013 Collinear(c,d,a) || Collinear(c,d,b) ) { return false; }
1014
1015 G4bool Positive;
1016 Positive = !(Left(a,b,c))^!(Left(a,b,d));
1017 return Positive && (!Left(c,d,a)^!Left(c,d,b));
1018}

Referenced by Intersect().

◆ Left()

G4bool G4PolyPhiFace::Left ( G4TwoVector  a,
G4TwoVector  b,
G4TwoVector  c 
)
protected

Definition at line 977 of file G4PolyPhiFace.cc.

980{
981 return Area2(a,b,c)>0;
982}

Referenced by InCone(), and IntersectProp().

◆ LeftOn()

G4bool G4PolyPhiFace::LeftOn ( G4TwoVector  a,
G4TwoVector  b,
G4TwoVector  c 
)
protected

Definition at line 987 of file G4PolyPhiFace.cc.

990{
991 return Area2(a,b,c)>=0;
992}

Referenced by InCone().

◆ Normal()

G4ThreeVector G4PolyPhiFace::Normal ( const G4ThreeVector p,
G4double bestDistance 
)
virtual

Implements G4VCSGface.

Definition at line 563 of file G4PolyPhiFace.cc.

565{
566 //
567 // Get distance along phi, which if negative means the point
568 // is nominally inside the shape.
569 //
570 G4double distPhi = normal.dot(p);
571
572 //
573 // Calculate projected point in r,z
574 //
575 G4double r = radial.dot(p);
576
577 //
578 // Are we inside the face?
579 //
580 G4double distRZ2;
581
582 if (InsideEdges( r, p.z(), &distRZ2, 0 ))
583 {
584 //
585 // Yup, answer is just distPhi
586 //
587 *bestDistance = std::fabs(distPhi);
588 }
589 else
590 {
591 //
592 // Nope. Penalize by distance out
593 //
594 *bestDistance = std::sqrt( distPhi*distPhi + distRZ2 );
595 }
596
597 return normal;
598}

◆ operator=()

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

Definition at line 321 of file G4PolyPhiFace.cc.

322{
323 if (this == &source) { return *this; }
324
325 delete [] edges;
326 delete [] corners;
327
328 CopyStuff( source );
329
330 return *this;
331}

◆ SurfaceArea()

G4double G4PolyPhiFace::SurfaceArea ( )
virtual

Implements G4VCSGface.

Definition at line 944 of file G4PolyPhiFace.cc.

945{
946 if ( fSurfaceArea==0. ) { Triangulate(); }
947 return fSurfaceArea;
948}

◆ SurfaceTriangle()

G4double G4PolyPhiFace::SurfaceTriangle ( G4ThreeVector  p1,
G4ThreeVector  p2,
G4ThreeVector  p3,
G4ThreeVector p4 
)

Definition at line 925 of file G4PolyPhiFace.cc.

929{
930 G4ThreeVector v, w;
931
932 v = p3 - p1;
933 w = p1 - p2;
934 G4double lambda1 = G4UniformRand();
935 G4double lambda2 = lambda1*G4UniformRand();
936
937 *p4=p2 + lambda1*w + lambda2*v;
938 return 0.5*(v.cross(w)).mag();
939}
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector cross(const Hep3Vector &) const

Referenced by Triangulate().

◆ Triangulate()

void G4PolyPhiFace::Triangulate ( )
protected

Definition at line 1157 of file G4PolyPhiFace.cc.

1158{
1159 // The copy of Polycone is made and this copy is reordered in order to
1160 // have a list of triangles. This list is used for GetPointOnFace().
1161
1163 triangles = tri_help;
1165
1166 std::vector<G4double> areas;
1167 std::vector<G4ThreeVector> points;
1168 G4double area=0.;
1169 G4PolyPhiFaceVertex *v0,*v1,*v2,*v3,*v4;
1170 v2=triangles;
1171
1172 // Make copy for prev/next for triang=corners
1173 //
1174 G4PolyPhiFaceVertex *helper = corners;
1175 G4PolyPhiFaceVertex *helper2 = corners;
1176 do
1177 {
1178 triang->r = helper->r;
1179 triang->z = helper->z;
1180 triang->x = helper->x;
1181 triang->y= helper->y;
1182
1183 // add pointer on prev corner
1184 //
1185 if( helper==corners )
1186 { triang->prev=triangles+numEdges-1; }
1187 else
1188 { triang->prev=helper2; }
1189
1190 // add pointer on next corner
1191 //
1192 if( helper<corners+numEdges-1 )
1193 { triang->next=triang+1; }
1194 else
1195 { triang->next=triangles; }
1196 helper2=triang;
1197 helper=helper->next;
1198 triang=triang->next;
1199
1200 } while( helper!=corners );
1201
1202 EarInit();
1203
1205 G4int i=0;
1206 G4ThreeVector p1,p2,p3,p4;
1207 const G4int max_n_loops=numEdges*10000; // protection against infinite loop
1208
1209 // Each step of outer loop removes one ear
1210 //
1211 while(n>3) // Inner loop searches for one ear
1212 {
1213 v2=triangles;
1214 do
1215 {
1216 if(v2->ear) // Ear found. Fill variables
1217 {
1218 // (v1,v3) is diagonal
1219 //
1220 v3=v2->next; v4=v3->next;
1221 v1=v2->prev; v0=v1->prev;
1222
1223 // Calculate areas and points
1224
1225 p1=G4ThreeVector((v2)->x,(v2)->y,(v2)->z);
1226 p2=G4ThreeVector((v1)->x,(v1)->y,(v1)->z);
1227 p3=G4ThreeVector((v3)->x,(v3)->y,(v3)->z);
1228
1229 G4double result1 = SurfaceTriangle(p1,p2,p3,&p4 );
1230 points.push_back(p4);
1231 areas.push_back(result1);
1232 area=area+result1;
1233
1234 // Update earity of diagonal endpoints
1235 //
1236 v1->ear=Diagonal(v0,v3);
1237 v3->ear=Diagonal(v1,v4);
1238
1239 // Cut off the ear v2
1240 // Has to be done for a copy and not for real PolyPhiFace
1241 //
1242 v1->next=v3;
1243 v3->prev=v1;
1244 triangles=v3; // In case the head was v2
1245 n--;
1246
1247 break; // out of inner loop
1248 } // end if ear found
1249
1250 v2=v2->next;
1251
1252 } while( v2!=triangles );
1253
1254 i++;
1255 if(i>=max_n_loops)
1256 {
1257 G4Exception( "G4PolyPhiFace::Triangulation()",
1258 "GeomSolids0003", FatalException,
1259 "Maximum number of steps is reached for triangulation!" );
1260 }
1261 } // end outer while loop
1262
1263 if(v2->next)
1264 {
1265 // add last triangle
1266 //
1267 v2=v2->next;
1268 p1=G4ThreeVector((v2)->x,(v2)->y,(v2)->z);
1269 p2=G4ThreeVector((v2->next)->x,(v2->next)->y,(v2->next)->z);
1270 p3=G4ThreeVector((v2->prev)->x,(v2->prev)->y,(v2->prev)->z);
1271 G4double result1 = SurfaceTriangle(p1,p2,p3,&p4 );
1272 points.push_back(p4);
1273 areas.push_back(result1);
1274 area=area+result1;
1275 }
1276
1277 // Surface Area is stored
1278 //
1279 fSurfaceArea = area;
1280
1281 // Second Step: choose randomly one surface
1282 //
1283 G4double chose = area*G4UniformRand();
1284
1285 // Third Step: Get a point on choosen surface
1286 //
1287 G4double Achose1, Achose2;
1288 Achose1=0; Achose2=0.;
1289 i=0;
1290 do
1291 {
1292 Achose2+=areas[i];
1293 if(chose>=Achose1 && chose<Achose2)
1294 {
1295 G4ThreeVector point;
1296 point=points[i] ;
1297 surface_point=point;
1298 break;
1299 }
1300 i++; Achose1=Achose2;
1301 } while( i<numEdges-2 );
1302
1303 delete [] tri_help;
1304 tri_help = 0;
1305}
G4double SurfaceTriangle(G4ThreeVector p1, G4ThreeVector p2, G4ThreeVector p3, G4ThreeVector *p4)

Referenced by GetPointOnFace(), and SurfaceArea().

Member Data Documentation

◆ allBehind

G4bool G4PolyPhiFace::allBehind
protected

Definition at line 231 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), G4PolyPhiFace(), and Intersect().

◆ corners

◆ edges

G4PolyPhiFaceEdge* G4PolyPhiFace::edges
protected

Definition at line 222 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), G4PolyPhiFace(), InsideEdges(), operator=(), and ~G4PolyPhiFace().

◆ fSurfaceArea

G4double G4PolyPhiFace::fSurfaceArea
protected

Definition at line 234 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), SurfaceArea(), and Triangulate().

◆ kCarTolerance

G4double G4PolyPhiFace::kCarTolerance
protected

Definition at line 233 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), Distance(), G4PolyPhiFace(), and InsideEdgesExact().

◆ normal

G4ThreeVector G4PolyPhiFace::normal
protected

◆ numEdges

G4int G4PolyPhiFace::numEdges
protected

◆ radial

G4ThreeVector G4PolyPhiFace::radial
protected

◆ rMax

G4double G4PolyPhiFace::rMax
protected

Definition at line 229 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), G4PolyPhiFace(), InsideEdges(), and InsideEdgesExact().

◆ rMin

G4double G4PolyPhiFace::rMin
protected

Definition at line 229 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), G4PolyPhiFace(), and InsideEdgesExact().

◆ surface

G4ThreeVector G4PolyPhiFace::surface
protected

Definition at line 226 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), Distance(), G4PolyPhiFace(), Inside(), and Intersect().

◆ surface_point

G4ThreeVector G4PolyPhiFace::surface_point
protected

Definition at line 227 of file G4PolyPhiFace.hh.

Referenced by GetPointOnFace(), and Triangulate().

◆ triangles

G4PolyPhiFaceVertex* G4PolyPhiFace::triangles
protected

Definition at line 235 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), Diagonalie(), EarInit(), and Triangulate().

◆ zMax

G4double G4PolyPhiFace::zMax
protected

Definition at line 230 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), G4PolyPhiFace(), InsideEdges(), and InsideEdgesExact().

◆ zMin

G4double G4PolyPhiFace::zMin
protected

Definition at line 230 of file G4PolyPhiFace.hh.

Referenced by CopyStuff(), G4PolyPhiFace(), and InsideEdgesExact().


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