Geant4 Cross Reference

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


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
                                                   >>  26 // $Id: G4EllipticalCone.cc 105454 2017-07-27 13:16:40Z gcosmo $
                                                   >>  27 //
 26 // Implementation of G4EllipticalCone class        28 // Implementation of G4EllipticalCone class
 27 //                                                 29 //
 28 // This code implements an Elliptical Cone giv     30 // This code implements an Elliptical Cone given explicitly by the
 29 // equation:                                       31 // equation:
 30 //   x^2/a^2 + y^2/b^2 = (z-h)^2                   32 //   x^2/a^2 + y^2/b^2 = (z-h)^2
 31 // and specified by the parameters (a,b,h) and     33 // and specified by the parameters (a,b,h) and a cut parallel to the
 32 // xy plane above z = 0.                           34 // xy plane above z = 0.
 33 //                                                 35 //
 34 // Author: Dionysios Anninos                       36 // Author: Dionysios Anninos
 35 // Revised: Evgueni Tcherniaev                     37 // Revised: Evgueni Tcherniaev
                                                   >>  38 //
 36 // -------------------------------------------     39 // --------------------------------------------------------------------
 37                                                    40 
 38 #if !(defined(G4GEOM_USE_UELLIPTICALCONE) && d << 
 39                                                << 
 40 #include "globals.hh"                              41 #include "globals.hh"
 41                                                    42 
 42 #include "G4EllipticalCone.hh"                     43 #include "G4EllipticalCone.hh"
 43                                                    44 
 44 #include "G4RandomTools.hh"                        45 #include "G4RandomTools.hh"
 45 #include "G4GeomTools.hh"                          46 #include "G4GeomTools.hh"
 46 #include "G4ClippablePolygon.hh"                   47 #include "G4ClippablePolygon.hh"
 47 #include "G4VoxelLimits.hh"                        48 #include "G4VoxelLimits.hh"
 48 #include "G4AffineTransform.hh"                    49 #include "G4AffineTransform.hh"
 49 #include "G4BoundingEnvelope.hh"                   50 #include "G4BoundingEnvelope.hh"
 50 #include "G4GeometryTolerance.hh"                  51 #include "G4GeometryTolerance.hh"
 51                                                    52 
 52 #include "meshdefs.hh"                             53 #include "meshdefs.hh"
 53                                                    54 
 54 #include "Randomize.hh"                            55 #include "Randomize.hh"
 55                                                    56 
 56 #include "G4VGraphicsScene.hh"                     57 #include "G4VGraphicsScene.hh"
 57 #include "G4VisExtent.hh"                          58 #include "G4VisExtent.hh"
 58                                                    59 
 59 #include "G4AutoLock.hh"                           60 #include "G4AutoLock.hh"
 60                                                    61 
 61 namespace                                          62 namespace
 62 {                                                  63 {
 63   G4Mutex polyhedronMutex = G4MUTEX_INITIALIZE     64   G4Mutex polyhedronMutex = G4MUTEX_INITIALIZER;
 64 }                                                  65 }
 65                                                    66 
 66 using namespace CLHEP;                             67 using namespace CLHEP;
 67                                                    68 
 68 //////////////////////////////////////////////     69 /////////////////////////////////////////////////////////////////////////
 69 //                                                 70 //
 70 // Constructor - check parameters                  71 // Constructor - check parameters
 71                                                    72 
 72 G4EllipticalCone::G4EllipticalCone(const G4Str     73 G4EllipticalCone::G4EllipticalCone(const G4String& pName,
 73                                          G4dou     74                                          G4double  pxSemiAxis,
 74                                          G4dou     75                                          G4double  pySemiAxis,
 75                                          G4dou     76                                          G4double  pzMax,
 76                                          G4dou     77                                          G4double  pzTopCut)
 77   : G4VSolid(pName), zTopCut(0.)               <<  78   : G4VSolid(pName), fRebuildPolyhedron(false), fpPolyhedron(0),
                                                   >>  79     fCubicVolume(0.), fSurfaceArea(0.), zTopCut(0.)
 78 {                                                  80 {
 79   halfCarTol = 0.5*kCarTolerance;                  81   halfCarTol = 0.5*kCarTolerance;
 80                                                    82 
 81   // Check Semi-Axis & Z-cut                       83   // Check Semi-Axis & Z-cut
 82   //                                               84   //
 83   if ( (pxSemiAxis <= 0.) || (pySemiAxis <= 0.     85   if ( (pxSemiAxis <= 0.) || (pySemiAxis <= 0.) || (pzMax <= 0.) )
 84   {                                                86   {
 85      std::ostringstream message;                   87      std::ostringstream message;
 86      message << "Invalid semi-axis or height f     88      message << "Invalid semi-axis or height for solid: " << GetName()
 87              << "\n   X semi-axis, Y semi-axis     89              << "\n   X semi-axis, Y semi-axis, height = "
 88              << pxSemiAxis << ", " << pySemiAx     90              << pxSemiAxis << ", " << pySemiAxis << ", " << pzMax;
 89      G4Exception("G4EllipticalCone::G4Elliptic     91      G4Exception("G4EllipticalCone::G4EllipticalCone()", "GeomSolids0002",
 90                  FatalErrorInArgument, message     92                  FatalErrorInArgument, message);
 91    }                                               93    }
 92                                                    94 
 93   if ( pzTopCut <= 0 )                             95   if ( pzTopCut <= 0 )
 94   {                                                96   {
 95      std::ostringstream message;                   97      std::ostringstream message;
 96      message << "Invalid z-coordinate for cutt     98      message << "Invalid z-coordinate for cutting plane for solid: " << GetName()
 97              << "\n   Z top cut = " << pzTopCu     99              << "\n   Z top cut = " << pzTopCut;
 98      G4Exception("G4EllipticalCone::G4Elliptic    100      G4Exception("G4EllipticalCone::G4EllipticalCone()", "GeomSolids0002",
 99                  FatalErrorInArgument, message    101                  FatalErrorInArgument, message);
100   }                                               102   }
101                                                   103 
102   SetSemiAxis( pxSemiAxis, pySemiAxis, pzMax )    104   SetSemiAxis( pxSemiAxis, pySemiAxis, pzMax );
103   SetZCut(pzTopCut);                              105   SetZCut(pzTopCut);
104 }                                                 106 }
105                                                   107 
106 //////////////////////////////////////////////    108 /////////////////////////////////////////////////////////////////////////
107 //                                                109 //
108 // Fake default constructor - sets only member    110 // Fake default constructor - sets only member data and allocates memory
109 //                            for usage restri    111 //                            for usage restricted to object persistency.
110                                                   112 
111 G4EllipticalCone::G4EllipticalCone( __void__&     113 G4EllipticalCone::G4EllipticalCone( __void__& a )
112   : G4VSolid(a), halfCarTol(0.),               << 114   : G4VSolid(a), fRebuildPolyhedron(false), fpPolyhedron(0),
                                                   >> 115     halfCarTol(0.), fCubicVolume(0.), fSurfaceArea(0.),
113     xSemiAxis(0.), ySemiAxis(0.), zheight(0.),    116     xSemiAxis(0.), ySemiAxis(0.), zheight(0.), zTopCut(0.),
114     cosAxisMin(0.), invXX(0.), invYY(0.)          117     cosAxisMin(0.), invXX(0.), invYY(0.)
115 {                                                 118 {
116 }                                                 119 }
117                                                   120 
118 //////////////////////////////////////////////    121 /////////////////////////////////////////////////////////////////////////
119 //                                                122 //
120 // Destructor                                     123 // Destructor
121                                                   124 
122 G4EllipticalCone::~G4EllipticalCone()             125 G4EllipticalCone::~G4EllipticalCone()
123 {                                                 126 {
124   delete fpPolyhedron; fpPolyhedron = nullptr; << 127   delete fpPolyhedron; fpPolyhedron = 0;
125 }                                                 128 }
126                                                   129 
127 //////////////////////////////////////////////    130 /////////////////////////////////////////////////////////////////////////
128 //                                                131 //
129 // Copy constructor                               132 // Copy constructor
130                                                   133 
131 G4EllipticalCone::G4EllipticalCone(const G4Ell    134 G4EllipticalCone::G4EllipticalCone(const G4EllipticalCone& rhs)
132   : G4VSolid(rhs), halfCarTol(rhs.halfCarTol), << 135   : G4VSolid(rhs), fRebuildPolyhedron(false), fpPolyhedron(0),
                                                   >> 136     halfCarTol(rhs.halfCarTol),
133     fCubicVolume(rhs.fCubicVolume), fSurfaceAr    137     fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
134     xSemiAxis(rhs.xSemiAxis), ySemiAxis(rhs.yS    138     xSemiAxis(rhs.xSemiAxis), ySemiAxis(rhs.ySemiAxis),
135     zheight(rhs.zheight), zTopCut(rhs.zTopCut)    139     zheight(rhs.zheight), zTopCut(rhs.zTopCut),
136     cosAxisMin(rhs.cosAxisMin), invXX(rhs.invX    140     cosAxisMin(rhs.cosAxisMin), invXX(rhs.invXX), invYY(rhs.invYY)
137 {                                                 141 {
138 }                                                 142 }
139                                                   143 
140 //////////////////////////////////////////////    144 /////////////////////////////////////////////////////////////////////////
141 //                                                145 //
142 // Assignment operator                            146 // Assignment operator
143                                                   147 
144 G4EllipticalCone& G4EllipticalCone::operator =    148 G4EllipticalCone& G4EllipticalCone::operator = (const G4EllipticalCone& rhs) 
145 {                                                 149 {
146    // Check assignment to self                    150    // Check assignment to self
147    //                                             151    //
148    if (this == &rhs)  { return *this; }           152    if (this == &rhs)  { return *this; }
149                                                   153 
150    // Copy base class data                        154    // Copy base class data
151    //                                             155    //
152    G4VSolid::operator=(rhs);                      156    G4VSolid::operator=(rhs);
153                                                   157 
154    // Copy data                                   158    // Copy data
155    //                                             159    //
156    halfCarTol = rhs.halfCarTol;                   160    halfCarTol = rhs.halfCarTol;
157    fCubicVolume = rhs.fCubicVolume; fSurfaceAr    161    fCubicVolume = rhs.fCubicVolume; fSurfaceArea = rhs.fSurfaceArea;
158    xSemiAxis = rhs.xSemiAxis; ySemiAxis = rhs.    162    xSemiAxis = rhs.xSemiAxis; ySemiAxis = rhs.ySemiAxis;
159    zheight = rhs.zheight; zTopCut = rhs.zTopCu    163    zheight = rhs.zheight; zTopCut = rhs.zTopCut;
160    cosAxisMin = rhs.cosAxisMin; invXX = rhs.in    164    cosAxisMin = rhs.cosAxisMin; invXX = rhs.invXX; invYY = rhs.invYY;
161                                                   165 
162    fRebuildPolyhedron = false;                    166    fRebuildPolyhedron = false;
163    delete fpPolyhedron; fpPolyhedron = nullptr << 167    delete fpPolyhedron; fpPolyhedron = 0;
164                                                   168 
165    return *this;                                  169    return *this;
166 }                                                 170 }
167                                                   171 
168 //////////////////////////////////////////////    172 /////////////////////////////////////////////////////////////////////////
169 //                                                173 //
170 // Get bounding box                               174 // Get bounding box
171                                                   175 
172 void G4EllipticalCone::BoundingLimits(G4ThreeV    176 void G4EllipticalCone::BoundingLimits(G4ThreeVector& pMin,
173                                       G4ThreeV    177                                       G4ThreeVector& pMax) const
174 {                                                 178 {
175   G4double zcut   = GetZTopCut();                 179   G4double zcut   = GetZTopCut();
176   G4double height = GetZMax();                    180   G4double height = GetZMax(); 
177   G4double xmax   = GetSemiAxisX()*(height+zcu    181   G4double xmax   = GetSemiAxisX()*(height+zcut);
178   G4double ymax   = GetSemiAxisY()*(height+zcu    182   G4double ymax   = GetSemiAxisY()*(height+zcut);
179   pMin.set(-xmax,-ymax,-zcut);                    183   pMin.set(-xmax,-ymax,-zcut);
180   pMax.set( xmax, ymax, zcut);                    184   pMax.set( xmax, ymax, zcut);
181                                                   185 
182   // Check correctness of the bounding box        186   // Check correctness of the bounding box
183   //                                              187   //
184   if (pMin.x() >= pMax.x() || pMin.y() >= pMax    188   if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
185   {                                               189   {
186     std::ostringstream message;                   190     std::ostringstream message;
187     message << "Bad bounding box (min >= max)     191     message << "Bad bounding box (min >= max) for solid: "
188             << GetName() << " !"                  192             << GetName() << " !"
189             << "\npMin = " << pMin                193             << "\npMin = " << pMin
190             << "\npMax = " << pMax;               194             << "\npMax = " << pMax;
191     G4Exception("G4EllipticalCone::BoundingLim    195     G4Exception("G4EllipticalCone::BoundingLimits()", "GeomMgt0001",
192                 JustWarning, message);            196                 JustWarning, message);
193     DumpInfo();                                   197     DumpInfo();
194   }                                               198   }
195 }                                                 199 }
196                                                   200 
197 //////////////////////////////////////////////    201 /////////////////////////////////////////////////////////////////////////
198 //                                                202 //
199 // Calculate extent under transform and specif    203 // Calculate extent under transform and specified limit
200                                                   204 
201 G4bool                                            205 G4bool
202 G4EllipticalCone::CalculateExtent(const EAxis     206 G4EllipticalCone::CalculateExtent(const EAxis pAxis,
203                                   const G4Voxe    207                                   const G4VoxelLimits& pVoxelLimit,
204                                   const G4Affi    208                                   const G4AffineTransform& pTransform,
205                                         G4doub    209                                         G4double& pMin, G4double& pMax) const
206 {                                                 210 {
207   G4ThreeVector bmin,bmax;                        211   G4ThreeVector bmin,bmax;
208   G4bool exist;                                   212   G4bool exist;
209                                                   213 
210   // Check bounding box (bbox)                    214   // Check bounding box (bbox)
211   //                                              215   //
212   BoundingLimits(bmin,bmax);                      216   BoundingLimits(bmin,bmax);
213   G4BoundingEnvelope bbox(bmin,bmax);             217   G4BoundingEnvelope bbox(bmin,bmax);
214 #ifdef G4BBOX_EXTENT                              218 #ifdef G4BBOX_EXTENT
215   return bbox.CalculateExtent(pAxis,pVoxelLimi << 219   if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
216 #endif                                            220 #endif
217   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox    221   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
218   {                                               222   {
219     return exist = pMin < pMax;                << 223     return exist = (pMin < pMax) ? true : false;
220   }                                               224   }
221                                                   225 
222   // Set bounding envelope (benv) and calculat    226   // Set bounding envelope (benv) and calculate extent
223   //                                              227   //
224   static const G4int NSTEPS = 48; // number of    228   static const G4int NSTEPS = 48; // number of steps for whole circle
225   static const G4double ang = twopi/NSTEPS;       229   static const G4double ang = twopi/NSTEPS;
226   static const G4double sinHalf = std::sin(0.5    230   static const G4double sinHalf = std::sin(0.5*ang);
227   static const G4double cosHalf = std::cos(0.5    231   static const G4double cosHalf = std::cos(0.5*ang);
228   static const G4double sinStep = 2.*sinHalf*c    232   static const G4double sinStep = 2.*sinHalf*cosHalf;
229   static const G4double cosStep = 1. - 2.*sinH    233   static const G4double cosStep = 1. - 2.*sinHalf*sinHalf;
230   G4double zcut   = bmax.z();                     234   G4double zcut   = bmax.z();
231   G4double height = GetZMax();                    235   G4double height = GetZMax(); 
232   G4double sxmin  = GetSemiAxisX()*(height-zcu    236   G4double sxmin  = GetSemiAxisX()*(height-zcut)/cosHalf;
233   G4double symin  = GetSemiAxisY()*(height-zcu    237   G4double symin  = GetSemiAxisY()*(height-zcut)/cosHalf;
234   G4double sxmax  = bmax.x()/cosHalf;             238   G4double sxmax  = bmax.x()/cosHalf;
235   G4double symax  = bmax.y()/cosHalf;             239   G4double symax  = bmax.y()/cosHalf;
236                                                   240 
237   G4double sinCur = sinHalf;                      241   G4double sinCur = sinHalf;
238   G4double cosCur = cosHalf;                      242   G4double cosCur = cosHalf;
239   G4ThreeVectorList baseA(NSTEPS),baseB(NSTEPS    243   G4ThreeVectorList baseA(NSTEPS),baseB(NSTEPS);
240   for (G4int k=0; k<NSTEPS; ++k)                  244   for (G4int k=0; k<NSTEPS; ++k)
241   {                                               245   {
242     baseA[k].set(sxmax*cosCur,symax*sinCur,-zc    246     baseA[k].set(sxmax*cosCur,symax*sinCur,-zcut);
243     baseB[k].set(sxmin*cosCur,symin*sinCur, zc    247     baseB[k].set(sxmin*cosCur,symin*sinCur, zcut);
244                                                   248     
245     G4double sinTmp = sinCur;                     249     G4double sinTmp = sinCur;
246     sinCur = sinCur*cosStep + cosCur*sinStep;     250     sinCur = sinCur*cosStep + cosCur*sinStep;
247     cosCur = cosCur*cosStep - sinTmp*sinStep;     251     cosCur = cosCur*cosStep - sinTmp*sinStep;
248   }                                               252   }
249                                                   253 
250   std::vector<const G4ThreeVectorList *> polyg    254   std::vector<const G4ThreeVectorList *> polygons(2);
251   polygons[0] = &baseA;                           255   polygons[0] = &baseA;
252   polygons[1] = &baseB;                           256   polygons[1] = &baseB;
253   G4BoundingEnvelope benv(bmin,bmax,polygons);    257   G4BoundingEnvelope benv(bmin,bmax,polygons);
254   exist = benv.CalculateExtent(pAxis,pVoxelLim    258   exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
255   return exist;                                   259   return exist;
256 }                                                 260 }
257                                                   261 
258 //////////////////////////////////////////////    262 /////////////////////////////////////////////////////////////////////////
259 //                                                263 //
260 // Determine where is point: inside, outside o    264 // Determine where is point: inside, outside or on surface
261                                                   265 
262 EInside G4EllipticalCone::Inside(const G4Three    266 EInside G4EllipticalCone::Inside(const G4ThreeVector& p) const
263 {                                                 267 {
264   G4double hp = std::sqrt(p.x()*p.x()*invXX +     268   G4double hp = std::sqrt(p.x()*p.x()*invXX + p.y()*p.y()*invYY) + p.z();
265   G4double ds = (hp - zheight)*cosAxisMin;        269   G4double ds = (hp - zheight)*cosAxisMin;
266   G4double dz = std::abs(p.z()) - zTopCut;        270   G4double dz = std::abs(p.z()) - zTopCut;
267   G4double dist = std::max(ds,dz);                271   G4double dist = std::max(ds,dz);
268                                                   272 
269   if (dist > halfCarTol) return kOutside;         273   if (dist > halfCarTol) return kOutside;
270   return (dist > -halfCarTol) ? kSurface : kIn    274   return (dist > -halfCarTol) ? kSurface : kInside;
271 }                                                 275 }
272                                                   276 
273 //////////////////////////////////////////////    277 /////////////////////////////////////////////////////////////////////////
274 //                                                278 //
275 // Return unit normal at surface closest to p     279 // Return unit normal at surface closest to p
276                                                   280 
277 G4ThreeVector G4EllipticalCone::SurfaceNormal(    281 G4ThreeVector G4EllipticalCone::SurfaceNormal( const G4ThreeVector& p) const
278 {                                                 282 {
279   G4ThreeVector norm(0,0,0);                      283   G4ThreeVector norm(0,0,0);
280   G4int nsurf = 0;  // number of surfaces wher    284   G4int nsurf = 0;  // number of surfaces where p is placed
281                                                   285 
282   G4double hp = std::sqrt(p.x()*p.x()*invXX +     286   G4double hp = std::sqrt(p.x()*p.x()*invXX + p.y()*p.y()*invYY) + p.z();
283   G4double ds = (hp - zheight)*cosAxisMin;        287   G4double ds = (hp - zheight)*cosAxisMin;
284   if (std::abs(ds) <= halfCarTol)                 288   if (std::abs(ds) <= halfCarTol)
285   {                                               289   {
286     norm = G4ThreeVector(p.x()*invXX, p.y()*in    290     norm = G4ThreeVector(p.x()*invXX, p.y()*invYY, hp - p.z());
287     G4double mag = norm.mag();                    291     G4double mag = norm.mag();
288     if (mag == 0) return {0,0,1}; // apex      << 292     if (mag == 0) return G4ThreeVector(0,0,1); // apex
289     norm *= (1/mag);                              293     norm *= (1/mag);
290     ++nsurf;                                      294     ++nsurf;
291   }                                               295   }
292   G4double dz = std::abs(p.z()) - zTopCut;        296   G4double dz = std::abs(p.z()) - zTopCut;
293   if (std::abs(dz) <= halfCarTol)                 297   if (std::abs(dz) <= halfCarTol)
294   {                                               298   {
295     norm += G4ThreeVector(0., 0.,(p.z() < 0) ?    299     norm += G4ThreeVector(0., 0.,(p.z() < 0) ? -1. : 1.);
296     ++nsurf;                                      300     ++nsurf;
297   }                                               301   }
298                                                   302 
299   if      (nsurf == 1) return norm;               303   if      (nsurf == 1) return norm;
300   else if (nsurf >  1) return norm.unit(); //     304   else if (nsurf >  1) return norm.unit(); // elliptic edge
301   else                                            305   else
302   {                                               306   {
303     // Point is not on the surface                307     // Point is not on the surface
304     //                                            308     //
305 #ifdef G4CSGDEBUG                                 309 #ifdef G4CSGDEBUG
306     std::ostringstream message;                   310     std::ostringstream message;
307     G4long oldprc = message.precision(16);     << 311     G4int oldprc = message.precision(16);
308     message << "Point p is not on surface (!?)    312     message << "Point p is not on surface (!?) of solid: "
309             << GetName() << G4endl;               313             << GetName() << G4endl;
310     message << "Position:\n";                     314     message << "Position:\n";
311     message << "   p.x() = " << p.x()/mm << "     315     message << "   p.x() = " << p.x()/mm << " mm\n";
312     message << "   p.y() = " << p.y()/mm << "     316     message << "   p.y() = " << p.y()/mm << " mm\n";
313     message << "   p.z() = " << p.z()/mm << "     317     message << "   p.z() = " << p.z()/mm << " mm";
314     G4cout.precision(oldprc);                     318     G4cout.precision(oldprc);
315     G4Exception("G4EllipticalCone::SurfaceNorm    319     G4Exception("G4EllipticalCone::SurfaceNormal(p)", "GeomSolids1002",
316                 JustWarning, message );           320                 JustWarning, message );
317     DumpInfo();                                   321     DumpInfo();
318 #endif                                            322 #endif
319     return ApproxSurfaceNormal(p);                323     return ApproxSurfaceNormal(p);
320   }                                               324   }
321 }                                                 325 }
322                                                   326 
323 //////////////////////////////////////////////    327 /////////////////////////////////////////////////////////////////////////
324 //                                                328 //
325 // Find surface nearest to point and return co    329 // Find surface nearest to point and return corresponding normal.
326 // The algorithm is similar to the algorithm u    330 // The algorithm is similar to the algorithm used in Inside().
327 // This method normally should not be called.     331 // This method normally should not be called.
328                                                   332 
329 G4ThreeVector                                     333 G4ThreeVector
330 G4EllipticalCone::ApproxSurfaceNormal(const G4    334 G4EllipticalCone::ApproxSurfaceNormal(const G4ThreeVector& p) const
331 {                                                 335 {
332   G4double hp = std::sqrt(p.x()*p.x()*invXX +     336   G4double hp = std::sqrt(p.x()*p.x()*invXX + p.y()*p.y()*invYY) + p.z();
333   G4double ds = (hp - zheight)*cosAxisMin;        337   G4double ds = (hp - zheight)*cosAxisMin;
334   G4double dz = std::abs(p.z()) - zTopCut;        338   G4double dz = std::abs(p.z()) - zTopCut;
335   if (ds > dz && std::abs(hp - p.z()) > halfCa    339   if (ds > dz && std::abs(hp - p.z()) > halfCarTol)
336     return G4ThreeVector(p.x()*invXX, p.y()*in    340     return G4ThreeVector(p.x()*invXX, p.y()*invYY, hp - p.z()).unit();
337   else                                            341   else
338     return { 0., 0., (G4double)((p.z() < 0) ?  << 342     return G4ThreeVector(0., 0.,(p.z() < 0) ? -1. : 1.);
339 }                                                 343 }
340                                                   344 
341 //////////////////////////////////////////////    345 ////////////////////////////////////////////////////////////////////////
342 //                                                346 //
343 // Calculate distance to shape from outside, a    347 // Calculate distance to shape from outside, along normalised vector
344 // return kInfinity if no intersection, or int    348 // return kInfinity if no intersection, or intersection distance <= tolerance
345                                                   349 
346 G4double G4EllipticalCone::DistanceToIn( const    350 G4double G4EllipticalCone::DistanceToIn( const G4ThreeVector& p,
347                                          const    351                                          const G4ThreeVector& v  ) const
348 {                                                 352 {
349   G4double distMin = kInfinity;                   353   G4double distMin = kInfinity;
350                                                   354 
351   // code from EllipticalTube                     355   // code from EllipticalTube
352                                                   356 
353   G4double sigz = p.z()+zTopCut;                  357   G4double sigz = p.z()+zTopCut;
354                                                   358 
355   //                                              359   //
356   // Check z = -dz planer surface                 360   // Check z = -dz planer surface
357   //                                              361   //
358                                                   362 
359   if (sigz < halfCarTol)                          363   if (sigz < halfCarTol)
360   {                                               364   {
361     //                                            365     //
362     // We are "behind" the shape in z, and so     366     // We are "behind" the shape in z, and so can
363     // potentially hit the rear face. Correct     367     // potentially hit the rear face. Correct direction?
364     //                                            368     //
365     if (v.z() <= 0)                               369     if (v.z() <= 0)
366     {                                             370     {
367       //                                          371       //
368       // As long as we are far enough away, we    372       // As long as we are far enough away, we know we
369       // can't intersect                          373       // can't intersect
370       //                                          374       //
371       if (sigz < 0) return kInfinity;             375       if (sigz < 0) return kInfinity;
372                                                   376       
373       //                                          377       //
374       // Otherwise, we don't intersect unless     378       // Otherwise, we don't intersect unless we are
375       // on the surface of the ellipse            379       // on the surface of the ellipse
376       //                                          380       //
377                                                   381 
378       if ( sqr(p.x()/( xSemiAxis - halfCarTol     382       if ( sqr(p.x()/( xSemiAxis - halfCarTol ))
379          + sqr(p.y()/( ySemiAxis - halfCarTol     383          + sqr(p.y()/( ySemiAxis - halfCarTol )) <= sqr( zheight + zTopCut ) )
380         return kInfinity;                         384         return kInfinity;
381                                                   385 
382     }                                             386     }
383     else                                          387     else
384     {                                             388     {
385       //                                          389       //
386       // How far?                                 390       // How far?
387       //                                          391       //
388       G4double q = -sigz/v.z();                   392       G4double q = -sigz/v.z();
389                                                   393       
390       //                                          394       //
391       // Where does that place us?                395       // Where does that place us?
392       //                                          396       //
393       G4double xi = p.x() + q*v.x(),              397       G4double xi = p.x() + q*v.x(),
394                yi = p.y() + q*v.y();              398                yi = p.y() + q*v.y();
395                                                   399       
396       //                                          400       //
397       // Is this on the surface (within ellips    401       // Is this on the surface (within ellipse)?
398       //                                          402       //
399       if ( sqr(xi/xSemiAxis) + sqr(yi/ySemiAxi    403       if ( sqr(xi/xSemiAxis) + sqr(yi/ySemiAxis) <= sqr( zheight + zTopCut ) )
400       {                                           404       {
401         //                                        405         //
402         // Yup. Return q, unless we are on the    406         // Yup. Return q, unless we are on the surface
403         //                                        407         //
404         return (sigz < -halfCarTol) ? q : 0;      408         return (sigz < -halfCarTol) ? q : 0;
405       }                                           409       }
406       else if (xi/(xSemiAxis*xSemiAxis)*v.x()     410       else if (xi/(xSemiAxis*xSemiAxis)*v.x()
407              + yi/(ySemiAxis*ySemiAxis)*v.y()     411              + yi/(ySemiAxis*ySemiAxis)*v.y() >= 0)
408       {                                           412       {
409         //                                        413         //
410         // Else, if we are traveling outwards,    414         // Else, if we are traveling outwards, we know
411         // we must miss                           415         // we must miss
412         //                                        416         //
413         //        return kInfinity;               417         //        return kInfinity;
414       }                                           418       }
415     }                                             419     }
416   }                                               420   }
417                                                   421 
418   //                                              422   //
419   // Check z = +dz planer surface                 423   // Check z = +dz planer surface
420   //                                              424   //
421   sigz = p.z() - zTopCut;                         425   sigz = p.z() - zTopCut;
422                                                   426   
423   if (sigz > -halfCarTol)                         427   if (sigz > -halfCarTol)
424   {                                               428   {
425     if (v.z() >= 0)                               429     if (v.z() >= 0)
426     {                                             430     {
427                                                   431 
428       if (sigz > 0) return kInfinity;             432       if (sigz > 0) return kInfinity;
429                                                   433 
430       if ( sqr(p.x()/( xSemiAxis - halfCarTol     434       if ( sqr(p.x()/( xSemiAxis - halfCarTol ))
431          + sqr(p.y()/( ySemiAxis - halfCarTol     435          + sqr(p.y()/( ySemiAxis - halfCarTol )) <= sqr( zheight-zTopCut ) )
432         return kInfinity;                         436         return kInfinity;
433                                                   437 
434     }                                             438     }
435     else {                                        439     else {
436       G4double q = -sigz/v.z();                   440       G4double q = -sigz/v.z();
437                                                   441 
438       G4double xi = p.x() + q*v.x(),              442       G4double xi = p.x() + q*v.x(),
439                yi = p.y() + q*v.y();              443                yi = p.y() + q*v.y();
440                                                   444 
441       if ( sqr(xi/xSemiAxis) + sqr(yi/ySemiAxi    445       if ( sqr(xi/xSemiAxis) + sqr(yi/ySemiAxis) <= sqr( zheight - zTopCut ) )
442       {                                           446       {
443         return (sigz > -halfCarTol) ? q : 0;      447         return (sigz > -halfCarTol) ? q : 0;
444       }                                           448       }
445       else if (xi/(xSemiAxis*xSemiAxis)*v.x()     449       else if (xi/(xSemiAxis*xSemiAxis)*v.x()
446              + yi/(ySemiAxis*ySemiAxis)*v.y()     450              + yi/(ySemiAxis*ySemiAxis)*v.y() >= 0)
447       {                                           451       {
448         //        return kInfinity;               452         //        return kInfinity;
449       }                                           453       }
450     }                                             454     }
451   }                                               455   }
452                                                   456 
453                                                   457 
454 #if 0                                             458 #if 0
455                                                   459 
456   // check to see if Z plane is relevant          460   // check to see if Z plane is relevant
457   //                                              461   //
458   if (p.z() < -zTopCut - halfCarTol)              462   if (p.z() < -zTopCut - halfCarTol)
459   {                                               463   {
460     if (v.z() <= 0.0)                             464     if (v.z() <= 0.0)
461       return distMin;                             465       return distMin; 
462                                                   466 
463     G4double lambda = (-zTopCut - p.z())/v.z()    467     G4double lambda = (-zTopCut - p.z())/v.z();
464                                                   468     
465     if ( sqr((lambda*v.x()+p.x())/xSemiAxis) +    469     if ( sqr((lambda*v.x()+p.x())/xSemiAxis) + 
466          sqr((lambda*v.y()+p.y())/ySemiAxis) <    470          sqr((lambda*v.y()+p.y())/ySemiAxis) <=
467          sqr(zTopCut + zheight + halfCarTol) )    471          sqr(zTopCut + zheight + halfCarTol) ) 
468     {                                             472     { 
469       return distMin = std::fabs(lambda);         473       return distMin = std::fabs(lambda);    
470     }                                             474     }
471   }                                               475   }
472                                                   476 
473   if (p.z() > zTopCut + halfCarTol)               477   if (p.z() > zTopCut + halfCarTol) 
474   {                                               478   {
475     if (v.z() >= 0.0)                             479     if (v.z() >= 0.0)
476       { return distMin; }                         480       { return distMin; }
477                                                   481 
478     G4double lambda  = (zTopCut - p.z()) / v.z    482     G4double lambda  = (zTopCut - p.z()) / v.z();
479                                                   483 
480     if ( sqr((lambda*v.x() + p.x())/xSemiAxis)    484     if ( sqr((lambda*v.x() + p.x())/xSemiAxis) + 
481          sqr((lambda*v.y() + p.y())/ySemiAxis)    485          sqr((lambda*v.y() + p.y())/ySemiAxis) <=
482          sqr(zheight - zTopCut + halfCarTol) )    486          sqr(zheight - zTopCut + halfCarTol) )
483       {                                           487       {
484         return distMin = std::fabs(lambda);       488         return distMin = std::fabs(lambda);
485       }                                           489       }
486   }                                               490   }
487                                                   491   
488   if (p.z() > zTopCut - halfCarTol                492   if (p.z() > zTopCut - halfCarTol
489    && p.z() < zTopCut + halfCarTol )              493    && p.z() < zTopCut + halfCarTol )
490   {                                               494   {
491     if (v.z() > 0.)                               495     if (v.z() > 0.) 
492       { return kInfinity; }                       496       { return kInfinity; }
493                                                   497 
494     return distMin = 0.;                          498     return distMin = 0.;
495   }                                               499   }
496                                                   500   
497   if (p.z() < -zTopCut + halfCarTol               501   if (p.z() < -zTopCut + halfCarTol
498    && p.z() > -zTopCut - halfCarTol)              502    && p.z() > -zTopCut - halfCarTol)
499   {                                               503   {
500     if (v.z() < 0.)                               504     if (v.z() < 0.)
501       { return distMin = kInfinity; }             505       { return distMin = kInfinity; }
502                                                   506     
503     return distMin = 0.;                          507     return distMin = 0.;
504   }                                               508   }
505                                                   509   
506 #endif                                            510 #endif
507                                                   511 
508   // if we are here then it either intersects     512   // if we are here then it either intersects or grazes the curved surface 
509   // or it does not intersect at all              513   // or it does not intersect at all
510   //                                              514   //
511   G4double A = sqr(v.x()/xSemiAxis) + sqr(v.y(    515   G4double A = sqr(v.x()/xSemiAxis) + sqr(v.y()/ySemiAxis) - sqr(v.z());
512   G4double B = 2*(v.x()*p.x()/sqr(xSemiAxis) +    516   G4double B = 2*(v.x()*p.x()/sqr(xSemiAxis) + 
513                   v.y()*p.y()/sqr(ySemiAxis) +    517                   v.y()*p.y()/sqr(ySemiAxis) + v.z()*(zheight-p.z()));
514   G4double C = sqr(p.x()/xSemiAxis) + sqr(p.y(    518   G4double C = sqr(p.x()/xSemiAxis) + sqr(p.y()/ySemiAxis) - 
515                sqr(zheight - p.z());              519                sqr(zheight - p.z());
516                                                   520  
517   G4double discr = B*B - 4.*A*C;                  521   G4double discr = B*B - 4.*A*C;
518                                                   522    
519   // if the discriminant is negative it never     523   // if the discriminant is negative it never hits the curved object
520   //                                              524   //
521   if ( discr < -halfCarTol )                      525   if ( discr < -halfCarTol )
522     { return distMin; }                           526     { return distMin; }
523                                                   527   
524   // case below is when it hits or grazes the     528   // case below is when it hits or grazes the surface
525   //                                              529   //
526   if ( (discr >= -halfCarTol ) && (discr < hal    530   if ( (discr >= -halfCarTol ) && (discr < halfCarTol ) )
527   {                                               531   {
528     return distMin = std::fabs(-B/(2.*A));        532     return distMin = std::fabs(-B/(2.*A)); 
529   }                                               533   }
530                                                   534   
531   G4double plus  = (-B+std::sqrt(discr))/(2.*A    535   G4double plus  = (-B+std::sqrt(discr))/(2.*A);
532   G4double minus = (-B-std::sqrt(discr))/(2.*A    536   G4double minus = (-B-std::sqrt(discr))/(2.*A);
533                                                   537  
534   // Special case::Point on Surface, Check nor    538   // Special case::Point on Surface, Check norm.dot(v)
535                                                   539 
536   if ( ( std::fabs(plus) < halfCarTol )||( std    540   if ( ( std::fabs(plus) < halfCarTol )||( std::fabs(minus) < halfCarTol ) )
537   {                                               541   {
538     G4ThreeVector truenorm(p.x()/(xSemiAxis*xS    542     G4ThreeVector truenorm(p.x()/(xSemiAxis*xSemiAxis),
539                            p.y()/(ySemiAxis*yS    543                            p.y()/(ySemiAxis*ySemiAxis),
540                            -( p.z() - zheight     544                            -( p.z() - zheight ));
541     if ( truenorm*v >= 0)  //  going outside t    545     if ( truenorm*v >= 0)  //  going outside the solid from surface
542     {                                             546     {
543       return kInfinity;                           547       return kInfinity;
544     }                                             548     }
545     else                                          549     else
546     {                                             550     {
547       return 0;                                   551       return 0;
548     }                                             552     }
549   }                                               553   }
550                                                   554 
551   // G4double lambda = std::fabs(plus) < std::    555   // G4double lambda = std::fabs(plus) < std::fabs(minus) ? plus : minus;  
552   G4double lambda = 0;                            556   G4double lambda = 0;
553                                                   557 
554   if ( minus > halfCarTol && minus < distMin )    558   if ( minus > halfCarTol && minus < distMin ) 
555   {                                               559   {
556     lambda = minus ;                              560     lambda = minus ;
557     // check normal vector   n * v < 0            561     // check normal vector   n * v < 0
558     G4ThreeVector pin = p + lambda*v;             562     G4ThreeVector pin = p + lambda*v;
559     if(std::fabs(pin.z())< zTopCut + halfCarTo    563     if(std::fabs(pin.z())< zTopCut + halfCarTol)
560     {                                             564     {
561       G4ThreeVector truenorm(pin.x()/(xSemiAxi    565       G4ThreeVector truenorm(pin.x()/(xSemiAxis*xSemiAxis),
562                              pin.y()/(ySemiAxi    566                              pin.y()/(ySemiAxis*ySemiAxis),
563                              - ( pin.z() - zhe    567                              - ( pin.z() - zheight ));
564       if ( truenorm*v < 0)                        568       if ( truenorm*v < 0)
565       {   // yes, going inside the solid          569       {   // yes, going inside the solid
566         distMin = lambda;                         570         distMin = lambda;
567       }                                           571       }
568     }                                             572     }
569   }                                               573   }
570   if ( plus > halfCarTol  && plus < distMin )     574   if ( plus > halfCarTol  && plus < distMin )
571   {                                               575   {
572     lambda = plus ;                               576     lambda = plus ;
573     // check normal vector   n * v < 0            577     // check normal vector   n * v < 0
574     G4ThreeVector pin = p + lambda*v;             578     G4ThreeVector pin = p + lambda*v;
575     if(std::fabs(pin.z()) < zTopCut + halfCarT    579     if(std::fabs(pin.z()) < zTopCut + halfCarTol)
576     {                                             580     {
577       G4ThreeVector truenorm(pin.x()/(xSemiAxi    581       G4ThreeVector truenorm(pin.x()/(xSemiAxis*xSemiAxis),
578                              pin.y()/(ySemiAxi    582                              pin.y()/(ySemiAxis*ySemiAxis),
579                              - ( pin.z() - zhe    583                              - ( pin.z() - zheight ) );
580       if ( truenorm*v < 0)                        584       if ( truenorm*v < 0)
581       {   // yes, going inside the solid          585       {   // yes, going inside the solid
582         distMin = lambda;                         586         distMin = lambda;
583       }                                           587       }
584     }                                             588     }
585   }                                               589   }
586   if (distMin < halfCarTol) distMin=0.;           590   if (distMin < halfCarTol) distMin=0.;
587   return distMin ;                                591   return distMin ;
588 }                                                 592 }
589                                                   593 
590 //////////////////////////////////////////////    594 /////////////////////////////////////////////////////////////////////////
591 //                                                595 //
592 // Calculate distance (<= actual) to closest s    596 // Calculate distance (<= actual) to closest surface of shape from outside
593 // Return 0 if point inside                       597 // Return 0 if point inside
594                                                   598 
595 G4double G4EllipticalCone::DistanceToIn(const     599 G4double G4EllipticalCone::DistanceToIn(const G4ThreeVector& p) const
596 {                                                 600 {
597   G4double hp = std::sqrt(p.x()*p.x()*invXX +     601   G4double hp = std::sqrt(p.x()*p.x()*invXX + p.y()*p.y()*invYY) + p.z();
598   G4double ds = (hp - zheight)*cosAxisMin;        602   G4double ds = (hp - zheight)*cosAxisMin;
599   G4double dz = std::abs(p.z()) - zTopCut;        603   G4double dz = std::abs(p.z()) - zTopCut;
600   G4double dist = std::max(ds,dz);                604   G4double dist = std::max(ds,dz);
601   return (dist > 0) ? dist : 0.;                  605   return (dist > 0) ? dist : 0.;
602 }                                                 606 }
603                                                   607 
604 //////////////////////////////////////////////    608 ////////////////////////////////////////////////////////////////////////
605 //                                                609 //
606 // Calculate distance to surface of shape from    610 // Calculate distance to surface of shape from `inside',
607 // allowing for tolerance                         611 // allowing for tolerance
608                                                   612 
609 G4double G4EllipticalCone::DistanceToOut(const    613 G4double G4EllipticalCone::DistanceToOut(const G4ThreeVector& p,
610                                          const    614                                          const G4ThreeVector& v,
611                                          const    615                                          const G4bool calcNorm,
612                                                << 616                                                G4bool *validNorm,
613                                                << 617                                                G4ThreeVector *n  ) const
614 {                                                 618 {
615   G4double distMin, lambda;                       619   G4double distMin, lambda;
616   enum surface_e {kPlaneSurf, kCurvedSurf, kNo    620   enum surface_e {kPlaneSurf, kCurvedSurf, kNoSurf} surface;
617                                                   621   
618   distMin = kInfinity;                            622   distMin = kInfinity;
619   surface = kNoSurf;                              623   surface = kNoSurf;
620                                                   624 
621   if (v.z() < 0.0)                                625   if (v.z() < 0.0)
622   {                                               626   {
623     lambda = (-p.z() - zTopCut)/v.z();            627     lambda = (-p.z() - zTopCut)/v.z();
624                                                   628 
625     if ( (sqr((p.x() + lambda*v.x())/xSemiAxis    629     if ( (sqr((p.x() + lambda*v.x())/xSemiAxis) + 
626           sqr((p.y() + lambda*v.y())/ySemiAxis    630           sqr((p.y() + lambda*v.y())/ySemiAxis)) < 
627           sqr(zheight + zTopCut + halfCarTol)     631           sqr(zheight + zTopCut + halfCarTol) )
628     {                                             632     {
629       distMin = std::fabs(lambda);                633       distMin = std::fabs(lambda);
630                                                   634 
631       if (!calcNorm) { return distMin; }          635       if (!calcNorm) { return distMin; }
632     }                                             636     } 
633     distMin = std::fabs(lambda);                  637     distMin = std::fabs(lambda);
634     surface = kPlaneSurf;                         638     surface = kPlaneSurf;
635   }                                               639   }
636                                                   640 
637   if (v.z() > 0.0)                                641   if (v.z() > 0.0)
638   {                                               642   {
639     lambda = (zTopCut - p.z()) / v.z();           643     lambda = (zTopCut - p.z()) / v.z();
640                                                   644 
641     if ( (sqr((p.x() + lambda*v.x())/xSemiAxis    645     if ( (sqr((p.x() + lambda*v.x())/xSemiAxis)
642         + sqr((p.y() + lambda*v.y())/ySemiAxis    646         + sqr((p.y() + lambda*v.y())/ySemiAxis) )
643        < (sqr(zheight - zTopCut + halfCarTol))    647        < (sqr(zheight - zTopCut + halfCarTol)) )
644     {                                             648     {
645       distMin = std::fabs(lambda);                649       distMin = std::fabs(lambda);
646       if (!calcNorm) { return distMin; }          650       if (!calcNorm) { return distMin; }
647     }                                             651     }
648     distMin = std::fabs(lambda);                  652     distMin = std::fabs(lambda);
649     surface = kPlaneSurf;                         653     surface = kPlaneSurf;
650   }                                               654   }
651                                                   655   
652   // if we are here then it either intersects     656   // if we are here then it either intersects or grazes the 
653   // curved surface...                            657   // curved surface...
654   //                                              658   //
655   G4double A = sqr(v.x()/xSemiAxis) + sqr(v.y(    659   G4double A = sqr(v.x()/xSemiAxis) + sqr(v.y()/ySemiAxis) - sqr(v.z());
656   G4double B = 2.*(v.x()*p.x()/sqr(xSemiAxis)     660   G4double B = 2.*(v.x()*p.x()/sqr(xSemiAxis) +  
657                    v.y()*p.y()/sqr(ySemiAxis)     661                    v.y()*p.y()/sqr(ySemiAxis) + v.z()*(zheight-p.z()));
658   G4double C = sqr(p.x()/xSemiAxis) + sqr(p.y(    662   G4double C = sqr(p.x()/xSemiAxis) + sqr(p.y()/ySemiAxis)
659              - sqr(zheight - p.z());              663              - sqr(zheight - p.z());
660                                                   664  
661   G4double discr = B*B - 4.*A*C;                  665   G4double discr = B*B - 4.*A*C;
662                                                   666   
663   if ( discr >= - halfCarTol && discr < halfCa    667   if ( discr >= - halfCarTol && discr < halfCarTol )
664   {                                               668   { 
665     if(!calcNorm) { return distMin = std::fabs    669     if(!calcNorm) { return distMin = std::fabs(-B/(2.*A)); }
666   }                                               670   }
667                                                   671 
668   else if ( discr > halfCarTol )                  672   else if ( discr > halfCarTol )
669   {                                               673   {
670     G4double plus  = (-B+std::sqrt(discr))/(2.    674     G4double plus  = (-B+std::sqrt(discr))/(2.*A);
671     G4double minus = (-B-std::sqrt(discr))/(2.    675     G4double minus = (-B-std::sqrt(discr))/(2.*A);
672                                                   676 
673     if ( plus > halfCarTol && minus > halfCarT    677     if ( plus > halfCarTol && minus > halfCarTol )
674     {                                             678     {
675       // take the shorter distance                679       // take the shorter distance
676       //                                          680       //
677       lambda   = std::fabs(plus) < std::fabs(m    681       lambda   = std::fabs(plus) < std::fabs(minus) ? plus : minus;
678     }                                             682     }
679     else                                          683     else
680     {                                             684     {
681       // at least one solution is close to zer    685       // at least one solution is close to zero or negative
682       // so, take small positive solution or z    686       // so, take small positive solution or zero 
683       //                                          687       //
684       lambda   = plus > -halfCarTol ? plus : 0    688       lambda   = plus > -halfCarTol ? plus : 0;
685     }                                             689     }
686                                                   690 
687     if ( std::fabs(lambda) < distMin )            691     if ( std::fabs(lambda) < distMin )
688     {                                             692     {
689       if( std::fabs(lambda) > halfCarTol)         693       if( std::fabs(lambda) > halfCarTol)
690       {                                           694       {
691         distMin  = std::fabs(lambda);             695         distMin  = std::fabs(lambda);
692         surface  = kCurvedSurf;                   696         surface  = kCurvedSurf;
693       }                                           697       }
694       else  // Point is On the Surface, Check     698       else  // Point is On the Surface, Check Normal
695       {                                           699       {
696         G4ThreeVector truenorm(p.x()/(xSemiAxi    700         G4ThreeVector truenorm(p.x()/(xSemiAxis*xSemiAxis),
697                                p.y()/(ySemiAxi    701                                p.y()/(ySemiAxis*ySemiAxis),
698                                -( p.z() - zhei    702                                -( p.z() - zheight ));
699         if( truenorm.dot(v) > 0 )                 703         if( truenorm.dot(v) > 0 )
700         {                                         704         {
701           distMin  = 0.0;                         705           distMin  = 0.0;
702           surface  = kCurvedSurf;                 706           surface  = kCurvedSurf;
703         }                                         707         }
704       }                                           708       } 
705     }                                             709     }
706   }                                               710   }
707                                                   711 
708   // set normal if requested                      712   // set normal if requested
709   //                                              713   //
710   if (calcNorm)                                   714   if (calcNorm)
711   {                                               715   {
712     if (surface == kNoSurf)                       716     if (surface == kNoSurf)
713     {                                             717     {
714       *validNorm = false;                         718       *validNorm = false;
715     }                                             719     }
716     else                                          720     else
717     {                                             721     {
718       *validNorm = true;                          722       *validNorm = true;
719       switch (surface)                            723       switch (surface)
720       {                                           724       {
721         case kPlaneSurf:                          725         case kPlaneSurf:
722         {                                         726         {
723           *n = G4ThreeVector(0.,0.,(v.z() > 0.    727           *n = G4ThreeVector(0.,0.,(v.z() > 0.0 ? 1. : -1.));
724         }                                         728         }
725         break;                                    729         break;
726                                                   730 
727         case kCurvedSurf:                         731         case kCurvedSurf:
728         {                                         732         {
729           G4ThreeVector pexit = p + distMin*v;    733           G4ThreeVector pexit = p + distMin*v;
730           G4ThreeVector truenorm( pexit.x()/(x    734           G4ThreeVector truenorm( pexit.x()/(xSemiAxis*xSemiAxis),
731                                   pexit.y()/(y    735                                   pexit.y()/(ySemiAxis*ySemiAxis),
732                                   -( pexit.z()    736                                   -( pexit.z() - zheight ) );
733           truenorm /= truenorm.mag();             737           truenorm /= truenorm.mag();
734           *n= truenorm;                           738           *n= truenorm;
735         }                                         739         } 
736         break;                                    740         break;
737                                                   741 
738         default:            // Should never re    742         default:            // Should never reach this case ...
739           DumpInfo();                             743           DumpInfo();
740           std::ostringstream message;             744           std::ostringstream message;
741           G4long oldprc = message.precision(16 << 745           G4int oldprc = message.precision(16);
742           message << "Undefined side for valid    746           message << "Undefined side for valid surface normal to solid."
743                   << G4endl                       747                   << G4endl
744                   << "Position:"  << G4endl       748                   << "Position:"  << G4endl
745                   << "   p.x() = "   << p.x()/    749                   << "   p.x() = "   << p.x()/mm << " mm" << G4endl
746                   << "   p.y() = "   << p.y()/    750                   << "   p.y() = "   << p.y()/mm << " mm" << G4endl
747                   << "   p.z() = "   << p.z()/    751                   << "   p.z() = "   << p.z()/mm << " mm" << G4endl
748                   << "Direction:" << G4endl       752                   << "Direction:" << G4endl
749                   << "   v.x() = "   << v.x()     753                   << "   v.x() = "   << v.x() << G4endl
750                   << "   v.y() = "   << v.y()     754                   << "   v.y() = "   << v.y() << G4endl
751                   << "   v.z() = "   << v.z()     755                   << "   v.z() = "   << v.z() << G4endl
752                   << "Proposed distance :" <<     756                   << "Proposed distance :" << G4endl
753                   << "   distMin = "    << dis    757                   << "   distMin = "    << distMin/mm << " mm";
754           message.precision(oldprc);              758           message.precision(oldprc);
755           G4Exception("G4EllipticalCone::Dista    759           G4Exception("G4EllipticalCone::DistanceToOut(p,v,..)",
756                       "GeomSolids1002", JustWa    760                       "GeomSolids1002", JustWarning, message);
757           break;                                  761           break;
758       }                                           762       }
759     }                                             763     }
760   }                                               764   }
761                                                   765 
762   if (distMin < halfCarTol) { distMin=0; }        766   if (distMin < halfCarTol) { distMin=0; }
763                                                   767 
764   return distMin;                                 768   return distMin;
765 }                                                 769 }
766                                                   770 
767 //////////////////////////////////////////////    771 /////////////////////////////////////////////////////////////////////////
768 //                                                772 //
769 // Calculate distance (<=actual) to closest su    773 // Calculate distance (<=actual) to closest surface of shape from inside
770                                                   774 
771 G4double G4EllipticalCone::DistanceToOut(const    775 G4double G4EllipticalCone::DistanceToOut(const G4ThreeVector& p) const
772 {                                                 776 {
773 #ifdef G4SPECSDEBUG                               777 #ifdef G4SPECSDEBUG
774   if( Inside(p) == kOutside )                     778   if( Inside(p) == kOutside )
775   {                                               779   {
776      std::ostringstream message;                  780      std::ostringstream message;
777      G4long oldprc = message.precision(16);    << 781      G4int oldprc = message.precision(16);
778      message << "Point p is outside (!?) of so    782      message << "Point p is outside (!?) of solid: " << GetName() << "\n"
779              << "Position:\n"                     783              << "Position:\n"
780              << "   p.x() = "  << p.x()/mm <<     784              << "   p.x() = "  << p.x()/mm << " mm\n"
781              << "   p.y() = "  << p.y()/mm <<     785              << "   p.y() = "  << p.y()/mm << " mm\n"
782              << "   p.z() = "  << p.z()/mm <<     786              << "   p.z() = "  << p.z()/mm << " mm";
783      message.precision(oldprc) ;                  787      message.precision(oldprc) ;
784      G4Exception("G4Ellipsoid::DistanceToOut(p    788      G4Exception("G4Ellipsoid::DistanceToOut(p)", "GeomSolids1002",
785                  JustWarning, message);           789                  JustWarning, message);
786      DumpInfo();                                  790      DumpInfo();
787   }                                               791   }
788 #endif                                            792 #endif
789   G4double hp = std::sqrt(p.x()*p.x()*invXX +     793   G4double hp = std::sqrt(p.x()*p.x()*invXX + p.y()*p.y()*invYY) + p.z();
790   G4double ds = (zheight - hp)*cosAxisMin;        794   G4double ds = (zheight - hp)*cosAxisMin;
791   G4double dz = zTopCut - std::abs(p.z());        795   G4double dz = zTopCut - std::abs(p.z());
792   G4double dist = std::min(ds,dz);                796   G4double dist = std::min(ds,dz);
793   return (dist > 0) ? dist : 0.;                  797   return (dist > 0) ? dist : 0.;
794 }                                                 798 }
795                                                   799 
796 //////////////////////////////////////////////    800 /////////////////////////////////////////////////////////////////////////
797 //                                                801 //
798 // GetEntityType                                  802 // GetEntityType
799                                                   803 
800 G4GeometryType G4EllipticalCone::GetEntityType    804 G4GeometryType G4EllipticalCone::GetEntityType() const
801 {                                                 805 {
802   return {"G4EllipticalCone"};                 << 806   return G4String("G4EllipticalCone");
803 }                                                 807 }
804                                                   808 
805 //////////////////////////////////////////////    809 /////////////////////////////////////////////////////////////////////////
806 //                                                810 //
807 // Make a clone of the object                     811 // Make a clone of the object
808                                                   812 
809 G4VSolid* G4EllipticalCone::Clone() const         813 G4VSolid* G4EllipticalCone::Clone() const
810 {                                                 814 {
811   return new G4EllipticalCone(*this);             815   return new G4EllipticalCone(*this);
812 }                                                 816 }
813                                                   817 
814 //////////////////////////////////////////////    818 /////////////////////////////////////////////////////////////////////////
815 //                                                819 //
816 // Stream object contents to an output stream     820 // Stream object contents to an output stream
817                                                   821 
818 std::ostream& G4EllipticalCone::StreamInfo( st    822 std::ostream& G4EllipticalCone::StreamInfo( std::ostream& os ) const
819 {                                                 823 {
820   G4long oldprc = os.precision(16);            << 824   G4int oldprc = os.precision(16);
821   os << "-------------------------------------    825   os << "-----------------------------------------------------------\n"
822      << "    *** Dump for solid - " << GetName    826      << "    *** Dump for solid - " << GetName() << " ***\n"
823      << "    =================================    827      << "    ===================================================\n"
824      << " Solid type: G4EllipticalCone\n"         828      << " Solid type: G4EllipticalCone\n"
825      << " Parameters: \n"                         829      << " Parameters: \n"
826                                                   830 
827      << "    semi-axis x: " << xSemiAxis/mm <<    831      << "    semi-axis x: " << xSemiAxis/mm << " mm \n"
828      << "    semi-axis y: " << ySemiAxis/mm <<    832      << "    semi-axis y: " << ySemiAxis/mm << " mm \n"
829      << "    height    z: " << zheight/mm << "    833      << "    height    z: " << zheight/mm << " mm \n"
830      << "    half length in  z: " << zTopCut/m    834      << "    half length in  z: " << zTopCut/mm << " mm \n"
831      << "-------------------------------------    835      << "-----------------------------------------------------------\n";
832   os.precision(oldprc);                           836   os.precision(oldprc);
833                                                   837 
834   return os;                                      838   return os;
835 }                                                 839 }
836                                                   840 
837 //////////////////////////////////////////////    841 /////////////////////////////////////////////////////////////////////////
838 //                                                842 //
839 // Return random point on the surface of the s    843 // Return random point on the surface of the solid
840                                                   844 
841 G4ThreeVector G4EllipticalCone::GetPointOnSurf    845 G4ThreeVector G4EllipticalCone::GetPointOnSurface() const
842 {                                                 846 {
843   G4double x0 = xSemiAxis*zheight; // x semi a    847   G4double x0 = xSemiAxis*zheight; // x semi axis at z=0
844   G4double y0 = ySemiAxis*zheight; // y semi a    848   G4double y0 = ySemiAxis*zheight; // y semi axis at z=0
845   G4double s0 = G4GeomTools::EllipticConeLater    849   G4double s0 = G4GeomTools::EllipticConeLateralArea(x0,y0,zheight);
846   G4double kmin = (zTopCut >= zheight ) ? 0. :    850   G4double kmin = (zTopCut >= zheight ) ? 0. : (zheight - zTopCut)/zheight;
847   G4double kmax = (zTopCut >= zheight ) ? 2. :    851   G4double kmax = (zTopCut >= zheight ) ? 2. : (zheight + zTopCut)/zheight;
848                                                   852 
849   // Set areas (base at -Z, side surface, base    853   // Set areas (base at -Z, side surface, base at +Z)
850   //                                              854   //
851   G4double szmin =  pi*x0*y0*kmax*kmax;           855   G4double szmin =  pi*x0*y0*kmax*kmax;
852   G4double szmax =  pi*x0*y0*kmin*kmin;           856   G4double szmax =  pi*x0*y0*kmin*kmin;
853   G4double sside =  s0*(kmax*kmax - kmin*kmin)    857   G4double sside =  s0*(kmax*kmax - kmin*kmin);
854   G4double ssurf[3] = { szmin, sside, szmax };    858   G4double ssurf[3] = { szmin, sside, szmax };
855   for (auto i=1; i<3; ++i) { ssurf[i] += ssurf << 859   for (G4int i=1; i<3; ++i) { ssurf[i] += ssurf[i-1]; }
856                                                   860 
857   // Select surface                               861   // Select surface
858   //                                              862   //
859   G4double select = ssurf[2]*G4UniformRand();     863   G4double select = ssurf[2]*G4UniformRand();
860   G4int k = 2;                                    864   G4int k = 2;
861   if (select <= ssurf[1]) k = 1;                  865   if (select <= ssurf[1]) k = 1;
862   if (select <= ssurf[0]) k = 0;                  866   if (select <= ssurf[0]) k = 0;
863                                                   867 
864   // Pick random point on selected surface        868   // Pick random point on selected surface
865   //                                              869   //
866   G4ThreeVector p;                                870   G4ThreeVector p;
867   switch(k)                                       871   switch(k)
868   {                                               872   {
869     case 0: // base at -Z, uniform distributio    873     case 0: // base at -Z, uniform distribution, rejection sampling
870     {                                             874     {
871       G4double zh = zheight + zTopCut;            875       G4double zh = zheight + zTopCut;
872       G4TwoVector rho = G4RandomPointInEllipse    876       G4TwoVector rho = G4RandomPointInEllipse(zh*xSemiAxis,zh*ySemiAxis);
873       p.set(rho.x(),rho.y(),-zTopCut);            877       p.set(rho.x(),rho.y(),-zTopCut);
874       break;                                      878       break;
875     }                                             879     }
876     case 1: // side surface, uniform distribut    880     case 1: // side surface, uniform distribution, rejection sampling
877     {                                             881     {
878       G4double zh = G4RandomRadiusInRing(zheig    882       G4double zh = G4RandomRadiusInRing(zheight-zTopCut, zheight+zTopCut);
879       G4double a = x0;                            883       G4double a = x0;
880       G4double b = y0;                            884       G4double b = y0;
881                                                   885 
882       G4double hh = zheight*zheight;              886       G4double hh = zheight*zheight;
883       G4double aa = a*a;                          887       G4double aa = a*a;
884       G4double bb = b*b;                          888       G4double bb = b*b;
885       G4double R  = std::max(a,b);                889       G4double R  = std::max(a,b);
886       G4double mu_max = R*std::sqrt(hh + R*R);    890       G4double mu_max = R*std::sqrt(hh + R*R);
887                                                   891 
888       G4double x,y;                               892       G4double x,y;
889       for (auto i=0; i<1000; ++i)              << 893       for (G4int i=0; i<1000; ++i)
890       {                                           894       {
891   G4double phi = CLHEP::twopi*G4UniformRand();    895   G4double phi = CLHEP::twopi*G4UniformRand();
892         x = std::cos(phi);                        896         x = std::cos(phi);
893         y = std::sin(phi);                        897         y = std::sin(phi);
894         G4double xx = x*x;                        898         G4double xx = x*x;
895         G4double yy = y*y;                        899         G4double yy = y*y;
896         G4double E = hh + aa*xx + bb*yy;          900         G4double E = hh + aa*xx + bb*yy;
897         G4double F = (aa-bb)*x*y;                 901         G4double F = (aa-bb)*x*y;
898         G4double G = aa*yy + bb*xx;               902         G4double G = aa*yy + bb*xx;
899         G4double mu = std::sqrt(E*G - F*F);       903         G4double mu = std::sqrt(E*G - F*F);
900         if (mu_max*G4UniformRand() <= mu) brea    904         if (mu_max*G4UniformRand() <= mu) break;
901       }                                           905       }
902       p.set(zh*xSemiAxis*x,zh*ySemiAxis*y,zhei    906       p.set(zh*xSemiAxis*x,zh*ySemiAxis*y,zheight-zh);
903       break;                                      907       break;
904     }                                             908     }
905     case 2: // base at +Z, uniform distributio    909     case 2: // base at +Z, uniform distribution, rejection sampling
906     {                                             910     {
907       G4double zh = zheight - zTopCut;            911       G4double zh = zheight - zTopCut;
908       G4TwoVector rho = G4RandomPointInEllipse    912       G4TwoVector rho = G4RandomPointInEllipse(zh*xSemiAxis,zh*ySemiAxis);
909       p.set(rho.x(),rho.y(),zTopCut);             913       p.set(rho.x(),rho.y(),zTopCut);
910       break;                                      914       break;
911     }                                             915     }
912   }                                               916   }
913   return p;                                       917   return p;
914 }                                                 918 }
915                                                   919 
916 //////////////////////////////////////////////    920 /////////////////////////////////////////////////////////////////////////
917 //                                                921 //
918 // Get cubic volume                               922 // Get cubic volume
919                                                   923 
920 G4double G4EllipticalCone::GetCubicVolume()       924 G4double G4EllipticalCone::GetCubicVolume()
921 {                                                 925 {
922   if (fCubicVolume == 0.0)                     << 926   if (fCubicVolume == 0)
923   {                                               927   {
924     G4double x0 = xSemiAxis*zheight; // x semi    928     G4double x0 = xSemiAxis*zheight; // x semi axis at z=0
925     G4double y0 = ySemiAxis*zheight; // y semi    929     G4double y0 = ySemiAxis*zheight; // y semi axis at z=0
926     G4double v0 = CLHEP::pi*x0*y0*zheight/3.;     930     G4double v0 = CLHEP::pi*x0*y0*zheight/3.;
927     G4double kmin = (zTopCut >= zheight ) ? 0.    931     G4double kmin = (zTopCut >= zheight ) ? 0. : (zheight - zTopCut)/zheight;
928     G4double kmax = (zTopCut >= zheight ) ? 2.    932     G4double kmax = (zTopCut >= zheight ) ? 2. : (zheight + zTopCut)/zheight;
929     fCubicVolume = (kmax - kmin)*(kmax*kmax +     933     fCubicVolume = (kmax - kmin)*(kmax*kmax + kmax*kmin + kmin*kmin)*v0;
930   }                                               934   }
931   return fCubicVolume;                            935   return fCubicVolume;
932 }                                                 936 }
933                                                   937 
934 //////////////////////////////////////////////    938 /////////////////////////////////////////////////////////////////////////
935 //                                                939 //
936 // Get surface area                               940 // Get surface area
937                                                   941 
938 G4double G4EllipticalCone::GetSurfaceArea()       942 G4double G4EllipticalCone::GetSurfaceArea()
939 {                                                 943 {
940   if (fSurfaceArea == 0.0)                     << 944   if (fSurfaceArea == 0)
941   {                                               945   {
942     G4double x0 = xSemiAxis*zheight; // x semi    946     G4double x0 = xSemiAxis*zheight; // x semi axis at z=0
943     G4double y0 = ySemiAxis*zheight; // y semi    947     G4double y0 = ySemiAxis*zheight; // y semi axis at z=0
944     G4double s0 = G4GeomTools::EllipticConeLat    948     G4double s0 = G4GeomTools::EllipticConeLateralArea(x0,y0,zheight);
945     G4double kmin = (zTopCut >= zheight ) ? 0.    949     G4double kmin = (zTopCut >= zheight ) ? 0. : (zheight - zTopCut)/zheight;
946     G4double kmax = (zTopCut >= zheight ) ? 2.    950     G4double kmax = (zTopCut >= zheight ) ? 2. : (zheight + zTopCut)/zheight;
947     fSurfaceArea = (kmax - kmin)*(kmax + kmin)    951     fSurfaceArea = (kmax - kmin)*(kmax + kmin)*s0
948                  + CLHEP::pi*x0*y0*(kmin*kmin     952                  + CLHEP::pi*x0*y0*(kmin*kmin + kmax*kmax);
949   }                                               953   }
950   return fSurfaceArea;                            954   return fSurfaceArea;
951 }                                                 955 }
952                                                   956 
953 //////////////////////////////////////////////    957 /////////////////////////////////////////////////////////////////////////
954 //                                                958 //
955 // Methods for visualisation                      959 // Methods for visualisation
956                                                   960 
957 void G4EllipticalCone::DescribeYourselfTo (G4V    961 void G4EllipticalCone::DescribeYourselfTo (G4VGraphicsScene& scene) const
958 {                                                 962 {
959   scene.AddSolid(*this);                          963   scene.AddSolid(*this);
960 }                                                 964 }
961                                                   965 
962 G4VisExtent G4EllipticalCone::GetExtent() cons    966 G4VisExtent G4EllipticalCone::GetExtent() const
963 {                                                 967 {
964   // Define the sides of the box into which th    968   // Define the sides of the box into which the solid instance would fit.
965   //                                              969   //
966   G4ThreeVector pmin,pmax;                        970   G4ThreeVector pmin,pmax;
967   BoundingLimits(pmin,pmax);                      971   BoundingLimits(pmin,pmax);
968   return { pmin.x(), pmax.x(), pmin.y(), pmax. << 972   return G4VisExtent(pmin.x(),pmax.x(),
                                                   >> 973                      pmin.y(),pmax.y(),
                                                   >> 974                      pmin.z(),pmax.z());
969 }                                                 975 }
970                                                   976 
971 G4Polyhedron* G4EllipticalCone::CreatePolyhedr    977 G4Polyhedron* G4EllipticalCone::CreatePolyhedron () const
972 {                                                 978 {
973   return new G4PolyhedronEllipticalCone(xSemiA    979   return new G4PolyhedronEllipticalCone(xSemiAxis, ySemiAxis, zheight, zTopCut);
974 }                                                 980 }
975                                                   981 
976 G4Polyhedron* G4EllipticalCone::GetPolyhedron     982 G4Polyhedron* G4EllipticalCone::GetPolyhedron () const
977 {                                                 983 {
978   if ( (fpPolyhedron == nullptr)               << 984   if ( (!fpPolyhedron)
979     || fRebuildPolyhedron                         985     || fRebuildPolyhedron
980     || (fpPolyhedron->GetNumberOfRotationSteps    986     || (fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
981         fpPolyhedron->GetNumberOfRotationSteps    987         fpPolyhedron->GetNumberOfRotationSteps()) )
982     {                                             988     {
983       G4AutoLock l(&polyhedronMutex);             989       G4AutoLock l(&polyhedronMutex);
984       delete fpPolyhedron;                        990       delete fpPolyhedron;
985       fpPolyhedron = CreatePolyhedron();          991       fpPolyhedron = CreatePolyhedron();
986       fRebuildPolyhedron = false;                 992       fRebuildPolyhedron = false;
987       l.unlock();                                 993       l.unlock();
988     }                                             994     }
989   return fpPolyhedron;                            995   return fpPolyhedron;
990 }                                                 996 }
991                                                << 
992 #endif // !defined(G4GEOM_USE_UELLIPTICALCONE) << 
993                                                   997