Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/specific/src/G4PolyconeSide.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/G4PolyconeSide.cc (Version 11.3.0) and /geometry/solids/specific/src/G4PolyconeSide.cc (Version 4.0)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                    <<   3 // * DISCLAIMER                                                       *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th <<   5 // * The following disclaimer summarizes all the specific disclaimers *
  6 // * the Geant4 Collaboration.  It is provided <<   6 // * of contributors to this software. The specific disclaimers,which *
  7 // * conditions of the Geant4 Software License <<   7 // * govern, are listed with their locations in:                      *
  8 // * LICENSE and available at  http://cern.ch/ <<   8 // *   http://cern.ch/geant4/license                                  *
  9 // * include a list of copyright holders.      << 
 10 // *                                                9 // *                                                                  *
 11 // * Neither the authors of this software syst     10 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     11 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     12 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     13 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  <<  14 // * use.                                                             *
 16 // * for the full disclaimer and the limitatio << 
 17 // *                                               15 // *                                                                  *
 18 // * This  code  implementation is the result  <<  16 // * This  code  implementation is the  intellectual property  of the *
 19 // * technical work of the GEANT4 collaboratio <<  17 // * GEANT4 collaboration.                                            *
 20 // * By using,  copying,  modifying or  distri <<  18 // * By copying,  distributing  or modifying the Program (or any work *
 21 // * any work based  on the software)  you  ag <<  19 // * based  on  the Program)  you indicate  your  acceptance of  this *
 22 // * use  in  resulting  scientific  publicati <<  20 // * statement, and all its terms.                                    *
 23 // * acceptance of all terms of the Geant4 Sof << 
 24 // *******************************************     21 // ********************************************************************
 25 //                                                 22 //
 26 // Implementation of G4PolyconeSide, the face  << 
 27 // one conical side of a polycone              << 
 28 //                                                 23 //
 29 // Author: David C. Williams (davidw@scipp.ucs <<  24 // $Id: G4PolyconeSide.cc,v 1.4 2001/07/11 10:00:16 gunter Exp $
                                                   >>  25 // GEANT4 tag $Name: geant4-04-00 $
                                                   >>  26 //
                                                   >>  27 // 
                                                   >>  28 // --------------------------------------------------------------------
                                                   >>  29 // GEANT 4 class source file
                                                   >>  30 //
                                                   >>  31 //
                                                   >>  32 // G4PolyconeSide.cc
                                                   >>  33 //
                                                   >>  34 // Implementation of the face representing one conical side of a polycone
                                                   >>  35 //
 30 // -------------------------------------------     36 // --------------------------------------------------------------------
 31                                                    37 
 32 #include "G4PolyconeSide.hh"                       38 #include "G4PolyconeSide.hh"
 33 #include "meshdefs.hh"                         << 
 34 #include "G4PhysicalConstants.hh"              << 
 35 #include "G4IntersectingCone.hh"                   39 #include "G4IntersectingCone.hh"
 36 #include "G4ClippablePolygon.hh"                   40 #include "G4ClippablePolygon.hh"
 37 #include "G4AffineTransform.hh"                    41 #include "G4AffineTransform.hh"
                                                   >>  42 #include "meshdefs.hh"
 38 #include "G4SolidExtentList.hh"                    43 #include "G4SolidExtentList.hh"
 39 #include "G4GeometryTolerance.hh"              << 
 40                                                << 
 41 #include "Randomize.hh"                        << 
 42                                                    44 
 43 // This new field helps to use the class G4PlS << 
 44 //                                                 45 //
 45 G4PlSideManager G4PolyconeSide::subInstanceMan << 
 46                                                << 
 47 // This macro changes the references to fields << 
 48 // in the class G4PlSideData.                  << 
 49 //                                             << 
 50 #define G4MT_pcphix ((subInstanceManager.offse << 
 51 #define G4MT_pcphiy ((subInstanceManager.offse << 
 52 #define G4MT_pcphiz ((subInstanceManager.offse << 
 53 #define G4MT_pcphik ((subInstanceManager.offse << 
 54                                                << 
 55 // Returns the private data instance manager.  << 
 56 //                                             << 
 57 const G4PlSideManager& G4PolyconeSide::GetSubI << 
 58 {                                              << 
 59   return subInstanceManager;                   << 
 60 }                                              << 
 61                                                << 
 62 // Constructor                                     46 // Constructor
 63 //                                                 47 //
 64 // Values for r1,z1 and r2,z2 should be specif     48 // Values for r1,z1 and r2,z2 should be specified in clockwise
 65 // order in (r,z).                                 49 // order in (r,z).
 66 //                                                 50 //
 67 G4PolyconeSide::G4PolyconeSide( const G4Polyco <<  51 G4PolyconeSide::G4PolyconeSide( const G4PolyconeSideRZ *prevRZ,
 68                                 const G4Polyco <<  52                           const G4PolyconeSideRZ *tail,
 69                                 const G4Polyco <<  53                           const G4PolyconeSideRZ *head,
 70                                 const G4Polyco <<  54                           const G4PolyconeSideRZ *nextRZ,
 71                                       G4double <<  55               G4double thePhiStart, 
 72                                       G4double <<  56               G4double theDeltaPhi, 
 73                                       G4bool t <<  57               G4bool thePhiIsOpen, 
 74                                       G4bool i <<  58               G4bool isAllBehind )
 75 {                                              <<  59 {
 76   instanceID = subInstanceManager.CreateSubIns <<  60   //
 77                                                <<  61   // Record values
 78   kCarTolerance = G4GeometryTolerance::GetInst <<  62   //
 79   G4MT_pcphix = 0.0; G4MT_pcphiy = 0.0; G4MT_p <<  63   r[0] = tail->r; z[0] = tail->z;
 80                                                <<  64   r[1] = head->r; z[1] = head->z;
 81   //                                           <<  65   
 82   // Record values                             <<  66   phiIsOpen = thePhiIsOpen;
 83   //                                           <<  67   if (phiIsOpen) {
 84   r[0] = tail->r; z[0] = tail->z;              <<  68     deltaPhi = theDeltaPhi;
 85   r[1] = head->r; z[1] = head->z;              <<  69     startPhi = thePhiStart;
 86                                                <<  70 
 87   phiIsOpen = thePhiIsOpen;                    <<  71     //
 88   if (phiIsOpen)                               <<  72     // Set phi values to our conventions
 89   {                                            <<  73     //
 90     deltaPhi = theDeltaPhi;                    <<  74     while (deltaPhi < 0.0) deltaPhi += 2.0*M_PI;
 91     startPhi = thePhiStart;                    <<  75     while (startPhi < 0.0) startPhi += 2.0*M_PI;
 92                                                <<  76     
 93     //                                         <<  77     //
 94     // Set phi values to our conventions       <<  78     // Calculate corner coordinates
 95     //                                         <<  79     //
 96     while (deltaPhi < 0.0)    // Loop checking <<  80     corners = new G4ThreeVector[4];
 97      deltaPhi += twopi;                        <<  81     
 98     while (startPhi < 0.0)    // Loop checking <<  82     corners[0] = G4ThreeVector( tail->r*cos(startPhi), tail->r*sin(startPhi), tail->z );
 99      startPhi += twopi;                        <<  83     corners[1] = G4ThreeVector( head->r*cos(startPhi), head->r*sin(startPhi), head->z );
100                                                <<  84     corners[2] = G4ThreeVector( tail->r*cos(startPhi+deltaPhi), tail->r*sin(startPhi+deltaPhi), tail->z );
101     //                                         <<  85     corners[3] = G4ThreeVector( head->r*cos(startPhi+deltaPhi), head->r*sin(startPhi+deltaPhi), head->z );
102     // Calculate corner coordinates            <<  86   }
103     //                                         <<  87   else {
104     ncorners = 4;                              <<  88     deltaPhi = 2*M_PI;
105     corners = new G4ThreeVector[ncorners];     <<  89     startPhi = 0.0;
106                                                <<  90   }
107     corners[0] = G4ThreeVector( tail->r*std::c <<  91   
108                                 tail->r*std::s <<  92   allBehind = isAllBehind;
109     corners[1] = G4ThreeVector( head->r*std::c <<  93     
110                                 head->r*std::s <<  94   //
111     corners[2] = G4ThreeVector( tail->r*std::c <<  95   // Make our intersecting cone
112                                 tail->r*std::s <<  96   //
113     corners[3] = G4ThreeVector( head->r*std::c <<  97   cone = new G4IntersectingCone( r, z );
114                                 head->r*std::s <<  98   
115   }                                            <<  99   //
116   else                                         << 100   // Calculate vectors in r,z space
117   {                                            << 101   //
118     deltaPhi = twopi;                          << 102   rS = r[1]-r[0]; zS = z[1]-z[0];
119     startPhi = 0.0;                            << 103   length = sqrt( rS*rS + zS*zS);
120   }                                            << 104   rS /= length; zS /= length;
121                                                << 105   
122   allBehind = isAllBehind;                     << 106   rNorm = +zS;
123                                                << 107   zNorm = -rS;
124   //                                           << 108   
125   // Make our intersecting cone                << 109   G4double lAdj;
126   //                                           << 110   
127   cone = new G4IntersectingCone( r, z );       << 111   prevRS = r[0]-prevRZ->r;
128                                                << 112   prevZS = z[0]-prevRZ->z;
129   //                                           << 113   lAdj = sqrt( prevRS*prevRS + prevZS*prevZS );
130   // Calculate vectors in r,z space            << 114   prevRS /= lAdj;
131   //                                           << 115   prevZS /= lAdj;
132   rS = r[1]-r[0]; zS = z[1]-z[0];              << 116 
133   length = std::sqrt( rS*rS + zS*zS);          << 117   rNormEdge[0] = rNorm + prevZS;
134   rS /= length; zS /= length;                  << 118   zNormEdge[0] = zNorm - prevRS;
135                                                << 119   lAdj = sqrt( rNormEdge[0]*rNormEdge[0] + zNormEdge[0]*zNormEdge[0] );
136   rNorm = +zS;                                 << 120   rNormEdge[0] /= lAdj;
137   zNorm = -rS;                                 << 121   zNormEdge[0] /= lAdj;
138                                                << 122 
139   G4double lAdj;                               << 123   nextRS = nextRZ->r-r[1];
140                                                << 124   nextZS = nextRZ->z-z[1];
141   prevRS = r[0]-prevRZ->r;                     << 125   lAdj = sqrt( nextRS*nextRS + nextZS*nextZS );
142   prevZS = z[0]-prevRZ->z;                     << 126   nextRS /= lAdj;
143   lAdj = std::sqrt( prevRS*prevRS + prevZS*pre << 127   nextZS /= lAdj;
144   prevRS /= lAdj;                              << 128 
145   prevZS /= lAdj;                              << 129   rNormEdge[1] = rNorm + nextZS;
146                                                << 130   zNormEdge[1] = zNorm - nextRS;
147   rNormEdge[0] = rNorm + prevZS;               << 131   lAdj = sqrt( rNormEdge[1]*rNormEdge[1] + zNormEdge[1]*zNormEdge[1] );
148   zNormEdge[0] = zNorm - prevRS;               << 132   rNormEdge[1] /= lAdj;
149   lAdj = std::sqrt( rNormEdge[0]*rNormEdge[0]  << 133   zNormEdge[1] /= lAdj;
150   rNormEdge[0] /= lAdj;                        << 
151   zNormEdge[0] /= lAdj;                        << 
152                                                << 
153   nextRS = nextRZ->r-r[1];                     << 
154   nextZS = nextRZ->z-z[1];                     << 
155   lAdj = std::sqrt( nextRS*nextRS + nextZS*nex << 
156   nextRS /= lAdj;                              << 
157   nextZS /= lAdj;                              << 
158                                                << 
159   rNormEdge[1] = rNorm + nextZS;               << 
160   zNormEdge[1] = zNorm - nextRS;               << 
161   lAdj = std::sqrt( rNormEdge[1]*rNormEdge[1]  << 
162   rNormEdge[1] /= lAdj;                        << 
163   zNormEdge[1] /= lAdj;                        << 
164 }                                                 134 }
165                                                   135 
166 // Fake default constructor - sets only member << 
167 //                            for usage restri << 
168 //                                             << 
169 G4PolyconeSide::G4PolyconeSide( __void__& )    << 
170   : startPhi(0.), deltaPhi(0.),                << 
171     rNorm(0.), zNorm(0.), rS(0.), zS(0.), leng << 
172     prevRS(0.), prevZS(0.), nextRS(0.), nextZS << 
173     kCarTolerance(0.), instanceID(0)           << 
174 {                                              << 
175   r[0] = r[1] = 0.;                            << 
176   z[0] = z[1] = 0.;                            << 
177   rNormEdge[0]= rNormEdge[1] = 0.;             << 
178   zNormEdge[0]= zNormEdge[1] = 0.;             << 
179 }                                              << 
180                                                   136 
                                                   >> 137 //
181 // Destructor                                     138 // Destructor
182 //                                             << 139 //  
183 G4PolyconeSide::~G4PolyconeSide()                 140 G4PolyconeSide::~G4PolyconeSide()
184 {                                                 141 {
185   delete cone;                                 << 142   delete cone;
186   if (phiIsOpen)  { delete [] corners; }       << 143   if (phiIsOpen) delete [] corners;
187 }                                                 144 }
188                                                   145 
                                                   >> 146 
                                                   >> 147 //
189 // Copy constructor                               148 // Copy constructor
190 //                                                149 //
191 G4PolyconeSide::G4PolyconeSide( const G4Polyco << 150 G4PolyconeSide::G4PolyconeSide( const G4PolyconeSide &source )
192 {                                                 151 {
193   instanceID = subInstanceManager.CreateSubIns << 152   CopyStuff( source );
194                                                << 
195   CopyStuff( source );                         << 
196 }                                                 153 }
197                                                   154 
                                                   >> 155 
                                                   >> 156 //
198 // Assignment operator                            157 // Assignment operator
199 //                                                158 //
200 G4PolyconeSide& G4PolyconeSide::operator=( con << 159 G4PolyconeSide& G4PolyconeSide::operator=( const G4PolyconeSide &source )
201 {                                                 160 {
202   if (this == &source)  { return *this; }      << 161   if (this == &source) return *this;
203                                                   162 
204   delete cone;                                 << 163   delete cone;
205   if (phiIsOpen)  { delete [] corners; }       << 164   if (phiIsOpen) delete [] corners;
206                                                << 165   
207   CopyStuff( source );                         << 166   CopyStuff( source );
208                                                << 167   
209   return *this;                                << 168   return *this;
210 }                                                 169 }
211                                                   170 
                                                   >> 171 
                                                   >> 172 //
212 // CopyStuff                                      173 // CopyStuff
213 //                                                174 //
214 void G4PolyconeSide::CopyStuff( const G4Polyco << 175 void G4PolyconeSide::CopyStuff( const G4PolyconeSide &source )
215 {                                                 176 {
216   r[0]    = source.r[0];                       << 177   r[0]    = source.r[0];
217   r[1]    = source.r[1];                       << 178   r[1]    = source.r[1];
218   z[0]    = source.z[0];                       << 179   z[0]    = source.z[0];
219   z[1]    = source.z[1];                       << 180   z[1]    = source.z[1];
220                                                << 181   
221   startPhi  = source.startPhi;                 << 182   startPhi  = source.startPhi;
222   deltaPhi  = source.deltaPhi;                 << 183   deltaPhi  = source.deltaPhi;
223   phiIsOpen  = source.phiIsOpen;               << 184   phiIsOpen = source.phiIsOpen;
224   allBehind  = source.allBehind;               << 185   allBehind = source.allBehind;
225                                                << 186   
226   kCarTolerance = source.kCarTolerance;        << 187   cone    = new G4IntersectingCone( *source.cone );
227   fSurfaceArea = source.fSurfaceArea;          << 188   
228                                                << 189   rNorm   = source.rNorm;
229   cone    = new G4IntersectingCone( *source.co << 190   zNorm   = source.zNorm;
230                                                << 191   rS    = source.rS;
231   rNorm    = source.rNorm;                     << 192   zS    = source.zS;
232   zNorm    = source.zNorm;                     << 193   length    = source.length;
233   rS    = source.rS;                           << 194   prevRS    = source.prevRS;
234   zS    = source.zS;                           << 195   prevZS    = source.prevZS;
235   length    = source.length;                   << 196   nextRS    = source.nextRS;
236   prevRS    = source.prevRS;                   << 197   nextZS    = source.nextZS;
237   prevZS    = source.prevZS;                   << 198   
238   nextRS    = source.nextRS;                   << 199   rNormEdge[0]  = source.rNormEdge[0];
239   nextZS    = source.nextZS;                   << 200   rNormEdge[1]  = source.rNormEdge[1];
240                                                << 201   zNormEdge[0]  = source.zNormEdge[0];
241   rNormEdge[0]   = source.rNormEdge[0];        << 202   zNormEdge[1]  = source.zNormEdge[1];
242   rNormEdge[1]  = source.rNormEdge[1];         << 203   
243   zNormEdge[0]  = source.zNormEdge[0];         << 204   if (phiIsOpen) {
244   zNormEdge[1]  = source.zNormEdge[1];         << 205     corners = new G4ThreeVector[4];
245                                                << 206     
246   if (phiIsOpen)                               << 207     corners[0] = source.corners[0];
247   {                                            << 208     corners[1] = source.corners[1];
248     ncorners = 4;                              << 209     corners[2] = source.corners[2];
249     corners = new G4ThreeVector[ncorners];     << 210     corners[3] = source.corners[3];
250                                                << 211   }
251     corners[0] = source.corners[0];            << 
252     corners[1] = source.corners[1];            << 
253     corners[2] = source.corners[2];            << 
254     corners[3] = source.corners[3];            << 
255   }                                            << 
256 }                                                 212 }
257                                                   213 
                                                   >> 214 
                                                   >> 215 //
258 // Intersect                                      216 // Intersect
259 //                                                217 //
260 G4bool G4PolyconeSide::Intersect( const G4Thre << 218 G4bool G4PolyconeSide::Intersect( const G4ThreeVector &p, const G4ThreeVector &v, 
261                                   const G4Thre << 219           G4bool outgoing, G4double surfTolerance,
262                                         G4bool << 220           G4double &distance, G4double &distFromSurface,
263                                         G4doub << 221           G4ThreeVector &normal, G4bool &isAllBehind )
264                                         G4doub << 222 {
265                                         G4doub << 223   G4double s1, s2;
266                                         G4Thre << 224   G4double normSign = outgoing ? +1 : -1;
267                                         G4bool << 225   
268 {                                              << 226   isAllBehind = allBehind;
269   G4double s1=0., s2=0.;                       << 227 
270   G4double normSign = outgoing ? +1 : -1;      << 228   //
271                                                << 229   // Check for two possible intersections
272   isAllBehind = allBehind;                     << 230   //
273                                                << 231   G4int nside = cone->LineHitsCone( p, v, &s1, &s2 );
274   //                                           << 232   if (nside == 0) return false;
275   // Check for two possible intersections      << 233     
276   //                                           << 234   //
277   G4int nside = cone->LineHitsCone( p, v, &s1, << 235   // Check the first side first, since it is (supposed to be) closest
278   if (nside == 0) return false;                << 236   //
279                                                << 237   G4ThreeVector hit = p + s1*v;
280   //                                           << 238   
281   // Check the first side first, since it is ( << 239   if (PointOnCone( hit, normSign, p, v, normal )) {
282   //                                           << 240     //
283   G4ThreeVector hit = p + s1*v;                << 241     // Good intersection! What about the normal? 
284                                                << 242     //
285   if (PointOnCone( hit, normSign, p, v, normal << 243     if (normSign*v.dot(normal) > 0) {
286   {                                            << 244       //
287     //                                         << 245       // We have a valid intersection, but it could very easily
288     // Good intersection! What about the norma << 246       // be behind the point. To decide if we tolerate this,
289     //                                         << 247       // we have to see if the point p is on the surface near
290     if (normSign*v.dot(normal) > 0)            << 248       // the intersecting point.
291     {                                          << 249       //
292       //                                       << 250       // What does it mean exactly for the point p to be "near"
293       // We have a valid intersection, but it  << 251       // the intersection? It means that if we draw a line from
294       // be behind the point. To decide if we  << 252       // p to the hit, the line remains entirely within the
295       // we have to see if the point p is on t << 253       // tolerance bounds of the cone. To test this, we can
296       // the intersecting point.               << 254       // ask if the normal is correct near p.
297       //                                       << 255       //
298       // What does it mean exactly for the poi << 256       G4double pr = p.perp();
299       // the intersection? It means that if we << 257       if (pr < DBL_MIN) pr = DBL_MIN;
300       // p to the hit, the line remains entire << 258       G4ThreeVector pNormal( rNorm*p.x()/pr, rNorm*p.y()/pr, zNorm );
301       // tolerance bounds of the cone. To test << 259       if (normSign*v.dot(pNormal) > 0) {
302       // ask if the normal is correct near p.  << 260         //
303       //                                       << 261         // p and intersection in same hemisphere
304       G4double pr = p.perp();                  << 262         //
305       if (pr < DBL_MIN) pr = DBL_MIN;          << 263         G4double distOutside2;
306       G4ThreeVector pNormal( rNorm*p.x()/pr, r << 264         distFromSurface = -normSign*DistanceAway( p, false, distOutside2 );
307       if (normSign*v.dot(pNormal) > 0)         << 265         if (distOutside2 < surfTolerance*surfTolerance) {
308       {                                        << 266           if (distFromSurface > -surfTolerance) {
309         //                                     << 267             //
310         // p and intersection in same hemisphe << 268             // We are just inside or away from the
311         //                                     << 269             // surface. Accept *any* value of distance.
312         G4double distOutside2;                 << 270             //
313         distFromSurface = -normSign*DistanceAw << 271             distance = s1;
314         if (distOutside2 < surfTolerance*surfT << 272             return true;
315         {                                      << 273           }
316           if (distFromSurface > -surfTolerance << 274         }
317           {                                    << 275       }
318             //                                 << 276       else 
319             // We are just inside or away from << 277         distFromSurface = s1;
320             // surface. Accept *any* value of  << 278       
321             //                                 << 279       //
322             distance = s1;                     << 280       // Accept positive distances
323             return true;                       << 281       //
324           }                                    << 282       if (s1 > 0) {
325         }                                      << 283         distance = s1;
326       }                                        << 284         return true;
327       else                                     << 285       }
328         distFromSurface = s1;                  << 286     }
329                                                << 287   } 
330       //                                       << 288   
331       // Accept positive distances             << 289   if (nside==1) return false;
332       //                                       << 290   
333       if (s1 > 0)                              << 291   //
334       {                                        << 292   // Well, try the second hit
335         distance = s1;                         << 293   //  
336         return true;                           << 294   hit = p + s2*v;
337       }                                        << 295   
338     }                                          << 296   if (PointOnCone( hit, normSign, p, v, normal )) {
339   }                                            << 297     //
340                                                << 298     // Good intersection! What about the normal? 
341   if (nside==1) return false;                  << 299     //
342                                                << 300     if (normSign*v.dot(normal) > 0) {
343   //                                           << 301       G4double pr = p.perp();
344   // Well, try the second hit                  << 302       if (pr < DBL_MIN) pr = DBL_MIN;
345   //                                           << 303       G4ThreeVector pNormal( rNorm*p.x()/pr, rNorm*p.y()/pr, zNorm );
346   hit = p + s2*v;                              << 304       if (normSign*v.dot(pNormal) > 0) {
347                                                << 305         G4double distOutside2;
348   if (PointOnCone( hit, normSign, p, v, normal << 306         distFromSurface = -normSign*DistanceAway( p, false, distOutside2 );
349   {                                            << 307         if (distOutside2 < surfTolerance*surfTolerance) {
350     //                                         << 308           if (distFromSurface > -surfTolerance) {
351     // Good intersection! What about the norma << 309             distance = s2;
352     //                                         << 310             return true;
353     if (normSign*v.dot(normal) > 0)            << 311           }
354     {                                          << 312         }
355       G4double pr = p.perp();                  << 313       }
356       if (pr < DBL_MIN) pr = DBL_MIN;          << 314       else 
357       G4ThreeVector pNormal( rNorm*p.x()/pr, r << 315         distFromSurface = s2;
358       if (normSign*v.dot(pNormal) > 0)         << 316       
359       {                                        << 317       if (s2 > 0) {
360         G4double distOutside2;                 << 318         distance = s2;
361         distFromSurface = -normSign*DistanceAw << 319         return true;
362         if (distOutside2 < surfTolerance*surfT << 320       }
363         {                                      << 321     }
364           if (distFromSurface > -surfTolerance << 322   } 
365           {                                    << 323 
366             distance = s2;                     << 324   //
367             return true;                       << 325   // Better luck next time
368           }                                    << 326   //
369         }                                      << 327   return false;
370       }                                        << 328 }
371       else                                     << 329 
372         distFromSurface = s2;                  << 330 
373                                                << 331 G4double G4PolyconeSide::Distance( const G4ThreeVector &p, G4bool outgoing )
374       if (s2 > 0)                              << 332 {
375       {                                        << 333   G4double normSign = outgoing ? -1 : +1;
376         distance = s2;                         << 334   G4double distFrom, distOut2;
377         return true;                           << 335   
378       }                                        << 336   //
379     }                                          << 337   // We have two tries for each hemisphere. Try the closest first.
380   }                                            << 338   //
381                                                << 339   distFrom = normSign*DistanceAway( p, false, distOut2 );
382   //                                           << 340   if (distFrom > -0.5*kCarTolerance ) {
383   // Better luck next time                     << 341     //
384   //                                           << 342     // Good answer
385   return false;                                << 343     //
                                                   >> 344     if (distOut2 > 0) 
                                                   >> 345       return sqrt( distFrom*distFrom + distOut2 );
                                                   >> 346     else 
                                                   >> 347       return fabs(distFrom);
                                                   >> 348   }
                                                   >> 349   
                                                   >> 350   //
                                                   >> 351   // Try second side. 
                                                   >> 352   //
                                                   >> 353   distFrom = normSign*DistanceAway( p,  true, distOut2 );
                                                   >> 354   if (distFrom > -0.5*kCarTolerance) {
                                                   >> 355 
                                                   >> 356     if (distOut2 > 0) 
                                                   >> 357       return sqrt( distFrom*distFrom + distOut2 );
                                                   >> 358     else
                                                   >> 359       return fabs(distFrom);
                                                   >> 360   }
                                                   >> 361   
                                                   >> 362   return kInfinity;
386 }                                                 363 }
387                                                   364 
388 // Distance                                    << 
389 //                                             << 
390 G4double G4PolyconeSide::Distance( const G4Thr << 
391 {                                              << 
392   G4double normSign = outgoing ? -1 : +1;      << 
393   G4double distFrom, distOut2;                 << 
394                                                << 
395   //                                           << 
396   // We have two tries for each hemisphere. Tr << 
397   //                                           << 
398   distFrom = normSign*DistanceAway( p, false,  << 
399   if (distFrom > -0.5*kCarTolerance )          << 
400   {                                            << 
401     //                                         << 
402     // Good answer                             << 
403     //                                         << 
404     if (distOut2 > 0)                          << 
405       return std::sqrt( distFrom*distFrom + di << 
406     else                                       << 
407       return std::fabs(distFrom);              << 
408   }                                            << 
409                                                << 
410   //                                           << 
411   // Try second side.                          << 
412   //                                           << 
413   distFrom = normSign*DistanceAway( p,  true,  << 
414   if (distFrom > -0.5*kCarTolerance)           << 
415   {                                            << 
416                                                << 
417     if (distOut2 > 0)                          << 
418       return std::sqrt( distFrom*distFrom + di << 
419     else                                       << 
420       return std::fabs(distFrom);              << 
421   }                                            << 
422                                                << 
423   return kInfinity;                            << 
424 }                                              << 
425                                                   365 
                                                   >> 366 //
426 // Inside                                         367 // Inside
427 //                                                368 //
428 EInside G4PolyconeSide::Inside( const G4ThreeV << 369 EInside G4PolyconeSide::Inside( const G4ThreeVector &p, G4double tolerance, 
429                                       G4double << 370         G4double *bestDistance )
430                                       G4double << 
431 {                                                 371 {
432   G4double distFrom, distOut2, dist2;          << 372   //
433   G4double edgeRZnorm;                         << 373   // Check both sides
434                                                << 374   //
435   distFrom =  DistanceAway( p, distOut2, &edge << 375   G4double distFrom[2], distOut2[2], dist2[2];
436   dist2 = distFrom*distFrom + distOut2;        << 376   G4double edgeRZnorm[2];
437                                                << 377      
438   *bestDistance = std::sqrt( dist2);           << 378   distFrom[0] =  DistanceAway( p, false, distOut2[0], edgeRZnorm   );
439                                                << 379   distFrom[1] =  DistanceAway( p,  true, distOut2[1], edgeRZnorm+1 );
440   // Okay then, inside or out?                 << 380   
441   //                                           << 381   dist2[0] = distFrom[0]*distFrom[0] + distOut2[0];
442   if ( (std::fabs(edgeRZnorm) < tolerance)     << 382   dist2[1] = distFrom[1]*distFrom[1] + distOut2[1];
443     && (distOut2< tolerance*tolerance) )       << 383   
444     return kSurface;                           << 384   //
445   else if (edgeRZnorm < 0)                     << 385   // Who's closest?
446     return kInside;                            << 386   //
447   else                                         << 387   G4int i = fabs(dist2[0]) < fabs(dist2[1]) ? 0 : 1;
448     return kOutside;                           << 388   
                                                   >> 389   *bestDistance = sqrt( dist2[i] );
                                                   >> 390   
                                                   >> 391   //
                                                   >> 392   // Okay then, inside or out?
                                                   >> 393   //
                                                   >> 394   if ( (fabs(edgeRZnorm[i]) < tolerance) && (distOut2[i] < tolerance*tolerance) )
                                                   >> 395     return kSurface;
                                                   >> 396   else if (edgeRZnorm[i] < 0)
                                                   >> 397     return kInside;
                                                   >> 398   else
                                                   >> 399     return kOutside;
449 }                                                 400 }
450                                                   401 
                                                   >> 402 
                                                   >> 403 //
451 // Normal                                         404 // Normal
452 //                                                405 //
453 G4ThreeVector G4PolyconeSide::Normal( const G4 << 406 G4ThreeVector G4PolyconeSide::Normal( const G4ThreeVector &p,  G4double *bestDistance )
454                                             G4 << 
455 {                                                 407 {
456   if (p == G4ThreeVector(0.,0.,0.))  { return  << 408   G4ThreeVector dFrom;
457                                                << 409   G4double dOut2;
458   G4double dFrom, dOut2;                       << 410   
459                                                << 411   dFrom = DistanceAway( p, false, dOut2 );
460   dFrom = DistanceAway( p, false, dOut2 );     << 412   
461                                                << 413   *bestDistance = sqrt( dFrom*dFrom + dOut2 );
462   *bestDistance = std::sqrt( dFrom*dFrom + dOu << 414   
463                                                << 415   G4double rad = p.perp();
464   G4double rds = p.perp();                     << 416   return G4ThreeVector( rNorm*p.x()/rad, rNorm*p.y()/rad, zNorm );
465   if (rds!=0.) { return {rNorm*p.x()/rds,rNorm << 
466   return G4ThreeVector( 0.,0., zNorm ).unit(); << 
467 }                                                 417 }
468                                                   418 
                                                   >> 419 
                                                   >> 420 //
469 // Extent                                         421 // Extent
470 //                                                422 //
471 G4double G4PolyconeSide::Extent( const G4Three    423 G4double G4PolyconeSide::Extent( const G4ThreeVector axis )
472 {                                                 424 {
473   if (axis.perp2() < DBL_MIN)                  << 425   if (axis.perp2() < DBL_MIN) {
474   {                                            << 426     //
475     //                                         << 427     // Special case
476     // Special case                            << 428     //
477     //                                         << 429     return axis.z() < 0 ? -cone->ZLo() : cone->ZHi();
478     return axis.z() < 0 ? -cone->ZLo() : cone- << 430   }
479   }                                            << 431 
480                                                << 432   //
481   //                                           << 433   // Is the axis pointing inside our phi gap?
482   // Is the axis pointing inside our phi gap?  << 434   //
483   //                                           << 435   if (phiIsOpen) {
484   if (phiIsOpen)                               << 436     G4double phi = axis.phi();
485   {                                            << 437     while( phi < startPhi ) phi += 2*M_PI;
486     G4double phi = GetPhi(axis);               << 438     
487     while( phi < startPhi )    // Loop checkin << 439     if (phi > deltaPhi+startPhi) {
488       phi += twopi;                            << 440       //
489                                                << 441       // Yeah, looks so. Make four three vectors defining the phi
490     if (phi > deltaPhi+startPhi)               << 442       // opening
491     {                                          << 443       //
492       //                                       << 444       G4double cosP = cos(startPhi), sinP = sin(startPhi);
493       // Yeah, looks so. Make four three vecto << 445       G4ThreeVector a( r[0]*cosP, r[0]*sinP, z[0] );
494       // opening                               << 446       G4ThreeVector b( r[1]*cosP, r[1]*sinP, z[1] );
495       //                                       << 447       cosP = cos(startPhi+deltaPhi); sinP = sin(startPhi+deltaPhi);
496       G4double cosP = std::cos(startPhi), sinP << 448       G4ThreeVector c( r[0]*cosP, r[0]*sinP, z[0] );
497       G4ThreeVector a( r[0]*cosP, r[0]*sinP, z << 449       G4ThreeVector d( r[1]*cosP, r[1]*sinP, z[1] );
498       G4ThreeVector b( r[1]*cosP, r[1]*sinP, z << 450       
499       cosP = std::cos(startPhi+deltaPhi); sinP << 451       G4double ad = axis.dot(a),
500       G4ThreeVector c( r[0]*cosP, r[0]*sinP, z << 452          bd = axis.dot(b),
501       G4ThreeVector d( r[1]*cosP, r[1]*sinP, z << 453          cd = axis.dot(c),
502                                                << 454          dd = axis.dot(d);
503       G4double ad = axis.dot(a),               << 455       
504                bd = axis.dot(b),               << 456       if (bd > ad) ad = bd;
505                cd = axis.dot(c),               << 457       if (cd > ad) ad = cd;
506                dd = axis.dot(d);               << 458       if (dd > ad) ad = dd;
507                                                << 459       
508       if (bd > ad) ad = bd;                    << 460       return ad;
509       if (cd > ad) ad = cd;                    << 461     }
510       if (dd > ad) ad = dd;                    << 462   }
511                                                << 463 
512       return ad;                               << 464   //
513     }                                          << 465   // Check either end
514   }                                            << 466   //
515                                                << 467   G4double aPerp = axis.perp();
516   //                                           << 468   
517   // Check either end                          << 469   G4double a = aPerp*r[0] + axis.z()*z[0];
518   //                                           << 470   G4double b = aPerp*r[1] + axis.z()*z[1];
519   G4double aPerp = axis.perp();                << 471   
520                                                << 472   if (b > a) a = b;
521   G4double a = aPerp*r[0] + axis.z()*z[0];     << 473   
522   G4double b = aPerp*r[1] + axis.z()*z[1];     << 474   return a;
523                                                << 
524   if (b > a) a = b;                            << 
525                                                << 
526   return a;                                    << 
527 }                                                 475 }
528                                                   476 
                                                   >> 477 
                                                   >> 478 
                                                   >> 479 //
529 // CalculateExtent                                480 // CalculateExtent
530 //                                                481 //
531 // See notes in G4VCSGface                        482 // See notes in G4VCSGface
532 //                                                483 //
533 void G4PolyconeSide::CalculateExtent( const EA    484 void G4PolyconeSide::CalculateExtent( const EAxis axis, 
534                                       const G4 << 485               const G4VoxelLimits &voxelLimit,
535                                       const G4 << 486               const G4AffineTransform &transform,
536                                             G4 << 487               G4SolidExtentList &extentList        )
537 {                                              << 488 {
538   G4ClippablePolygon polygon;                  << 489   G4ClippablePolygon polygon;
539                                                << 490   
540   //                                           << 491   //
541   // Here we will approximate (ala G4Cons) and << 492   // Here we will approximate (ala G4Cons) and divide our conical section
542   // into segments, like G4Polyhedra. When doi << 493   // into segments, like G4Polyhedra. When doing so, the radius
543   // is extented far enough such that the segm << 494   // is extented far enough such that the segments always lie
544   // just outside the surface of the conical s << 495   // just outside the surface of the conical section we are
545   // approximating.                            << 496   // approximating.
546   //                                           << 497   //
547                                                << 498   
548   //                                           << 499   //
549   // Choose phi size of our segment(s) based o << 500   // Choose phi size of our segment(s) based on constants as
550   // defined in meshdefs.hh                    << 501   // defined in meshdefs.hh
551   //                                           << 502   //
552   G4int numPhi = (G4int)(deltaPhi/kMeshAngleDe << 503   G4int numPhi = (G4int)(deltaPhi/kMeshAngleDefault) + 1;
553   if (numPhi < kMinMeshSections)               << 504   if (numPhi < kMinMeshSections) 
554     numPhi = kMinMeshSections;                 << 505     numPhi = kMinMeshSections;
555   else if (numPhi > kMaxMeshSections)          << 506   else if (numPhi > kMaxMeshSections)
556     numPhi = kMaxMeshSections;                 << 507     numPhi = kMaxMeshSections;
557                                                << 508     
558   G4double sigPhi = deltaPhi/numPhi;           << 509   G4double sigPhi = deltaPhi/numPhi;
559                                                << 510   
560   //                                           << 511   //
561   // Determine radius factor to keep segments  << 512   // Determine radius factor to keep segments outside
562   //                                           << 513   //
563   G4double rFudge = 1.0/std::cos(0.5*sigPhi);  << 514   G4double rFudge = 1.0/cos(0.5*sigPhi);
564                                                << 515   
565   //                                           << 516   //
566   // Decide which radius to use on each end of << 517   // Decide which radius to use on each end of the side,
567   // and whether a transition mesh is required << 518   // and whether a transition mesh is required
568   //                                           << 519   //
569   // {r0,z0}  - Beginning of this side         << 520   // {r0,z0}  - Beginning of this side
570   // {r1,z1}  - Ending of this side            << 521   // {r1,z1}  - Ending of this side
571   // {r2,z0}  - Beginning of transition piece  << 522   // {r2,z0}  - Beginning of transition piece connecting previous
572   //            side (and ends at beginning of << 523   //            side (and ends at beginning of this side)
573   //                                           << 524   //
574   // So, order is 2 --> 0 --> 1.               << 525   // So, order is 2 --> 0 --> 1.
575   //                    -------                << 526   //                    -------
576   //                                           << 527   //
577   // r2 < 0 indicates that no transition piece << 528   // r2 < 0 indicates that no transition piece is required
578   //                                           << 529   //
579   G4double r0, r1, r2, z0, z1;                 << 530   G4double r0, r1, r2, z0, z1;
580                                                << 531   
581   r2 = -1;  // By default: no transition piece << 532   r2 = -1;  // By default: no transition piece
582                                                << 533   
583   if (rNorm < -DBL_MIN)                        << 534   if (rNorm < -DBL_MIN) {
584   {                                            << 535     //
585     //                                         << 536     // This side faces *inward*, and so our mesh has
586     // This side faces *inward*, and so our me << 537     // the same radius
587     // the same radius                         << 538     //
588     //                                         << 539     r1 = r[1];
589     r1 = r[1];                                 << 540     z1 = z[1];
590     z1 = z[1];                                 << 541     z0 = z[0];
591     z0 = z[0];                                 << 542     r0 = r[0];
592     r0 = r[0];                                 << 543     
593                                                << 544     r2 = -1;
594     r2 = -1;                                   << 545     
595                                                << 546     if (prevZS > DBL_MIN) {
596     if (prevZS > DBL_MIN)                      << 547       //
597     {                                          << 548       // The previous side is facing outwards
598       //                                       << 549       //
599       // The previous side is facing outwards  << 550       if ( prevRS*zS - prevZS*rS > 0 ) {
600       //                                       << 551         //
601       if ( prevRS*zS - prevZS*rS > 0 )         << 552         // Transition was convex: build transition piece
602       {                                        << 553         //
603         //                                     << 554         if (r[0] > DBL_MIN) r2 = r[0]*rFudge;
604         // Transition was convex: build transi << 555       }
605         //                                     << 556       else {
606         if (r[0] > DBL_MIN) r2 = r[0]*rFudge;  << 557         //
607       }                                        << 558         // Transition was concave: short this side
608       else                                     << 559         //
609       {                                        << 560         FindLineIntersect( z0, r0, zS, rS,
610         //                                     << 561                z0, r0*rFudge, prevZS, prevRS*rFudge, z0, r0 );
611         // Transition was concave: short this  << 562       }
612         //                                     << 563     }
613         FindLineIntersect( z0, r0, zS, rS,     << 564     
614                            z0, r0*rFudge, prev << 565     if ( nextZS > DBL_MIN && (rS*nextZS - zS*nextRS < 0) ) {
615       }                                        << 566       //
616     }                                          << 567       // The next side is facing outwards, forming a 
617                                                << 568       // concave transition: short this side
618     if ( nextZS > DBL_MIN && (rS*nextZS - zS*n << 569       //
619     {                                          << 570       FindLineIntersect( z1, r1, zS, rS,
620       //                                       << 571              z1, r1*rFudge, nextZS, nextRS*rFudge, z1, r1 );
621       // The next side is facing outwards, for << 572     }
622       // concave transition: short this side   << 573   }
623       //                                       << 574   else if (rNorm > DBL_MIN) {
624       FindLineIntersect( z1, r1, zS, rS,       << 575     //
625                          z1, r1*rFudge, nextZS << 576     // This side faces *outward* and is given a boost to
626     }                                          << 577     // it radius
627   }                                            << 578     //
628   else if (rNorm > DBL_MIN)                    << 579     r0 = r[0]*rFudge;
629   {                                            << 580     z0 = z[0];
630     //                                         << 581     r1 = r[1]*rFudge;
631     // This side faces *outward* and is given  << 582     z1 = z[1];
632     // it radius                               << 583     
633     //                                         << 584     if (prevZS < -DBL_MIN) {
634     r0 = r[0]*rFudge;                          << 585       //
635     z0 = z[0];                                 << 586       // The previous side is facing inwards
636     r1 = r[1]*rFudge;                          << 587       //
637     z1 = z[1];                                 << 588       if ( prevRS*zS - prevZS*rS > 0 ) {
638                                                << 589         //
639     if (prevZS < -DBL_MIN)                     << 590         // Transition was convex: build transition piece
640     {                                          << 591         //
641       //                                       << 592         if (r[0] > DBL_MIN) r2 = r[0];
642       // The previous side is facing inwards   << 593       }
643       //                                       << 594       else {
644       if ( prevRS*zS - prevZS*rS > 0 )         << 595         //
645       {                                        << 596         // Transition was concave: short this side
646         //                                     << 597         //
647         // Transition was convex: build transi << 598         FindLineIntersect( z0, r0, zS, rS*rFudge,
648         //                                     << 599                z0, r[0], prevZS, prevRS, z0, r0 );
649         if (r[0] > DBL_MIN) r2 = r[0];         << 600       }
650       }                                        << 601     }
651       else                                     << 602     
652       {                                        << 603     if ( nextZS < -DBL_MIN && (rS*nextZS - zS*nextRS < 0) ) {
653         //                                     << 604       //
654         // Transition was concave: short this  << 605       // The next side is facing inwards, forming a 
655         //                                     << 606       // concave transition: short this side
656         FindLineIntersect( z0, r0, zS, rS*rFud << 607       //
657                            z0, r[0], prevZS, p << 608       FindLineIntersect( z1, r1, zS, rS*rFudge,
658       }                                        << 609              z1, r[1], nextZS, nextRS, z1, r1 );
659     }                                          << 610     }
660                                                << 611   }
661     if ( nextZS < -DBL_MIN && (rS*nextZS - zS* << 612   else {
662     {                                          << 613     //
663       //                                       << 614     // This side is perpendicular to the z axis (is a disk)
664       // The next side is facing inwards, form << 615     //
665       // concave transition: short this side   << 616     // Whether or not r0 needs a rFudge factor depends
666       //                                       << 617     // on the normal of the previous edge. Similar with r1
667       FindLineIntersect( z1, r1, zS, rS*rFudge << 618     // and the next edge. No transition piece is required.
668                          z1, r[1], nextZS, nex << 619     //
669     }                                          << 620     r0 = r[0];
670   }                                            << 621     r1 = r[1];
671   else                                         << 622     z0 = z[0];
672   {                                            << 623     z1 = z[1];
673     //                                         << 624     
674     // This side is perpendicular to the z axi << 625     if (prevZS > DBL_MIN) r0 *= rFudge;
675     //                                         << 626     if (nextZS > DBL_MIN) r1 *= rFudge;
676     // Whether or not r0 needs a rFudge factor << 627   }
677     // on the normal of the previous edge. Sim << 628   
678     // and the next edge. No transition piece  << 629   //
679     //                                         << 630   // Loop
680     r0 = r[0];                                 << 631   //
681     r1 = r[1];                                 << 632   G4double phi = startPhi, 
682     z0 = z[0];                                 << 633            cosPhi = cos(phi), 
683     z1 = z[1];                                 << 634      sinPhi = sin(phi);
684                                                << 635   
685     if (prevZS > DBL_MIN) r0 *= rFudge;        << 636   G4ThreeVector v0( r0*cosPhi, r0*sinPhi, z0 ),
686     if (nextZS > DBL_MIN) r1 *= rFudge;        << 637           v1( r1*cosPhi, r1*sinPhi, z1 ),
687   }                                            << 638           v2, w0, w1, w2;
688                                                << 639   transform.ApplyPointTransform( v0 );
689   //                                           << 640   transform.ApplyPointTransform( v1 );
690   // Loop                                      << 641   
691   //                                           << 642   if (r2 >= 0) {
692   G4double phi = startPhi,                     << 643     v2 = G4ThreeVector( r2*cosPhi, r2*sinPhi, z0 );
693            cosPhi = std::cos(phi),             << 644     transform.ApplyPointTransform( v2 );
694            sinPhi = std::sin(phi);             << 645   }
695                                                << 646 
696   G4ThreeVector v0( r0*cosPhi, r0*sinPhi, z0 ) << 647   do {
697                     v1( r1*cosPhi, r1*sinPhi,  << 648   
698   v2, w0, w1, w2;                              << 649     phi += sigPhi;
699   transform.ApplyPointTransform( v0 );         << 650     if (numPhi == 1) phi = startPhi+deltaPhi; // Try to avoid roundoff
700   transform.ApplyPointTransform( v1 );         << 651           cosPhi = cos(phi), 
701                                                << 652     sinPhi = sin(phi);
702   if (r2 >= 0)                                 << 653     
703   {                                            << 654     w0 = G4ThreeVector( r0*cosPhi, r0*sinPhi, z0 );
704     v2 = G4ThreeVector( r2*cosPhi, r2*sinPhi,  << 655     w1 = G4ThreeVector( r1*cosPhi, r1*sinPhi, z1 );
705     transform.ApplyPointTransform( v2 );       << 656     transform.ApplyPointTransform( w0 );
706   }                                            << 657     transform.ApplyPointTransform( w1 );
707                                                << 658     
708   do    // Loop checking, 13.08.2015, G.Cosmo  << 659     G4ThreeVector deltaV = r0 > r1 ? w0-v0 : w1-v1;
709   {                                            << 660     
710     phi += sigPhi;                             << 661     //
711     if (numPhi == 1) phi = startPhi+deltaPhi;  << 662     // Build polygon, taking special care to keep the vertices
712     cosPhi = std::cos(phi),                    << 663     // in order
713     sinPhi = std::sin(phi);                    << 664     //
714                                                << 665     polygon.ClearAllVertices();
715     w0 = G4ThreeVector( r0*cosPhi, r0*sinPhi,  << 666 
716     w1 = G4ThreeVector( r1*cosPhi, r1*sinPhi,  << 667     polygon.AddVertexInOrder( v0 );
717     transform.ApplyPointTransform( w0 );       << 668     polygon.AddVertexInOrder( v1 );
718     transform.ApplyPointTransform( w1 );       << 669     polygon.AddVertexInOrder( w1 );
719                                                << 670     polygon.AddVertexInOrder( w0 );
720     G4ThreeVector deltaV = r0 > r1 ? w0-v0 : w << 671 
721                                                << 672     //
722     //                                         << 673     // Get extent
723     // Build polygon, taking special care to k << 674     //
724     // in order                                << 675     if (polygon.PartialClip( voxelLimit, axis )) {
725     //                                         << 676       //
726     polygon.ClearAllVertices();                << 677       // Get dot product of normal with target axis
727                                                << 678       //
728     polygon.AddVertexInOrder( v0 );            << 679       polygon.SetNormal( deltaV.cross(v1-v0).unit() );
729     polygon.AddVertexInOrder( v1 );            << 680       
730     polygon.AddVertexInOrder( w1 );            << 681       extentList.AddSurface( polygon );
731     polygon.AddVertexInOrder( w0 );            << 682     }
732                                                << 683     
733     //                                         << 684     if (r2 >= 0) {
734     // Get extent                              << 685       //
735     //                                         << 686       // Repeat, for transition piece
736     if (polygon.PartialClip( voxelLimit, axis  << 687       //
737     {                                          << 688       w2 = G4ThreeVector( r2*cosPhi, r2*sinPhi, z0 );
738       //                                       << 689       transform.ApplyPointTransform( w2 );
739       // Get dot product of normal with target << 690 
740       //                                       << 691       polygon.ClearAllVertices();
741       polygon.SetNormal( deltaV.cross(v1-v0).u << 692 
742                                                << 693       polygon.AddVertexInOrder( v2 );
743       extentList.AddSurface( polygon );        << 694       polygon.AddVertexInOrder( v0 );
744     }                                          << 695       polygon.AddVertexInOrder( w0 );
745                                                << 696       polygon.AddVertexInOrder( w2 );
746     if (r2 >= 0)                               << 697 
747     {                                          << 698       if (polygon.PartialClip( voxelLimit, axis )) {
748       //                                       << 699         polygon.SetNormal( deltaV.cross(v0-v2).unit() );
749       // Repeat, for transition piece          << 700         
750       //                                       << 701         extentList.AddSurface( polygon );
751       w2 = G4ThreeVector( r2*cosPhi, r2*sinPhi << 702       }
752       transform.ApplyPointTransform( w2 );     << 703       
753                                                << 704       v2 = w2;
754       polygon.ClearAllVertices();              << 705     }
755                                                << 706     
756       polygon.AddVertexInOrder( v2 );          << 707     //
757       polygon.AddVertexInOrder( v0 );          << 708     // Next vertex
758       polygon.AddVertexInOrder( w0 );          << 709     //    
759       polygon.AddVertexInOrder( w2 );          << 710     v0 = w0;
760                                                << 711     v1 = w1;
761       if (polygon.PartialClip( voxelLimit, axi << 712   } while( --numPhi > 0 );
762       {                                        << 713   
763         polygon.SetNormal( deltaV.cross(v0-v2) << 714   //
764                                                << 715   // We are almost done. But, it is important that we leave no
765         extentList.AddSurface( polygon );      << 716   // gaps in the surface of our solid. By using rFudge, however,
766       }                                        << 717   // we've done exactly that, if we have a phi segment. 
767                                                << 718   // Add two additional faces if necessary
768       v2 = w2;                                 << 719   //
769     }                                          << 720   if (phiIsOpen && rNorm > DBL_MIN) {
770                                                << 721     
771     //                                         << 722     G4double cosPhi = cos(startPhi),
772     // Next vertex                             << 723        sinPhi = sin(startPhi);
773     //                                         << 724 
774     v0 = w0;                                   << 725     G4ThreeVector a0( r[0]*cosPhi, r[0]*sinPhi, z[0] ),
775     v1 = w1;                                   << 726             a1( r[1]*cosPhi, r[1]*sinPhi, z[1] ),
776   } while( --numPhi > 0 );                     << 727             b0( r0*cosPhi, r0*sinPhi, z[0] ),
777                                                << 728             b1( r1*cosPhi, r1*sinPhi, z[1] );
778   //                                           << 729   
779   // We are almost done. But, it is important  << 730     transform.ApplyPointTransform( a0 );
780   // gaps in the surface of our solid. By usin << 731     transform.ApplyPointTransform( a1 );
781   // we've done exactly that, if we have a phi << 732     transform.ApplyPointTransform( b0 );
782   // Add two additional faces if necessary     << 733     transform.ApplyPointTransform( b1 );
783   //                                           << 734 
784   if (phiIsOpen && rNorm > DBL_MIN)            << 735     polygon.ClearAllVertices();
785   {                                            << 736 
786     cosPhi = std::cos(startPhi);               << 737     polygon.AddVertexInOrder( a0 );
787     sinPhi = std::sin(startPhi);               << 738     polygon.AddVertexInOrder( a1 );
788                                                << 739     polygon.AddVertexInOrder( b0 );
789     G4ThreeVector a0( r[0]*cosPhi, r[0]*sinPhi << 740     polygon.AddVertexInOrder( b1 );
790                   a1( r[1]*cosPhi, r[1]*sinPhi << 741     
791                   b0( r0*cosPhi, r0*sinPhi, z[ << 742     if (polygon.PartialClip( voxelLimit , axis)) {
792                   b1( r1*cosPhi, r1*sinPhi, z[ << 743       G4ThreeVector normal( sinPhi, -cosPhi, 0 );
793                                                << 744       polygon.SetNormal( transform.TransformAxis( normal ) );
794     transform.ApplyPointTransform( a0 );       << 745         
795     transform.ApplyPointTransform( a1 );       << 746       extentList.AddSurface( polygon );
796     transform.ApplyPointTransform( b0 );       << 747     }
797     transform.ApplyPointTransform( b1 );       << 748     
798                                                << 749     cosPhi = cos(startPhi+deltaPhi);
799     polygon.ClearAllVertices();                << 750     sinPhi = sin(startPhi+deltaPhi);
800                                                << 751     
801     polygon.AddVertexInOrder( a0 );            << 752     a0 = G4ThreeVector( r[0]*cosPhi, r[0]*sinPhi, z[0] ),
802     polygon.AddVertexInOrder( a1 );            << 753     a1 = G4ThreeVector( r[1]*cosPhi, r[1]*sinPhi, z[1] ),
803     polygon.AddVertexInOrder( b0 );            << 754     b0 = G4ThreeVector( r0*cosPhi, r0*sinPhi, z[0] ),
804     polygon.AddVertexInOrder( b1 );            << 755     b1 = G4ThreeVector( r1*cosPhi, r1*sinPhi, z[1] );
805                                                << 756     transform.ApplyPointTransform( a0 );
806     if (polygon.PartialClip( voxelLimit , axis << 757     transform.ApplyPointTransform( a1 );
807     {                                          << 758     transform.ApplyPointTransform( b0 );
808       G4ThreeVector normal( sinPhi, -cosPhi, 0 << 759     transform.ApplyPointTransform( b1 );
809       polygon.SetNormal( transform.TransformAx << 760 
810                                                << 761     polygon.ClearAllVertices();
811       extentList.AddSurface( polygon );        << 762 
812     }                                          << 763     polygon.AddVertexInOrder( a0 );
813                                                << 764     polygon.AddVertexInOrder( a1 );
814     cosPhi = std::cos(startPhi+deltaPhi);      << 765     polygon.AddVertexInOrder( b0 );
815     sinPhi = std::sin(startPhi+deltaPhi);      << 766     polygon.AddVertexInOrder( b1 );
816                                                << 767     
817     a0 = G4ThreeVector( r[0]*cosPhi, r[0]*sinP << 768     if (polygon.PartialClip( voxelLimit, axis )) {
818     a1 = G4ThreeVector( r[1]*cosPhi, r[1]*sinP << 769       G4ThreeVector normal( -sinPhi, cosPhi, 0 );
819     b0 = G4ThreeVector( r0*cosPhi, r0*sinPhi,  << 770       polygon.SetNormal( transform.TransformAxis( normal ) );
820     b1 = G4ThreeVector( r1*cosPhi, r1*sinPhi,  << 771         
821     transform.ApplyPointTransform( a0 );       << 772       extentList.AddSurface( polygon );
822     transform.ApplyPointTransform( a1 );       << 773     }
823     transform.ApplyPointTransform( b0 );       << 774   }
824     transform.ApplyPointTransform( b1 );       << 775     
825                                                << 776   return;
826     polygon.ClearAllVertices();                << 
827                                                << 
828     polygon.AddVertexInOrder( a0 );            << 
829     polygon.AddVertexInOrder( a1 );            << 
830     polygon.AddVertexInOrder( b0 );            << 
831     polygon.AddVertexInOrder( b1 );            << 
832                                                << 
833     if (polygon.PartialClip( voxelLimit, axis  << 
834     {                                          << 
835       G4ThreeVector normal( -sinPhi, cosPhi, 0 << 
836       polygon.SetNormal( transform.TransformAx << 
837                                                << 
838       extentList.AddSurface( polygon );        << 
839     }                                          << 
840   }                                            << 
841                                                << 
842   return;                                      << 
843 }                                                 777 }
844                                                   778 
845 // GetPhi                                      << 
846 //                                             << 
847 // Calculate Phi for a given 3-vector (point), << 
848 // same point, in the attempt to avoid consecu << 
849 // quantity                                    << 
850 //                                             << 
851 G4double G4PolyconeSide::GetPhi( const G4Three << 
852 {                                              << 
853   G4double val=0.;                             << 
854   G4ThreeVector vphi(G4MT_pcphix, G4MT_pcphiy, << 
855                                                   779 
856   if (vphi != p)                               << 780 //
857   {                                            << 781 // -------------------------------------------------------
858     val = p.phi();                             << 
859     G4MT_pcphix = p.x(); G4MT_pcphiy = p.y();  << 
860     G4MT_pcphik = val;                         << 
861   }                                            << 
862   else                                         << 
863   {                                            << 
864     val = G4MT_pcphik;                         << 
865   }                                            << 
866   return val;                                  << 
867 }                                              << 
868                                                   782 
                                                   >> 783 //
869 // DistanceAway                                   784 // DistanceAway
870 //                                                785 //
871 // Calculate distance of a point from our coni    786 // Calculate distance of a point from our conical surface, including the effect
872 // of any phi segmentation                        787 // of any phi segmentation
873 //                                                788 //
874 // Arguments:                                     789 // Arguments:
875 //  p             - (in) Point to check        << 790 //  p   - (in) Point to check
876 //  opposite      - (in) If true, check opposi << 791 //  opposite  - (in) If true, check opposite hemisphere (see below)
877 //  distOutside   - (out) Additional distance  << 792 //  distOutside - (out) Additional distance outside the edges of the
878 //  edgeRZnorm    - (out) if negative, point i << 793 //        surface
879 //                                             << 794 //  edgeRZnorm  - (out) if negative, point is inside
880 //  return value = distance from the conical p << 795 //  return value = distance from the conical plane, if extrapolated beyond edges,
881 //                 signed by whether the point << 796 //           signed by whether the point is in inside or outside the shape
882 //                                                797 //
883 // Notes:                                         798 // Notes:
884 //  * There are two answers, depending on whic << 799 //  * There are two answers, depending on which hemisphere is considered.
885 //                                                800 //
886 G4double G4PolyconeSide::DistanceAway( const G << 801 G4double G4PolyconeSide::DistanceAway( const G4ThreeVector &p, G4bool opposite,
887                                              G << 802                G4double &distOutside2, G4double *edgeRZnorm  )
888                                              G << 
889                                              G << 
890 {                                                 803 {
891   //                                           << 804   //
892   // Convert our point to r and z              << 805   // Convert our point to r and z
893   //                                           << 806   //
894   G4double rx = p.perp(), zx = p.z();          << 807   G4double rx = p.perp(), zx = p.z();
895                                                << 808   
896   //                                           << 809   //
897   // Change sign of r if opposite says we shou << 810   // Change sign of r if opposite says we should
898   //                                           << 811   //
899   if (opposite) rx = -rx;                      << 812   if (opposite) rx = -rx;
900                                                << 813   
901   //                                           << 814   //
902   // Calculate return value                    << 815   // Calculate return value
903   //                                           << 816   //
904   G4double deltaR  = rx - r[0], deltaZ = zx -  << 817   G4double deltaR  = rx - r[0], deltaZ = zx - z[0];
905   G4double answer = deltaR*rNorm + deltaZ*zNor << 818   G4double answer = deltaR*rNorm + deltaZ*zNorm;
906                                                << 819   
907   //                                           << 820   //
908   // Are we off the surface in r,z space?      << 821   // Are we off the surface in r,z space?
909   //                                           << 822   //
910   G4double q = deltaR*rS + deltaZ*zS;          << 823   G4double s = deltaR*rS + deltaZ*zS;
911   if (q < 0)                                   << 824   if (s < 0) {
912   {                                            << 825     distOutside2 = s*s;
913     distOutside2 = q*q;                        << 826     if (edgeRZnorm) *edgeRZnorm = deltaR*rNormEdge[0] + deltaZ*zNormEdge[0];
914     if (edgeRZnorm != nullptr)                 << 827   }
915       *edgeRZnorm = deltaR*rNormEdge[0] + delt << 828   else if (s > length) {
916   }                                            << 829     distOutside2 = sqr( s-length );
917   else if (q > length)                         << 830     if (edgeRZnorm) {
918   {                                            << 831       G4double deltaR  = rx - r[1], deltaZ = zx - z[1];
919     distOutside2 = sqr( q-length );            << 832       *edgeRZnorm = deltaR*rNormEdge[1] + deltaZ*zNormEdge[1];
920     if (edgeRZnorm != nullptr)                 << 833     }
921     {                                          << 834   }
922       deltaR = rx - r[1];                      << 835   else {
923       deltaZ = zx - z[1];                      << 836     distOutside2 = 0;
924       *edgeRZnorm = deltaR*rNormEdge[1] + delt << 837     if (edgeRZnorm) *edgeRZnorm = answer;
925     }                                          << 838   }
926   }                                            << 839 
927   else                                         << 840   if (phiIsOpen) {
928   {                                            << 841     //
929     distOutside2 = 0.;                         << 842     // Finally, check phi
930     if (edgeRZnorm != nullptr) *edgeRZnorm = a << 843     //
931   }                                            << 844     G4double phi = p.phi();
932                                                << 845     while( phi < startPhi ) phi += 2*M_PI;
933   if (phiIsOpen)                               << 846     
934   {                                            << 847     if (phi > startPhi+deltaPhi) {
935     //                                         << 848       //
936     // Finally, check phi                      << 849       // Oops. Are we closer to the start phi or end phi?
937     //                                         << 850       //
938     G4double phi = GetPhi(p);                  << 851       G4double d1 = phi-startPhi-deltaPhi;
939     while( phi < startPhi )    // Loop checkin << 852       while( phi > startPhi ) phi -= 2*M_PI;
940       phi += twopi;                            << 853       G4double d2 = startPhi-phi;
941                                                << 854       
942     if (phi > startPhi+deltaPhi)               << 855       if (d2 < d1) d1 = d2;
943     {                                          << 856       
944       //                                       << 857       //
945       // Oops. Are we closer to the start phi  << 858       // Add result to our distance
946       //                                       << 859       //
947       G4double d1 = phi-startPhi-deltaPhi;     << 860       G4double dist = d1*rx;
948       while( phi > startPhi )    // Loop check << 861       
949         phi -= twopi;                          << 862       distOutside2 += dist*dist;
950       G4double d2 = startPhi-phi;              << 863       if (edgeRZnorm) *edgeRZnorm = fabs(dist);
951                                                << 864     }
952       if (d2 < d1) d1 = d2;                    << 865   }
953                                                << 
954       //                                       << 
955       // Add result to our distance            << 
956       //                                       << 
957       G4double dist = d1*rx;                   << 
958                                                << 
959       distOutside2 += dist*dist;               << 
960       if (edgeRZnorm != nullptr)               << 
961       {                                        << 
962         *edgeRZnorm = std::max(std::fabs(*edge << 
963       }                                        << 
964     }                                          << 
965   }                                            << 
966                                                   866 
967   return answer;                               << 867   return answer;
968 }                                                 868 }
969                                                   869 
970 // DistanceAway                                << 
971 //                                             << 
972 // Special version of DistanceAway for Inside. << 
973 // Opposite parameter is not used, instead use << 
974 //                                             << 
975 G4double G4PolyconeSide::DistanceAway( const G << 
976                                              G << 
977                                              G << 
978 {                                              << 
979   //                                           << 
980   // Convert our point to r and z              << 
981   //                                           << 
982   G4double rx = p.perp(), zx = p.z();          << 
983                                                << 
984   //                                           << 
985   // Change sign of r if we should             << 
986   //                                           << 
987   G4int part = 1;                              << 
988   if (rx < 0) part = -1;                       << 
989                                                << 
990   //                                           << 
991   // Calculate return value                    << 
992   //                                           << 
993   G4double deltaR = rx - r[0]*part, deltaZ = z << 
994   G4double answer = deltaR*rNorm*part + deltaZ << 
995                                                << 
996   //                                           << 
997   // Are we off the surface in r,z space?      << 
998   //                                           << 
999   G4double q = deltaR*rS*part + deltaZ*zS;     << 
1000   if (q < 0)                                  << 
1001   {                                           << 
1002     distOutside2 = q*q;                       << 
1003     if (edgeRZnorm != nullptr)                << 
1004     {                                         << 
1005       *edgeRZnorm = deltaR*rNormEdge[0]*part  << 
1006     }                                         << 
1007   }                                           << 
1008   else if (q > length)                        << 
1009   {                                           << 
1010     distOutside2 = sqr( q-length );           << 
1011     if (edgeRZnorm != nullptr)                << 
1012     {                                         << 
1013       deltaR = rx - r[1]*part;                << 
1014       deltaZ = zx - z[1];                     << 
1015       *edgeRZnorm = deltaR*rNormEdge[1]*part  << 
1016     }                                         << 
1017   }                                           << 
1018   else                                        << 
1019   {                                           << 
1020     distOutside2 = 0.;                        << 
1021     if (edgeRZnorm != nullptr) *edgeRZnorm =  << 
1022   }                                           << 
1023                                               << 
1024   if (phiIsOpen)                              << 
1025   {                                           << 
1026     //                                        << 
1027     // Finally, check phi                     << 
1028     //                                        << 
1029     G4double phi = GetPhi(p);                 << 
1030     while( phi < startPhi )    // Loop checki << 
1031       phi += twopi;                           << 
1032                                               << 
1033     if (phi > startPhi+deltaPhi)              << 
1034     {                                         << 
1035       //                                      << 
1036       // Oops. Are we closer to the start phi << 
1037       //                                      << 
1038       G4double d1 = phi-startPhi-deltaPhi;    << 
1039       while( phi > startPhi )    // Loop chec << 
1040         phi -= twopi;                         << 
1041       G4double d2 = startPhi-phi;             << 
1042                                               << 
1043       if (d2 < d1) d1 = d2;                   << 
1044                                               << 
1045       //                                      << 
1046       // Add result to our distance           << 
1047       //                                      << 
1048       G4double dist = d1*rx*part;             << 
1049                                               << 
1050       distOutside2 += dist*dist;              << 
1051       if (edgeRZnorm != nullptr)              << 
1052       {                                       << 
1053         *edgeRZnorm = std::max(std::fabs(*edg << 
1054       }                                       << 
1055     }                                         << 
1056   }                                           << 
1057                                               << 
1058   return answer;                              << 
1059 }                                             << 
1060                                                  870 
                                                   >> 871 //
1061 // PointOnCone                                   872 // PointOnCone
1062 //                                               873 //
1063 // Decide if a point is on a cone and return     874 // Decide if a point is on a cone and return normal if it is
1064 //                                               875 //
1065 G4bool G4PolyconeSide::PointOnCone( const G4T << 876 G4bool G4PolyconeSide::PointOnCone( const G4ThreeVector &hit, G4double normSign,
1066                                           G4d << 877             const G4ThreeVector &p, const G4ThreeVector &v,
1067                                     const G4T << 878             G4ThreeVector &normal )
1068                                     const G4T << 879 {
1069                                           G4T << 880   G4double rx = hit.perp();
1070 {                                             << 881   //
1071   G4double rx = hit.perp();                   << 882   // Check radial/z extent, as appropriate
1072   //                                          << 883   //
1073   // Check radial/z extent, as appropriate    << 884   if (!cone->HitOn( rx, hit.z() )) return false;
1074   //                                          << 885   
1075   if (!cone->HitOn( rx, hit.z() )) return fal << 886   if (phiIsOpen) {
1076                                               << 887     G4double phiTolerant = 2.0*kCarTolerance/(rx+kCarTolerance);
1077   if (phiIsOpen)                              << 888     //
1078   {                                           << 889     // Check phi segment. Here we have to be careful
1079     G4double phiTolerant = 2.0*kCarTolerance/ << 890     // to use the standard method consistent with
1080     //                                        << 891     // PolyPhiFace. See PolyPhiFace::InsideEdgesExact
1081     // Check phi segment. Here we have to be  << 892     //
1082     // to use the standard method consistent  << 893     G4double phi = hit.phi();
1083     // PolyPhiFace. See PolyPhiFace::InsideEd << 894     while( phi < startPhi-phiTolerant ) phi += 2*M_PI;
1084     //                                        << 895     
1085     G4double phi = GetPhi(hit);               << 896     if (phi > startPhi+deltaPhi+phiTolerant) return false;
1086     while( phi < startPhi-phiTolerant )   //  << 897     
1087       phi += twopi;                           << 898     if (phi > startPhi+deltaPhi-phiTolerant) {
1088                                               << 899       //
1089     if (phi > startPhi+deltaPhi+phiTolerant)  << 900       // Exact treatment
1090                                               << 901       //
1091     if (phi > startPhi+deltaPhi-phiTolerant)  << 902       G4ThreeVector qx = p + v;
1092     {                                         << 903       G4ThreeVector qa = qx - corners[2],
1093       //                                      << 904               qb = qx - corners[3];
1094       // Exact treatment                      << 905       G4ThreeVector qacb = qa.cross(qb);
1095       //                                      << 906       
1096       G4ThreeVector qx = p + v;               << 907       if (normSign*qacb.dot(v) < 0) return false;
1097       G4ThreeVector qa = qx - corners[2],     << 908     }
1098               qb = qx - corners[3];           << 909     else if (phi < phiTolerant) {
1099       G4ThreeVector qacb = qa.cross(qb);      << 910       G4ThreeVector qx = p + v;
1100                                               << 911       G4ThreeVector qa = qx - corners[1],
1101       if (normSign*qacb.dot(v) < 0) return fa << 912               qb = qx - corners[0];
1102     }                                         << 913       G4ThreeVector qacb = qa.cross(qb);
1103     else if (phi < phiTolerant)               << 914       
1104     {                                         << 915       if (normSign*qacb.dot(v) < 0) return false;
1105       G4ThreeVector qx = p + v;               << 916     }
1106       G4ThreeVector qa = qx - corners[1],     << 917   }
1107               qb = qx - corners[0];           << 918   
1108       G4ThreeVector qacb = qa.cross(qb);      << 919   //
1109                                               << 920   // We have a good hit! Calculate normal
1110       if (normSign*qacb.dot(v) < 0) return fa << 921   //
1111     }                                         << 922   if (rx < DBL_MIN) 
1112   }                                           << 923     normal = G4ThreeVector( 0, 0, zNorm < 0 ? -1 : 1 );
1113                                               << 924   else
1114   //                                          << 925     normal = G4ThreeVector( rNorm*hit.x()/rx, rNorm*hit.y()/rx, zNorm );
1115   // We have a good hit! Calculate normal     << 926   return true;
1116   //                                          << 
1117   if (rx < DBL_MIN)                           << 
1118     normal = G4ThreeVector( 0, 0, zNorm < 0 ? << 
1119   else                                        << 
1120     normal = G4ThreeVector( rNorm*hit.x()/rx, << 
1121   return true;                                << 
1122 }                                                927 }
1123                                                  928 
                                                   >> 929 
                                                   >> 930 //
1124 // FindLineIntersect                             931 // FindLineIntersect
1125 //                                               932 //
1126 // Decide the point at which two 2-dimensiona    933 // Decide the point at which two 2-dimensional lines intersect
1127 //                                               934 //
1128 // Equation of line: x = x1 + s*tx1              935 // Equation of line: x = x1 + s*tx1
1129 //                   y = y1 + s*ty1              936 //                   y = y1 + s*ty1
1130 //                                               937 //
1131 // It is assumed that the lines are *not* par    938 // It is assumed that the lines are *not* parallel
1132 //                                               939 //
1133 void G4PolyconeSide::FindLineIntersect( G4dou    940 void G4PolyconeSide::FindLineIntersect( G4double x1,  G4double y1,
1134                                         G4dou << 941           G4double tx1, G4double ty1,
1135                                         G4dou << 942                 G4double x2,  G4double y2,
1136                                         G4dou << 943           G4double tx2, G4double ty2,
1137                                         G4dou << 944           G4double &x,  G4double &y )
1138 {                                             << 945 {
1139   //                                          << 946   //
1140   // The solution is a simple linear equation << 947   // The solution is a simple linear equation
1141   //                                          << 948   //
1142   G4double deter = tx1*ty2 - tx2*ty1;         << 949   G4double deter = tx1*ty2 - tx2*ty1;
1143                                               << 950   
1144   G4double s1 = ((x2-x1)*ty2 - tx2*(y2-y1))/d << 951   G4double s1 = ((x2-x1)*ty2 - tx2*(y2-y1))/deter;
1145   G4double s2 = ((x2-x1)*ty1 - tx1*(y2-y1))/d << 952   G4double s2 = ((x2-x1)*ty1 - tx1*(y2-y1))/deter;
1146                                               << 953 
1147   //                                          << 954   //
1148   // We want the answer to not depend on whic << 955   // We want the answer to not depend on which order the
1149   // lines were specified. Take average.      << 956   // lines were specified. Take average.
1150   //                                          << 957   //
1151   x = 0.5*( x1+s1*tx1 + x2+s2*tx2 );          << 958   x = 0.5*( x1+s1*tx1 + x2+s2*tx2 );
1152   y = 0.5*( y1+s1*ty1 + y2+s2*ty2 );          << 959   y = 0.5*( y1+s1*ty1 + y2+s2*ty2 );
1153 }                                             << 
1154                                               << 
1155 // Calculate surface area for GetPointOnSurfa << 
1156 //                                            << 
1157 G4double G4PolyconeSide::SurfaceArea()        << 
1158 {                                             << 
1159   if(fSurfaceArea==0.)                        << 
1160   {                                           << 
1161     fSurfaceArea = (r[0]+r[1])* std::sqrt(sqr << 
1162     fSurfaceArea *= 0.5*(deltaPhi);           << 
1163   }                                           << 
1164   return fSurfaceArea;                        << 
1165 }                                             << 
1166                                               << 
1167 // GetPointOnFace                             << 
1168 //                                            << 
1169 G4ThreeVector G4PolyconeSide::GetPointOnFace( << 
1170 {                                             << 
1171   G4double x,y,zz;                            << 
1172   G4double rr,phi,dz,dr;                      << 
1173   dr=r[1]-r[0];dz=z[1]-z[0];                  << 
1174   phi=startPhi+deltaPhi*G4UniformRand();      << 
1175   rr=r[0]+dr*G4UniformRand();                 << 
1176                                               << 
1177   x=rr*std::cos(phi);                         << 
1178   y=rr*std::sin(phi);                         << 
1179                                               << 
1180   // PolyconeSide has a Ring Form             << 
1181   //                                          << 
1182   if (dz==0.)                                 << 
1183   {                                           << 
1184     zz=z[0];                                  << 
1185   }                                           << 
1186   else                                        << 
1187   {                                           << 
1188     if(dr==0.)  // PolyconeSide has a Tube Fo << 
1189     {                                         << 
1190       zz = z[0]+dz*G4UniformRand();           << 
1191     }                                         << 
1192     else                                      << 
1193     {                                         << 
1194       zz = z[0]+(rr-r[0])*dz/dr;              << 
1195     }                                         << 
1196   }                                           << 
1197                                               << 
1198   return {x,y,zz};                            << 
1199 }                                                960 }
1200                                                  961