Geant4 11.1.1
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 914 of file G4PolyPhiFace.cc.

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

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

945{
946 return Area2(a,b,c)==0;
947}
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:59
@ kInside
Definition: geomdefs.hh:70

◆ Diagonal()

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

Definition at line 1063 of file G4PolyPhiFace.cc.

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

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

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

903{
904 Triangulate();
905 return surface_point;
906}
G4ThreeVector surface_point

◆ InCone()

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

Definition at line 1037 of file G4PolyPhiFace.cc.

1038{
1039 // a0,a and a1 are consecutive vertices
1040 //
1042 a1=a->next;
1043 a0=a->prev;
1044
1045 G4TwoVector arz,arz0,arz1,brz;
1046 arz=G4TwoVector(a->r,a->z);arz0=G4TwoVector(a0->r,a0->z);
1047 arz1=G4TwoVector(a1->r,a1->z);brz=G4TwoVector(b->r,b->z);
1048
1049
1050 if(LeftOn(arz,arz1,arz0)) // If a is convex vertex
1051 {
1052 return Left(arz,brz,arz0)&&Left(brz,arz,arz1);
1053 }
1054 else // Else a is reflex
1055 {
1056 return !( LeftOn(arz,brz,arz1)&&LeftOn(brz,arz,arz0));
1057 }
1058}
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 = nullptr;
810 G4PolyPhiFaceVertex* v0_vertex = edge->v0;
811 G4PolyPhiFaceVertex* v1_vertex = edge->v1;
812 //
813 // Get distance perpendicular to the edge
814 //
815 G4double dr = (r-v0_vertex->r), dz = (z-v0_vertex->z);
816
817 G4double distOut = dr*edge->tz - dz*edge->tr;
818 G4double distance2 = distOut*distOut;
819 if (distance2 > bestDistance2) continue; // No hope!
820
821 //
822 // Check to see if normal intersects edge within the edge's boundary
823 //
824 G4double q = dr*edge->tr + dz*edge->tz;
825
826 //
827 // If it doesn't, penalize distance2 appropriately
828 //
829 if (q < 0)
830 {
831 distance2 += q*q;
832 testMe = v0_vertex;
833 }
834 else if (q > edge->length)
835 {
836 G4double s2 = q-edge->length;
837 distance2 += s2*s2;
838 testMe = v1_vertex;
839 }
840
841 //
842 // Closest edge so far?
843 //
844 if (distance2 < bestDistance2)
845 {
846 bestDistance2 = distance2;
847 if (testMe != nullptr)
848 {
849 G4double distNorm = dr*testMe->rNorm + dz*testMe->zNorm;
850 answer = (distNorm <= 0);
851 if (base3Dnorm != nullptr)
852 {
853 *base3Dnorm = testMe;
854 *head3Dnorm = &testMe->norm3D;
855 }
856 }
857 else
858 {
859 answer = (distOut <= 0);
860 if (base3Dnorm != nullptr)
861 {
862 *base3Dnorm = v0_vertex;
863 *head3Dnorm = &edge->norm3D;
864 }
865 }
866 }
867 } while( ++edge < edges + numEdges );
868
869 *bestDist2 = bestDistance2;
870 return answer;
871}

◆ 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 986 of file G4PolyPhiFace.cc.

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

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

Referenced by Intersect().

◆ Left()

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

Definition at line 924 of file G4PolyPhiFace.cc.

927{
928 return Area2(a,b,c)>0;
929}

Referenced by InCone(), and IntersectProp().

◆ LeftOn()

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

Definition at line 933 of file G4PolyPhiFace.cc.

936{
937 return Area2(a,b,c)>=0;
938}

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 894 of file G4PolyPhiFace.cc.

895{
896 if ( fSurfaceArea==0. ) { Triangulate(); }
897 return fSurfaceArea;
898}

◆ SurfaceTriangle()

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

Definition at line 876 of file G4PolyPhiFace.cc.

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

Referenced by Triangulate().

◆ Triangulate()

void G4PolyPhiFace::Triangulate ( )
protected

Definition at line 1094 of file G4PolyPhiFace.cc.

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