Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/CSG/src/G4Orb.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/CSG/src/G4Orb.cc (Version 11.3.0) and /geometry/solids/CSG/src/G4Orb.cc (Version 11.0.p4)


  1 // *******************************************      1 // ********************************************************************
  2 // * License and Disclaimer                         2 // * License and Disclaimer                                           *
  3 // *                                                3 // *                                                                  *
  4 // * The  Geant4 software  is  copyright of th      4 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  5 // * the Geant4 Collaboration.  It is provided      5 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  6 // * conditions of the Geant4 Software License      6 // * conditions of the Geant4 Software License,  included in the file *
  7 // * LICENSE and available at  http://cern.ch/      7 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  8 // * include a list of copyright holders.           8 // * include a list of copyright holders.                             *
  9 // *                                                9 // *                                                                  *
 10 // * Neither the authors of this software syst     10 // * Neither the authors of this software system, nor their employing *
 11 // * institutes,nor the agencies providing fin     11 // * institutes,nor the agencies providing financial support for this *
 12 // * work  make  any representation or  warran     12 // * work  make  any representation or  warranty, express or implied, *
 13 // * regarding  this  software system or assum     13 // * regarding  this  software system or assume any liability for its *
 14 // * use.  Please see the license in the file      14 // * use.  Please see the license in the file  LICENSE  and URL above *
 15 // * for the full disclaimer and the limitatio     15 // * for the full disclaimer and the limitation of liability.         *
 16 // *                                               16 // *                                                                  *
 17 // * This  code  implementation is the result      17 // * This  code  implementation is the result of  the  scientific and *
 18 // * technical work of the GEANT4 collaboratio     18 // * technical work of the GEANT4 collaboration.                      *
 19 // * By using,  copying,  modifying or  distri     19 // * By using,  copying,  modifying or  distributing the software (or *
 20 // * any work based  on the software)  you  ag     20 // * any work based  on the software)  you  agree  to acknowledge its *
 21 // * use  in  resulting  scientific  publicati     21 // * use  in  resulting  scientific  publications,  and indicate your *
 22 // * acceptance of all terms of the Geant4 Sof     22 // * acceptance of all terms of the Geant4 Software license.          *
 23 // *******************************************     23 // ********************************************************************
 24 //                                                 24 //
 25 // Implementation for G4Orb class                  25 // Implementation for G4Orb class
 26 //                                                 26 //
 27 // 20.08.03 V.Grichine - created                   27 // 20.08.03 V.Grichine - created
 28 // 08.08.17 E.Tcherniaev - complete revision,      28 // 08.08.17 E.Tcherniaev - complete revision, speed-up
 29 // -------------------------------------------     29 // --------------------------------------------------------------------
 30                                                    30 
 31 #include "G4Orb.hh"                                31 #include "G4Orb.hh"
 32                                                    32 
 33 #if !defined(G4GEOM_USE_UORB)                      33 #if !defined(G4GEOM_USE_UORB)
 34                                                    34 
 35 #include "G4TwoVector.hh"                          35 #include "G4TwoVector.hh"
 36 #include "G4VoxelLimits.hh"                        36 #include "G4VoxelLimits.hh"
 37 #include "G4AffineTransform.hh"                    37 #include "G4AffineTransform.hh"
 38 #include "G4GeometryTolerance.hh"                  38 #include "G4GeometryTolerance.hh"
 39 #include "G4BoundingEnvelope.hh"                   39 #include "G4BoundingEnvelope.hh"
 40                                                    40 
 41 #include "G4VPVParameterisation.hh"                41 #include "G4VPVParameterisation.hh"
 42                                                    42 
 43 #include "G4RandomDirection.hh"                    43 #include "G4RandomDirection.hh"
 44 #include "Randomize.hh"                            44 #include "Randomize.hh"
 45                                                    45 
 46 #include "G4VGraphicsScene.hh"                     46 #include "G4VGraphicsScene.hh"
 47 #include "G4VisExtent.hh"                          47 #include "G4VisExtent.hh"
 48                                                    48 
 49 using namespace CLHEP;                             49 using namespace CLHEP;
 50                                                    50 
 51 //////////////////////////////////////////////     51 //////////////////////////////////////////////////////////////////////////
 52 //                                                 52 //
 53 // Constructor                                     53 // Constructor
 54                                                    54 
 55 G4Orb::G4Orb( const G4String& pName, G4double      55 G4Orb::G4Orb( const G4String& pName, G4double pRmax )
 56   : G4CSGSolid(pName), fRmax(pRmax)                56   : G4CSGSolid(pName), fRmax(pRmax)
 57 {                                                  57 {
 58   Initialize();                                    58   Initialize();
 59 }                                                  59 }
 60                                                    60 
 61 //////////////////////////////////////////////     61 //////////////////////////////////////////////////////////////////////////
 62 //                                                 62 //
 63 // Fake default constructor - sets only member     63 // Fake default constructor - sets only member data and allocates memory
 64 //                            for usage restri     64 //                            for usage restricted to object persistency
 65                                                    65 
 66 G4Orb::G4Orb( __void__& a )                        66 G4Orb::G4Orb( __void__& a )
 67   : G4CSGSolid(a)                                  67   : G4CSGSolid(a)
 68 {                                                  68 {
 69 }                                                  69 }
 70                                                    70 
 71 //////////////////////////////////////////////     71 //////////////////////////////////////////////////////////////////////////
 72 //                                                 72 //
 73 // Destructor                                      73 // Destructor
 74                                                    74 
 75 G4Orb::~G4Orb() = default;                     <<  75 G4Orb::~G4Orb()
                                                   >>  76 {
                                                   >>  77 }
 76                                                    78 
 77 //////////////////////////////////////////////     79 //////////////////////////////////////////////////////////////////////////
 78 //                                                 80 //
 79 // Copy constructor                                81 // Copy constructor
 80                                                    82 
 81 G4Orb::G4Orb(const G4Orb&) = default;          <<  83 G4Orb::G4Orb(const G4Orb& rhs)
                                                   >>  84   : G4CSGSolid(rhs), fRmax(rhs.fRmax), halfRmaxTol(rhs.halfRmaxTol),
                                                   >>  85     sqrRmaxPlusTol(rhs.sqrRmaxPlusTol), sqrRmaxMinusTol(rhs.sqrRmaxMinusTol)
                                                   >>  86 {
                                                   >>  87 }
 82                                                    88 
 83 //////////////////////////////////////////////     89 //////////////////////////////////////////////////////////////////////////
 84 //                                                 90 //
 85 // Assignment operator                             91 // Assignment operator
 86                                                    92 
 87 G4Orb& G4Orb::operator = (const G4Orb& rhs)        93 G4Orb& G4Orb::operator = (const G4Orb& rhs)
 88 {                                                  94 {
 89    // Check assignment to self                     95    // Check assignment to self
 90    //                                              96    //
 91    if (this == &rhs)  { return *this; }            97    if (this == &rhs)  { return *this; }
 92                                                    98 
 93    // Copy base class data                         99    // Copy base class data
 94    //                                             100    //
 95    G4CSGSolid::operator=(rhs);                    101    G4CSGSolid::operator=(rhs);
 96                                                   102 
 97    // Copy data                                   103    // Copy data
 98    //                                             104    //
 99    fRmax = rhs.fRmax;                             105    fRmax = rhs.fRmax;
100    halfRmaxTol = rhs.halfRmaxTol;                 106    halfRmaxTol = rhs.halfRmaxTol;
101    sqrRmaxPlusTol = rhs.sqrRmaxPlusTol;           107    sqrRmaxPlusTol = rhs.sqrRmaxPlusTol;
102    sqrRmaxMinusTol = rhs.sqrRmaxMinusTol;         108    sqrRmaxMinusTol = rhs.sqrRmaxMinusTol;
103                                                   109 
104    return *this;                                  110    return *this;
105 }                                                 111 }
106                                                   112 
107 //////////////////////////////////////////////    113 //////////////////////////////////////////////////////////////////////////
108 //                                                114 //
109 // Check radius and initialize dada members       115 // Check radius and initialize dada members
110                                                   116 
111 void G4Orb::Initialize()                          117 void G4Orb::Initialize()
112 {                                                 118 {
113   const G4double fEpsilon = 2.e-11;  // relati    119   const G4double fEpsilon = 2.e-11;  // relative tolerance of fRmax
114                                                   120 
115   // Check radius                                 121   // Check radius
116   //                                              122   //
117   if ( fRmax < 10*kCarTolerance )                 123   if ( fRmax < 10*kCarTolerance )
118   {                                               124   {
119     G4Exception("G4Orb::Initialize()", "GeomSo    125     G4Exception("G4Orb::Initialize()", "GeomSolids0002", FatalException,
120                 "Invalid radius < 10*kCarToler    126                 "Invalid radius < 10*kCarTolerance.");
121   }                                               127   }
122   halfRmaxTol = 0.5 * std::max(kCarTolerance,     128   halfRmaxTol = 0.5 * std::max(kCarTolerance, fEpsilon*fRmax);
123   G4double rmaxPlusTol  = fRmax + halfRmaxTol;    129   G4double rmaxPlusTol  = fRmax + halfRmaxTol;
124   G4double rmaxMinusTol = fRmax - halfRmaxTol;    130   G4double rmaxMinusTol = fRmax - halfRmaxTol;
125   sqrRmaxPlusTol = rmaxPlusTol*rmaxPlusTol;       131   sqrRmaxPlusTol = rmaxPlusTol*rmaxPlusTol;
126   sqrRmaxMinusTol = rmaxMinusTol*rmaxMinusTol;    132   sqrRmaxMinusTol = rmaxMinusTol*rmaxMinusTol;
127 }                                                 133 }
128                                                   134 
129 //////////////////////////////////////////////    135 //////////////////////////////////////////////////////////////////////////
130 //                                                136 //
131 // Dispatch to parameterisation for replicatio    137 // Dispatch to parameterisation for replication mechanism dimension
132 // computation & modification                     138 // computation & modification
133                                                   139 
134 void G4Orb::ComputeDimensions(       G4VPVPara    140 void G4Orb::ComputeDimensions(       G4VPVParameterisation* p,
135                                const G4int n,     141                                const G4int n,
136                                const G4VPhysic    142                                const G4VPhysicalVolume* pRep )
137 {                                                 143 {
138   p->ComputeDimensions(*this,n,pRep);             144   p->ComputeDimensions(*this,n,pRep);
139 }                                                 145 }
140                                                   146 
141 //////////////////////////////////////////////    147 //////////////////////////////////////////////////////////////////////////
142 //                                                148 //
143 // Get bounding box                               149 // Get bounding box
144                                                   150 
145 void G4Orb::BoundingLimits(G4ThreeVector& pMin    151 void G4Orb::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
146 {                                                 152 {
147   G4double radius = GetRadius();                  153   G4double radius = GetRadius();
148   pMin.set(-radius,-radius,-radius);              154   pMin.set(-radius,-radius,-radius);
149   pMax.set( radius, radius, radius);              155   pMax.set( radius, radius, radius);
150                                                   156 
151   // Check correctness of the bounding box        157   // Check correctness of the bounding box
152   //                                              158   //
153   if (pMin.x() >= pMax.x() || pMin.y() >= pMax    159   if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
154   {                                               160   {
155     std::ostringstream message;                   161     std::ostringstream message;
156     message << "Bad bounding box (min >= max)     162     message << "Bad bounding box (min >= max) for solid: "
157             << GetName() << " !"                  163             << GetName() << " !"
158             << "\npMin = " << pMin                164             << "\npMin = " << pMin
159             << "\npMax = " << pMax;               165             << "\npMax = " << pMax;
160     G4Exception("G4Orb::BoundingLimits()", "Ge    166     G4Exception("G4Orb::BoundingLimits()", "GeomMgt0001",
161                 JustWarning, message);            167                 JustWarning, message);
162     DumpInfo();                                   168     DumpInfo();
163   }                                               169   }
164 }                                                 170 }
165                                                   171 
166 //////////////////////////////////////////////    172 //////////////////////////////////////////////////////////////////////////
167 //                                                173 //
168 // Calculate extent under transform and specif    174 // Calculate extent under transform and specified limit
169                                                   175 
170 G4bool G4Orb::CalculateExtent(const EAxis pAxi    176 G4bool G4Orb::CalculateExtent(const EAxis pAxis,
171                               const G4VoxelLim    177                               const G4VoxelLimits& pVoxelLimit,
172                               const G4AffineTr    178                               const G4AffineTransform& pTransform,
173                                         G4doub    179                                         G4double& pMin, G4double& pMax) const
174 {                                                 180 {
175   G4ThreeVector bmin, bmax;                       181   G4ThreeVector bmin, bmax;
176   G4bool exist;                                   182   G4bool exist;
177                                                   183 
178   // Get bounding box                             184   // Get bounding box
179   BoundingLimits(bmin,bmax);                      185   BoundingLimits(bmin,bmax);
180                                                   186 
181   // Check bounding box                           187   // Check bounding box
182   G4BoundingEnvelope bbox(bmin,bmax);             188   G4BoundingEnvelope bbox(bmin,bmax);
183 #ifdef G4BBOX_EXTENT                              189 #ifdef G4BBOX_EXTENT
184   return bbox.CalculateExtent(pAxis,pVoxelLimi    190   return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
185 #endif                                            191 #endif
186   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox    192   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
187   {                                               193   {
188     return exist = pMin < pMax;                << 194     return exist = (pMin < pMax) ? true : false;
189   }                                               195   }
190                                                   196 
191   // Find bounding envelope and calculate exte    197   // Find bounding envelope and calculate extent
192   //                                              198   //
193   static const G4int NTHETA = 8;  // number of    199   static const G4int NTHETA = 8;  // number of steps along Theta
194   static const G4int NPHI   = 16; // number of    200   static const G4int NPHI   = 16; // number of steps along Phi
195   static const G4double sinHalfTheta = std::si    201   static const G4double sinHalfTheta = std::sin(halfpi/NTHETA);
196   static const G4double cosHalfTheta = std::co    202   static const G4double cosHalfTheta = std::cos(halfpi/NTHETA);
197   static const G4double sinHalfPhi   = std::si    203   static const G4double sinHalfPhi   = std::sin(pi/NPHI);
198   static const G4double cosHalfPhi   = std::co    204   static const G4double cosHalfPhi   = std::cos(pi/NPHI);
199   static const G4double sinStepTheta = 2.*sinH    205   static const G4double sinStepTheta = 2.*sinHalfTheta*cosHalfTheta;
200   static const G4double cosStepTheta = 1. - 2.    206   static const G4double cosStepTheta = 1. - 2.*sinHalfTheta*sinHalfTheta;
201   static const G4double sinStepPhi   = 2.*sinH    207   static const G4double sinStepPhi   = 2.*sinHalfPhi*cosHalfPhi;
202   static const G4double cosStepPhi   = 1. - 2.    208   static const G4double cosStepPhi   = 1. - 2.*sinHalfPhi*sinHalfPhi;
203                                                   209 
204   G4double radius = GetRadius();                  210   G4double radius = GetRadius();
205   G4double rtheta = radius/cosHalfTheta;          211   G4double rtheta = radius/cosHalfTheta;
206   G4double rphi   = rtheta/cosHalfPhi;            212   G4double rphi   = rtheta/cosHalfPhi;
207                                                   213 
208   // set reference circle                         214   // set reference circle
209   G4TwoVector xy[NPHI];                           215   G4TwoVector xy[NPHI];
210   G4double sinCurPhi = sinHalfPhi;                216   G4double sinCurPhi = sinHalfPhi;
211   G4double cosCurPhi = cosHalfPhi;                217   G4double cosCurPhi = cosHalfPhi;
212   for (auto & k : xy)                          << 218   for (G4int k=0; k<NPHI; ++k)
213   {                                               219   {
214     k.set(cosCurPhi,sinCurPhi);                << 220     xy[k].set(cosCurPhi,sinCurPhi);
215     G4double sinTmpPhi = sinCurPhi;               221     G4double sinTmpPhi = sinCurPhi;
216     sinCurPhi = sinCurPhi*cosStepPhi + cosCurP    222     sinCurPhi = sinCurPhi*cosStepPhi + cosCurPhi*sinStepPhi;
217     cosCurPhi = cosCurPhi*cosStepPhi - sinTmpP    223     cosCurPhi = cosCurPhi*cosStepPhi - sinTmpPhi*sinStepPhi;
218   }                                               224   }
219                                                   225   
220   // set bounding circles                         226   // set bounding circles
221   G4ThreeVectorList circles[NTHETA];              227   G4ThreeVectorList circles[NTHETA];
222   for (auto & circle : circles) { circle.resiz << 228   for (G4int i=0; i<NTHETA; ++i) { circles[i].resize(NPHI); }
223                                                   229 
224   G4double sinCurTheta = sinHalfTheta;            230   G4double sinCurTheta = sinHalfTheta;
225   G4double cosCurTheta = cosHalfTheta;            231   G4double cosCurTheta = cosHalfTheta;
226   for (auto & circle : circles)                << 232   for (G4int i=0; i<NTHETA; ++i)
227   {                                               233   {
228     G4double z = rtheta*cosCurTheta;              234     G4double z = rtheta*cosCurTheta;
229     G4double rho = rphi*sinCurTheta;              235     G4double rho = rphi*sinCurTheta;
230     for (G4int k=0; k<NPHI; ++k)                  236     for (G4int k=0; k<NPHI; ++k)
231     {                                             237     {
232       circle[k].set(rho*xy[k].x(),rho*xy[k].y( << 238       circles[i][k].set(rho*xy[k].x(),rho*xy[k].y(),z);
233     }                                             239     }
234     G4double sinTmpTheta = sinCurTheta;           240     G4double sinTmpTheta = sinCurTheta;
235     sinCurTheta = sinCurTheta*cosStepTheta + c    241     sinCurTheta = sinCurTheta*cosStepTheta + cosCurTheta*sinStepTheta;
236     cosCurTheta = cosCurTheta*cosStepTheta - s    242     cosCurTheta = cosCurTheta*cosStepTheta - sinTmpTheta*sinStepTheta;
237   }                                               243   }
238                                                   244 
239   // set envelope and calculate extent            245   // set envelope and calculate extent
240   std::vector<const G4ThreeVectorList *> polyg    246   std::vector<const G4ThreeVectorList *> polygons;
241   polygons.resize(NTHETA);                        247   polygons.resize(NTHETA);
242   for (G4int i=0; i<NTHETA; ++i) { polygons[i]    248   for (G4int i=0; i<NTHETA; ++i) { polygons[i] = &circles[i]; }
243                                                   249 
244   G4BoundingEnvelope benv(bmin,bmax,polygons);    250   G4BoundingEnvelope benv(bmin,bmax,polygons);
245   exist = benv.CalculateExtent(pAxis,pVoxelLim    251   exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
246   return exist;                                   252   return exist;
247 }                                                 253 }
248                                                   254 
249 //////////////////////////////////////////////    255 //////////////////////////////////////////////////////////////////////////
250 //                                                256 //
251 // Return whether point is inside/outside/on s    257 // Return whether point is inside/outside/on surface
252                                                   258 
253 EInside G4Orb::Inside( const G4ThreeVector& p     259 EInside G4Orb::Inside( const G4ThreeVector& p ) const
254 {                                                 260 {
255   G4double rr = p.mag2();                         261   G4double rr = p.mag2();
256   if (rr > sqrRmaxPlusTol) return kOutside;       262   if (rr > sqrRmaxPlusTol) return kOutside;
257   return (rr > sqrRmaxMinusTol) ? kSurface : k    263   return (rr > sqrRmaxMinusTol) ? kSurface : kInside;
258 }                                                 264 }
259                                                   265 
260 //////////////////////////////////////////////    266 //////////////////////////////////////////////////////////////////////////
261 //                                                267 //
262 // Return unit normal of surface closest to p     268 // Return unit normal of surface closest to p
263                                                   269 
264 G4ThreeVector G4Orb::SurfaceNormal( const G4Th    270 G4ThreeVector G4Orb::SurfaceNormal( const G4ThreeVector& p ) const
265 {                                                 271 {
266   return (1/p.mag())*p;                           272   return (1/p.mag())*p;
267 }                                                 273 }
268                                                   274 
269 //////////////////////////////////////////////    275 //////////////////////////////////////////////////////////////////////////
270 //                                                276 //
271 // Calculate distance to the surface of the or    277 // Calculate distance to the surface of the orb from outside
272 // - return kInfinity if no intersection or       278 // - return kInfinity if no intersection or
273 //   intersection distance <= tolerance           279 //   intersection distance <= tolerance
274                                                   280 
275 G4double G4Orb::DistanceToIn( const G4ThreeVec    281 G4double G4Orb::DistanceToIn( const G4ThreeVector& p,
276                               const G4ThreeVec    282                               const G4ThreeVector& v  ) const
277 {                                                 283 {
278   // Check if point is on the surface and trav    284   // Check if point is on the surface and traveling away
279   //                                              285   //
280   G4double rr = p.mag2();                         286   G4double rr = p.mag2();
281   G4double pv = p.dot(v);                         287   G4double pv = p.dot(v);
282   if (rr >= sqrRmaxMinusTol && pv >= 0) return    288   if (rr >= sqrRmaxMinusTol && pv >= 0) return kInfinity;
283                                                   289 
284   // Find intersection                            290   // Find intersection
285   //                                              291   //
286   //    Sphere eqn: x^2 + y^2 + z^2 = R^2         292   //    Sphere eqn: x^2 + y^2 + z^2 = R^2
287   //                                              293   //
288   //    => (px + t*vx)^2 + (py + t*vy)^2 + (pz    294   //    => (px + t*vx)^2 + (py + t*vy)^2 + (pz + t*vz)^2 = R^2
289   //    => r^2 + 2t(p.v) + t^2 = R^2              295   //    => r^2 + 2t(p.v) + t^2 = R^2
290   //    => tmin = -(p.v) - Sqrt((p.v)^2 - (r^2    296   //    => tmin = -(p.v) - Sqrt((p.v)^2 - (r^2 - R^2))
291   //                                              297   //
292   G4double D  = pv*pv - rr + fRmax*fRmax;         298   G4double D  = pv*pv - rr + fRmax*fRmax;
293   if (D < 0) return kInfinity; // no intersect    299   if (D < 0) return kInfinity; // no intersection
294                                                   300 
295   G4double sqrtD = std::sqrt(D);                  301   G4double sqrtD = std::sqrt(D);
296   G4double dist = -pv - sqrtD;                    302   G4double dist = -pv - sqrtD;
297                                                   303 
298   // Avoid rounding errors due to precision is    304   // Avoid rounding errors due to precision issues seen on 64 bits systems.
299   // Split long distances and recompute           305   // Split long distances and recompute
300   //                                              306   //
301   G4double Dmax = 32*fRmax;                       307   G4double Dmax = 32*fRmax; 
302   if (dist > Dmax)                                308   if (dist > Dmax)
303   {                                               309   {
304     dist  = dist - 1.e-8*dist - fRmax; // to s    310     dist  = dist - 1.e-8*dist - fRmax; // to stay outside after the move
305     dist += DistanceToIn(p + dist*v, v);          311     dist += DistanceToIn(p + dist*v, v);
306     return (dist >= kInfinity) ? kInfinity : d    312     return (dist >= kInfinity) ? kInfinity : dist;
307   }                                               313   }
308                                                   314 
309   if (sqrtD*2 <= halfRmaxTol) return kInfinity    315   if (sqrtD*2 <= halfRmaxTol) return kInfinity; // touch
310   return (dist < halfRmaxTol) ? 0. : dist;        316   return (dist < halfRmaxTol) ? 0. : dist;
311 }                                                 317 }
312                                                   318 
313 //////////////////////////////////////////////    319 //////////////////////////////////////////////////////////////////////////
314 //                                                320 //
315 // Calculate shortest distance to the boundary    321 // Calculate shortest distance to the boundary from outside
316 // - Return 0 if point is inside                  322 // - Return 0 if point is inside
317                                                   323 
318 G4double G4Orb::DistanceToIn( const G4ThreeVec    324 G4double G4Orb::DistanceToIn( const G4ThreeVector& p ) const
319 {                                                 325 {
320   G4double dist = p.mag() - fRmax;                326   G4double dist = p.mag() - fRmax;
321   return (dist > 0) ? dist : 0.;                  327   return (dist > 0) ? dist : 0.;
322 }                                                 328 }
323                                                   329 
324 //////////////////////////////////////////////    330 //////////////////////////////////////////////////////////////////////////
325 //                                                331 //
326 // Calculate distance to the surface of the or    332 // Calculate distance to the surface of the orb from inside and
327 // find normal at exit point, if required         333 // find normal at exit point, if required
328 // - when leaving the surface, return 0           334 // - when leaving the surface, return 0
329                                                   335 
330 G4double G4Orb::DistanceToOut( const G4ThreeVe    336 G4double G4Orb::DistanceToOut( const G4ThreeVector& p,
331                                const G4ThreeVe    337                                const G4ThreeVector& v,
332                                const G4bool ca    338                                const G4bool calcNorm,
333                                      G4bool* v    339                                      G4bool* validNorm,
334                                      G4ThreeVe    340                                      G4ThreeVector* n ) const
335 {                                                 341 {
336   // Check if point is on the surface and trav    342   // Check if point is on the surface and traveling away
337   //                                              343   //
338   G4double rr = p.mag2();                         344   G4double rr = p.mag2();
339   G4double pv = p.dot(v);                         345   G4double pv = p.dot(v);
340   if (rr >= sqrRmaxMinusTol && pv > 0)            346   if (rr >= sqrRmaxMinusTol && pv > 0)
341   {                                               347   {
342     if (calcNorm)                                 348     if (calcNorm)
343     {                                             349     {
344       *validNorm = true;                          350       *validNorm = true;
345       *n = p*(1./std::sqrt(rr));                  351       *n = p*(1./std::sqrt(rr));
346     }                                             352     }
347     return 0.;                                    353     return 0.;
348   }                                               354   }
349                                                   355 
350   // Find intersection                            356   // Find intersection
351   //                                              357   //
352   //    Sphere eqn: x^2 + y^2 + z^2 = R^2         358   //    Sphere eqn: x^2 + y^2 + z^2 = R^2
353   //                                              359   //
354   //    => (px + t*vx)^2 + (py + t*vy)^2 + (pz    360   //    => (px + t*vx)^2 + (py + t*vy)^2 + (pz + t*vz)^2 = R^2
355   //    => r^2 + 2t(p.v) + t^2 = R^2              361   //    => r^2 + 2t(p.v) + t^2 = R^2
356   //    => tmax = -(p.v) + Sqrt((p.v)^2 - (r^2    362   //    => tmax = -(p.v) + Sqrt((p.v)^2 - (r^2 - R^2))
357   //                                              363   //
358   G4double D  = pv*pv - rr + fRmax*fRmax;         364   G4double D  = pv*pv - rr + fRmax*fRmax;
359   G4double tmax = (D <= 0) ? 0. : std::sqrt(D)    365   G4double tmax = (D <= 0) ? 0. : std::sqrt(D) - pv;
360   if (tmax < halfRmaxTol) tmax = 0.;              366   if (tmax < halfRmaxTol) tmax = 0.;
361   if (calcNorm)                                   367   if (calcNorm)
362   {                                               368   {
363     *validNorm = true;                            369     *validNorm = true;
364     G4ThreeVector ptmax = p + tmax*v;             370     G4ThreeVector ptmax = p + tmax*v;
365     *n = ptmax*(1./ptmax.mag());                  371     *n = ptmax*(1./ptmax.mag());
366   }                                               372   }
367   return tmax;                                    373   return tmax;
368 }                                                 374 }
369                                                   375 
370 //////////////////////////////////////////////    376 //////////////////////////////////////////////////////////////////////////
371 //                                                377 //
372 // Calculate distance (<=actual) to closest su    378 // Calculate distance (<=actual) to closest surface of shape from inside
373                                                   379 
374 G4double G4Orb::DistanceToOut( const G4ThreeVe    380 G4double G4Orb::DistanceToOut( const G4ThreeVector& p ) const
375 {                                                 381 {
376 #ifdef G4CSGDEBUG                                 382 #ifdef G4CSGDEBUG
377   if( Inside(p) == kOutside )                     383   if( Inside(p) == kOutside )
378   {                                               384   {
379     std::ostringstream message;                   385     std::ostringstream message;
380     G4int oldprc = message.precision(16);         386     G4int oldprc = message.precision(16);
381     message << "Point p is outside (!?) of sol    387     message << "Point p is outside (!?) of solid: " << GetName() << "\n";
382     message << "Position:\n";                     388     message << "Position:\n";
383     message << "   p.x() = " << p.x()/mm << "     389     message << "   p.x() = " << p.x()/mm << " mm\n";
384     message << "   p.y() = " << p.y()/mm << "     390     message << "   p.y() = " << p.y()/mm << " mm\n";
385     message << "   p.z() = " << p.z()/mm << "     391     message << "   p.z() = " << p.z()/mm << " mm";
386     G4cout.precision(oldprc);                     392     G4cout.precision(oldprc);
387     G4Exception("G4Trap::DistanceToOut(p)", "G    393     G4Exception("G4Trap::DistanceToOut(p)", "GeomSolids1002",
388                 JustWarning, message );           394                 JustWarning, message );
389     DumpInfo();                                   395     DumpInfo();
390   }                                               396   }
391 #endif                                            397 #endif
392   G4double dist = fRmax - p.mag();                398   G4double dist = fRmax - p.mag();
393   return (dist > 0) ? dist : 0.;                  399   return (dist > 0) ? dist : 0.;
394 }                                                 400 }
395                                                   401 
396 //////////////////////////////////////////////    402 //////////////////////////////////////////////////////////////////////////
397 //                                                403 //
398 // G4EntityType                                   404 // G4EntityType
399                                                   405 
400 G4GeometryType G4Orb::GetEntityType() const       406 G4GeometryType G4Orb::GetEntityType() const
401 {                                                 407 {
402   return {"G4Orb"};                            << 408   return G4String("G4Orb");
403 }                                                 409 }
404                                                   410 
405 //////////////////////////////////////////////    411 //////////////////////////////////////////////////////////////////////////
406 //                                                412 //
407 // Make a clone of the object                     413 // Make a clone of the object
408                                                   414 
409 G4VSolid* G4Orb::Clone() const                    415 G4VSolid* G4Orb::Clone() const
410 {                                                 416 {
411   return new G4Orb(*this);                        417   return new G4Orb(*this);
412 }                                                 418 }
413                                                   419 
414 //////////////////////////////////////////////    420 //////////////////////////////////////////////////////////////////////////
415 //                                                421 //
416 // Stream object contents to an output stream     422 // Stream object contents to an output stream
417                                                   423 
418 std::ostream& G4Orb::StreamInfo( std::ostream&    424 std::ostream& G4Orb::StreamInfo( std::ostream& os ) const
419 {                                                 425 {
420   G4long oldprc = os.precision(16);            << 426   G4int oldprc = os.precision(16);
421   os << "-------------------------------------    427   os << "-----------------------------------------------------------\n"
422      << "    *** Dump for solid - " << GetName    428      << "    *** Dump for solid - " << GetName() << " ***\n"
423      << "    =================================    429      << "    ===================================================\n"
424      << " Solid type: G4Orb\n"                    430      << " Solid type: G4Orb\n"
425      << " Parameters: \n"                         431      << " Parameters: \n"
426      << "    outer radius: " << fRmax/mm << "     432      << "    outer radius: " << fRmax/mm << " mm \n"
427      << "-------------------------------------    433      << "-----------------------------------------------------------\n";
428   os.precision(oldprc);                           434   os.precision(oldprc);
429   return os;                                      435   return os;
430 }                                                 436 }
431                                                   437 
432 //////////////////////////////////////////////    438 //////////////////////////////////////////////////////////////////////////
433 //                                                439 //
434 // GetPointOnSurface                              440 // GetPointOnSurface
435                                                   441 
436 G4ThreeVector G4Orb::GetPointOnSurface() const    442 G4ThreeVector G4Orb::GetPointOnSurface() const
437 {                                                 443 {
438   return fRmax * G4RandomDirection();             444   return fRmax * G4RandomDirection();
439 }                                                 445 }
440                                                   446 
441 //////////////////////////////////////////////    447 //////////////////////////////////////////////////////////////////////////
442 //                                                448 //
443 // Methods for visualisation                      449 // Methods for visualisation
444                                                   450 
445 void G4Orb::DescribeYourselfTo ( G4VGraphicsSc    451 void G4Orb::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
446 {                                                 452 {
447   scene.AddSolid (*this);                         453   scene.AddSolid (*this);
448 }                                                 454 }
449                                                   455 
450 G4VisExtent G4Orb::GetExtent() const              456 G4VisExtent G4Orb::GetExtent() const
451 {                                                 457 {
452   return {-fRmax, fRmax, -fRmax, fRmax, -fRmax << 458   return G4VisExtent (-fRmax, fRmax, -fRmax, fRmax, -fRmax, fRmax);
453 }                                                 459 }
454                                                   460 
455 G4Polyhedron* G4Orb::CreatePolyhedron () const    461 G4Polyhedron* G4Orb::CreatePolyhedron () const
456 {                                                 462 {
457   return new G4PolyhedronSphere (0., fRmax, 0.    463   return new G4PolyhedronSphere (0., fRmax, 0., 2*pi, 0., pi);
458 }                                                 464 }
459                                                   465 
460 #endif                                            466 #endif
461                                                   467