Geant4 10.7.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=nullptr, G4ThreeVector **head3Dnorm=nullptr)
 
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 = nullptr
 
G4PolyPhiFaceVertexcorners = nullptr
 
G4ThreeVector normal
 
G4ThreeVector radial
 
G4ThreeVector surface
 
G4ThreeVector surface_point
 
G4double rMin
 
G4double rMax
 
G4double zMin
 
G4double zMax
 
G4bool allBehind = false
 
G4double kCarTolerance
 
G4double fSurfaceArea = 0.0
 
G4PolyPhiFaceVertextriangles = nullptr
 

Detailed Description

Definition at line 75 of file G4PolyPhiFace.hh.

Constructor & Destructor Documentation

◆ G4PolyPhiFace() [1/3]

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

Definition at line 51 of file G4PolyPhiFace.cc.

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

◆ ~G4PolyPhiFace()

G4PolyPhiFace::~G4PolyPhiFace ( )
virtual

Definition at line 284 of file G4PolyPhiFace.cc.

285{
286 delete [] edges;
287 delete [] corners;
288}

◆ G4PolyPhiFace() [2/3]

G4PolyPhiFace::G4PolyPhiFace ( const G4PolyPhiFace source)

Definition at line 294 of file G4PolyPhiFace.cc.

295 : G4VCSGface()
296{
297 CopyStuff( source );
298}
void CopyStuff(const G4PolyPhiFace &source)

◆ G4PolyPhiFace() [3/3]

G4PolyPhiFace::G4PolyPhiFace ( __void__ &  )

Definition at line 275 of file G4PolyPhiFace.cc.

276 : numEdges(0), rMin(0.), rMax(0.), zMin(0.), zMax(0.), kCarTolerance(0.)
277{
278}

Member Function Documentation

◆ Area2()

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

Definition at line 916 of file G4PolyPhiFace.cc.

919{
920 return ((b.x()-a.x())*(c.y()-a.y())-
921 (c.x()-a.x())*(b.y()-a.y()));
922}
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 969 of file G4PolyPhiFace.cc.

970{
971 if( !Collinear(a,b,c) ) { return false; }
972
973 if(a.x()!=b.x())
974 {
975 return ((a.x()<=c.x())&&(c.x()<=b.x()))||
976 ((a.x()>=c.x())&&(c.x()>=b.x()));
977 }
978 else
979 {
980 return ((a.y()<=c.y())&&(c.y()<=b.y()))||
981 ((a.y()>=c.y())&&(c.y()>=b.y()));
982 }
983}
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 599 of file G4PolyPhiFace.cc.

603{
604 //
605 // Construct a (sometimes big) clippable polygon,
606 //
607 // Perform the necessary transformations while doing so
608 //
609 G4ClippablePolygon polygon;
610
612 do // Loop checking, 13.08.2015, G.Cosmo
613 {
614 G4ThreeVector point( 0, 0, corner->z );
615 point += radial*corner->r;
616
617 polygon.AddVertexInOrder( transform.TransformPoint( point ) );
618 } while( ++corner < corners + numEdges );
619
620 //
621 // Clip away
622 //
623 if (polygon.PartialClip( voxelLimit, axis ))
624 {
625 //
626 // Add it to the list
627 //
628 polygon.SetNormal( transform.TransformAxis(normal) );
629 extentList.AddSurface( polygon );
630 }
631}
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 944 of file G4PolyPhiFace.cc.

947{
948 return Area2(a,b,c)==0;
949}
G4double Area2(G4TwoVector a, G4TwoVector b, G4TwoVector c)

Referenced by Between(), and IntersectProp().

◆ CopyStuff()

void G4PolyPhiFace::CopyStuff ( const G4PolyPhiFace source)
protected

Definition at line 320 of file G4PolyPhiFace.cc.

321{
322 //
323 // The simple stuff
324 //
325 numEdges = source.numEdges;
326 normal = source.normal;
327 radial = source.radial;
328 surface = source.surface;
329 rMin = source.rMin;
330 rMax = source.rMax;
331 zMin = source.zMin;
332 zMax = source.zMax;
333 allBehind = source.allBehind;
334 triangles = nullptr;
335
337 fSurfaceArea = source.fSurfaceArea;
338
339 //
340 // Corner dynamic array
341 //
344 *sourceCorn = source.corners;
345 do // Loop checking, 13.08.2015, G.Cosmo
346 {
347 *corn = *sourceCorn;
348 } while( ++sourceCorn, ++corn < corners+numEdges );
349
350 //
351 // Edge dynamic array
352 //
354
356 * here = corners;
357 G4PolyPhiFaceEdge* edge = edges,
358 * sourceEdge = source.edges;
359 do // Loop checking, 13.08.2015, G.Cosmo
360 {
361 *edge = *sourceEdge;
362 edge->v0 = prev;
363 edge->v1 = here;
364 } while( ++sourceEdge, ++edge, prev=here, ++here < corners+numEdges );
365}
G4double fSurfaceArea
G4PolyPhiFaceVertex * triangles

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

◆ Diagnose()

void G4PolyPhiFace::Diagnose ( G4VSolid solid)

Definition at line 258 of file G4PolyPhiFace.cc.

259{
261 do // Loop checking, 13.08.2015, G.Cosmo
262 {
263 G4ThreeVector test(corner->x, corner->y, corner->z);
264 test -= 1E-6*corner->norm3D;
265
266 if (owner->Inside(test) != kInside)
267 G4Exception( "G4PolyPhiFace::Diagnose()", "GeomSolids0002",
268 FatalException, "Bad vertex normal found." );
269 } while( ++corner < corners+numEdges );
270}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
@ kInside
Definition: geomdefs.hh:70

◆ Diagonal()

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

Definition at line 1065 of file G4PolyPhiFace.cc.

1066{
1067 return InCone(a,b) && InCone(b,a) && Diagonalie(a,b);
1068}
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 1006 of file G4PolyPhiFace.cc.

1008{
1010 G4PolyPhiFaceVertex *corner_next=triangles;
1011
1012 // For each Edge (corner,corner_next)
1013 do // Loop checking, 13.08.2015, G.Cosmo
1014 {
1015 corner_next=corner->next;
1016
1017 // Skip edges incident to a of b
1018 //
1019 if( (corner!=a)&&(corner_next!=a)
1020 &&(corner!=b)&&(corner_next!=b) )
1021 {
1022 G4TwoVector rz1,rz2,rz3,rz4;
1023 rz1 = G4TwoVector(a->r,a->z);
1024 rz2 = G4TwoVector(b->r,b->z);
1025 rz3 = G4TwoVector(corner->r,corner->z);
1026 rz4 = G4TwoVector(corner_next->r,corner_next->z);
1027 if( Intersect(rz1,rz2,rz3,rz4) ) { return false; }
1028 }
1029 corner=corner->next;
1030
1031 } while( corner != triangles );
1032
1033 return true;
1034}
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:36
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 424 of file G4PolyPhiFace.cc.

425{
426 G4double normSign = outgoing ? +1 : -1;
427 //
428 // Correct normal?
429 //
430 G4ThreeVector ps = p - surface;
431 G4double distPhi = -normSign*normal.dot(ps);
432
433 if (distPhi < -0.5*kCarTolerance)
434 return kInfinity;
435 else if (distPhi < 0)
436 distPhi = 0.0;
437
438 //
439 // Calculate projected point in r,z
440 //
441 G4double r = radial.dot(p);
442
443 //
444 // Are we inside the face?
445 //
446 G4double distRZ2;
447
448 if (InsideEdges( r, p.z(), &distRZ2, 0 ))
449 {
450 //
451 // Yup, answer is just distPhi
452 //
453 return distPhi;
454 }
455 else
456 {
457 //
458 // Nope. Penalize by distance out
459 //
460 return std::sqrt( distPhi*distPhi + distRZ2 );
461 }
462}
double z() const
double dot(const Hep3Vector &) const
G4bool InsideEdges(G4double r, G4double z)

◆ EarInit()

void G4PolyPhiFace::EarInit ( )
protected

Definition at line 1073 of file G4PolyPhiFace.cc.

1074{
1076 G4PolyPhiFaceVertex* c_prev, *c_next;
1077
1078 do // Loop checking, 13.08.2015, G.Cosmo
1079 {
1080 // We need to determine three consecutive vertices
1081 //
1082 c_next=corner->next;
1083 c_prev=corner->prev;
1084
1085 // Calculation of ears
1086 //
1087 corner->ear=Diagonal(c_prev,c_next);
1088 corner=corner->next;
1089
1090 } while( corner!=triangles );
1091}
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 579 of file G4PolyPhiFace.cc.

580{
581 G4double max = -kInfinity;
582
584 do // Loop checking, 13.08.2015, G.Cosmo
585 {
586 G4double here = axis.x()*corner->r*radial.x()
587 + axis.y()*corner->r*radial.y()
588 + axis.z()*corner->z;
589 if (here > max) max = here;
590 } while( ++corner < corners + numEdges );
591
592 return max;
593}
T max(const T t1, const T t2)
brief Return the largest of the two arguments

◆ GetPointOnFace()

G4ThreeVector G4PolyPhiFace::GetPointOnFace ( )
virtual

Implements G4VCSGface.

Definition at line 904 of file G4PolyPhiFace.cc.

905{
906 Triangulate();
907 return surface_point;
908}
G4ThreeVector surface_point

◆ InCone()

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

Definition at line 1039 of file G4PolyPhiFace.cc.

1040{
1041 // a0,a and a1 are consecutive vertices
1042 //
1044 a1=a->next;
1045 a0=a->prev;
1046
1047 G4TwoVector arz,arz0,arz1,brz;
1048 arz=G4TwoVector(a->r,a->z);arz0=G4TwoVector(a0->r,a0->z);
1049 arz1=G4TwoVector(a1->r,a1->z);brz=G4TwoVector(b->r,b->z);
1050
1051
1052 if(LeftOn(arz,arz1,arz0)) // If a is convex vertex
1053 {
1054 return Left(arz,brz,arz0)&&Left(brz,arz,arz1);
1055 }
1056 else // Else a is reflex
1057 {
1058 return !( LeftOn(arz,brz,arz1)&&LeftOn(brz,arz,arz0));
1059 }
1060}
const G4double a0
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 466 of file G4PolyPhiFace.cc.

469{
470 //
471 // Get distance along phi, which if negative means the point
472 // is nominally inside the shape.
473 //
474 G4ThreeVector ps = p - surface;
475 G4double distPhi = normal.dot(ps);
476
477 //
478 // Calculate projected point in r,z
479 //
480 G4double r = radial.dot(p);
481
482 //
483 // Are we inside the face?
484 //
485 G4double distRZ2;
486 G4PolyPhiFaceVertex* base3Dnorm = nullptr;
487 G4ThreeVector* head3Dnorm = nullptr;
488
489 if (InsideEdges( r, p.z(), &distRZ2, &base3Dnorm, &head3Dnorm ))
490 {
491 //
492 // Looks like we're inside. Distance is distance in phi.
493 //
494 *bestDistance = std::fabs(distPhi);
495
496 //
497 // Use distPhi to decide fate
498 //
499 if (distPhi < -tolerance) return kInside;
500 if (distPhi < tolerance) return kSurface;
501 return kOutside;
502 }
503 else
504 {
505 //
506 // We're outside the extent of the face,
507 // so the distance is penalized by distance from edges in RZ
508 //
509 *bestDistance = std::sqrt( distPhi*distPhi + distRZ2 );
510
511 //
512 // Use edge normal to decide fate
513 //
514 G4ThreeVector cc( base3Dnorm->r*radial.x(),
515 base3Dnorm->r*radial.y(),
516 base3Dnorm->z );
517 cc = p - cc;
518 G4double normDist = head3Dnorm->dot(cc);
519 if ( distRZ2 > tolerance*tolerance )
520 {
521 //
522 // We're far enough away that kSurface is not possible
523 //
524 return normDist < 0 ? kInside : kOutside;
525 }
526
527 if (normDist < -tolerance) return kInside;
528 if (normDist < tolerance) return kSurface;
529 return kOutside;
530 }
531}
@ kOutside
Definition: geomdefs.hh:68
@ kSurface
Definition: geomdefs.hh:69

◆ InsideEdges() [1/2]

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

Definition at line 778 of file G4PolyPhiFace.cc.

779{
780 //
781 // Quick check of extent
782 //
783 if ( r < rMin || r > rMax ) return false;
784 if ( z < zMin || z > zMax ) return false;
785
786 //
787 // More thorough check
788 //
789 G4double notUsed;
790
791 return InsideEdges( r, z, &notUsed, 0 );
792}

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

◆ InsideEdges() [2/2]

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

Definition at line 798 of file G4PolyPhiFace.cc.

802{
803 G4double bestDistance2 = kInfinity;
804 G4bool answer = false;
805
806 G4PolyPhiFaceEdge* edge = edges;
807 do // Loop checking, 13.08.2015, G.Cosmo
808 {
809 G4PolyPhiFaceVertex* testMe;
810 //
811 // Get distance perpendicular to the edge
812 //
813 G4double dr = (r-edge->v0->r), dz = (z-edge->v0->z);
814
815 G4double distOut = dr*edge->tz - dz*edge->tr;
816 G4double distance2 = distOut*distOut;
817 if (distance2 > bestDistance2) continue; // No hope!
818
819 //
820 // Check to see if normal intersects edge within the edge's boundary
821 //
822 G4double q = dr*edge->tr + dz*edge->tz;
823
824 //
825 // If it doesn't, penalize distance2 appropriately
826 //
827 if (q < 0)
828 {
829 distance2 += q*q;
830 testMe = edge->v0;
831 }
832 else if (q > edge->length)
833 {
834 G4double s2 = q-edge->length;
835 distance2 += s2*s2;
836 testMe = edge->v1;
837 }
838 else
839 {
840 testMe = nullptr;
841 }
842
843 //
844 // Closest edge so far?
845 //
846 if (distance2 < bestDistance2)
847 {
848 bestDistance2 = distance2;
849 if (testMe)
850 {
851 G4double distNorm = dr*testMe->rNorm + dz*testMe->zNorm;
852 answer = (distNorm <= 0);
853 if (base3Dnorm)
854 {
855 *base3Dnorm = testMe;
856 *head3Dnorm = &testMe->norm3D;
857 }
858 }
859 else
860 {
861 answer = (distOut <= 0);
862 if (base3Dnorm)
863 {
864 *base3Dnorm = edge->v0;
865 *head3Dnorm = &edge->norm3D;
866 }
867 }
868 }
869 } while( ++edge < edges + numEdges );
870
871 *bestDist2 = bestDistance2;
872 return answer;
873}

◆ InsideEdgesExact()

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

Definition at line 648 of file G4PolyPhiFace.cc.

652{
653 //
654 // Quick check of extent
655 //
656 if ( (r < rMin-kCarTolerance)
657 || (r > rMax+kCarTolerance) ) return false;
658
659 if ( (z < zMin-kCarTolerance)
660 || (z > zMax+kCarTolerance) ) return false;
661
662 //
663 // Exact check: loop over all vertices
664 //
665 G4double qx = p.x() + v.x(),
666 qy = p.y() + v.y(),
667 qz = p.z() + v.z();
668
669 G4int answer = 0;
671 *prev = corners+numEdges-1;
672
673 G4double cornZ, prevZ;
674
675 prevZ = ExactZOrder( z, qx, qy, qz, v, normSign, prev );
676 do // Loop checking, 13.08.2015, G.Cosmo
677 {
678 //
679 // Get z order of this vertex, and compare to previous vertex
680 //
681 cornZ = ExactZOrder( z, qx, qy, qz, v, normSign, corn );
682
683 if (cornZ < 0)
684 {
685 if (prevZ < 0) continue;
686 }
687 else if (cornZ > 0)
688 {
689 if (prevZ > 0) continue;
690 }
691 else
692 {
693 //
694 // By chance, we overlap exactly (within precision) with
695 // the current vertex. Continue if the same happened previously
696 // (e.g. the previous vertex had the same z value)
697 //
698 if (prevZ == 0) continue;
699
700 //
701 // Otherwise, to decide what to do, we need to know what is
702 // coming up next. Specifically, we need to find the next vertex
703 // with a non-zero z order.
704 //
705 // One might worry about infinite loops, but the above conditional
706 // should prevent it
707 //
708 G4PolyPhiFaceVertex *next = corn;
709 G4double nextZ;
710 do // Loop checking, 13.08.2015, G.Cosmo
711 {
712 ++next;
713 if (next == corners+numEdges) next = corners;
714
715 nextZ = ExactZOrder( z, qx, qy, qz, v, normSign, next );
716 } while( nextZ == 0 );
717
718 //
719 // If we won't be changing direction, go to the next vertex
720 //
721 if (nextZ*prevZ < 0) continue;
722 }
723
724
725 //
726 // We overlap in z with the side of the face that stretches from
727 // vertex "prev" to "corn". On which side (left or right) do
728 // we lay with respect to this segment?
729 //
730 G4ThreeVector qa( qx - prev->x, qy - prev->y, qz - prev->z ),
731 qb( qx - corn->x, qy - corn->y, qz - corn->z );
732
733 G4double aboveOrBelow = normSign*qa.cross(qb).dot(v);
734
735 if (aboveOrBelow > 0)
736 ++answer;
737 else if (aboveOrBelow < 0)
738 --answer;
739 else
740 {
741 //
742 // A precisely zero answer here means we exactly
743 // intersect (within roundoff) the edge of the face.
744 // Return true in this case.
745 //
746 return true;
747 }
748 } while( prevZ = cornZ, prev=corn, ++corn < corners+numEdges );
749
750 return answer!=0;
751}
int G4int
Definition: G4Types.hh:85
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 369 of file G4PolyPhiFace.cc.

377{
378 G4double normSign = outgoing ? +1 : -1;
379
380 //
381 // These don't change
382 //
383 isAllBehind = allBehind;
384 aNormal = normal;
385
386 //
387 // Correct normal? Here we have straight sides, and can safely ignore
388 // intersections where the dot product with the normal is zero.
389 //
390 G4double dotProd = normSign*normal.dot(v);
391
392 if (dotProd <= 0) return false;
393
394 //
395 // Calculate distance to surface. If the side is too far
396 // behind the point, we must reject it.
397 //
398 G4ThreeVector ps = p - surface;
399 distFromSurface = -normSign*ps.dot(normal);
400
401 if (distFromSurface < -surfTolerance) return false;
402
403 //
404 // Calculate precise distance to intersection with the side
405 // (along the trajectory, not normal to the surface)
406 //
407 distance = distFromSurface/dotProd;
408
409 //
410 // Calculate intersection point in r,z
411 //
412 G4ThreeVector ip = p + distance*v;
413
414 G4double r = radial.dot(ip);
415
416 //
417 // And is it inside the r/z extent?
418 //
419 return InsideEdgesExact( r, ip.z(), normSign, p, v );
420}
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 988 of file G4PolyPhiFace.cc.

991{
992 if( IntersectProp(a,b,c,d) )
993 { return true; }
994 else if( Between(a,b,c)||
995 Between(a,b,d)||
996 Between(c,d,a)||
997 Between(c,d,b) )
998 { return true; }
999 else
1000 { return false; }
1001}
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 954 of file G4PolyPhiFace.cc.

957{
958 if( Collinear(a,b,c) || Collinear(a,b,d)||
959 Collinear(c,d,a) || Collinear(c,d,b) ) { return false; }
960
961 G4bool Positive;
962 Positive = !(Left(a,b,c))^!(Left(a,b,d));
963 return Positive && (!Left(c,d,a)^!Left(c,d,b));
964}

Referenced by Intersect().

◆ Left()

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

Definition at line 926 of file G4PolyPhiFace.cc.

929{
930 return Area2(a,b,c)>0;
931}

Referenced by InCone(), and IntersectProp().

◆ LeftOn()

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

Definition at line 935 of file G4PolyPhiFace.cc.

938{
939 return Area2(a,b,c)>=0;
940}

Referenced by InCone().

◆ Normal()

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

Implements G4VCSGface.

Definition at line 538 of file G4PolyPhiFace.cc.

540{
541 //
542 // Get distance along phi, which if negative means the point
543 // is nominally inside the shape.
544 //
545 G4double distPhi = normal.dot(p);
546
547 //
548 // Calculate projected point in r,z
549 //
550 G4double r = radial.dot(p);
551
552 //
553 // Are we inside the face?
554 //
555 G4double distRZ2;
556
557 if (InsideEdges( r, p.z(), &distRZ2, 0 ))
558 {
559 //
560 // Yup, answer is just distPhi
561 //
562 *bestDistance = std::fabs(distPhi);
563 }
564 else
565 {
566 //
567 // Nope. Penalize by distance out
568 //
569 *bestDistance = std::sqrt( distPhi*distPhi + distRZ2 );
570 }
571
572 return normal;
573}

◆ operator=()

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

Definition at line 304 of file G4PolyPhiFace.cc.

305{
306 if (this == &source) { return *this; }
307
308 delete [] edges;
309 delete [] corners;
310
311 CopyStuff( source );
312
313 return *this;
314}

◆ SurfaceArea()

G4double G4PolyPhiFace::SurfaceArea ( )
virtual

Implements G4VCSGface.

Definition at line 896 of file G4PolyPhiFace.cc.

897{
898 if ( fSurfaceArea==0. ) { Triangulate(); }
899 return fSurfaceArea;
900}

◆ SurfaceTriangle()

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

Definition at line 878 of file G4PolyPhiFace.cc.

882{
883 G4ThreeVector v, w;
884
885 v = p3 - p1;
886 w = p1 - p2;
887 G4double lambda1 = G4UniformRand();
888 G4double lambda2 = lambda1*G4UniformRand();
889
890 *p4=p2 + lambda1*w + lambda2*v;
891 return 0.5*(v.cross(w)).mag();
892}
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector cross(const Hep3Vector &) const

Referenced by Triangulate().

◆ Triangulate()

void G4PolyPhiFace::Triangulate ( )
protected

Definition at line 1096 of file G4PolyPhiFace.cc.

1097{
1098 // The copy of Polycone is made and this copy is reordered in order to
1099 // have a list of triangles. This list is used for GetPointOnFace().
1100
1102 triangles = tri_help;
1104
1105 std::vector<G4double> areas;
1106 std::vector<G4ThreeVector> points;
1107 G4double area=0.;
1108 G4PolyPhiFaceVertex *v0,*v1,*v2,*v3,*v4;
1109 v2=triangles;
1110
1111 // Make copy for prev/next for triang=corners
1112 //
1113 G4PolyPhiFaceVertex* helper = corners;
1114 G4PolyPhiFaceVertex* helper2 = corners;
1115 do // Loop checking, 13.08.2015, G.Cosmo
1116 {
1117 triang->r = helper->r;
1118 triang->z = helper->z;
1119 triang->x = helper->x;
1120 triang->y= helper->y;
1121
1122 // add pointer on prev corner
1123 //
1124 if( helper==corners )
1125 { triang->prev=triangles+numEdges-1; }
1126 else
1127 { triang->prev=helper2; }
1128
1129 // add pointer on next corner
1130 //
1131 if( helper<corners+numEdges-1 )
1132 { triang->next=triang+1; }
1133 else
1134 { triang->next=triangles; }
1135 helper2=triang;
1136 helper=helper->next;
1137 triang=triang->next;
1138
1139 } while( helper!=corners );
1140
1141 EarInit();
1142
1144 G4int i=0;
1145 G4ThreeVector p1,p2,p3,p4;
1146 const G4int max_n_loops=numEdges*10000; // protection against infinite loop
1147
1148 // Each step of outer loop removes one ear
1149 //
1150 while(n>3) // Loop checking, 13.08.2015, G.Cosmo
1151 { // Inner loop searches for one ear
1152 v2=triangles;
1153 do // Loop checking, 13.08.2015, G.Cosmo
1154 {
1155 if(v2->ear) // Ear found. Fill variables
1156 {
1157 // (v1,v3) is diagonal
1158 //
1159 v3=v2->next; v4=v3->next;
1160 v1=v2->prev; v0=v1->prev;
1161
1162 // Calculate areas and points
1163
1164 p1=G4ThreeVector((v2)->x,(v2)->y,(v2)->z);
1165 p2=G4ThreeVector((v1)->x,(v1)->y,(v1)->z);
1166 p3=G4ThreeVector((v3)->x,(v3)->y,(v3)->z);
1167
1168 G4double result1 = SurfaceTriangle(p1,p2,p3,&p4 );
1169 points.push_back(p4);
1170 areas.push_back(result1);
1171 area=area+result1;
1172
1173 // Update earity of diagonal endpoints
1174 //
1175 v1->ear=Diagonal(v0,v3);
1176 v3->ear=Diagonal(v1,v4);
1177
1178 // Cut off the ear v2
1179 // Has to be done for a copy and not for real PolyPhiFace
1180 //
1181 v1->next=v3;
1182 v3->prev=v1;
1183 triangles=v3; // In case the head was v2
1184 --n;
1185
1186 break; // out of inner loop
1187 } // end if ear found
1188
1189 v2=v2->next;
1190
1191 } while( v2!=triangles );
1192
1193 ++i;
1194 if(i>=max_n_loops)
1195 {
1196 G4Exception( "G4PolyPhiFace::Triangulation()",
1197 "GeomSolids0003", FatalException,
1198 "Maximum number of steps is reached for triangulation!" );
1199 }
1200 } // end outer while loop
1201
1202 if(v2->next)
1203 {
1204 // add last triangle
1205 //
1206 v2=v2->next;
1207 p1=G4ThreeVector((v2)->x,(v2)->y,(v2)->z);
1208 p2=G4ThreeVector((v2->next)->x,(v2->next)->y,(v2->next)->z);
1209 p3=G4ThreeVector((v2->prev)->x,(v2->prev)->y,(v2->prev)->z);
1210 G4double result1 = SurfaceTriangle(p1,p2,p3,&p4 );
1211 points.push_back(p4);
1212 areas.push_back(result1);
1213 area=area+result1;
1214 }
1215
1216 // Surface Area is stored
1217 //
1218 fSurfaceArea = area;
1219
1220 // Second Step: choose randomly one surface
1221 //
1222 G4double chose = area*G4UniformRand();
1223
1224 // Third Step: Get a point on choosen surface
1225 //
1226 G4double Achose1, Achose2;
1227 Achose1=0; Achose2=0.;
1228 i=0;
1229 do // Loop checking, 13.08.2015, G.Cosmo
1230 {
1231 Achose2+=areas[i];
1232 if(chose>=Achose1 && chose<Achose2)
1233 {
1234 G4ThreeVector point;
1235 point=points[i] ;
1236 surface_point=point;
1237 break;
1238 }
1239 i++; Achose1=Achose2;
1240 } while( i<numEdges-2 );
1241
1242 delete [] tri_help;
1243 tri_help = nullptr;
1244}
G4double SurfaceTriangle(G4ThreeVector p1, G4ThreeVector p2, G4ThreeVector p3, G4ThreeVector *p4)

Referenced by GetPointOnFace(), and SurfaceArea().

Member Data Documentation

◆ allBehind

G4bool G4PolyPhiFace::allBehind = false
protected

Definition at line 221 of file G4PolyPhiFace.hh.

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

◆ corners

G4PolyPhiFaceVertex* G4PolyPhiFace::corners = nullptr
protected

◆ edges

G4PolyPhiFaceEdge* G4PolyPhiFace::edges = nullptr
protected

Definition at line 212 of file G4PolyPhiFace.hh.

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

◆ fSurfaceArea

G4double G4PolyPhiFace::fSurfaceArea = 0.0
protected

Definition at line 224 of file G4PolyPhiFace.hh.

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

◆ kCarTolerance

G4double G4PolyPhiFace::kCarTolerance
protected

Definition at line 223 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 219 of file G4PolyPhiFace.hh.

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

◆ rMin

G4double G4PolyPhiFace::rMin
protected

Definition at line 219 of file G4PolyPhiFace.hh.

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

◆ surface

G4ThreeVector G4PolyPhiFace::surface
protected

Definition at line 216 of file G4PolyPhiFace.hh.

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

◆ surface_point

G4ThreeVector G4PolyPhiFace::surface_point
protected

Definition at line 217 of file G4PolyPhiFace.hh.

Referenced by GetPointOnFace(), and Triangulate().

◆ triangles

G4PolyPhiFaceVertex* G4PolyPhiFace::triangles = nullptr
protected

Definition at line 225 of file G4PolyPhiFace.hh.

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

◆ zMax

G4double G4PolyPhiFace::zMax
protected

Definition at line 220 of file G4PolyPhiFace.hh.

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

◆ zMin

G4double G4PolyPhiFace::zMin
protected

Definition at line 220 of file G4PolyPhiFace.hh.

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


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