Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/specific/src/G4PolyPhiFace.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /geometry/solids/specific/src/G4PolyPhiFace.cc (Version 11.3.0) and /geometry/solids/specific/src/G4PolyPhiFace.cc (Version 9.2.p3)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // Implementation of G4PolyPhiFace, the face t << 
 27 // polyhedra at its phi opening.               << 
 28 //                                                 26 //
 29 // Author: David C. Williams (davidw@scipp.ucs <<  27 // $Id: G4PolyPhiFace.cc,v 1.15 2008/05/15 11:41:59 gcosmo Exp $
                                                   >>  28 // GEANT4 tag $Name: geant4-09-02-patch-03 $
                                                   >>  29 //
                                                   >>  30 // 
                                                   >>  31 // --------------------------------------------------------------------
                                                   >>  32 // GEANT 4 class source file
                                                   >>  33 //
                                                   >>  34 //
                                                   >>  35 // G4PolyPhiFace.cc
                                                   >>  36 //
                                                   >>  37 // Implementation of the face that bounds a polycone or polyhedra at
                                                   >>  38 // its phi opening.
                                                   >>  39 //
 30 // -------------------------------------------     40 // --------------------------------------------------------------------
 31                                                    41 
 32 #include "G4PolyPhiFace.hh"                        42 #include "G4PolyPhiFace.hh"
 33 #include "G4ClippablePolygon.hh"                   43 #include "G4ClippablePolygon.hh"
 34 #include "G4ReduciblePolygon.hh"                   44 #include "G4ReduciblePolygon.hh"
 35 #include "G4AffineTransform.hh"                    45 #include "G4AffineTransform.hh"
 36 #include "G4SolidExtentList.hh"                    46 #include "G4SolidExtentList.hh"
 37 #include "G4GeometryTolerance.hh"                  47 #include "G4GeometryTolerance.hh"
 38                                                    48 
 39 #include "Randomize.hh"                            49 #include "Randomize.hh"
 40 #include "G4TwoVector.hh"                          50 #include "G4TwoVector.hh"
 41                                                    51 
                                                   >>  52 //
 42 // Constructor                                     53 // Constructor
 43 //                                                 54 //
 44 // Points r,z should be supplied in clockwise      55 // Points r,z should be supplied in clockwise order in r,z. For example:
 45 //                                                 56 //
 46 //                [1]---------[2]         ^ R      57 //                [1]---------[2]         ^ R
 47 //                 |           |          |        58 //                 |           |          |
 48 //                 |           |          +-->     59 //                 |           |          +--> z
 49 //                [0]---------[3]                  60 //                [0]---------[3]
 50 //                                                 61 //
 51 G4PolyPhiFace::G4PolyPhiFace( const G4Reducibl <<  62 G4PolyPhiFace::G4PolyPhiFace( const G4ReduciblePolygon *rz,
 52                                     G4double p     63                                     G4double phi, 
 53                                     G4double d     64                                     G4double deltaPhi,
 54                                     G4double p     65                                     G4double phiOther )
 55 {                                                  66 {
 56   kCarTolerance = G4GeometryTolerance::GetInst     67   kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
                                                   >>  68   fSurfaceArea = 0.;  
 57                                                    69 
 58   numEdges = rz->NumVertices();                    70   numEdges = rz->NumVertices();
 59                                                <<  71   
 60   rMin = rz->Amin();                               72   rMin = rz->Amin();
 61   rMax = rz->Amax();                               73   rMax = rz->Amax();
 62   zMin = rz->Bmin();                               74   zMin = rz->Bmin();
 63   zMax = rz->Bmax();                               75   zMax = rz->Bmax();
 64                                                    76 
 65   //                                               77   //
 66   // Is this the "starting" phi edge of the tw     78   // Is this the "starting" phi edge of the two?
 67   //                                               79   //
 68   G4bool start = (phiOther > phi);                 80   G4bool start = (phiOther > phi);
 69                                                    81   
 70   //                                               82   //
 71   // Build radial vector                           83   // Build radial vector
 72   //                                               84   //
 73   radial = G4ThreeVector( std::cos(phi), std::     85   radial = G4ThreeVector( std::cos(phi), std::sin(phi), 0.0 );
 74                                                    86   
 75   //                                               87   //
 76   // Build normal                                  88   // Build normal
 77   //                                               89   //
 78   G4double zSign = start ? 1 : -1;                 90   G4double zSign = start ? 1 : -1;
 79   normal = G4ThreeVector( zSign*radial.y(), -z     91   normal = G4ThreeVector( zSign*radial.y(), -zSign*radial.x(), 0 );
 80                                                    92   
 81   //                                               93   //
 82   // Is allBehind?                                 94   // Is allBehind?
 83   //                                               95   //
 84   allBehind = (zSign*(std::cos(phiOther)*radia     96   allBehind = (zSign*(std::cos(phiOther)*radial.y() - std::sin(phiOther)*radial.x()) < 0);
 85                                                    97   
 86   //                                               98   //
 87   // Adjacent edges                                99   // Adjacent edges
 88   //                                              100   //
 89   G4double midPhi = phi + (start ? +0.5 : -0.5    101   G4double midPhi = phi + (start ? +0.5 : -0.5)*deltaPhi;
 90   G4double cosMid = std::cos(midPhi),             102   G4double cosMid = std::cos(midPhi), 
 91                  sinMid = std::sin(midPhi);       103                  sinMid = std::sin(midPhi);
                                                   >> 104 
 92   //                                              105   //
 93   // Allocate corners                             106   // Allocate corners
 94   //                                              107   //
 95   const std::size_t maxEdges = numEdges>0 ? nu << 108   corners = new G4PolyPhiFaceVertex[numEdges];
 96   corners = new G4PolyPhiFaceVertex[maxEdges]; << 
 97   //                                              109   //
 98   // Fill them                                    110   // Fill them
 99   //                                              111   //
100   G4ReduciblePolygonIterator iterRZ(rz);          112   G4ReduciblePolygonIterator iterRZ(rz);
101                                                   113   
102   G4PolyPhiFaceVertex* corn   = corners;       << 114   G4PolyPhiFaceVertex *corn = corners;
103   G4PolyPhiFaceVertex* helper = corners;       << 115   G4PolyPhiFaceVertex *helper=corners;
104                                                   116 
105   iterRZ.Begin();                                 117   iterRZ.Begin();
106   do    // Loop checking, 13.08.2015, G.Cosmo  << 118   do
107   {                                               119   {
108     corn->r = iterRZ.GetA();                      120     corn->r = iterRZ.GetA();
109     corn->z = iterRZ.GetB();                      121     corn->z = iterRZ.GetB();
110     corn->x = corn->r*radial.x();                 122     corn->x = corn->r*radial.x();
111     corn->y = corn->r*radial.y();                 123     corn->y = corn->r*radial.y();
112                                                   124 
113     // Add pointer on prev corner                 125     // Add pointer on prev corner
114     //                                            126     //
115     if( corn == corners )                         127     if( corn == corners )
116       { corn->prev = corners+maxEdges-1;}      << 128       { corn->prev = corners+numEdges-1;}
117     else                                          129     else
118       { corn->prev = helper; }                    130       { corn->prev = helper; }
119                                                   131 
120     // Add pointer on next corner                 132     // Add pointer on next corner
121     //                                            133     //
122     if( corn < corners+maxEdges-1 )            << 134     if( corn < corners+numEdges-1 )
123       { corn->next = corn+1;}                     135       { corn->next = corn+1;}
124     else                                          136     else
125       { corn->next = corners; }                   137       { corn->next = corners; }
126                                                   138 
127     helper = corn;                                139     helper = corn;
128   } while( ++corn, iterRZ.Next() );               140   } while( ++corn, iterRZ.Next() );
129                                                   141 
130   //                                              142   //
131   // Allocate edges                               143   // Allocate edges
132   //                                              144   //
133   edges = new G4PolyPhiFaceEdge[maxEdges];     << 145   edges = new G4PolyPhiFaceEdge[numEdges];
134                                                   146 
135   //                                              147   //
136   // Fill them                                    148   // Fill them
137   //                                              149   //
138   G4double rFact = std::cos(0.5*deltaPhi);        150   G4double rFact = std::cos(0.5*deltaPhi);
139   G4double rFactNormalize = 1.0/std::sqrt(1.0+    151   G4double rFactNormalize = 1.0/std::sqrt(1.0+rFact*rFact);
140                                                   152 
141   G4PolyPhiFaceVertex* prev = corners+maxEdges << 153   G4PolyPhiFaceVertex *prev = corners+numEdges-1,
142                      * here = corners;         << 154                       *here = corners;
143   G4PolyPhiFaceEdge*   edge = edges;           << 155   G4PolyPhiFaceEdge   *edge = edges;
144   do    // Loop checking, 13.08.2015, G.Cosmo  << 156   do
145   {                                               157   {
146     G4ThreeVector sideNorm;                       158     G4ThreeVector sideNorm;
147                                                   159     
148     edge->v0 = prev;                              160     edge->v0 = prev;
149     edge->v1 = here;                              161     edge->v1 = here;
150                                                   162 
151     G4double dr = here->r - prev->r,              163     G4double dr = here->r - prev->r,
152              dz = here->z - prev->z;              164              dz = here->z - prev->z;
153                                                   165                          
154     edge->length = std::sqrt( dr*dr + dz*dz );    166     edge->length = std::sqrt( dr*dr + dz*dz );
155                                                   167 
156     edge->tr = dr/edge->length;                   168     edge->tr = dr/edge->length;
157     edge->tz = dz/edge->length;                   169     edge->tz = dz/edge->length;
158                                                   170     
159     if ((here->r < DBL_MIN) && (prev->r < DBL_    171     if ((here->r < DBL_MIN) && (prev->r < DBL_MIN))
160     {                                             172     {
161       //                                          173       //
162       // Sigh! Always exceptions!                 174       // Sigh! Always exceptions!
163       // This edge runs at r==0, so its adjoin    175       // This edge runs at r==0, so its adjoing surface is not a
164       // PolyconeSide or PolyhedraSide, but th    176       // PolyconeSide or PolyhedraSide, but the opposite PolyPhiFace.
165       //                                          177       //
166       G4double zSignOther = start ? -1 : 1;       178       G4double zSignOther = start ? -1 : 1;
167       sideNorm = G4ThreeVector(  zSignOther*st    179       sideNorm = G4ThreeVector(  zSignOther*std::sin(phiOther), 
168                                 -zSignOther*st    180                                 -zSignOther*std::cos(phiOther), 0 );
169     }                                             181     }
170     else                                          182     else
171     {                                             183     {
172       sideNorm = G4ThreeVector( edge->tz*cosMi    184       sideNorm = G4ThreeVector( edge->tz*cosMid,
173                                 edge->tz*sinMi    185                                 edge->tz*sinMid,
174                                -edge->tr*rFact    186                                -edge->tr*rFact );
175       sideNorm *= rFactNormalize;                 187       sideNorm *= rFactNormalize;
176     }                                             188     }
177     sideNorm += normal;                           189     sideNorm += normal;
178                                                   190     
179     edge->norm3D = sideNorm.unit();               191     edge->norm3D = sideNorm.unit();
180   } while( edge++, prev=here, ++here < corners << 192   } while( edge++, prev=here, ++here < corners+numEdges );
181                                                   193 
182   //                                              194   //
183   // Go back and fill in corner "normals"         195   // Go back and fill in corner "normals"
184   //                                              196   //
185   G4PolyPhiFaceEdge* prevEdge = edges+maxEdges << 197   G4PolyPhiFaceEdge *prevEdge = edges+numEdges-1;
186   edge = edges;                                   198   edge = edges;
187   do    // Loop checking, 13.08.2015, G.Cosmo  << 199   do
188   {                                               200   {
189     //                                            201     //
190     // Calculate vertex 2D normals (on the phi    202     // Calculate vertex 2D normals (on the phi surface)
191     //                                            203     //
192     G4double rPart = prevEdge->tr + edge->tr;     204     G4double rPart = prevEdge->tr + edge->tr;
193     G4double zPart = prevEdge->tz + edge->tz;     205     G4double zPart = prevEdge->tz + edge->tz;
194     G4double norm = std::sqrt( rPart*rPart + z    206     G4double norm = std::sqrt( rPart*rPart + zPart*zPart );
195     G4double rNorm = +zPart/norm;                 207     G4double rNorm = +zPart/norm;
196     G4double zNorm = -rPart/norm;                 208     G4double zNorm = -rPart/norm;
197                                                   209     
198     edge->v0->rNorm = rNorm;                      210     edge->v0->rNorm = rNorm;
199     edge->v0->zNorm = zNorm;                      211     edge->v0->zNorm = zNorm;
200                                                   212     
201     //                                            213     //
202     // Calculate the 3D normals.                  214     // Calculate the 3D normals.
203     //                                            215     //
204     // Find the vector perpendicular to the z     216     // Find the vector perpendicular to the z axis
205     // that defines the plane that contains th    217     // that defines the plane that contains the vertex normal
206     //                                            218     //
207     G4ThreeVector xyVector;                       219     G4ThreeVector xyVector;
208                                                   220     
209     if (edge->v0->r < DBL_MIN)                    221     if (edge->v0->r < DBL_MIN)
210     {                                             222     {
211       //                                          223       //
212       // This is a vertex at r==0, which is a     224       // This is a vertex at r==0, which is a special
213       // case. The normal we will construct la    225       // case. The normal we will construct lays in the
214       // plane at the center of the phi openin    226       // plane at the center of the phi opening.
215       //                                          227       //
216       // We also know that rNorm < 0              228       // We also know that rNorm < 0
217       //                                          229       //
218       G4double zSignOther = start ? -1 : 1;       230       G4double zSignOther = start ? -1 : 1;
219       G4ThreeVector normalOther(  zSignOther*s    231       G4ThreeVector normalOther(  zSignOther*std::sin(phiOther), 
220                                  -zSignOther*s    232                                  -zSignOther*std::cos(phiOther), 0 );
221                                                   233                 
222       xyVector = - normal - normalOther;          234       xyVector = - normal - normalOther;
223     }                                             235     }
224     else                                          236     else
225     {                                             237     {
226       //                                          238       //
227       // This is a vertex at r > 0. The plane     239       // This is a vertex at r > 0. The plane
228       // is the average of the normal and the     240       // is the average of the normal and the
229       // normal of the adjacent phi face          241       // normal of the adjacent phi face
230       //                                          242       //
231       xyVector = G4ThreeVector( cosMid, sinMid    243       xyVector = G4ThreeVector( cosMid, sinMid, 0 );
232       if (rNorm < 0)                              244       if (rNorm < 0)
233         xyVector -= normal;                       245         xyVector -= normal;
234       else                                        246       else
235         xyVector += normal;                       247         xyVector += normal;
236     }                                             248     }
237                                                   249     
238     //                                            250     //
239     // Combine it with the r/z direction from     251     // Combine it with the r/z direction from the face
240     //                                            252     //
241     edge->v0->norm3D = rNorm*xyVector.unit() +    253     edge->v0->norm3D = rNorm*xyVector.unit() + G4ThreeVector( 0, 0, zNorm );
242   } while(  prevEdge=edge, ++edge < edges+maxE << 254   } while(  prevEdge=edge, ++edge < edges+numEdges );
243                                                   255   
244   //                                              256   //
245   // Build point on surface                       257   // Build point on surface
246   //                                              258   //
247   G4double rAve = 0.5*(rMax-rMin),                259   G4double rAve = 0.5*(rMax-rMin),
248            zAve = 0.5*(zMax-zMin);                260            zAve = 0.5*(zMax-zMin);
249   surface = G4ThreeVector( rAve*radial.x(), rA    261   surface = G4ThreeVector( rAve*radial.x(), rAve*radial.y(), zAve );
250 }                                                 262 }
251                                                   263 
                                                   >> 264 
                                                   >> 265 //
252 // Diagnose                                       266 // Diagnose
253 //                                                267 //
254 // Throw an exception if something is found in    268 // Throw an exception if something is found inconsistent with
255 // the solid.                                     269 // the solid.
256 //                                                270 //
257 // For debugging purposes only                    271 // For debugging purposes only
258 //                                                272 //
259 void G4PolyPhiFace::Diagnose( G4VSolid* owner  << 273 void G4PolyPhiFace::Diagnose( G4VSolid *owner )
260 {                                                 274 {
261   G4PolyPhiFaceVertex* corner = corners;       << 275   G4PolyPhiFaceVertex   *corner = corners;
262   do    // Loop checking, 13.08.2015, G.Cosmo  << 276   do
263   {                                               277   {
264     G4ThreeVector test(corner->x, corner->y, c    278     G4ThreeVector test(corner->x, corner->y, corner->z);
265     test -= 1E-6*corner->norm3D;                  279     test -= 1E-6*corner->norm3D;
266                                                   280     
267     if (owner->Inside(test) != kInside)           281     if (owner->Inside(test) != kInside) 
268       G4Exception( "G4PolyPhiFace::Diagnose()" << 282       G4Exception( "G4PolyPhiFace::Diagnose()", "InvalidSetup",
269                    FatalException, "Bad vertex    283                    FatalException, "Bad vertex normal found." );
270   } while( ++corner < corners+numEdges );         284   } while( ++corner < corners+numEdges );
271 }                                                 285 }
272                                                   286 
                                                   >> 287 
                                                   >> 288 //
273 // Fake default constructor - sets only member    289 // Fake default constructor - sets only member data and allocates memory
274 //                            for usage restri    290 //                            for usage restricted to object persistency.
275 //                                                291 //
276 G4PolyPhiFace::G4PolyPhiFace( __void__&)          292 G4PolyPhiFace::G4PolyPhiFace( __void__&)
277   : numEdges(0), rMin(0.), rMax(0.), zMin(0.), << 293   : edges(0), corners(0)
278 {                                                 294 {
279 }                                                 295 }
280                                                   296 
281                                                   297 
282 //                                                298 //
283 // Destructor                                     299 // Destructor
284 //                                                300 //
285 G4PolyPhiFace::~G4PolyPhiFace()                   301 G4PolyPhiFace::~G4PolyPhiFace()
286 {                                                 302 {
287   delete [] edges;                                303   delete [] edges;
288   delete [] corners;                              304   delete [] corners;
289 }                                                 305 }
290                                                   306 
291                                                   307 
292 //                                                308 //
293 // Copy constructor                               309 // Copy constructor
294 //                                                310 //
295 G4PolyPhiFace::G4PolyPhiFace( const G4PolyPhiF << 311 G4PolyPhiFace::G4PolyPhiFace( const G4PolyPhiFace &source )
                                                   >> 312   : G4VCSGface()
296 {                                                 313 {
297   CopyStuff( source );                            314   CopyStuff( source );
298 }                                                 315 }
299                                                   316 
300                                                   317 
301 //                                                318 //
302 // Assignment operator                            319 // Assignment operator
303 //                                                320 //
304 G4PolyPhiFace& G4PolyPhiFace::operator=( const << 321 G4PolyPhiFace& G4PolyPhiFace::operator=( const G4PolyPhiFace &source )
305 {                                                 322 {
306   if (this == &source)  { return *this; }      << 323   if (this == &source) return *this;
307                                                   324 
308   delete [] edges;                                325   delete [] edges;
309   delete [] corners;                              326   delete [] corners;
310                                                   327   
311   CopyStuff( source );                            328   CopyStuff( source );
312                                                   329   
313   return *this;                                   330   return *this;
314 }                                                 331 }
315                                                   332 
316                                                   333 
317 //                                                334 //
318 // CopyStuff (protected)                          335 // CopyStuff (protected)
319 //                                                336 //
320 void G4PolyPhiFace::CopyStuff( const G4PolyPhi << 337 void G4PolyPhiFace::CopyStuff( const G4PolyPhiFace &source )
321 {                                                 338 {
322   //                                              339   //
323   // The simple stuff                             340   // The simple stuff
324   //                                              341   //
325   numEdges  = source.numEdges;                    342   numEdges  = source.numEdges;
326   normal    = source.normal;                      343   normal    = source.normal;
327   radial    = source.radial;                      344   radial    = source.radial;
328   surface   = source.surface;                     345   surface   = source.surface;
329   rMin    = source.rMin;                          346   rMin    = source.rMin;
330   rMax    = source.rMax;                          347   rMax    = source.rMax;
331   zMin    = source.zMin;                          348   zMin    = source.zMin;
332   zMax    = source.zMax;                          349   zMax    = source.zMax;
333   allBehind  = source.allBehind;                  350   allBehind  = source.allBehind;
334   triangles  = nullptr;                        << 
335                                                   351 
336   kCarTolerance = source.kCarTolerance;           352   kCarTolerance = source.kCarTolerance;
337   fSurfaceArea = source.fSurfaceArea;             353   fSurfaceArea = source.fSurfaceArea;
338                                                   354 
339   const std::size_t maxEdges = (numEdges > 0)  << 
340                                                << 
341   //                                              355   //
342   // Corner dynamic array                         356   // Corner dynamic array
343   //                                              357   //
344   corners = new G4PolyPhiFaceVertex[maxEdges]; << 358   corners = new G4PolyPhiFaceVertex[numEdges];
345   G4PolyPhiFaceVertex *corn = corners,            359   G4PolyPhiFaceVertex *corn = corners,
346                       *sourceCorn = source.cor    360                       *sourceCorn = source.corners;
347   do    // Loop checking, 13.08.2015, G.Cosmo  << 361   do
348   {                                               362   {
349     *corn = *sourceCorn;                          363     *corn = *sourceCorn;
350   } while( ++sourceCorn, ++corn < corners+maxE << 364   } while( ++sourceCorn, ++corn < corners+numEdges );
351                                                   365   
352   //                                              366   //
353   // Edge dynamic array                           367   // Edge dynamic array
354   //                                              368   //
355   edges = new G4PolyPhiFaceEdge[maxEdges];     << 369   edges = new G4PolyPhiFaceEdge[numEdges];
356                                                   370 
357   G4PolyPhiFaceVertex* prev = corners+maxEdges << 371   G4PolyPhiFaceVertex *prev = corners+numEdges-1,
358                      * here = corners;         << 372                       *here = corners;
359   G4PolyPhiFaceEdge*   edge = edges,           << 373   G4PolyPhiFaceEdge   *edge = edges,
360                    *   sourceEdge = source.edg << 374                       *sourceEdge = source.edges;
361   do    // Loop checking, 13.08.2015, G.Cosmo  << 375   do
362   {                                               376   {
363     *edge = *sourceEdge;                          377     *edge = *sourceEdge;
364     edge->v0 = prev;                              378     edge->v0 = prev;
365     edge->v1 = here;                              379     edge->v1 = here;
366   } while( ++sourceEdge, ++edge, prev=here, ++ << 380   } while( ++sourceEdge, ++edge, prev=here, ++here < corners+numEdges );
367 }                                                 381 }
368                                                   382 
                                                   >> 383 
                                                   >> 384 //
369 // Intersect                                      385 // Intersect
370 //                                                386 //
371 G4bool G4PolyPhiFace::Intersect( const G4Three << 387 G4bool G4PolyPhiFace::Intersect( const G4ThreeVector &p,
372                                  const G4Three << 388                                  const G4ThreeVector &v,
373                                        G4bool     389                                        G4bool outgoing,
374                                        G4doubl    390                                        G4double surfTolerance,
375                                        G4doubl << 391                                        G4double &distance,
376                                        G4doubl << 392                                        G4double &distFromSurface,
377                                        G4Three << 393                                        G4ThreeVector &aNormal,
378                                        G4bool& << 394                                        G4bool &isAllBehind )
379 {                                                 395 {
380   G4double normSign = outgoing ? +1 : -1;         396   G4double normSign = outgoing ? +1 : -1;
381                                                   397   
382   //                                              398   //
383   // These don't change                           399   // These don't change
384   //                                              400   //
385   isAllBehind = allBehind;                        401   isAllBehind = allBehind;
386   aNormal = normal;                               402   aNormal = normal;
387                                                   403 
388   //                                              404   //
389   // Correct normal? Here we have straight sid    405   // Correct normal? Here we have straight sides, and can safely ignore
390   // intersections where the dot product with     406   // intersections where the dot product with the normal is zero.
391   //                                              407   //
392   G4double dotProd = normSign*normal.dot(v);      408   G4double dotProd = normSign*normal.dot(v);
393                                                   409   
394   if (dotProd <= 0) return false;                 410   if (dotProd <= 0) return false;
395                                                   411 
396   //                                              412   //
397   // Calculate distance to surface. If the sid    413   // Calculate distance to surface. If the side is too far
398   // behind the point, we must reject it.         414   // behind the point, we must reject it.
399   //                                              415   //
400   G4ThreeVector ps = p - surface;                 416   G4ThreeVector ps = p - surface;
401   distFromSurface = -normSign*ps.dot(normal);     417   distFromSurface = -normSign*ps.dot(normal);
402                                                   418     
403   if (distFromSurface < -surfTolerance) return    419   if (distFromSurface < -surfTolerance) return false;
404                                                   420 
405   //                                              421   //
406   // Calculate precise distance to intersectio    422   // Calculate precise distance to intersection with the side
407   // (along the trajectory, not normal to the     423   // (along the trajectory, not normal to the surface)
408   //                                              424   //
409   distance = distFromSurface/dotProd;             425   distance = distFromSurface/dotProd;
410                                                   426 
411   //                                              427   //
412   // Calculate intersection point in r,z          428   // Calculate intersection point in r,z
413   //                                              429   //
414   G4ThreeVector ip = p + distance*v;              430   G4ThreeVector ip = p + distance*v;
415                                                   431   
416   G4double r = radial.dot(ip);                    432   G4double r = radial.dot(ip);
417                                                   433   
418   //                                              434   //
419   // And is it inside the r/z extent?             435   // And is it inside the r/z extent?
420   //                                              436   //
421   return InsideEdgesExact( r, ip.z(), normSign    437   return InsideEdgesExact( r, ip.z(), normSign, p, v );
422 }                                                 438 }
423                                                   439 
                                                   >> 440 
                                                   >> 441 //
424 // Distance                                       442 // Distance
425 //                                                443 //
426 G4double G4PolyPhiFace::Distance( const G4Thre << 444 G4double G4PolyPhiFace::Distance( const G4ThreeVector &p, G4bool outgoing )
427 {                                                 445 {
428   G4double normSign = outgoing ? +1 : -1;         446   G4double normSign = outgoing ? +1 : -1;
429   //                                              447   //
430   // Correct normal?                              448   // Correct normal? 
431   //                                              449   //
432   G4ThreeVector ps = p - surface;                 450   G4ThreeVector ps = p - surface;
433   G4double distPhi = -normSign*normal.dot(ps);    451   G4double distPhi = -normSign*normal.dot(ps);
434                                                   452   
435   if (distPhi < -0.5*kCarTolerance)               453   if (distPhi < -0.5*kCarTolerance) 
436     return kInfinity;                             454     return kInfinity;
437   else if (distPhi < 0)                           455   else if (distPhi < 0)
438     distPhi = 0.0;                                456     distPhi = 0.0;
439                                                   457   
440   //                                              458   //
441   // Calculate projected point in r,z             459   // Calculate projected point in r,z
442   //                                              460   //
443   G4double r = radial.dot(p);                     461   G4double r = radial.dot(p);
444                                                   462   
445   //                                              463   //
446   // Are we inside the face?                      464   // Are we inside the face?
447   //                                              465   //
448   G4double distRZ2;                               466   G4double distRZ2;
449                                                   467   
450   if (InsideEdges( r, p.z(), &distRZ2, nullptr << 468   if (InsideEdges( r, p.z(), &distRZ2, 0 ))
451   {                                               469   {
452     //                                            470     //
453     // Yup, answer is just distPhi                471     // Yup, answer is just distPhi
454     //                                            472     //
455     return distPhi;                               473     return distPhi;
456   }                                               474   }
457   else                                            475   else
458   {                                               476   {
459     //                                            477     //
460     // Nope. Penalize by distance out             478     // Nope. Penalize by distance out
461     //                                            479     //
462     return std::sqrt( distPhi*distPhi + distRZ    480     return std::sqrt( distPhi*distPhi + distRZ2 );
463   }                                               481   }
464 }                                                 482 }  
                                                   >> 483   
465                                                   484 
                                                   >> 485 //
466 // Inside                                         486 // Inside
467 //                                                487 //
468 EInside G4PolyPhiFace::Inside( const G4ThreeVe << 488 EInside G4PolyPhiFace::Inside( const G4ThreeVector &p,
469                                      G4double     489                                      G4double tolerance, 
470                                      G4double* << 490                                      G4double *bestDistance )
471 {                                                 491 {
472   //                                              492   //
473   // Get distance along phi, which if negative    493   // Get distance along phi, which if negative means the point
474   // is nominally inside the shape.               494   // is nominally inside the shape.
475   //                                              495   //
476   G4ThreeVector ps = p - surface;                 496   G4ThreeVector ps = p - surface;
477   G4double distPhi = normal.dot(ps);              497   G4double distPhi = normal.dot(ps);
478                                                   498   
479   //                                              499   //
480   // Calculate projected point in r,z             500   // Calculate projected point in r,z
481   //                                              501   //
482   G4double r = radial.dot(p);                     502   G4double r = radial.dot(p);
483                                                   503   
484   //                                              504   //
485   // Are we inside the face?                      505   // Are we inside the face?
486   //                                              506   //
487   G4double distRZ2;                               507   G4double distRZ2;
488   G4PolyPhiFaceVertex* base3Dnorm = nullptr;   << 508   G4PolyPhiFaceVertex *base3Dnorm;
489   G4ThreeVector*       head3Dnorm = nullptr;   << 509   G4ThreeVector      *head3Dnorm;
490                                                   510   
491   if (InsideEdges( r, p.z(), &distRZ2, &base3D    511   if (InsideEdges( r, p.z(), &distRZ2, &base3Dnorm, &head3Dnorm ))
492   {                                               512   {
493     //                                            513     //
494     // Looks like we're inside. Distance is di    514     // Looks like we're inside. Distance is distance in phi.
495     //                                            515     //
496     *bestDistance = std::fabs(distPhi);           516     *bestDistance = std::fabs(distPhi);
497                                                   517     
498     //                                            518     //
499     // Use distPhi to decide fate                 519     // Use distPhi to decide fate
500     //                                            520     //
501     if (distPhi < -tolerance) return kInside;     521     if (distPhi < -tolerance) return kInside;
502     if (distPhi <  tolerance) return kSurface;    522     if (distPhi <  tolerance) return kSurface;
503     return kOutside;                              523     return kOutside;
504   }                                               524   }
505   else                                            525   else
506   {                                               526   {
507     //                                            527     //
508     // We're outside the extent of the face,      528     // We're outside the extent of the face,
509     // so the distance is penalized by distanc    529     // so the distance is penalized by distance from edges in RZ
510     //                                            530     //
511     *bestDistance = std::sqrt( distPhi*distPhi    531     *bestDistance = std::sqrt( distPhi*distPhi + distRZ2 );
512                                                   532     
513     //                                            533     //
514     // Use edge normal to decide fate             534     // Use edge normal to decide fate
515     //                                            535     //
516     G4ThreeVector cc( base3Dnorm->r*radial.x()    536     G4ThreeVector cc( base3Dnorm->r*radial.x(),
517                       base3Dnorm->r*radial.y() << 537           base3Dnorm->r*radial.y(),
518                       base3Dnorm->z );         << 538           base3Dnorm->z );
519     cc = p - cc;                                  539     cc = p - cc;
520     G4double normDist = head3Dnorm->dot(cc);      540     G4double normDist = head3Dnorm->dot(cc);
521     if ( distRZ2 > tolerance*tolerance )          541     if ( distRZ2 > tolerance*tolerance )
522     {                                             542     {
523       //                                          543       //
524       // We're far enough away that kSurface i    544       // We're far enough away that kSurface is not possible
525       //                                          545       //
526       return normDist < 0 ? kInside : kOutside    546       return normDist < 0 ? kInside : kOutside;
527     }                                             547     }
528                                                   548     
529     if (normDist < -tolerance) return kInside;    549     if (normDist < -tolerance) return kInside;
530     if (normDist <  tolerance) return kSurface    550     if (normDist <  tolerance) return kSurface;
531     return kOutside;                              551     return kOutside;
532   }                                               552   }
533 }                                                 553 }  
534                                                   554 
                                                   >> 555 
                                                   >> 556 //
535 // Normal                                         557 // Normal
536 //                                                558 //
537 // This virtual member is simple for our plane    559 // This virtual member is simple for our planer shape,
538 // which has only one normal                      560 // which has only one normal
539 //                                                561 //
540 G4ThreeVector G4PolyPhiFace::Normal( const G4T << 562 G4ThreeVector G4PolyPhiFace::Normal( const G4ThreeVector &p,
541                                            G4d << 563                                            G4double *bestDistance )
542 {                                                 564 {
543   //                                              565   //
544   // Get distance along phi, which if negative    566   // Get distance along phi, which if negative means the point
545   // is nominally inside the shape.               567   // is nominally inside the shape.
546   //                                              568   //
547   G4double distPhi = normal.dot(p);               569   G4double distPhi = normal.dot(p);
548                                                   570 
549   //                                              571   //
550   // Calculate projected point in r,z             572   // Calculate projected point in r,z
551   //                                              573   //
552   G4double r = radial.dot(p);                     574   G4double r = radial.dot(p);
553                                                   575   
554   //                                              576   //
555   // Are we inside the face?                      577   // Are we inside the face?
556   //                                              578   //
557   G4double distRZ2;                               579   G4double distRZ2;
558                                                   580   
559   if (InsideEdges( r, p.z(), &distRZ2, nullptr << 581   if (InsideEdges( r, p.z(), &distRZ2, 0 ))
560   {                                               582   {
561     //                                            583     //
562     // Yup, answer is just distPhi                584     // Yup, answer is just distPhi
563     //                                            585     //
564     *bestDistance = std::fabs(distPhi);           586     *bestDistance = std::fabs(distPhi);
565   }                                               587   }
566   else                                            588   else
567   {                                               589   {
568     //                                            590     //
569     // Nope. Penalize by distance out             591     // Nope. Penalize by distance out
570     //                                            592     //
571     *bestDistance = std::sqrt( distPhi*distPhi    593     *bestDistance = std::sqrt( distPhi*distPhi + distRZ2 );
572   }                                               594   }
573                                                   595   
574   return normal;                                  596   return normal;
575 }                                                 597 }
576                                                   598 
                                                   >> 599 
                                                   >> 600 //
577 // Extent                                         601 // Extent
578 //                                                602 //
579 // This actually isn't needed by polycone or p    603 // This actually isn't needed by polycone or polyhedra...
580 //                                                604 //
581 G4double G4PolyPhiFace::Extent( const G4ThreeV    605 G4double G4PolyPhiFace::Extent( const G4ThreeVector axis )
582 {                                                 606 {
583   G4double max = -kInfinity;                      607   G4double max = -kInfinity;
584                                                   608   
585   G4PolyPhiFaceVertex* corner = corners;       << 609   G4PolyPhiFaceVertex *corner = corners;
586   do    // Loop checking, 13.08.2015, G.Cosmo  << 610   do
587   {                                               611   {
588     G4double here = axis.x()*corner->r*radial.    612     G4double here = axis.x()*corner->r*radial.x()
589             + axis.y()*corner->r*radial.y()       613             + axis.y()*corner->r*radial.y()
590             + axis.z()*corner->z;                 614             + axis.z()*corner->z;
591     if (here > max) max = here;                   615     if (here > max) max = here;
592   } while( ++corner < corners + numEdges );       616   } while( ++corner < corners + numEdges );
593                                                   617   
594   return max;                                     618   return max;
595 }                                                 619 }  
596                                                   620 
                                                   >> 621 
                                                   >> 622 //
597 // CalculateExtent                                623 // CalculateExtent
598 //                                                624 //
599 // See notes in G4VCSGface                        625 // See notes in G4VCSGface
600 //                                                626 //
601 void G4PolyPhiFace::CalculateExtent( const EAx    627 void G4PolyPhiFace::CalculateExtent( const EAxis axis, 
602                                      const G4V << 628                                      const G4VoxelLimits &voxelLimit,
603                                      const G4A << 629                                      const G4AffineTransform &transform,
604                                            G4S << 630                                            G4SolidExtentList &extentList )
605 {                                                 631 {
606   //                                              632   //
607   // Construct a (sometimes big) clippable pol    633   // Construct a (sometimes big) clippable polygon, 
608   //                                              634   //
609   // Perform the necessary transformations whi    635   // Perform the necessary transformations while doing so
610   //                                              636   //
611   G4ClippablePolygon polygon;                     637   G4ClippablePolygon polygon;
612                                                   638   
613   G4PolyPhiFaceVertex* corner = corners;       << 639   G4PolyPhiFaceVertex *corner = corners;
614   do    // Loop checking, 13.08.2015, G.Cosmo  << 640   do
615   {                                               641   {
616     G4ThreeVector point( 0, 0, corner->z );       642     G4ThreeVector point( 0, 0, corner->z );
617     point += radial*corner->r;                    643     point += radial*corner->r;
618                                                   644     
619     polygon.AddVertexInOrder( transform.Transf    645     polygon.AddVertexInOrder( transform.TransformPoint( point ) );
620   } while( ++corner < corners + numEdges );       646   } while( ++corner < corners + numEdges );
621                                                   647   
622   //                                              648   //
623   // Clip away                                    649   // Clip away
624   //                                              650   //
625   if (polygon.PartialClip( voxelLimit, axis ))    651   if (polygon.PartialClip( voxelLimit, axis ))
626   {                                               652   {
627     //                                            653     //
628     // Add it to the list                         654     // Add it to the list
629     //                                            655     //
630     polygon.SetNormal( transform.TransformAxis    656     polygon.SetNormal( transform.TransformAxis(normal) );
631     extentList.AddSurface( polygon );             657     extentList.AddSurface( polygon );
632   }                                               658   }
633 }                                                 659 }
634                                                   660 
                                                   >> 661 
                                                   >> 662 //
                                                   >> 663 //-------------------------------------------------------
                                                   >> 664   
                                                   >> 665   
                                                   >> 666 //
635 // InsideEdgesExact                               667 // InsideEdgesExact
636 //                                                668 //
637 // Decide if the point in r,z is inside the ed    669 // Decide if the point in r,z is inside the edges of our face,
638 // **but** do so consistently with other faces    670 // **but** do so consistently with other faces.
639 //                                                671 //
640 // This routine has functionality similar to I    672 // This routine has functionality similar to InsideEdges, but uses
641 // an algorithm to decide if a trajectory fall    673 // an algorithm to decide if a trajectory falls inside or outside the
642 // face that uses only the trajectory p,v valu    674 // face that uses only the trajectory p,v values and the three dimensional
643 // points representing the edges of the polygo    675 // points representing the edges of the polygon. The objective is to plug up
644 // any leaks between touching G4PolyPhiFaces (    676 // any leaks between touching G4PolyPhiFaces (at r==0) and any other face
645 // that uses the same convention.                 677 // that uses the same convention.
646 //                                                678 //
647 // See: "Computational Geometry in C (Second E    679 // See: "Computational Geometry in C (Second Edition)"
648 // http://cs.smith.edu/~orourke/                  680 // http://cs.smith.edu/~orourke/
649 //                                                681 //
650 G4bool G4PolyPhiFace::InsideEdgesExact( G4doub    682 G4bool G4PolyPhiFace::InsideEdgesExact( G4double r, G4double z,
651                                         G4doub    683                                         G4double normSign,
652                                   const G4Thre << 684                                   const G4ThreeVector &p,
653                                   const G4Thre << 685                                   const G4ThreeVector &v )
654 {                                                 686 {
655   //                                              687   //
656   // Quick check of extent                        688   // Quick check of extent
657   //                                              689   //
658   if ( (r < rMin-kCarTolerance)                   690   if ( (r < rMin-kCarTolerance)
659     || (r > rMax+kCarTolerance) ) return false    691     || (r > rMax+kCarTolerance) ) return false;
660                                                   692        
661   if ( (z < zMin-kCarTolerance)                   693   if ( (z < zMin-kCarTolerance)
662     || (z > zMax+kCarTolerance) ) return false    694     || (z > zMax+kCarTolerance) ) return false;
663                                                   695   
664   //                                              696   //
665   // Exact check: loop over all vertices          697   // Exact check: loop over all vertices
666   //                                              698   //
667   G4double qx = p.x() + v.x(),                    699   G4double qx = p.x() + v.x(),
668            qy = p.y() + v.y(),                    700            qy = p.y() + v.y(),
669            qz = p.z() + v.z();                    701            qz = p.z() + v.z();
670                                                   702 
671   G4int answer = 0;                               703   G4int answer = 0;
672   G4PolyPhiFaceVertex *corn = corners,            704   G4PolyPhiFaceVertex *corn = corners, 
673                       *prev = corners+numEdges    705                       *prev = corners+numEdges-1;
674                                                   706 
675   G4double cornZ, prevZ;                          707   G4double cornZ, prevZ;
676                                                   708   
677   prevZ = ExactZOrder( z, qx, qy, qz, v, normS    709   prevZ = ExactZOrder( z, qx, qy, qz, v, normSign, prev );
678   do    // Loop checking, 13.08.2015, G.Cosmo  << 710   do
679   {                                               711   {
680     //                                            712     //
681     // Get z order of this vertex, and compare    713     // Get z order of this vertex, and compare to previous vertex
682     //                                            714     //
683     cornZ = ExactZOrder( z, qx, qy, qz, v, nor    715     cornZ = ExactZOrder( z, qx, qy, qz, v, normSign, corn );
684                                                   716     
685     if (cornZ < 0)                                717     if (cornZ < 0)
686     {                                             718     {
687       if (prevZ < 0) continue;                    719       if (prevZ < 0) continue;
688     }                                             720     }
689     else if (cornZ > 0)                           721     else if (cornZ > 0)
690     {                                             722     {
691       if (prevZ > 0) continue;                    723       if (prevZ > 0) continue;
692     }                                             724     }
693     else                                          725     else
694     {                                             726     {
695       //                                          727       //
696       // By chance, we overlap exactly (within    728       // By chance, we overlap exactly (within precision) with 
697       // the current vertex. Continue if the s    729       // the current vertex. Continue if the same happened previously
698       // (e.g. the previous vertex had the sam    730       // (e.g. the previous vertex had the same z value)
699       //                                          731       //
700       if (prevZ == 0) continue;                   732       if (prevZ == 0) continue;
701                                                   733       
702       //                                          734       //
703       // Otherwise, to decide what to do, we n    735       // Otherwise, to decide what to do, we need to know what is
704       // coming up next. Specifically, we need    736       // coming up next. Specifically, we need to find the next vertex
705       // with a non-zero z order.                 737       // with a non-zero z order.
706       //                                          738       //
707       // One might worry about infinite loops,    739       // One might worry about infinite loops, but the above conditional
708       // should prevent it                        740       // should prevent it
709       //                                          741       //
710       G4PolyPhiFaceVertex *next = corn;           742       G4PolyPhiFaceVertex *next = corn;
711       G4double nextZ;                             743       G4double nextZ;
712       do    // Loop checking, 13.08.2015, G.Co << 744       do
713       {                                           745       {
714         ++next;                                << 746         next++;
715         if (next == corners+numEdges) next = c    747         if (next == corners+numEdges) next = corners;
716                                                   748 
717         nextZ = ExactZOrder( z, qx, qy, qz, v,    749         nextZ = ExactZOrder( z, qx, qy, qz, v, normSign, next );
718       } while( nextZ == 0 );                      750       } while( nextZ == 0 );
719                                                   751       
720       //                                          752       //
721       // If we won't be changing direction, go    753       // If we won't be changing direction, go to the next vertex
722       //                                          754       //
723       if (nextZ*prevZ < 0) continue;              755       if (nextZ*prevZ < 0) continue;
724     }                                             756     }
725                                                   757   
726                                                   758       
727     //                                            759     //
728     // We overlap in z with the side of the fa    760     // We overlap in z with the side of the face that stretches from
729     // vertex "prev" to "corn". On which side     761     // vertex "prev" to "corn". On which side (left or right) do
730     // we lay with respect to this segment?       762     // we lay with respect to this segment?
731     //                                            763     //  
732     G4ThreeVector qa( qx - prev->x, qy - prev-    764     G4ThreeVector qa( qx - prev->x, qy - prev->y, qz - prev->z ),
733                   qb( qx - corn->x, qy - corn-    765                   qb( qx - corn->x, qy - corn->y, qz - corn->z );
734                                                   766 
735     G4double aboveOrBelow = normSign*qa.cross(    767     G4double aboveOrBelow = normSign*qa.cross(qb).dot(v);
736                                                   768     
737     if (aboveOrBelow > 0)                         769     if (aboveOrBelow > 0) 
738       ++answer;                                << 770       answer++;
739     else if (aboveOrBelow < 0)                    771     else if (aboveOrBelow < 0)
740       --answer;                                << 772       answer--;
741     else                                          773     else
742     {                                             774     {
743       //                                          775       //
744       // A precisely zero answer here means we    776       // A precisely zero answer here means we exactly
745       // intersect (within roundoff) the edge     777       // intersect (within roundoff) the edge of the face.
746       // Return true in this case.                778       // Return true in this case.
747       //                                          779       //
748       return true;                                780       return true;
749     }                                             781     }
750   } while( prevZ = cornZ, prev=corn, ++corn <     782   } while( prevZ = cornZ, prev=corn, ++corn < corners+numEdges );
751                                                   783   
                                                   >> 784 //  G4int fanswer = std::abs(answer);
                                                   >> 785 //  if (fanswer==1 || fanswer>2) {
                                                   >> 786 //    G4cerr << "G4PolyPhiFace::InsideEdgesExact: answer is "
                                                   >> 787 //           << answer << G4endl;
                                                   >> 788 //  }
                                                   >> 789 
752   return answer!=0;                               790   return answer!=0;
753 }                                                 791 }
754                                                << 792   
755 // InsideEdges (don't care about distance)     << 793   
                                                   >> 794 //
                                                   >> 795 // InsideEdges (don't care aboud distance)
756 //                                                796 //
757 // Decide if the point in r,z is inside the ed    797 // Decide if the point in r,z is inside the edges of our face
758 //                                                798 //
759 // This routine can be made a zillion times qu    799 // This routine can be made a zillion times quicker by implementing
760 // better code, for example:                      800 // better code, for example:
761 //                                                801 //
762 //    int pnpoly(int npol, float *xp, float *y    802 //    int pnpoly(int npol, float *xp, float *yp, float x, float y)
763 //    {                                           803 //    {
764 //      int i, j, c = 0;                          804 //      int i, j, c = 0;
765 //      for (i = 0, j = npol-1; i < npol; j =     805 //      for (i = 0, j = npol-1; i < npol; j = i++) {
766 //        if ((((yp[i]<=y) && (y<yp[j])) ||       806 //        if ((((yp[i]<=y) && (y<yp[j])) ||
767 //             ((yp[j]<=y) && (y<yp[i]))) &&      807 //             ((yp[j]<=y) && (y<yp[i]))) &&
768 //            (x < (xp[j] - xp[i]) * (y - yp[i    808 //            (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
769 //                                                809 //
770 //          c = !c;                               810 //          c = !c;
771 //      }                                         811 //      }
772 //      return c;                                 812 //      return c;
773 //    }                                           813 //    }
774 //                                                814 //
775 // See "Point in Polyon Strategies", Eric Hain    815 // See "Point in Polyon Strategies", Eric Haines [Graphic Gems IV]  pp. 24-46
776 //                                                816 //
777 // The algorithm below is rather unique, but i << 817 // My algorithm below is rather unique, but is based on code needed to
778 // calculate the distance to the shape. Left h << 818 // calculate the distance to the shape. I left it in here because ...
                                                   >> 819 // well ... to test it better.
779 //                                                820 //
780 G4bool G4PolyPhiFace::InsideEdges( G4double r,    821 G4bool G4PolyPhiFace::InsideEdges( G4double r, G4double z )
781 {                                                 822 {
782   //                                              823   //
783   // Quick check of extent                        824   // Quick check of extent
784   //                                              825   //
785   if ( r < rMin || r > rMax ) return false;       826   if ( r < rMin || r > rMax ) return false;
786   if ( z < zMin || z > zMax ) return false;       827   if ( z < zMin || z > zMax ) return false;
787                                                   828   
788   //                                              829   //
789   // More thorough check                          830   // More thorough check
790   //                                              831   //
791   G4double notUsed;                               832   G4double notUsed;
792                                                   833   
793   return InsideEdges( r, z, &notUsed, nullptr  << 834   return InsideEdges( r, z, &notUsed, 0 );
794 }                                                 835 }
795                                                   836 
                                                   >> 837 
                                                   >> 838 //
796 // InsideEdges (care about distance)              839 // InsideEdges (care about distance)
797 //                                                840 //
798 // Decide if the point in r,z is inside the ed    841 // Decide if the point in r,z is inside the edges of our face
799 //                                                842 //
800 G4bool G4PolyPhiFace::InsideEdges( G4double r,    843 G4bool G4PolyPhiFace::InsideEdges( G4double r, G4double z,
801                                    G4double* b << 844                                    G4double *bestDist2, 
802                                    G4PolyPhiFa << 845                                    G4PolyPhiFaceVertex **base3Dnorm, 
803                                    G4ThreeVect << 846                                    G4ThreeVector **head3Dnorm )
804 {                                                 847 {
805   G4double bestDistance2 = kInfinity;             848   G4double bestDistance2 = kInfinity;
806   G4bool answer = false;                       << 849   G4bool   answer = 0;
807                                                   850   
808   G4PolyPhiFaceEdge* edge = edges;             << 851   G4PolyPhiFaceEdge *edge = edges;
809   do    // Loop checking, 13.08.2015, G.Cosmo  << 852   do
810   {                                               853   {
811     G4PolyPhiFaceVertex* testMe = nullptr;     << 854     G4PolyPhiFaceVertex *testMe;
812     G4PolyPhiFaceVertex* v0_vertex = edge->v0; << 
813     G4PolyPhiFaceVertex* v1_vertex = edge->v1; << 
814     //                                            855     //
815     // Get distance perpendicular to the edge     856     // Get distance perpendicular to the edge
816     //                                            857     //
817     G4double dr = (r-v0_vertex->r), dz = (z-v0 << 858     G4double dr = (r-edge->v0->r), dz = (z-edge->v0->z);
818                                                   859 
819     G4double distOut = dr*edge->tz - dz*edge->    860     G4double distOut = dr*edge->tz - dz*edge->tr;
820     G4double distance2 = distOut*distOut;         861     G4double distance2 = distOut*distOut;
821     if (distance2 > bestDistance2) continue;      862     if (distance2 > bestDistance2) continue;        // No hope!
822                                                   863 
823     //                                            864     //
824     // Check to see if normal intersects edge     865     // Check to see if normal intersects edge within the edge's boundary
825     //                                            866     //
826     G4double q = dr*edge->tr + dz*edge->tz;    << 867     G4double s = dr*edge->tr + dz*edge->tz;
827                                                   868 
828     //                                            869     //
829     // If it doesn't, penalize distance2 appro    870     // If it doesn't, penalize distance2 appropriately
830     //                                            871     //
831     if (q < 0)                                 << 872     if (s < 0)
832     {                                             873     {
833       distance2 += q*q;                        << 874       distance2 += s*s;
834       testMe = v0_vertex;                      << 875       testMe = edge->v0;
835     }                                             876     }
836     else if (q > edge->length)                 << 877     else if (s > edge->length)
837     {                                             878     {
838       G4double s2 = q-edge->length;            << 879       G4double s2 = s-edge->length;
839       distance2 += s2*s2;                         880       distance2 += s2*s2;
840       testMe = v1_vertex;                      << 881       testMe = edge->v1;
                                                   >> 882     }
                                                   >> 883     else
                                                   >> 884     {
                                                   >> 885       testMe = 0;
841     }                                             886     }
842                                                   887     
843     //                                            888     //
844     // Closest edge so far?                       889     // Closest edge so far?
845     //                                            890     //
846     if (distance2 < bestDistance2)                891     if (distance2 < bestDistance2)
847     {                                             892     {
848       bestDistance2 = distance2;                  893       bestDistance2 = distance2;
849       if (testMe != nullptr)                   << 894       if (testMe)
850       {                                           895       {
851         G4double distNorm = dr*testMe->rNorm +    896         G4double distNorm = dr*testMe->rNorm + dz*testMe->zNorm;
852         answer = (distNorm <= 0);                 897         answer = (distNorm <= 0);
853         if (base3Dnorm != nullptr)             << 898         if (base3Dnorm)
854         {                                         899         {
855           *base3Dnorm = testMe;                   900           *base3Dnorm = testMe;
856           *head3Dnorm = &testMe->norm3D;          901           *head3Dnorm = &testMe->norm3D;
857         }                                         902         }
858       }                                           903       }
859       else                                        904       else
860       {                                           905       {
861         answer = (distOut <= 0);                  906         answer = (distOut <= 0);                        
862         if (base3Dnorm != nullptr)             << 907         if (base3Dnorm)
863         {                                         908         {
864           *base3Dnorm = v0_vertex;             << 909           *base3Dnorm = edge->v0;
865           *head3Dnorm = &edge->norm3D;            910           *head3Dnorm = &edge->norm3D;
866         }                                         911         }
867       }                                           912       }
868     }                                             913     }
869   } while( ++edge < edges + numEdges );           914   } while( ++edge < edges + numEdges );
870                                                   915   
871   *bestDist2 = bestDistance2;                     916   *bestDist2 = bestDistance2;
872   return answer;                                  917   return answer;
873 }                                                 918 }
874                                                   919 
                                                   >> 920 //
875 // Calculation of Surface Area of a Triangle      921 // Calculation of Surface Area of a Triangle 
876 // In the same time Random Point in Triangle i    922 // In the same time Random Point in Triangle is given
877 //                                                923 //
878 G4double G4PolyPhiFace::SurfaceTriangle( const << 924 G4double G4PolyPhiFace::SurfaceTriangle( G4ThreeVector p1,
879                                          const << 925                                          G4ThreeVector p2,
880                                          const << 926                                          G4ThreeVector p3,
881                                          G4Thr << 927                                          G4ThreeVector *p4 )
882 {                                                 928 {
883   G4ThreeVector v, w;                             929   G4ThreeVector v, w;
884                                                   930   
885   v = p3 - p1;                                    931   v = p3 - p1;
886   w = p1 - p2;                                    932   w = p1 - p2;
887   G4double lambda1 = G4UniformRand();             933   G4double lambda1 = G4UniformRand();
888   G4double lambda2 = lambda1*G4UniformRand();     934   G4double lambda2 = lambda1*G4UniformRand();
889                                                   935  
890   *p4=p2 + lambda1*w + lambda2*v;                 936   *p4=p2 + lambda1*w + lambda2*v;
891   return 0.5*(v.cross(w)).mag();                  937   return 0.5*(v.cross(w)).mag();
892 }                                                 938 }
893                                                   939 
                                                   >> 940 //
894 // Compute surface area                           941 // Compute surface area
895 //                                                942 //
896 G4double G4PolyPhiFace::SurfaceArea()             943 G4double G4PolyPhiFace::SurfaceArea()
897 {                                                 944 {
898   if ( fSurfaceArea==0. ) { Triangulate(); }      945   if ( fSurfaceArea==0. ) { Triangulate(); }
899   return fSurfaceArea;                            946   return fSurfaceArea;
900 }                                                 947 }
901                                                   948 
                                                   >> 949 //
902 // Return random point on face                    950 // Return random point on face
903 //                                                951 //
904 G4ThreeVector G4PolyPhiFace::GetPointOnFace()     952 G4ThreeVector G4PolyPhiFace::GetPointOnFace()
905 {                                                 953 {
906   Triangulate();                                  954   Triangulate();
907   return surface_point;                           955   return surface_point;
908 }                                                 956 }
909                                                   957 
910 //                                                958 //
911 // Auxiliary Functions used for Finding the Po    959 // Auxiliary Functions used for Finding the PointOnFace using Triangulation
912 //                                                960 //
913                                                   961 
                                                   >> 962 //
914 // Calculation of 2*Area of Triangle with Sign    963 // Calculation of 2*Area of Triangle with Sign
915 //                                                964 //
916 G4double G4PolyPhiFace::Area2( const G4TwoVect << 965 G4double G4PolyPhiFace::Area2( G4TwoVector a,
917                                const G4TwoVect << 966                                G4TwoVector b,
918                                const G4TwoVect << 967                                G4TwoVector c )
919 {                                                 968 {
920   return ((b.x()-a.x())*(c.y()-a.y())-            969   return ((b.x()-a.x())*(c.y()-a.y())-
921           (c.x()-a.x())*(b.y()-a.y()));           970           (c.x()-a.x())*(b.y()-a.y()));
922 }                                                 971 }
923                                                   972 
                                                   >> 973 //
924 // Boolean function for sign of Surface           974 // Boolean function for sign of Surface
925 //                                                975 //
926 G4bool G4PolyPhiFace::Left( const G4TwoVector& << 976 G4bool G4PolyPhiFace::Left( G4TwoVector a,
927                             const G4TwoVector& << 977                             G4TwoVector b,
928                             const G4TwoVector& << 978                             G4TwoVector c )
929 {                                                 979 {
930   return Area2(a,b,c)>0;                          980   return Area2(a,b,c)>0;
931 }                                                 981 }
932                                                   982 
                                                   >> 983 //
933 // Boolean function for sign of Surface           984 // Boolean function for sign of Surface
934 //                                                985 //
935 G4bool G4PolyPhiFace::LeftOn( const G4TwoVecto << 986 G4bool G4PolyPhiFace::LeftOn( G4TwoVector a,
936                               const G4TwoVecto << 987                               G4TwoVector b,
937                               const G4TwoVecto << 988                               G4TwoVector c )
938 {                                                 989 {
939   return Area2(a,b,c)>=0;                         990   return Area2(a,b,c)>=0;
940 }                                                 991 }
941                                                   992 
                                                   >> 993 //
942 // Boolean function for sign of Surface           994 // Boolean function for sign of Surface
943 //                                                995 //
944 G4bool G4PolyPhiFace::Collinear( const G4TwoVe << 996 G4bool G4PolyPhiFace::Collinear( G4TwoVector a,
945                                  const G4TwoVe << 997                                  G4TwoVector b,
946                                  const G4TwoVe << 998                                  G4TwoVector c )
947 {                                                 999 {
948   return Area2(a,b,c)==0;                         1000   return Area2(a,b,c)==0;
949 }                                                 1001 }
950                                                   1002 
                                                   >> 1003 //
951 // Boolean function for finding "Proper" Inter    1004 // Boolean function for finding "Proper" Intersection
952 // That means Intersection of two lines segmen    1005 // That means Intersection of two lines segments (a,b) and (c,d)
953 //                                                1006 // 
954 G4bool G4PolyPhiFace::IntersectProp( const G4T << 1007 G4bool G4PolyPhiFace::IntersectProp( G4TwoVector a,
955                                      const G4T << 1008                                      G4TwoVector b,
956                                      const G4T << 1009                                      G4TwoVector c, G4TwoVector d )
957 {                                                 1010 {
958   if( Collinear(a,b,c) || Collinear(a,b,d)||      1011   if( Collinear(a,b,c) || Collinear(a,b,d)||
959       Collinear(c,d,a) || Collinear(c,d,b) )      1012       Collinear(c,d,a) || Collinear(c,d,b) )  { return false; }
960                                                   1013 
961   G4bool Positive;                                1014   G4bool Positive;
962   Positive = !(Left(a,b,c))^!(Left(a,b,d));       1015   Positive = !(Left(a,b,c))^!(Left(a,b,d));
963   return Positive && ((!Left(c,d,a)^!Left(c,d, << 1016   return Positive && (!Left(c,d,a)^!Left(c,d,b));
964 }                                                 1017 }
965                                                   1018 
                                                   >> 1019 //
966 // Boolean function for determining if Point c    1020 // Boolean function for determining if Point c is between a and b
967 // For the tree points(a,b,c) on the same line    1021 // For the tree points(a,b,c) on the same line
968 //                                                1022 //
969 G4bool G4PolyPhiFace::Between( const G4TwoVect << 1023 G4bool G4PolyPhiFace::Between( G4TwoVector a, G4TwoVector b, G4TwoVector c )
970 {                                                 1024 {
971   if( !Collinear(a,b,c) ) { return false; }       1025   if( !Collinear(a,b,c) ) { return false; }
972                                                   1026 
973   if(a.x()!=b.x())                                1027   if(a.x()!=b.x())
974   {                                               1028   {
975     return ((a.x()<=c.x())&&(c.x()<=b.x()))||     1029     return ((a.x()<=c.x())&&(c.x()<=b.x()))||
976            ((a.x()>=c.x())&&(c.x()>=b.x()));      1030            ((a.x()>=c.x())&&(c.x()>=b.x()));
977   }                                               1031   }
978   else                                            1032   else
979   {                                               1033   {
980     return ((a.y()<=c.y())&&(c.y()<=b.y()))||     1034     return ((a.y()<=c.y())&&(c.y()<=b.y()))||
981            ((a.y()>=c.y())&&(c.y()>=b.y()));      1035            ((a.y()>=c.y())&&(c.y()>=b.y()));
982   }                                               1036   }
983 }                                                 1037 }
984                                                   1038 
                                                   >> 1039 //
985 // Boolean function for finding Intersection "    1040 // Boolean function for finding Intersection "Proper" or not
986 // Between two line segments (a,b) and (c,d)      1041 // Between two line segments (a,b) and (c,d)
987 //                                                1042 //
988 G4bool G4PolyPhiFace::Intersect( const G4TwoVe << 1043 G4bool G4PolyPhiFace::Intersect( G4TwoVector a,
989                                  const G4TwoVe << 1044                                  G4TwoVector b,
990                                  const G4TwoVe << 1045                                  G4TwoVector c, G4TwoVector d )
991 {                                                 1046 {
992  if( IntersectProp(a,b,c,d) )                     1047  if( IntersectProp(a,b,c,d) )
993    { return true; }                               1048    { return true; }
994  else if( Between(a,b,c)||                        1049  else if( Between(a,b,c)||
995           Between(a,b,d)||                        1050           Between(a,b,d)||
996           Between(c,d,a)||                        1051           Between(c,d,a)||
997           Between(c,d,b) )                        1052           Between(c,d,b) )
998    { return true; }                               1053    { return true; }
999  else                                             1054  else
1000    { return false; }                             1055    { return false; }
1001 }                                                1056 }
1002                                                  1057 
                                                   >> 1058 //
1003 // Boolean Diagonalie help to determine          1059 // Boolean Diagonalie help to determine 
1004 // if diagonal s of segment (a,b) is convex o    1060 // if diagonal s of segment (a,b) is convex or reflex
1005 //                                               1061 //
1006 G4bool G4PolyPhiFace::Diagonalie( G4PolyPhiFa << 1062 G4bool G4PolyPhiFace::Diagonalie( G4PolyPhiFaceVertex *a,
1007                                   G4PolyPhiFa << 1063                                   G4PolyPhiFaceVertex *b )
1008 {                                                1064 {
1009   G4PolyPhiFaceVertex   *corner = triangles;     1065   G4PolyPhiFaceVertex   *corner = triangles;
1010   G4PolyPhiFaceVertex   *corner_next=triangle    1066   G4PolyPhiFaceVertex   *corner_next=triangles;
1011                                                  1067 
1012   // For each Edge (corner,corner_next)          1068   // For each Edge (corner,corner_next) 
1013   do    // Loop checking, 13.08.2015, G.Cosmo << 1069   do
1014   {                                              1070   {
1015     corner_next=corner->next;                    1071     corner_next=corner->next;
1016                                                  1072 
1017     // Skip edges incident to a of b             1073     // Skip edges incident to a of b
1018     //                                           1074     //
1019     if( (corner!=a)&&(corner_next!=a)            1075     if( (corner!=a)&&(corner_next!=a)
1020       &&(corner!=b)&&(corner_next!=b) )          1076       &&(corner!=b)&&(corner_next!=b) )
1021     {                                            1077     {
1022        G4TwoVector rz1,rz2,rz3,rz4;              1078        G4TwoVector rz1,rz2,rz3,rz4;
1023        rz1 = G4TwoVector(a->r,a->z);             1079        rz1 = G4TwoVector(a->r,a->z);
1024        rz2 = G4TwoVector(b->r,b->z);             1080        rz2 = G4TwoVector(b->r,b->z);
1025        rz3 = G4TwoVector(corner->r,corner->z)    1081        rz3 = G4TwoVector(corner->r,corner->z);
1026        rz4 = G4TwoVector(corner_next->r,corne    1082        rz4 = G4TwoVector(corner_next->r,corner_next->z);
1027        if( Intersect(rz1,rz2,rz3,rz4) ) { ret    1083        if( Intersect(rz1,rz2,rz3,rz4) ) { return false; }
1028     }                                            1084     }
1029     corner=corner->next;                         1085     corner=corner->next;   
1030                                                  1086    
1031   } while( corner != triangles );                1087   } while( corner != triangles );
1032                                                  1088 
1033   return true;                                   1089   return true;
1034 }                                                1090 }
1035                                                  1091 
                                                   >> 1092 //
1036 // Boolean function that determine if b is In    1093 // Boolean function that determine if b is Inside Cone (a0,a,a1)
1037 // being a the center of the Cone                1094 // being a the center of the Cone
1038 //                                               1095 //
1039 G4bool G4PolyPhiFace::InCone( G4PolyPhiFaceVe << 1096 G4bool G4PolyPhiFace::InCone( G4PolyPhiFaceVertex *a, G4PolyPhiFaceVertex *b )
1040 {                                                1097 {
1041   // a0,a and a1 are consecutive vertices        1098   // a0,a and a1 are consecutive vertices
1042   //                                             1099   //
1043   G4PolyPhiFaceVertex *a0,*a1;                   1100   G4PolyPhiFaceVertex *a0,*a1;
1044   a1=a->next;                                    1101   a1=a->next;
1045   a0=a->prev;                                    1102   a0=a->prev;
1046                                                  1103 
1047   G4TwoVector arz,arz0,arz1,brz;                 1104   G4TwoVector arz,arz0,arz1,brz;
1048   arz=G4TwoVector(a->r,a->z);arz0=G4TwoVector    1105   arz=G4TwoVector(a->r,a->z);arz0=G4TwoVector(a0->r,a0->z);
1049   arz1=G4TwoVector(a1->r,a1->z);brz=G4TwoVect    1106   arz1=G4TwoVector(a1->r,a1->z);brz=G4TwoVector(b->r,b->z);
1050                                                  1107     
1051                                                  1108   
1052   if(LeftOn(arz,arz1,arz0))  // If a is conve    1109   if(LeftOn(arz,arz1,arz0))  // If a is convex vertex
1053   {                                              1110   {
1054     return Left(arz,brz,arz0)&&Left(brz,arz,a    1111     return Left(arz,brz,arz0)&&Left(brz,arz,arz1);
1055   }                                              1112   }
1056   else                       // Else a is ref    1113   else                       // Else a is reflex
1057   {                                              1114   {
1058     return !( LeftOn(arz,brz,arz1)&&LeftOn(br    1115     return !( LeftOn(arz,brz,arz1)&&LeftOn(brz,arz,arz0));
1059   }                                              1116   }
1060 }                                                1117 }
1061                                                  1118 
                                                   >> 1119 //
1062 // Boolean function finding if Diagonal is po    1120 // Boolean function finding if Diagonal is possible
1063 // inside Polycone or PolyHedra                  1121 // inside Polycone or PolyHedra
1064 //                                               1122 //
1065 G4bool G4PolyPhiFace::Diagonal( G4PolyPhiFace << 1123 G4bool G4PolyPhiFace::Diagonal( G4PolyPhiFaceVertex *a, G4PolyPhiFaceVertex *b )
1066 {                                                1124 { 
1067   return InCone(a,b) && InCone(b,a) && Diagon    1125   return InCone(a,b) && InCone(b,a) && Diagonalie(a,b);
1068 }                                                1126 }
1069                                                  1127 
                                                   >> 1128 //
1070 // Initialisation for Triangulisation by ear     1129 // Initialisation for Triangulisation by ear tips
1071 // For details see "Computational Geometry in    1130 // For details see "Computational Geometry in C" by Joseph O'Rourke
1072 //                                               1131 //
1073 void G4PolyPhiFace::EarInit()                    1132 void G4PolyPhiFace::EarInit()
1074 {                                                1133 {
1075   G4PolyPhiFaceVertex* corner = triangles;    << 1134   G4PolyPhiFaceVertex   *corner = triangles;
1076   G4PolyPhiFaceVertex* c_prev, *c_next;       << 1135   G4PolyPhiFaceVertex *c_prev,*c_next;
1077                                                  1136   
1078   do    // Loop checking, 13.08.2015, G.Cosmo << 1137   do
1079   {                                              1138   {
1080      // We need to determine three consecutiv    1139      // We need to determine three consecutive vertices
1081      //                                          1140      //
1082      c_next=corner->next;                        1141      c_next=corner->next;
1083      c_prev=corner->prev;                        1142      c_prev=corner->prev; 
1084                                                  1143 
1085      // Calculation of ears                      1144      // Calculation of ears
1086      //                                          1145      //
1087      corner->ear=Diagonal(c_prev,c_next);        1146      corner->ear=Diagonal(c_prev,c_next);   
1088      corner=corner->next;                        1147      corner=corner->next;
1089                                                  1148 
1090   } while( corner!=triangles );                  1149   } while( corner!=triangles );
1091 }                                                1150 }
1092                                                  1151 
                                                   >> 1152 //
1093 // Triangulisation by ear tips for Polycone o    1153 // Triangulisation by ear tips for Polycone or Polyhedra
1094 // For details see "Computational Geometry in    1154 // For details see "Computational Geometry in C" by Joseph O'Rourke
1095 //                                               1155 //
1096 void G4PolyPhiFace::Triangulate()                1156 void G4PolyPhiFace::Triangulate()
1097 {                                                1157 { 
1098   // The copy of Polycone is made and this co    1158   // The copy of Polycone is made and this copy is reordered in order to 
1099   // have a list of triangles. This list is u    1159   // have a list of triangles. This list is used for GetPointOnFace().
1100                                                  1160 
1101   const std::size_t maxEdges = (numEdges > 0) << 1161   G4PolyPhiFaceVertex *tri_help = new G4PolyPhiFaceVertex[numEdges];
1102   auto tri_help = new G4PolyPhiFaceVertex[max << 
1103   triangles = tri_help;                          1162   triangles = tri_help;
1104   G4PolyPhiFaceVertex* triang = triangles;    << 1163   G4PolyPhiFaceVertex *triang = triangles;
1105                                                  1164 
1106   std::vector<G4double> areas;                   1165   std::vector<G4double> areas;
1107   std::vector<G4ThreeVector> points;             1166   std::vector<G4ThreeVector> points;
1108   G4double area=0.;                              1167   G4double area=0.;
1109   G4PolyPhiFaceVertex *v0,*v1,*v2,*v3,*v4;       1168   G4PolyPhiFaceVertex *v0,*v1,*v2,*v3,*v4;
1110   v2=triangles;                                  1169   v2=triangles;
1111                                                  1170 
1112   // Make copy for prev/next for triang=corne    1171   // Make copy for prev/next for triang=corners
1113   //                                             1172   //
1114   G4PolyPhiFaceVertex* helper  = corners;     << 1173   G4PolyPhiFaceVertex *helper = corners;
1115   G4PolyPhiFaceVertex* helper2 = corners;     << 1174   G4PolyPhiFaceVertex *helper2 = corners;
1116   do    // Loop checking, 13.08.2015, G.Cosmo << 1175   do
1117   {                                              1176   {
1118     triang->r = helper->r;                       1177     triang->r = helper->r;
1119     triang->z = helper->z;                       1178     triang->z = helper->z;
1120     triang->x = helper->x;                       1179     triang->x = helper->x;
1121     triang->y = helper->y;                    << 1180     triang->y= helper->y;
1122                                                  1181 
1123     // add pointer on prev corner                1182     // add pointer on prev corner
1124     //                                           1183     //
1125     if( helper==corners )                        1184     if( helper==corners )
1126       { triang->prev=triangles+maxEdges-1; }  << 1185       { triang->prev=triangles+numEdges-1; }
1127     else                                         1186     else
1128       { triang->prev=helper2; }                  1187       { triang->prev=helper2; }
1129                                                  1188 
1130     // add pointer on next corner                1189     // add pointer on next corner
1131     //                                           1190     //
1132     if( helper<corners+maxEdges-1 )           << 1191     if( helper<corners+numEdges-1 )
1133       { triang->next=triang+1; }                 1192       { triang->next=triang+1; }
1134     else                                         1193     else
1135       { triang->next=triangles; }                1194       { triang->next=triangles; }
1136     helper2=triang;                              1195     helper2=triang;
1137     helper=helper->next;                         1196     helper=helper->next;
1138     triang=triang->next;                         1197     triang=triang->next;
1139                                                  1198 
1140   } while( helper!=corners );                    1199   } while( helper!=corners );
1141                                                  1200 
1142   EarInit();                                     1201   EarInit();
1143                                                  1202  
1144   G4int n=numEdges;                              1203   G4int n=numEdges;
1145   G4int i=0;                                     1204   G4int i=0;
1146   G4ThreeVector p1,p2,p3,p4;                     1205   G4ThreeVector p1,p2,p3,p4;
1147   const G4int max_n_loops=numEdges*10000; //     1206   const G4int max_n_loops=numEdges*10000; // protection against infinite loop
1148                                                  1207 
1149   // Each step of outer loop removes one ear     1208   // Each step of outer loop removes one ear
1150   //                                             1209   //
1151   while(n>3)      // Loop checking, 13.08.201 << 1210   while(n>3)  // Inner loop searches for one ear
1152   {               // Inner loop searches for  << 1211   {
1153     v2=triangles;                                1212     v2=triangles; 
1154     do    // Loop checking, 13.08.2015, G.Cos << 1213     do
1155     {                                            1214     {
1156       if(v2->ear)  // Ear found. Fill variabl    1215       if(v2->ear)  // Ear found. Fill variables
1157       {                                          1216       {
1158         // (v1,v3) is diagonal                   1217         // (v1,v3) is diagonal
1159         //                                       1218         //
1160         v3=v2->next; v4=v3->next;                1219         v3=v2->next; v4=v3->next;
1161         v1=v2->prev; v0=v1->prev;                1220         v1=v2->prev; v0=v1->prev;
1162                                                  1221         
1163         // Calculate areas and points            1222         // Calculate areas and points
1164                                                  1223 
1165         p1=G4ThreeVector((v2)->x,(v2)->y,(v2)    1224         p1=G4ThreeVector((v2)->x,(v2)->y,(v2)->z);
1166         p2=G4ThreeVector((v1)->x,(v1)->y,(v1)    1225         p2=G4ThreeVector((v1)->x,(v1)->y,(v1)->z);
1167         p3=G4ThreeVector((v3)->x,(v3)->y,(v3)    1226         p3=G4ThreeVector((v3)->x,(v3)->y,(v3)->z);
1168                                                  1227 
1169         G4double result1 = SurfaceTriangle(p1    1228         G4double result1 = SurfaceTriangle(p1,p2,p3,&p4 );
1170         points.push_back(p4);                    1229         points.push_back(p4);
1171         areas.push_back(result1);                1230         areas.push_back(result1);
1172         area=area+result1;                       1231         area=area+result1;
1173                                                  1232 
1174         // Update earity of diagonal endpoint    1233         // Update earity of diagonal endpoints
1175         //                                       1234         //
1176         v1->ear=Diagonal(v0,v3);                 1235         v1->ear=Diagonal(v0,v3);
1177         v3->ear=Diagonal(v1,v4);                 1236         v3->ear=Diagonal(v1,v4);
1178                                                  1237 
1179         // Cut off the ear v2                    1238         // Cut off the ear v2 
1180         // Has to be done for a copy and not     1239         // Has to be done for a copy and not for real PolyPhiFace
1181         //                                       1240         //
1182         v1->next=v3;                             1241         v1->next=v3;
1183         v3->prev=v1;                             1242         v3->prev=v1;
1184         triangles=v3; // In case the head was    1243         triangles=v3; // In case the head was v2
1185         --n;                                  << 1244         n--;
1186                                                  1245  
1187         break; // out of inner loop              1246         break; // out of inner loop
1188       }        // end if ear found               1247       }        // end if ear found
1189                                                  1248 
1190       v2=v2->next;                               1249       v2=v2->next;
1191                                                  1250     
1192     } while( v2!=triangles );                    1251     } while( v2!=triangles );
1193                                                  1252 
1194     ++i;                                      << 1253     i++;
1195     if(i>=max_n_loops)                           1254     if(i>=max_n_loops)
1196     {                                            1255     {
1197       G4Exception( "G4PolyPhiFace::Triangulat    1256       G4Exception( "G4PolyPhiFace::Triangulation()",
1198                    "GeomSolids0003", FatalExc << 1257                    "Bad_Definition_of_Solid", FatalException,
1199                    "Maximum number of steps i    1258                    "Maximum number of steps is reached for triangulation!" );
1200     }                                            1259     }
1201   }   // end outer while loop                    1260   }   // end outer while loop
1202                                                  1261 
1203   if(v2->next != nullptr)                     << 1262   if(v2->next)
1204   {                                              1263   {
1205      // add last triangle                        1264      // add last triangle
1206      //                                          1265      //
1207      v2=v2->next;                                1266      v2=v2->next;
1208      p1=G4ThreeVector((v2)->x,(v2)->y,(v2)->z    1267      p1=G4ThreeVector((v2)->x,(v2)->y,(v2)->z);
1209      p2=G4ThreeVector((v2->next)->x,(v2->next    1268      p2=G4ThreeVector((v2->next)->x,(v2->next)->y,(v2->next)->z);
1210      p3=G4ThreeVector((v2->prev)->x,(v2->prev    1269      p3=G4ThreeVector((v2->prev)->x,(v2->prev)->y,(v2->prev)->z);
1211      G4double result1 = SurfaceTriangle(p1,p2    1270      G4double result1 = SurfaceTriangle(p1,p2,p3,&p4 );
1212      points.push_back(p4);                       1271      points.push_back(p4);
1213      areas.push_back(result1);                   1272      areas.push_back(result1);
1214      area=area+result1;                          1273      area=area+result1;
1215   }                                              1274   }
1216                                                  1275  
1217   // Surface Area is stored                      1276   // Surface Area is stored
1218   //                                             1277   //
1219   fSurfaceArea = area;                           1278   fSurfaceArea = area;
1220                                                  1279   
1221   // Second Step: choose randomly one surface    1280   // Second Step: choose randomly one surface
1222   //                                             1281   //
1223   G4double chose = area*G4UniformRand();         1282   G4double chose = area*G4UniformRand();
1224                                                  1283    
1225   // Third Step: Get a point on choosen surfa    1284   // Third Step: Get a point on choosen surface
1226   //                                             1285   //
1227   G4double Achose1, Achose2;                     1286   G4double Achose1, Achose2;
1228   Achose1=0; Achose2=0.;                         1287   Achose1=0; Achose2=0.; 
1229   i=0;                                           1288   i=0;
1230   do     // Loop checking, 13.08.2015, G.Cosm << 1289   do 
1231   {                                              1290   {
1232     Achose2+=areas[i];                           1291     Achose2+=areas[i];
1233     if(chose>=Achose1 && chose<Achose2)          1292     if(chose>=Achose1 && chose<Achose2)
1234     {                                            1293     {
1235       G4ThreeVector point;                       1294       G4ThreeVector point;
1236       point=points[i];                        << 1295        point=points[i] ;
1237       surface_point=point;                    << 1296        surface_point=point;
1238       break;                                  << 1297        break;     
1239     }                                            1298     }
1240     ++i; Achose1=Achose2;                     << 1299     i++; Achose1=Achose2;
1241   } while( i<numEdges-2 );                       1300   } while( i<numEdges-2 );
1242                                                  1301  
1243   delete [] tri_help;                            1302   delete [] tri_help;
1244   tri_help = nullptr;                         << 
1245 }                                                1303 }
1246                                                  1304