Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/CSG/src/G4Box.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/G4Box.cc (Version 11.3.0) and /geometry/solids/CSG/src/G4Box.cc (Version 10.6.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // Implementation for G4Box class                  26 // Implementation for G4Box class
 27 //                                                 27 //
 28 //  30.06.95 - P.Kent: First version               28 //  30.06.95 - P.Kent: First version
 29 //  20.09.98 - V.Grichine: new algorithm of Di     29 //  20.09.98 - V.Grichine: new algorithm of DistanceToIn(p,v)
 30 //  18.04.17 - E.Tcherniaev: complete revision     30 //  18.04.17 - E.Tcherniaev: complete revision, speed-up
 31 // -------------------------------------------     31 // --------------------------------------------------------------------
 32                                                    32 
 33 #include "G4Box.hh"                                33 #include "G4Box.hh"
 34                                                    34 
 35 #if !defined(G4GEOM_USE_UBOX)                      35 #if !defined(G4GEOM_USE_UBOX)
 36                                                    36 
 37 #include "G4SystemOfUnits.hh"                      37 #include "G4SystemOfUnits.hh"
 38 #include "G4VoxelLimits.hh"                        38 #include "G4VoxelLimits.hh"
 39 #include "G4AffineTransform.hh"                    39 #include "G4AffineTransform.hh"
 40 #include "G4BoundingEnvelope.hh"                   40 #include "G4BoundingEnvelope.hh"
 41 #include "G4QuickRand.hh"                      <<  41 #include "Randomize.hh"
 42                                                    42 
 43 #include "G4VPVParameterisation.hh"                43 #include "G4VPVParameterisation.hh"
 44                                                    44 
 45 #include "G4VGraphicsScene.hh"                     45 #include "G4VGraphicsScene.hh"
 46 #include "G4VisExtent.hh"                          46 #include "G4VisExtent.hh"
 47                                                    47 
 48 //////////////////////////////////////////////     48 ////////////////////////////////////////////////////////////////////////
 49 //                                                 49 //
 50 // Constructor - check & set half widths           50 // Constructor - check & set half widths
 51                                                    51 
 52 G4Box::G4Box(const G4String& pName,                52 G4Box::G4Box(const G4String& pName,
 53                    G4double pX,                    53                    G4double pX,
 54                    G4double pY,                    54                    G4double pY,
 55                    G4double pZ)                    55                    G4double pZ)
 56   : G4CSGSolid(pName), fDx(pX), fDy(pY), fDz(p     56   : G4CSGSolid(pName), fDx(pX), fDy(pY), fDz(pZ)
 57 {                                                  57 {
 58   delta = 0.5*kCarTolerance;                       58   delta = 0.5*kCarTolerance;
 59   if (pX < 2*kCarTolerance ||                      59   if (pX < 2*kCarTolerance ||
 60       pY < 2*kCarTolerance ||                      60       pY < 2*kCarTolerance ||
 61       pZ < 2*kCarTolerance)  // limit to thick     61       pZ < 2*kCarTolerance)  // limit to thickness of surfaces
 62   {                                                62   {
 63     std::ostringstream message;                    63     std::ostringstream message;
 64     message << "Dimensions too small for Solid     64     message << "Dimensions too small for Solid: " << GetName() << "!" << G4endl
 65             << "     hX, hY, hZ = " << pX << "     65             << "     hX, hY, hZ = " << pX << ", " << pY << ", " << pZ;
 66     G4Exception("G4Box::G4Box()", "GeomSolids0     66     G4Exception("G4Box::G4Box()", "GeomSolids0002", FatalException, message);
 67   }                                                67   }
 68 }                                                  68 }
 69                                                    69 
 70 //////////////////////////////////////////////     70 //////////////////////////////////////////////////////////////////////////
 71 //                                                 71 //
 72 // Fake default constructor - sets only member     72 // Fake default constructor - sets only member data and allocates memory
 73 //                            for usage restri     73 //                            for usage restricted to object persistency
 74                                                    74 
 75 G4Box::G4Box( __void__& a )                        75 G4Box::G4Box( __void__& a )
 76   : G4CSGSolid(a)                              <<  76   : G4CSGSolid(a), delta(0.)
 77 {                                                  77 {
 78 }                                                  78 }
 79                                                    79 
 80 //////////////////////////////////////////////     80 //////////////////////////////////////////////////////////////////////////
 81 //                                                 81 //
 82 // Destructor                                      82 // Destructor
 83                                                    83 
 84 G4Box::~G4Box() = default;                     <<  84 G4Box::~G4Box()
                                                   >>  85 {
                                                   >>  86 }
 85                                                    87 
 86 //////////////////////////////////////////////     88 //////////////////////////////////////////////////////////////////////////
 87 //                                                 89 //
 88 // Copy constructor                                90 // Copy constructor
 89                                                    91 
 90 G4Box::G4Box(const G4Box&) = default;          <<  92 G4Box::G4Box(const G4Box& rhs)
                                                   >>  93   : G4CSGSolid(rhs), fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz), delta(rhs.delta)
                                                   >>  94 {
                                                   >>  95 }
 91                                                    96 
 92 //////////////////////////////////////////////     97 //////////////////////////////////////////////////////////////////////////
 93 //                                                 98 //
 94 // Assignment operator                             99 // Assignment operator
 95                                                   100 
 96 G4Box& G4Box::operator = (const G4Box& rhs)       101 G4Box& G4Box::operator = (const G4Box& rhs)
 97 {                                                 102 {
 98    // Check assignment to self                    103    // Check assignment to self
 99    //                                             104    //
100    if (this == &rhs)  { return *this; }           105    if (this == &rhs)  { return *this; }
101                                                   106 
102    // Copy base class data                        107    // Copy base class data
103    //                                             108    //
104    G4CSGSolid::operator=(rhs);                    109    G4CSGSolid::operator=(rhs);
105                                                   110 
106    // Copy data                                   111    // Copy data
107    //                                             112    //
108    fDx = rhs.fDx;                                 113    fDx = rhs.fDx;
109    fDy = rhs.fDy;                                 114    fDy = rhs.fDy;
110    fDz = rhs.fDz;                                 115    fDz = rhs.fDz;
111    delta = rhs.delta;                             116    delta = rhs.delta;
112                                                   117 
113    return *this;                                  118    return *this;
114 }                                                 119 }
115                                                   120 
116 //////////////////////////////////////////////    121 //////////////////////////////////////////////////////////////////////////
117 //                                                122 //
118 //  Set X dimension                               123 //  Set X dimension
119                                                   124 
120 void G4Box::SetXHalfLength(G4double dx)           125 void G4Box::SetXHalfLength(G4double dx)
121 {                                                 126 {
122   if(dx > 2*kCarTolerance)  // limit to thickn    127   if(dx > 2*kCarTolerance)  // limit to thickness of surfaces
123   {                                               128   {
124     fDx = dx;                                     129     fDx = dx;
125   }                                               130   }
126   else                                            131   else
127   {                                               132   {
128     std::ostringstream message;                   133     std::ostringstream message;
129     message << "Dimension X too small for soli    134     message << "Dimension X too small for solid: " << GetName() << "!"
130             << G4endl                             135             << G4endl
131             << "       hX = " << dx;              136             << "       hX = " << dx;
132     G4Exception("G4Box::SetXHalfLength()", "Ge    137     G4Exception("G4Box::SetXHalfLength()", "GeomSolids0002",
133                 FatalException, message);         138                 FatalException, message);
134   }                                               139   }
135   fCubicVolume = 0.;                              140   fCubicVolume = 0.;
136   fSurfaceArea = 0.;                              141   fSurfaceArea = 0.;
137   fRebuildPolyhedron = true;                      142   fRebuildPolyhedron = true;
138 }                                              << 143 } 
139                                                   144 
140 //////////////////////////////////////////////    145 //////////////////////////////////////////////////////////////////////////
141 //                                                146 //
142 //  Set Y dimension                               147 //  Set Y dimension
143                                                   148 
144 void G4Box::SetYHalfLength(G4double dy)        << 149 void G4Box::SetYHalfLength(G4double dy) 
145 {                                                 150 {
146   if(dy > 2*kCarTolerance)  // limit to thickn    151   if(dy > 2*kCarTolerance)  // limit to thickness of surfaces
147   {                                               152   {
148     fDy = dy;                                     153     fDy = dy;
149   }                                               154   }
150   else                                            155   else
151   {                                               156   {
152     std::ostringstream message;                   157     std::ostringstream message;
153     message << "Dimension Y too small for soli    158     message << "Dimension Y too small for solid: " << GetName() << "!\n"
154             << "       hY = " << dy;              159             << "       hY = " << dy;
155     G4Exception("G4Box::SetYHalfLength()", "Ge    160     G4Exception("G4Box::SetYHalfLength()", "GeomSolids0002",
156                 FatalException, message);         161                 FatalException, message);
157   }                                               162   }
158   fCubicVolume = 0.;                              163   fCubicVolume = 0.;
159   fSurfaceArea = 0.;                              164   fSurfaceArea = 0.;
160   fRebuildPolyhedron = true;                      165   fRebuildPolyhedron = true;
161 }                                              << 166 } 
162                                                   167 
163 //////////////////////////////////////////////    168 //////////////////////////////////////////////////////////////////////////
164 //                                                169 //
165 //  Set Z dimension                               170 //  Set Z dimension
166                                                   171 
167 void G4Box::SetZHalfLength(G4double dz)           172 void G4Box::SetZHalfLength(G4double dz)
168 {                                                 173 {
169   if(dz > 2*kCarTolerance)  // limit to thickn    174   if(dz > 2*kCarTolerance)  // limit to thickness of surfaces
170   {                                               175   {
171     fDz = dz;                                     176     fDz = dz;
172   }                                               177   }
173   else                                            178   else
174   {                                               179   {
175     std::ostringstream message;                   180     std::ostringstream message;
176     message << "Dimension Z too small for soli    181     message << "Dimension Z too small for solid: " << GetName() << "!\n"
177             << "       hZ = " << dz;              182             << "       hZ = " << dz;
178     G4Exception("G4Box::SetZHalfLength()", "Ge    183     G4Exception("G4Box::SetZHalfLength()", "GeomSolids0002",
179                 FatalException, message);         184                 FatalException, message);
180   }                                               185   }
181   fCubicVolume = 0.;                              186   fCubicVolume = 0.;
182   fSurfaceArea = 0.;                              187   fSurfaceArea = 0.;
183   fRebuildPolyhedron = true;                      188   fRebuildPolyhedron = true;
184 }                                              << 189 } 
185                                                   190 
186 //////////////////////////////////////////////    191 //////////////////////////////////////////////////////////////////////////
187 //                                                192 //
188 // Dispatch to parameterisation for replicatio    193 // Dispatch to parameterisation for replication mechanism dimension
189 // computation & modification.                    194 // computation & modification.
190                                                   195 
191 void G4Box::ComputeDimensions(G4VPVParameteris    196 void G4Box::ComputeDimensions(G4VPVParameterisation* p,
192                               const G4int n,      197                               const G4int n,
193                               const G4VPhysica    198                               const G4VPhysicalVolume* pRep)
194 {                                                 199 {
195   p->ComputeDimensions(*this,n,pRep);             200   p->ComputeDimensions(*this,n,pRep);
196 }                                                 201 }
197                                                   202 
198 //////////////////////////////////////////////    203 //////////////////////////////////////////////////////////////////////////
199 //                                                204 //
200 // Get bounding box                               205 // Get bounding box
201                                                   206 
202 void G4Box::BoundingLimits(G4ThreeVector& pMin    207 void G4Box::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
203 {                                                 208 {
204   pMin.set(-fDx,-fDy,-fDz);                       209   pMin.set(-fDx,-fDy,-fDz);
205   pMax.set( fDx, fDy, fDz);                       210   pMax.set( fDx, fDy, fDz);
206                                                   211 
207   // Check correctness of the bounding box        212   // Check correctness of the bounding box
208   //                                              213   //
209   if (pMin.x() >= pMax.x() || pMin.y() >= pMax    214   if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
210   {                                               215   {
211     std::ostringstream message;                   216     std::ostringstream message;
212     message << "Bad bounding box (min >= max)     217     message << "Bad bounding box (min >= max) for solid: "
213             << GetName() << " !"                  218             << GetName() << " !"
214             << "\npMin = " << pMin                219             << "\npMin = " << pMin
215             << "\npMax = " << pMax;               220             << "\npMax = " << pMax;
216     G4Exception("G4Box::BoundingLimits()", "Ge    221     G4Exception("G4Box::BoundingLimits()", "GeomMgt0001", JustWarning, message);
217     DumpInfo();                                   222     DumpInfo();
218   }                                               223   }
219 }                                                 224 }
220                                                   225 
221 //////////////////////////////////////////////    226 //////////////////////////////////////////////////////////////////////////
222 //                                                227 //
223 // Calculate extent under transform and specif    228 // Calculate extent under transform and specified limit
224                                                   229 
225 G4bool G4Box::CalculateExtent(const EAxis pAxi    230 G4bool G4Box::CalculateExtent(const EAxis pAxis,
226                               const G4VoxelLim    231                               const G4VoxelLimits& pVoxelLimit,
227                               const G4AffineTr    232                               const G4AffineTransform& pTransform,
228                                     G4double&     233                                     G4double& pMin, G4double& pMax) const
229 {                                                 234 {
230   G4ThreeVector bmin, bmax;                       235   G4ThreeVector bmin, bmax;
231                                                   236 
232   // Get bounding box                             237   // Get bounding box
233   BoundingLimits(bmin,bmax);                      238   BoundingLimits(bmin,bmax);
234                                                   239 
235   // Find extent                                  240   // Find extent
236   G4BoundingEnvelope bbox(bmin,bmax);             241   G4BoundingEnvelope bbox(bmin,bmax);
237   return bbox.CalculateExtent(pAxis,pVoxelLimi    242   return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
238 }                                                 243 }
239                                                   244 
240 //////////////////////////////////////////////    245 //////////////////////////////////////////////////////////////////////////
241 //                                                246 //
242 // Return whether point inside/outside/on surf    247 // Return whether point inside/outside/on surface, using tolerance
243                                                   248 
244 EInside G4Box::Inside(const G4ThreeVector& p)     249 EInside G4Box::Inside(const G4ThreeVector& p) const
245 {                                                 250 {
246   G4double dist = std::max(std::max(              251   G4double dist = std::max(std::max(
247                   std::abs(p.x())-fDx,            252                   std::abs(p.x())-fDx,
248                   std::abs(p.y())-fDy),           253                   std::abs(p.y())-fDy),
249                   std::abs(p.z())-fDz);           254                   std::abs(p.z())-fDz);
250   return (dist > delta) ? kOutside :           << 255   if (dist > delta) return kOutside;
251     ((dist > -delta) ? kSurface : kInside);    << 256   return (dist > -delta) ? kSurface : kInside;
252 }                                                 257 }
253                                                   258 
254 //////////////////////////////////////////////    259 //////////////////////////////////////////////////////////////////////////
255 //                                                260 //
256 // Detect the side(s) and return corresponding    261 // Detect the side(s) and return corresponding normal
257                                                   262 
258 G4ThreeVector G4Box::SurfaceNormal( const G4Th    263 G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
259 {                                                 264 {
260   G4ThreeVector norm(0,0,0);                      265   G4ThreeVector norm(0,0,0);
261   G4double px = p.x();                            266   G4double px = p.x();
262   if (std::abs(std::abs(px) - fDx) <= delta) n    267   if (std::abs(std::abs(px) - fDx) <= delta) norm.setX(px < 0 ? -1. : 1.);
263   G4double py = p.y();                            268   G4double py = p.y();
264   if (std::abs(std::abs(py) - fDy) <= delta) n    269   if (std::abs(std::abs(py) - fDy) <= delta) norm.setY(py < 0 ? -1. : 1.);
265   G4double pz = p.z();                            270   G4double pz = p.z();
266   if (std::abs(std::abs(pz) - fDz) <= delta) n    271   if (std::abs(std::abs(pz) - fDz) <= delta) norm.setZ(pz < 0 ? -1. : 1.);
267                                                   272 
268   G4double nside = norm.mag2(); // number of s    273   G4double nside = norm.mag2(); // number of sides = magnitude squared
269   if (nside == 1)                                 274   if (nside == 1)
270     return norm;                                  275     return norm;
271   else if (nside > 1)                             276   else if (nside > 1)
272     return norm.unit(); // edge or corner         277     return norm.unit(); // edge or corner
273   else                                            278   else
274   {                                               279   {
275     // Point is not on the surface                280     // Point is not on the surface
276     //                                         << 281     // 
277 #ifdef G4CSGDEBUG                                 282 #ifdef G4CSGDEBUG
278     std::ostringstream message;                   283     std::ostringstream message;
279     G4int oldprc = message.precision(16);         284     G4int oldprc = message.precision(16);
280     message << "Point p is not on surface (!?)    285     message << "Point p is not on surface (!?) of solid: "
281             << GetName() << G4endl;               286             << GetName() << G4endl;
282     message << "Position:\n";                     287     message << "Position:\n";
283     message << "   p.x() = " << p.x()/mm << "     288     message << "   p.x() = " << p.x()/mm << " mm\n";
284     message << "   p.y() = " << p.y()/mm << "     289     message << "   p.y() = " << p.y()/mm << " mm\n";
285     message << "   p.z() = " << p.z()/mm << "     290     message << "   p.z() = " << p.z()/mm << " mm";
286     G4cout.precision(oldprc);                     291     G4cout.precision(oldprc);
287     G4Exception("G4Box::SurfaceNormal(p)", "Ge    292     G4Exception("G4Box::SurfaceNormal(p)", "GeomSolids1002",
288                 JustWarning, message );           293                 JustWarning, message );
289     DumpInfo();                                   294     DumpInfo();
290 #endif                                            295 #endif
291     return ApproxSurfaceNormal(p);                296     return ApproxSurfaceNormal(p);
292   }                                               297   }
293 }                                                 298 }
294                                                   299 
295 //////////////////////////////////////////////    300 //////////////////////////////////////////////////////////////////////////
296 //                                                301 //
297 // Algorithm for SurfaceNormal() following the    302 // Algorithm for SurfaceNormal() following the original specification
298 // for points not on the surface                  303 // for points not on the surface
299                                                   304 
300 G4ThreeVector G4Box::ApproxSurfaceNormal(const    305 G4ThreeVector G4Box::ApproxSurfaceNormal(const G4ThreeVector& p) const
301 {                                                 306 {
302   G4double distx = std::abs(p.x()) - fDx;         307   G4double distx = std::abs(p.x()) - fDx;
303   G4double disty = std::abs(p.y()) - fDy;         308   G4double disty = std::abs(p.y()) - fDy;
304   G4double distz = std::abs(p.z()) - fDz;         309   G4double distz = std::abs(p.z()) - fDz;
305                                                   310 
306   if (distx >= disty && distx >= distz)           311   if (distx >= disty && distx >= distz)
307     return {std::copysign(1.,p.x()), 0., 0.};  << 312     return G4ThreeVector(std::copysign(1.,p.x()), 0., 0.);
308   if (disty >= distx && disty >= distz)           313   if (disty >= distx && disty >= distz)
309     return {0., std::copysign(1.,p.y()), 0.};  << 314     return G4ThreeVector(0., std::copysign(1.,p.y()), 0.);
310   else                                            315   else
311     return {0., 0., std::copysign(1.,p.z())};  << 316     return G4ThreeVector(0., 0., std::copysign(1.,p.z()));
312 }                                                 317 }
313                                                   318 
314 //////////////////////////////////////////////    319 //////////////////////////////////////////////////////////////////////////
315 //                                                320 //
316 // Calculate distance to box from an outside p    321 // Calculate distance to box from an outside point
317 // - return kInfinity if no intersection          322 // - return kInfinity if no intersection
318 //                                                323 //
319                                                   324 
320 G4double G4Box::DistanceToIn(const G4ThreeVect    325 G4double G4Box::DistanceToIn(const G4ThreeVector& p,
321                              const G4ThreeVect    326                              const G4ThreeVector& v) const
322 {                                                 327 {
323   // Check if point is on the surface and trav    328   // Check if point is on the surface and traveling away
324   //                                              329   //
325   if ((std::abs(p.x()) - fDx) >= -delta && p.x    330   if ((std::abs(p.x()) - fDx) >= -delta && p.x()*v.x() >= 0) return kInfinity;
326   if ((std::abs(p.y()) - fDy) >= -delta && p.y    331   if ((std::abs(p.y()) - fDy) >= -delta && p.y()*v.y() >= 0) return kInfinity;
327   if ((std::abs(p.z()) - fDz) >= -delta && p.z    332   if ((std::abs(p.z()) - fDz) >= -delta && p.z()*v.z() >= 0) return kInfinity;
328                                                   333 
329   // Find intersection                            334   // Find intersection
330   //                                              335   //
331   G4double invx = (v.x() == 0) ? DBL_MAX : -1.    336   G4double invx = (v.x() == 0) ? DBL_MAX : -1./v.x();
332   G4double dx = std::copysign(fDx,invx);          337   G4double dx = std::copysign(fDx,invx);
333   G4double txmin = (p.x() - dx)*invx;             338   G4double txmin = (p.x() - dx)*invx;
334   G4double txmax = (p.x() + dx)*invx;             339   G4double txmax = (p.x() + dx)*invx;
335                                                   340 
336   G4double invy = (v.y() == 0) ? DBL_MAX : -1.    341   G4double invy = (v.y() == 0) ? DBL_MAX : -1./v.y();
337   G4double dy = std::copysign(fDy,invy);          342   G4double dy = std::copysign(fDy,invy);
338   G4double tymin = std::max(txmin,(p.y() - dy)    343   G4double tymin = std::max(txmin,(p.y() - dy)*invy);
339   G4double tymax = std::min(txmax,(p.y() + dy)    344   G4double tymax = std::min(txmax,(p.y() + dy)*invy);
340                                                   345 
341   G4double invz = (v.z() == 0) ? DBL_MAX : -1.    346   G4double invz = (v.z() == 0) ? DBL_MAX : -1./v.z();
342   G4double dz = std::copysign(fDz,invz);          347   G4double dz = std::copysign(fDz,invz);
343   G4double tmin = std::max(tymin,(p.z() - dz)*    348   G4double tmin = std::max(tymin,(p.z() - dz)*invz);
344   G4double tmax = std::min(tymax,(p.z() + dz)*    349   G4double tmax = std::min(tymax,(p.z() + dz)*invz);
345                                                   350 
346   if (tmax <= tmin + delta) return kInfinity;     351   if (tmax <= tmin + delta) return kInfinity; // touch or no hit
347   return (tmin < delta) ? 0. : tmin;              352   return (tmin < delta) ? 0. : tmin;
348 }                                                 353 }
349                                                   354 
350 //////////////////////////////////////////////    355 //////////////////////////////////////////////////////////////////////////
351 //                                             << 356 // 
352 // Appoximate distance to box.                    357 // Appoximate distance to box.
353 // Returns largest perpendicular distance to t    358 // Returns largest perpendicular distance to the closest x/y/z sides of
354 // the box, which is the most fast estimation     359 // the box, which is the most fast estimation of the shortest distance to box
355 // - If inside return 0                           360 // - If inside return 0
356                                                   361 
357 G4double G4Box::DistanceToIn(const G4ThreeVect    362 G4double G4Box::DistanceToIn(const G4ThreeVector& p) const
358 {                                                 363 {
359   G4double dist = std::max(std::max(           << 364   G4double dist = std::max(std::max(std::abs(p.x())-fDx,
360                   std::abs(p.x())-fDx,         << 365                                     std::abs(p.y())-fDy),
361                   std::abs(p.y())-fDy),        << 366                            std::abs(p.z())-fDz);
362                   std::abs(p.z())-fDz);        << 
363   return (dist > 0) ? dist : 0.;                  367   return (dist > 0) ? dist : 0.;
364 }                                                 368 }
365                                                   369 
366 //////////////////////////////////////////////    370 //////////////////////////////////////////////////////////////////////////
367 //                                                371 //
368 // Calculate distance to surface of the box fr    372 // Calculate distance to surface of the box from inside and
369 // find normal at exit point, if required         373 // find normal at exit point, if required
370 // - when leaving the surface, return 0           374 // - when leaving the surface, return 0
371                                                   375 
372 G4double G4Box::DistanceToOut( const G4ThreeVe    376 G4double G4Box::DistanceToOut( const G4ThreeVector& p,
373                                const G4ThreeVe    377                                const G4ThreeVector& v,
374                                const G4bool ca    378                                const G4bool calcNorm,
375                                G4bool* validNo    379                                G4bool* validNorm, G4ThreeVector* n) const
376 {                                                 380 {
377   // Check if point is on the surface and trav    381   // Check if point is on the surface and traveling away
378   //                                              382   //
379   if ((std::abs(p.x()) - fDx) >= -delta && p.x    383   if ((std::abs(p.x()) - fDx) >= -delta && p.x()*v.x() > 0)
380   {                                               384   {
381     if (calcNorm)                                 385     if (calcNorm)
382     {                                             386     {
383       *validNorm = true;                          387       *validNorm = true;
384       n->set((p.x() < 0) ? -1. : 1., 0., 0.);     388       n->set((p.x() < 0) ? -1. : 1., 0., 0.);
385     }                                             389     }
386     return 0.;                                    390     return 0.;
387   }                                               391   }
388   if ((std::abs(p.y()) - fDy) >= -delta && p.y    392   if ((std::abs(p.y()) - fDy) >= -delta && p.y()*v.y() > 0)
389   {                                               393   {
390     if (calcNorm)                                 394     if (calcNorm)
391     {                                             395     {
392       *validNorm = true;                          396       *validNorm = true;
393       n->set(0., (p.y() < 0) ? -1. : 1., 0.);     397       n->set(0., (p.y() < 0) ? -1. : 1., 0.);
394     }                                             398     }
395     return 0.;                                    399     return 0.;
396   }                                               400   }
397   if ((std::abs(p.z()) - fDz) >= -delta && p.z    401   if ((std::abs(p.z()) - fDz) >= -delta && p.z()*v.z() > 0)
398   {                                               402   {
399     if (calcNorm)                                 403     if (calcNorm)
400     {                                             404     {
401       *validNorm = true;                          405       *validNorm = true;
402       n->set(0., 0., (p.z() < 0) ? -1. : 1.);     406       n->set(0., 0., (p.z() < 0) ? -1. : 1.);
403     }                                             407     }
404     return 0.;                                    408     return 0.;
405   }                                               409   }
406                                                   410 
407   // Find intersection                            411   // Find intersection
408   //                                              412   //
409   G4double vx = v.x();                            413   G4double vx = v.x();
410   G4double tx = (vx == 0) ? DBL_MAX : (std::co    414   G4double tx = (vx == 0) ? DBL_MAX : (std::copysign(fDx,vx) - p.x())/vx;
411                                                   415 
412   G4double vy = v.y();                            416   G4double vy = v.y();
413   G4double ty = (vy == 0) ? tx : (std::copysig    417   G4double ty = (vy == 0) ? tx : (std::copysign(fDy,vy) - p.y())/vy;
414   G4double txy = std::min(tx,ty);                 418   G4double txy = std::min(tx,ty);
415                                                   419 
416   G4double vz = v.z();                            420   G4double vz = v.z();
417   G4double tz = (vz == 0) ? txy : (std::copysi    421   G4double tz = (vz == 0) ? txy : (std::copysign(fDz,vz) - p.z())/vz;
418   G4double tmax = std::min(txy,tz);               422   G4double tmax = std::min(txy,tz);
419                                                   423 
420   // Set normal, if required, and return dista    424   // Set normal, if required, and return distance
421   //                                              425   //
422   if (calcNorm)                                   426   if (calcNorm)
423   {                                               427   {
424     *validNorm = true;                            428     *validNorm = true;
425     if (tmax == tx)      n->set((v.x() < 0) ?     429     if (tmax == tx)      n->set((v.x() < 0) ? -1. : 1., 0., 0.);
426     else if (tmax == ty) n->set(0., (v.y() < 0    430     else if (tmax == ty) n->set(0., (v.y() < 0) ? -1. : 1., 0.);
427     else                 n->set(0., 0., (v.z()    431     else                 n->set(0., 0., (v.z() < 0) ? -1. : 1.);
428   }                                               432   }
429   return tmax;                                    433   return tmax;
430 }                                                 434 }
431                                                   435 
432 //////////////////////////////////////////////    436 ////////////////////////////////////////////////////////////////////////////
433 //                                                437 //
434 // Calculate exact shortest distance to any bo    438 // Calculate exact shortest distance to any boundary from inside
435 // - if outside return 0                          439 // - if outside return 0
436                                                   440 
437 G4double G4Box::DistanceToOut(const G4ThreeVec    441 G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
438 {                                                 442 {
439 #ifdef G4CSGDEBUG                                 443 #ifdef G4CSGDEBUG
440   if( Inside(p) == kOutside )                     444   if( Inside(p) == kOutside )
441   {                                               445   {
442     std::ostringstream message;                   446     std::ostringstream message;
443     G4int oldprc = message.precision(16);         447     G4int oldprc = message.precision(16);
444     message << "Point p is outside (!?) of sol    448     message << "Point p is outside (!?) of solid: " << GetName() << G4endl;
445     message << "Position:\n";                     449     message << "Position:\n";
446     message << "   p.x() = " << p.x()/mm << "     450     message << "   p.x() = " << p.x()/mm << " mm\n";
447     message << "   p.y() = " << p.y()/mm << "     451     message << "   p.y() = " << p.y()/mm << " mm\n";
448     message << "   p.z() = " << p.z()/mm << "     452     message << "   p.z() = " << p.z()/mm << " mm";
449     G4cout.precision(oldprc);                     453     G4cout.precision(oldprc);
450     G4Exception("G4Box::DistanceToOut(p)", "Ge    454     G4Exception("G4Box::DistanceToOut(p)", "GeomSolids1002",
451                 JustWarning, message );           455                 JustWarning, message );
452     DumpInfo();                                   456     DumpInfo();
453   }                                               457   }
454 #endif                                            458 #endif
455   G4double dist = std::min(std::min(           << 459   G4double dist = std::min(std::min(fDx-std::abs(p.x()),
456                   fDx-std::abs(p.x()),         << 460                                     fDy-std::abs(p.y())),
457                   fDy-std::abs(p.y())),        << 461                            fDz-std::abs(p.z()));
458                   fDz-std::abs(p.z()));        << 
459   return (dist > 0) ? dist : 0.;                  462   return (dist > 0) ? dist : 0.;
460 }                                                 463 }
461                                                   464 
462 //////////////////////////////////////////////    465 //////////////////////////////////////////////////////////////////////////
463 //                                                466 //
464 // GetEntityType                                  467 // GetEntityType
465                                                   468 
466 G4GeometryType G4Box::GetEntityType() const       469 G4GeometryType G4Box::GetEntityType() const
467 {                                                 470 {
468   return {"G4Box"};                            << 471   return G4String("G4Box");
469 }                                              << 
470                                                << 
471 ////////////////////////////////////////////// << 
472 //                                             << 
473 // IsFaceted                                   << 
474                                                << 
475 G4bool G4Box::IsFaceted() const                << 
476 {                                              << 
477   return true;                                 << 
478 }                                                 472 }
479                                                   473 
480 //////////////////////////////////////////////    474 //////////////////////////////////////////////////////////////////////////
481 //                                                475 //
482 // Stream object contents to an output stream     476 // Stream object contents to an output stream
483                                                   477 
484 std::ostream& G4Box::StreamInfo(std::ostream&     478 std::ostream& G4Box::StreamInfo(std::ostream& os) const
485 {                                                 479 {
486   G4long oldprc = os.precision(16);            << 480   G4int oldprc = os.precision(16);
487   os << "-------------------------------------    481   os << "-----------------------------------------------------------\n"
488      << "    *** Dump for solid - " << GetName    482      << "    *** Dump for solid - " << GetName() << " ***\n"
489      << "    =================================    483      << "    ===================================================\n"
490      << "Solid type: G4Box\n"                     484      << "Solid type: G4Box\n"
491      << "Parameters: \n"                          485      << "Parameters: \n"
492      << "   half length X: " << fDx/mm << " mm    486      << "   half length X: " << fDx/mm << " mm \n"
493      << "   half length Y: " << fDy/mm << " mm    487      << "   half length Y: " << fDy/mm << " mm \n"
494      << "   half length Z: " << fDz/mm << " mm    488      << "   half length Z: " << fDz/mm << " mm \n"
495      << "-------------------------------------    489      << "-----------------------------------------------------------\n";
496   os.precision(oldprc);                           490   os.precision(oldprc);
497   return os;                                      491   return os;
498 }                                                 492 }
499                                                   493 
500 //////////////////////////////////////////////    494 //////////////////////////////////////////////////////////////////////////
501 //                                                495 //
502 // Return a point randomly and uniformly selec << 496 // GetPointOnSurface
                                                   >> 497 //
                                                   >> 498 // Return a point (G4ThreeVector) randomly and uniformly selected
                                                   >> 499 // on the solid surface
503                                                   500 
504 G4ThreeVector G4Box::GetPointOnSurface() const    501 G4ThreeVector G4Box::GetPointOnSurface() const
505 {                                                 502 {
506   G4double sxy = fDx*fDy, sxz = fDx*fDz, syz =    503   G4double sxy = fDx*fDy, sxz = fDx*fDz, syz = fDy*fDz;
507   G4double select = (sxy + sxz + syz)*G4QuickR << 504   G4double select = (sxy + sxz + syz)*G4UniformRand();
508   G4double u = 2.*G4QuickRand() - 1.;          << 
509   G4double v = 2.*G4QuickRand() - 1.;          << 
510                                                   505 
511   if (select < sxy)                               506   if (select < sxy)
512     return { u*fDx, v*fDy, ((select < 0.5*sxy) << 507     return G4ThreeVector((2.*G4UniformRand() - 1.)*fDx,
513   else if (select < sxy + sxz)                 << 508                          (2.*G4UniformRand() - 1.)*fDy,
514     return { u*fDx, ((select < sxy + 0.5*sxz)  << 509                          (select < 0.5*sxy) ? -fDz : fDz);
                                                   >> 510 
                                                   >> 511   if (select < sxy + sxz)
                                                   >> 512     return G4ThreeVector((2.*G4UniformRand() - 1.)*fDx,
                                                   >> 513                          (select < sxy + 0.5*sxz) ? -fDy : fDy,
                                                   >> 514                          (2.*G4UniformRand() - 1.)*fDz);
515   else                                            515   else
516     return { ((select < sxy + sxz + 0.5*syz) ? << 516     return G4ThreeVector((select < sxy + sxz + 0.5*syz) ? -fDx : fDx,
                                                   >> 517                          (2.*G4UniformRand() - 1.)*fDy,
                                                   >> 518                          (2.*G4UniformRand() - 1.)*fDz);
517 }                                                 519 }
518                                                   520 
519 //////////////////////////////////////////////    521 //////////////////////////////////////////////////////////////////////////
520 //                                                522 //
521 // Make a clone of the object                     523 // Make a clone of the object
522 //                                                524 //
523 G4VSolid* G4Box::Clone() const                    525 G4VSolid* G4Box::Clone() const
524 {                                                 526 {
525   return new G4Box(*this);                        527   return new G4Box(*this);
526 }                                                 528 }
527                                                   529 
528 //////////////////////////////////////////////    530 //////////////////////////////////////////////////////////////////////////
529 //                                                531 //
530 // Methods for visualisation                      532 // Methods for visualisation
531                                                   533 
532 void G4Box::DescribeYourselfTo (G4VGraphicsSce    534 void G4Box::DescribeYourselfTo (G4VGraphicsScene& scene) const
533 {                                                 535 {
534   scene.AddSolid (*this);                         536   scene.AddSolid (*this);
535 }                                                 537 }
536                                                   538 
537 G4VisExtent G4Box::GetExtent() const              539 G4VisExtent G4Box::GetExtent() const
538 {                                                 540 {
539   return { -fDx, fDx, -fDy, fDy, -fDz, fDz };  << 541   return G4VisExtent (-fDx, fDx, -fDy, fDy, -fDz, fDz);
540 }                                                 542 }
541                                                   543 
542 G4Polyhedron* G4Box::CreatePolyhedron () const    544 G4Polyhedron* G4Box::CreatePolyhedron () const
543 {                                                 545 {
544   return new G4PolyhedronBox (fDx, fDy, fDz);     546   return new G4PolyhedronBox (fDx, fDy, fDz);
545 }                                                 547 }
546 #endif                                            548 #endif
547                                                   549