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 7.1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                    <<   3 // * DISCLAIMER                                                       *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th <<   5 // * The following disclaimer summarizes all the specific disclaimers *
  6 // * the Geant4 Collaboration.  It is provided <<   6 // * of contributors to this software. The specific disclaimers,which *
  7 // * conditions of the Geant4 Software License <<   7 // * govern, are listed with their locations in:                      *
  8 // * LICENSE and available at  http://cern.ch/ <<   8 // *   http://cern.ch/geant4/license                                  *
  9 // * include a list of copyright holders.      << 
 10 // *                                                9 // *                                                                  *
 11 // * Neither the authors of this software syst     10 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     11 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     12 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     13 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  <<  14 // * use.                                                             *
 16 // * for the full disclaimer and the limitatio << 
 17 // *                                               15 // *                                                                  *
 18 // * This  code  implementation is the result  <<  16 // * This  code  implementation is the  intellectual property  of the *
 19 // * technical work of the GEANT4 collaboratio <<  17 // * GEANT4 collaboration.                                            *
 20 // * By using,  copying,  modifying or  distri <<  18 // * By copying,  distributing  or modifying the Program (or any work *
 21 // * any work based  on the software)  you  ag <<  19 // * based  on  the Program)  you indicate  your  acceptance of  this *
 22 // * use  in  resulting  scientific  publicati <<  20 // * statement, and all its terms.                                    *
 23 // * acceptance of all terms of the Geant4 Sof << 
 24 // *******************************************     21 // ********************************************************************
 25 //                                                 22 //
                                                   >>  23 //
                                                   >>  24 // $Id: G4Box.cc,v 1.39 2005/06/08 16:14:25 gcosmo Exp $
                                                   >>  25 // GEANT4 tag $Name: geant4-07-01 $
                                                   >>  26 //
                                                   >>  27 // 
                                                   >>  28 //
 26 // Implementation for G4Box class                  29 // Implementation for G4Box class
 27 //                                                 30 //
 28 //  30.06.95 - P.Kent: First version           <<  31 //  24.06.98 - V. Grichine: insideEdge in DistanceToIn(p,v)
 29 //  20.09.98 - V.Grichine: new algorithm of Di     32 //  20.09.98 - V.Grichine: new algorithm of DistanceToIn(p,v)
 30 //  18.04.17 - E.Tcherniaev: complete revision <<  33 //  07.05.00 - V.Grichine: d= DistanceToIn(p,v), if d<e/2, d=0
                                                   >>  34 //  09.06.00 - V.Grichine: safety in DistanceToIn(p) against Inside(p)=kOutside
                                                   >>  35 //             and information before exception in DistanceToOut(p,v,...)
                                                   >>  36 //  15.11.00 - D.Williams, V.Grichine: bug fixed in CalculateExtent - change
                                                   >>  37 //                                     algorithm for rotated vertices
 31 // -------------------------------------------     38 // --------------------------------------------------------------------
 32                                                    39 
 33 #include "G4Box.hh"                                40 #include "G4Box.hh"
 34                                                    41 
 35 #if !defined(G4GEOM_USE_UBOX)                  << 
 36                                                << 
 37 #include "G4SystemOfUnits.hh"                  << 
 38 #include "G4VoxelLimits.hh"                        42 #include "G4VoxelLimits.hh"
 39 #include "G4AffineTransform.hh"                    43 #include "G4AffineTransform.hh"
 40 #include "G4BoundingEnvelope.hh"               <<  44 #include "Randomize.hh"
 41 #include "G4QuickRand.hh"                      << 
 42                                                    45 
 43 #include "G4VPVParameterisation.hh"                46 #include "G4VPVParameterisation.hh"
 44                                                    47 
 45 #include "G4VGraphicsScene.hh"                     48 #include "G4VGraphicsScene.hh"
                                                   >>  49 #include "G4Polyhedron.hh"
                                                   >>  50 #include "G4NURBS.hh"
                                                   >>  51 #include "G4NURBSbox.hh"
 46 #include "G4VisExtent.hh"                          52 #include "G4VisExtent.hh"
 47                                                    53 
 48 //////////////////////////////////////////////     54 ////////////////////////////////////////////////////////////////////////
 49 //                                                 55 //
 50 // Constructor - check & set half widths           56 // Constructor - check & set half widths
 51                                                    57 
 52 G4Box::G4Box(const G4String& pName,                58 G4Box::G4Box(const G4String& pName,
 53                    G4double pX,                    59                    G4double pX,
 54                    G4double pY,                    60                    G4double pY,
 55                    G4double pZ)                    61                    G4double pZ)
 56   : G4CSGSolid(pName), fDx(pX), fDy(pY), fDz(p <<  62   : G4CSGSolid(pName)
 57 {                                                  63 {
 58   delta = 0.5*kCarTolerance;                   <<  64   if ( (pX > 2*kCarTolerance)
 59   if (pX < 2*kCarTolerance ||                  <<  65     && (pY > 2*kCarTolerance)
 60       pY < 2*kCarTolerance ||                  <<  66     && (pZ > 2*kCarTolerance) )
 61       pZ < 2*kCarTolerance)  // limit to thick <<  67   {
 62   {                                            <<  68     fDx = pX ;
 63     std::ostringstream message;                <<  69     fDy = pY ; 
 64     message << "Dimensions too small for Solid <<  70     fDz = pZ ;
 65             << "     hX, hY, hZ = " << pX << " <<  71   }
 66     G4Exception("G4Box::G4Box()", "GeomSolids0 <<  72   else
                                                   >>  73   {
                                                   >>  74     G4cerr << "ERROR - G4Box()::G4Box(): " << GetName() << G4endl
                                                   >>  75            << "        Dimensions too small ! - "
                                                   >>  76            << pX << ", " << pY << ", " << pZ << G4endl;
                                                   >>  77     G4Exception("G4Box::G4Box()", "InvalidSetup",
                                                   >>  78                 FatalException, "Invalid dimensions. Too small.");
 67   }                                                79   }
 68 }                                              << 
 69                                                << 
 70 ////////////////////////////////////////////// << 
 71 //                                             << 
 72 // Fake default constructor - sets only member << 
 73 //                            for usage restri << 
 74                                                << 
 75 G4Box::G4Box( __void__& a )                    << 
 76   : G4CSGSolid(a)                              << 
 77 {                                              << 
 78 }                                                  80 }
 79                                                    81 
 80 //////////////////////////////////////////////     82 //////////////////////////////////////////////////////////////////////////
 81 //                                                 83 //
 82 // Destructor                                      84 // Destructor
 83                                                    85 
 84 G4Box::~G4Box() = default;                     <<  86 G4Box::~G4Box()
 85                                                << 
 86 ////////////////////////////////////////////// << 
 87 //                                             << 
 88 // Copy constructor                            << 
 89                                                << 
 90 G4Box::G4Box(const G4Box&) = default;          << 
 91                                                << 
 92 ////////////////////////////////////////////// << 
 93 //                                             << 
 94 // Assignment operator                         << 
 95                                                << 
 96 G4Box& G4Box::operator = (const G4Box& rhs)    << 
 97 {                                                  87 {
 98    // Check assignment to self                 << 
 99    //                                          << 
100    if (this == &rhs)  { return *this; }        << 
101                                                << 
102    // Copy base class data                     << 
103    //                                          << 
104    G4CSGSolid::operator=(rhs);                 << 
105                                                << 
106    // Copy data                                << 
107    //                                          << 
108    fDx = rhs.fDx;                              << 
109    fDy = rhs.fDy;                              << 
110    fDz = rhs.fDz;                              << 
111    delta = rhs.delta;                          << 
112                                                << 
113    return *this;                               << 
114 }                                                  88 }
115                                                    89 
116 ////////////////////////////////////////////// <<  90 //////////////////////////////////////////////////////////////////////////////
117 //                                             << 
118 //  Set X dimension                            << 
119                                                    91 
120 void G4Box::SetXHalfLength(G4double dx)            92 void G4Box::SetXHalfLength(G4double dx)
121 {                                                  93 {
122   if(dx > 2*kCarTolerance)  // limit to thickn <<  94   if(dx > 2*kCarTolerance)
123   {                                            << 
124     fDx = dx;                                      95     fDx = dx;
125   }                                            << 
126   else                                             96   else
127   {                                                97   {
128     std::ostringstream message;                <<  98     G4cerr << "ERROR - G4Box()::SetXHalfLength(): " << GetName() << G4endl
129     message << "Dimension X too small for soli <<  99            << "        Dimension X too small ! - "
130             << G4endl                          << 100            << dx << G4endl;
131             << "       hX = " << dx;           << 101     G4Exception("G4Box::SetXHalfLength()", "InvalidSetup",
132     G4Exception("G4Box::SetXHalfLength()", "Ge << 102                 FatalException, "Invalid dimensions. Too small.");
133                 FatalException, message);      << 103   }
134   }                                            << 104   fCubicVolume= 0.;
135   fCubicVolume = 0.;                           << 105   fpPolyhedron = 0;
136   fSurfaceArea = 0.;                           << 106 } 
137   fRebuildPolyhedron = true;                   << 
138 }                                              << 
139                                                   107 
140 ////////////////////////////////////////////// << 108 void G4Box::SetYHalfLength(G4double dy) 
141 //                                             << 
142 //  Set Y dimension                            << 
143                                                << 
144 void G4Box::SetYHalfLength(G4double dy)        << 
145 {                                                 109 {
146   if(dy > 2*kCarTolerance)  // limit to thickn << 110   if(dy > 2*kCarTolerance)
147   {                                            << 
148     fDy = dy;                                     111     fDy = dy;
149   }                                            << 
150   else                                            112   else
151   {                                               113   {
152     std::ostringstream message;                << 114     G4cerr << "ERROR - G4Box()::SetYHalfLength(): " << GetName() << G4endl
153     message << "Dimension Y too small for soli << 115            << "        Dimension Y too small ! - "
154             << "       hY = " << dy;           << 116            << dy << G4endl;
155     G4Exception("G4Box::SetYHalfLength()", "Ge << 117     G4Exception("G4Box::SetYHalfLength()", "InvalidSetup",
156                 FatalException, message);      << 118                 FatalException, "Invalid dimensions. Too small.");
157   }                                            << 119   }
158   fCubicVolume = 0.;                           << 120   fCubicVolume= 0.;
159   fSurfaceArea = 0.;                           << 121   fpPolyhedron = 0;
160   fRebuildPolyhedron = true;                   << 122 } 
161 }                                              << 
162                                                << 
163 ////////////////////////////////////////////// << 
164 //                                             << 
165 //  Set Z dimension                            << 
166                                                   123 
167 void G4Box::SetZHalfLength(G4double dz)        << 124 void G4Box::SetZHalfLength(G4double dz) 
168 {                                                 125 {
169   if(dz > 2*kCarTolerance)  // limit to thickn << 126   if(dz > 2*kCarTolerance)
170   {                                            << 
171     fDz = dz;                                     127     fDz = dz;
172   }                                            << 
173   else                                            128   else
174   {                                               129   {
175     std::ostringstream message;                << 130     G4cerr << "ERROR - G4Box()::SetZHalfLength(): " << GetName() << G4endl
176     message << "Dimension Z too small for soli << 131            << "        Dimension Z too small ! - "
177             << "       hZ = " << dz;           << 132            << dz << G4endl;
178     G4Exception("G4Box::SetZHalfLength()", "Ge << 133     G4Exception("G4Box::SetZHalfLength()", "InvalidSetup",
179                 FatalException, message);      << 134                 FatalException, "Invalid dimensions. Too small.");
180   }                                            << 135   }
181   fCubicVolume = 0.;                           << 136   fCubicVolume= 0.;
182   fSurfaceArea = 0.;                           << 137   fpPolyhedron = 0;
183   fRebuildPolyhedron = true;                   << 138 } 
184 }                                              << 139     
185                                                   140 
186 ////////////////////////////////////////////// << 141 
                                                   >> 142 ////////////////////////////////////////////////////////////////////////
187 //                                                143 //
188 // Dispatch to parameterisation for replicatio    144 // Dispatch to parameterisation for replication mechanism dimension
189 // computation & modification.                    145 // computation & modification.
190                                                   146 
191 void G4Box::ComputeDimensions(G4VPVParameteris    147 void G4Box::ComputeDimensions(G4VPVParameterisation* p,
192                               const G4int n,      148                               const G4int n,
193                               const G4VPhysica    149                               const G4VPhysicalVolume* pRep)
194 {                                                 150 {
195   p->ComputeDimensions(*this,n,pRep);             151   p->ComputeDimensions(*this,n,pRep);
196 }                                                 152 }
197                                                   153 
198 //////////////////////////////////////////////    154 //////////////////////////////////////////////////////////////////////////
199 //                                                155 //
200 // Get bounding box                            << 
201                                                << 
202 void G4Box::BoundingLimits(G4ThreeVector& pMin << 
203 {                                              << 
204   pMin.set(-fDx,-fDy,-fDz);                    << 
205   pMax.set( fDx, fDy, fDz);                    << 
206                                                << 
207   // Check correctness of the bounding box     << 
208   //                                           << 
209   if (pMin.x() >= pMax.x() || pMin.y() >= pMax << 
210   {                                            << 
211     std::ostringstream message;                << 
212     message << "Bad bounding box (min >= max)  << 
213             << GetName() << " !"               << 
214             << "\npMin = " << pMin             << 
215             << "\npMax = " << pMax;            << 
216     G4Exception("G4Box::BoundingLimits()", "Ge << 
217     DumpInfo();                                << 
218   }                                            << 
219 }                                              << 
220                                                << 
221 ////////////////////////////////////////////// << 
222 //                                             << 
223 // Calculate extent under transform and specif    156 // Calculate extent under transform and specified limit
224                                                   157 
225 G4bool G4Box::CalculateExtent(const EAxis pAxi    158 G4bool G4Box::CalculateExtent(const EAxis pAxis,
226                               const G4VoxelLim    159                               const G4VoxelLimits& pVoxelLimit,
227                               const G4AffineTr    160                               const G4AffineTransform& pTransform,
228                                     G4double&     161                                     G4double& pMin, G4double& pMax) const
229 {                                                 162 {
230   G4ThreeVector bmin, bmax;                    << 163   if (!pTransform.IsRotated())
                                                   >> 164   {
                                                   >> 165     // Special case handling for unrotated boxes
                                                   >> 166     // Compute x/y/z mins and maxs respecting limits, with early returns
                                                   >> 167     // if outside limits. Then switch() on pAxis
231                                                   168 
232   // Get bounding box                          << 169     G4double xoffset,xMin,xMax;
233   BoundingLimits(bmin,bmax);                   << 170     G4double yoffset,yMin,yMax;
                                                   >> 171     G4double zoffset,zMin,zMax;
234                                                   172 
235   // Find extent                               << 173     xoffset = pTransform.NetTranslation().x() ;
236   G4BoundingEnvelope bbox(bmin,bmax);          << 174     xMin    = xoffset - fDx ;
237   return bbox.CalculateExtent(pAxis,pVoxelLimi << 175     xMax    = xoffset + fDx ;
238 }                                              << 
239                                                   176 
240 ////////////////////////////////////////////// << 177     if (pVoxelLimit.IsXLimited())
                                                   >> 178     {
                                                   >> 179       if ( xMin > pVoxelLimit.GetMaxXExtent()+kCarTolerance || 
                                                   >> 180            xMax < pVoxelLimit.GetMinXExtent()-kCarTolerance    ) return false ;
                                                   >> 181       else
                                                   >> 182       {
                                                   >> 183         if (xMin < pVoxelLimit.GetMinXExtent())
                                                   >> 184         {
                                                   >> 185           xMin = pVoxelLimit.GetMinXExtent() ;
                                                   >> 186         }
                                                   >> 187         if (xMax > pVoxelLimit.GetMaxXExtent())
                                                   >> 188         {
                                                   >> 189           xMax = pVoxelLimit.GetMaxXExtent() ;
                                                   >> 190         }
                                                   >> 191       }
                                                   >> 192     }
                                                   >> 193     yoffset = pTransform.NetTranslation().y() ;
                                                   >> 194     yMin    = yoffset - fDy ;
                                                   >> 195     yMax    = yoffset + fDy ;
                                                   >> 196 
                                                   >> 197     if (pVoxelLimit.IsYLimited())
                                                   >> 198     {
                                                   >> 199       if ( yMin > pVoxelLimit.GetMaxYExtent()+kCarTolerance ||
                                                   >> 200            yMax < pVoxelLimit.GetMinYExtent()-kCarTolerance   ) return false ;
                                                   >> 201       else
                                                   >> 202       {
                                                   >> 203         if (yMin < pVoxelLimit.GetMinYExtent())
                                                   >> 204         {
                                                   >> 205           yMin = pVoxelLimit.GetMinYExtent() ;
                                                   >> 206         }
                                                   >> 207         if (yMax > pVoxelLimit.GetMaxYExtent())
                                                   >> 208         {
                                                   >> 209           yMax = pVoxelLimit.GetMaxYExtent() ;
                                                   >> 210         }
                                                   >> 211       }
                                                   >> 212     }
                                                   >> 213     zoffset = pTransform.NetTranslation().z() ;
                                                   >> 214     zMin    = zoffset - fDz ;
                                                   >> 215     zMax    = zoffset + fDz ;
                                                   >> 216 
                                                   >> 217     if (pVoxelLimit.IsZLimited())
                                                   >> 218     {
                                                   >> 219       if ( zMin > pVoxelLimit.GetMaxZExtent()+kCarTolerance ||
                                                   >> 220            zMax < pVoxelLimit.GetMinZExtent()-kCarTolerance   ) return false ;
                                                   >> 221       else
                                                   >> 222       {
                                                   >> 223         if (zMin < pVoxelLimit.GetMinZExtent())
                                                   >> 224         {
                                                   >> 225           zMin = pVoxelLimit.GetMinZExtent() ;
                                                   >> 226         }
                                                   >> 227         if (zMax > pVoxelLimit.GetMaxZExtent())
                                                   >> 228         {
                                                   >> 229           zMax = pVoxelLimit.GetMaxZExtent() ;
                                                   >> 230         }
                                                   >> 231       }
                                                   >> 232     }
                                                   >> 233     switch (pAxis)
                                                   >> 234     {
                                                   >> 235       case kXAxis:
                                                   >> 236         pMin = xMin ;
                                                   >> 237         pMax = xMax ;
                                                   >> 238         break ;
                                                   >> 239       case kYAxis:
                                                   >> 240         pMin=yMin;
                                                   >> 241         pMax=yMax;
                                                   >> 242         break;
                                                   >> 243       case kZAxis:
                                                   >> 244         pMin=zMin;
                                                   >> 245         pMax=zMax;
                                                   >> 246         break;
                                                   >> 247       default:
                                                   >> 248         break;
                                                   >> 249     }
                                                   >> 250     pMin -= kCarTolerance ;
                                                   >> 251     pMax += kCarTolerance ;
                                                   >> 252 
                                                   >> 253     return true;
                                                   >> 254   }
                                                   >> 255   else  // General rotated case - create and clip mesh to boundaries
                                                   >> 256   {
                                                   >> 257     G4bool existsAfterClip = false ;
                                                   >> 258     G4ThreeVectorList* vertices ;
                                                   >> 259 
                                                   >> 260     pMin = +kInfinity ;
                                                   >> 261     pMax = -kInfinity ;
                                                   >> 262 
                                                   >> 263     // Calculate rotated vertex coordinates
                                                   >> 264 
                                                   >> 265     vertices = CreateRotatedVertices(pTransform) ;
                                                   >> 266     ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
                                                   >> 267     ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax) ;
                                                   >> 268     ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
                                                   >> 269 
                                                   >> 270     if (pVoxelLimit.IsLimited(pAxis) == false) 
                                                   >> 271     {  
                                                   >> 272       if ( pMin != kInfinity || pMax != -kInfinity ) 
                                                   >> 273       {
                                                   >> 274         existsAfterClip = true ;
                                                   >> 275 
                                                   >> 276         // Add 2*tolerance to avoid precision troubles
                                                   >> 277 
                                                   >> 278         pMin           -= kCarTolerance;
                                                   >> 279         pMax           += kCarTolerance;
                                                   >> 280       }
                                                   >> 281     }      
                                                   >> 282     else
                                                   >> 283     {
                                                   >> 284       G4ThreeVector clipCentre(
                                                   >> 285        ( pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
                                                   >> 286        ( pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
                                                   >> 287        ( pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
                                                   >> 288 
                                                   >> 289       if ( pMin != kInfinity || pMax != -kInfinity )
                                                   >> 290       {
                                                   >> 291         existsAfterClip = true ;
                                                   >> 292   
                                                   >> 293 
                                                   >> 294         // Check to see if endpoints are in the solid
                                                   >> 295 
                                                   >> 296         clipCentre(pAxis) = pVoxelLimit.GetMinExtent(pAxis);
                                                   >> 297 
                                                   >> 298         if (Inside(pTransform.Inverse().TransformPoint(clipCentre)) != kOutside)
                                                   >> 299         {
                                                   >> 300           pMin = pVoxelLimit.GetMinExtent(pAxis);
                                                   >> 301         }
                                                   >> 302         else
                                                   >> 303         {
                                                   >> 304           pMin -= kCarTolerance;
                                                   >> 305         }
                                                   >> 306         clipCentre(pAxis) = pVoxelLimit.GetMaxExtent(pAxis);
                                                   >> 307 
                                                   >> 308         if (Inside(pTransform.Inverse().TransformPoint(clipCentre)) != kOutside)
                                                   >> 309         {
                                                   >> 310           pMax = pVoxelLimit.GetMaxExtent(pAxis);
                                                   >> 311         }
                                                   >> 312         else
                                                   >> 313         {
                                                   >> 314           pMax += kCarTolerance;
                                                   >> 315         }
                                                   >> 316       }
                                                   >> 317 
                                                   >> 318       // Check for case where completely enveloping clipping volume
                                                   >> 319       // If point inside then we are confident that the solid completely
                                                   >> 320       // envelopes the clipping volume. Hence set min/max extents according
                                                   >> 321       // to clipping volume extents along the specified axis.
                                                   >> 322         
                                                   >> 323       else if (Inside(pTransform.Inverse().TransformPoint(clipCentre))
                                                   >> 324                       != kOutside)
                                                   >> 325       {
                                                   >> 326         existsAfterClip = true ;
                                                   >> 327         pMin            = pVoxelLimit.GetMinExtent(pAxis) ;
                                                   >> 328         pMax            = pVoxelLimit.GetMaxExtent(pAxis) ;
                                                   >> 329       }
                                                   >> 330     } 
                                                   >> 331     delete vertices;
                                                   >> 332     return existsAfterClip;
                                                   >> 333   } 
                                                   >> 334 } 
                                                   >> 335 
                                                   >> 336 /////////////////////////////////////////////////////////////////////////
241 //                                                337 //
242 // Return whether point inside/outside/on surf    338 // Return whether point inside/outside/on surface, using tolerance
243                                                   339 
244 EInside G4Box::Inside(const G4ThreeVector& p)     340 EInside G4Box::Inside(const G4ThreeVector& p) const
245 {                                                 341 {
246   G4double dist = std::max(std::max(           << 342   EInside in = kOutside ;
247                   std::abs(p.x())-fDx,         << 343 
248                   std::abs(p.y())-fDy),        << 344   if ( std::fabs(p.x()) <= fDx - kCarTolerance*0.5 )
249                   std::abs(p.z())-fDz);        << 345   {
250   return (dist > delta) ? kOutside :           << 346     if (std::fabs(p.y()) <= fDy - kCarTolerance*0.5 )
251     ((dist > -delta) ? kSurface : kInside);    << 347     {
                                                   >> 348       if      (std::fabs(p.z()) <= fDz - kCarTolerance*0.5 ) in = kInside ;
                                                   >> 349       else if (std::fabs(p.z()) <= fDz + kCarTolerance*0.5 ) in = kSurface ;
                                                   >> 350     }
                                                   >> 351     else if (std::fabs(p.y()) <= fDy + kCarTolerance*0.5 )
                                                   >> 352     {
                                                   >> 353       if (std::fabs(p.z()) <= fDz + kCarTolerance*0.5 ) in = kSurface ;
                                                   >> 354     }
                                                   >> 355   }
                                                   >> 356   else if (std::fabs(p.x()) <= fDx + kCarTolerance*0.5 )
                                                   >> 357   {
                                                   >> 358     if (std::fabs(p.y()) <= fDy + kCarTolerance*0.5 )
                                                   >> 359     {
                                                   >> 360       if (std::fabs(p.z()) <= fDz + kCarTolerance*0.5) in = kSurface ;
                                                   >> 361     }
                                                   >> 362   }
                                                   >> 363   return in ;
252 }                                                 364 }
253                                                   365 
254 ////////////////////////////////////////////// << 366 ///////////////////////////////////////////////////////////////////////
255 //                                                367 //
256 // Detect the side(s) and return corresponding << 368 // Calculate side nearest to p, and return normal
                                                   >> 369 // If two sides are equidistant, normal of first side (x/y/z) 
                                                   >> 370 // encountered returned
257                                                   371 
258 G4ThreeVector G4Box::SurfaceNormal( const G4Th    372 G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
259 {                                                 373 {
260   G4ThreeVector norm(0,0,0);                   << 374   G4double distx, disty, distz ;
261   G4double px = p.x();                         << 375   G4ThreeVector norm ;
262   if (std::abs(std::abs(px) - fDx) <= delta) n << 376 
263   G4double py = p.y();                         << 377   // Calculate distances as if in 1st octant
264   if (std::abs(std::abs(py) - fDy) <= delta) n << 378 
265   G4double pz = p.z();                         << 379   distx = std::fabs(std::fabs(p.x()) - fDx) ;
266   if (std::abs(std::abs(pz) - fDz) <= delta) n << 380   disty = std::fabs(std::fabs(p.y()) - fDy) ;
267                                                << 381   distz = std::fabs(std::fabs(p.z()) - fDz) ;
268   G4double nside = norm.mag2(); // number of s << 382 
269   if (nside == 1)                              << 383   // New code for particle on surface including edges and corners with specific
270     return norm;                               << 384   // normals
271   else if (nside > 1)                          << 385 
272     return norm.unit(); // edge or corner      << 386   const G4double delta    = 0.5*kCarTolerance;
273   else                                         << 387   const G4ThreeVector nX  = G4ThreeVector( 1.0, 0,0  );
                                                   >> 388   const G4ThreeVector nmX = G4ThreeVector(-1.0, 0,0  );
                                                   >> 389   const G4ThreeVector nY  = G4ThreeVector( 0, 1.0,0  );
                                                   >> 390   const G4ThreeVector nmY = G4ThreeVector( 0,-1.0,0  );
                                                   >> 391   const G4ThreeVector nZ  = G4ThreeVector( 0, 0,  1.0);
                                                   >> 392   const G4ThreeVector nmZ = G4ThreeVector( 0, 0,- 1.0);
                                                   >> 393 
                                                   >> 394   G4ThreeVector normX(0.,0.,0.), normY(0.,0.,0.), normZ(0.,0.,0.);
                                                   >> 395   G4ThreeVector sumnorm(0., 0., 0.);
                                                   >> 396   G4int noSurfaces=0; 
                                                   >> 397 
                                                   >> 398   if (distx <= delta)         // on X/mX surface and around
                                                   >> 399   {
                                                   >> 400     noSurfaces ++; 
                                                   >> 401     if ( p.x() >= 0.){        // on +X surface
                                                   >> 402       normX= nX ;    // G4ThreeVector( 1.0, 0., 0. );
                                                   >> 403     }else{
                                                   >> 404       normX= nmX;    // G4ThreeVector(-1.0, 0., 0. ); 
                                                   >> 405     }
                                                   >> 406     sumnorm= normX; 
                                                   >> 407   }
                                                   >> 408 
                                                   >> 409   if (disty <= delta)    // on one of the +Y or -Y surfaces
274   {                                               410   {
275     // Point is not on the surface             << 411     noSurfaces ++; 
276     //                                         << 412     if ( p.y() >= 0.){        // on +Y surface
                                                   >> 413       normY= nY;
                                                   >> 414     }else{
                                                   >> 415       normY = nmY; 
                                                   >> 416     }
                                                   >> 417     sumnorm += normY; 
                                                   >> 418   }
                                                   >> 419 
                                                   >> 420   if (distz <= delta)    // on one of the +Z or -Z surfaces
                                                   >> 421   {
                                                   >> 422     noSurfaces ++; 
                                                   >> 423     if ( p.z() >= 0.){        // on +Z surface
                                                   >> 424       normZ= nZ;
                                                   >> 425     }else{
                                                   >> 426       normZ = nmZ; 
                                                   >> 427     }
                                                   >> 428     sumnorm += normZ; 
                                                   >> 429   }
                                                   >> 430 
                                                   >> 431   // sumnorm= normX + normY + normZ; 
                                                   >> 432   const G4double invSqrt2 = 1.0 / std::sqrt( 2.0); 
                                                   >> 433   const G4double invSqrt3 = 1.0 / std::sqrt( 3.0); 
                                                   >> 434 
                                                   >> 435   norm= G4ThreeVector( 0., 0., 0.); 
                                                   >> 436   if( noSurfaces > 0 )
                                                   >> 437   { 
                                                   >> 438     if( noSurfaces == 1 ){ 
                                                   >> 439       norm= sumnorm; 
                                                   >> 440     }else{
                                                   >> 441       // norm = sumnorm . unit(); 
                                                   >> 442       if( noSurfaces == 2 ) { 
                                                   >> 443         // 2 surfaces -> on edge 
                                                   >> 444         norm = invSqrt2 * sumnorm; 
                                                   >> 445       } else { 
                                                   >> 446         // 3 surfaces (on corner)
                                                   >> 447         norm = invSqrt3 * sumnorm; 
                                                   >> 448       }
                                                   >> 449     }
                                                   >> 450   }else{
277 #ifdef G4CSGDEBUG                                 451 #ifdef G4CSGDEBUG
278     std::ostringstream message;                << 452      G4Exception("G4Box::SurfaceNormal(p)", "Notification", JustWarning, 
279     G4int oldprc = message.precision(16);      << 453                  "Point p is not on surface !?" );
280     message << "Point p is not on surface (!?) << 454 #endif 
281             << GetName() << G4endl;            << 455      norm = ApproxSurfaceNormal(p);
282     message << "Position:\n";                  << 
283     message << "   p.x() = " << p.x()/mm << "  << 
284     message << "   p.y() = " << p.y()/mm << "  << 
285     message << "   p.z() = " << p.z()/mm << "  << 
286     G4cout.precision(oldprc);                  << 
287     G4Exception("G4Box::SurfaceNormal(p)", "Ge << 
288                 JustWarning, message );        << 
289     DumpInfo();                                << 
290 #endif                                         << 
291     return ApproxSurfaceNormal(p);             << 
292   }                                               456   }
                                                   >> 457   
                                                   >> 458   return norm;
293 }                                                 459 }
294                                                   460 
295 //////////////////////////////////////////////    461 //////////////////////////////////////////////////////////////////////////
296 //                                                462 //
297 // Algorithm for SurfaceNormal() following the    463 // Algorithm for SurfaceNormal() following the original specification
298 // for points not on the surface                  464 // for points not on the surface
299                                                   465 
300 G4ThreeVector G4Box::ApproxSurfaceNormal(const << 466 G4ThreeVector G4Box::ApproxSurfaceNormal( const G4ThreeVector& p ) const
301 {                                                 467 {
302   G4double distx = std::abs(p.x()) - fDx;      << 468   G4double distx, disty, distz ;
303   G4double disty = std::abs(p.y()) - fDy;      << 469   G4ThreeVector norm ;
304   G4double distz = std::abs(p.z()) - fDz;      << 470 
305                                                << 471   // Calculate distances as if in 1st octant
306   if (distx >= disty && distx >= distz)        << 472 
307     return {std::copysign(1.,p.x()), 0., 0.};  << 473   distx = std::fabs(std::fabs(p.x()) - fDx) ;
308   if (disty >= distx && disty >= distz)        << 474   disty = std::fabs(std::fabs(p.y()) - fDy) ;
309     return {0., std::copysign(1.,p.y()), 0.};  << 475   distz = std::fabs(std::fabs(p.z()) - fDz) ;
                                                   >> 476 
                                                   >> 477   if ( distx <= disty )
                                                   >> 478   {
                                                   >> 479     if ( distx <= distz )     // Closest to X
                                                   >> 480     {
                                                   >> 481       if ( p.x() < 0 ) norm = G4ThreeVector(-1.0,0,0) ;
                                                   >> 482       else             norm = G4ThreeVector( 1.0,0,0) ;
                                                   >> 483     }
                                                   >> 484     else                      // Closest to Z
                                                   >> 485     {
                                                   >> 486       if ( p.z() < 0 ) norm = G4ThreeVector(0,0,-1.0) ;
                                                   >> 487       else             norm = G4ThreeVector(0,0, 1.0) ;
                                                   >> 488     }
                                                   >> 489   }
310   else                                            490   else
311     return {0., 0., std::copysign(1.,p.z())};  << 491   {
                                                   >> 492     if ( disty <= distz )      // Closest to Y
                                                   >> 493     {
                                                   >> 494       if ( p.y() < 0 ) norm = G4ThreeVector(0,-1.0,0) ;
                                                   >> 495       else             norm = G4ThreeVector(0, 1.0,0) ;
                                                   >> 496     }
                                                   >> 497     else                       // Closest to Z
                                                   >> 498     {
                                                   >> 499       if ( p.z() < 0 ) norm = G4ThreeVector(0,0,-1.0) ;
                                                   >> 500       else             norm = G4ThreeVector(0,0, 1.0) ;
                                                   >> 501     }
                                                   >> 502   }
                                                   >> 503   return norm;
312 }                                                 504 }
313                                                   505 
314 ////////////////////////////////////////////// << 506 ///////////////////////////////////////////////////////////////////////////
315 //                                                507 //
316 // Calculate distance to box from an outside p    508 // Calculate distance to box from an outside point
317 // - return kInfinity if no intersection       << 509 // - return kInfinity if no intersection.
                                                   >> 510 //
                                                   >> 511 // ALGORITHM:
                                                   >> 512 //
                                                   >> 513 // Check that if point lies outside x/y/z extent of box, travel is towards
                                                   >> 514 // the box (ie. there is a possibility of an intersection)
318 //                                                515 //
                                                   >> 516 // Calculate pairs of minimum and maximum distances for x/y/z travel for
                                                   >> 517 // intersection with the box's x/y/z extent.
                                                   >> 518 // If there is a valid intersection, it is given by the maximum min distance
                                                   >> 519 // (ie. distance to satisfy x/y/z intersections) *if* <= minimum max distance
                                                   >> 520 // (ie. distance after which 1+ of x/y/z intersections not satisfied)
                                                   >> 521 //
                                                   >> 522 // NOTE:
                                                   >> 523 //
                                                   >> 524 // `Inside' safe - meaningful answers given if point is inside the exact
                                                   >> 525 // shape.
319                                                   526 
320 G4double G4Box::DistanceToIn(const G4ThreeVect << 527 G4double G4Box::DistanceToIn(const G4ThreeVector& p,const G4ThreeVector& v) const
321                              const G4ThreeVect << 
322 {                                                 528 {
323   // Check if point is on the surface and trav << 529   G4double safx, safy, safz ;
324   //                                           << 530   G4double smin=0.0, sminy, sminz ; // , sminx ;
325   if ((std::abs(p.x()) - fDx) >= -delta && p.x << 531   G4double smax=kInfinity, smaxy, smaxz ; // , smaxx ;  // they always > 0
326   if ((std::abs(p.y()) - fDy) >= -delta && p.y << 532   G4double stmp ;
327   if ((std::abs(p.z()) - fDz) >= -delta && p.z << 533   G4double sOut=kInfinity, sOuty=kInfinity, sOutz=kInfinity ;
328                                                << 534 
329   // Find intersection                         << 535   safx = std::fabs(p.x()) - fDx ;     // minimum distance to x surface of shape
330   //                                           << 536   safy = std::fabs(p.y()) - fDy ;
331   G4double invx = (v.x() == 0) ? DBL_MAX : -1. << 537   safz = std::fabs(p.z()) - fDz ;
332   G4double dx = std::copysign(fDx,invx);       << 
333   G4double txmin = (p.x() - dx)*invx;          << 
334   G4double txmax = (p.x() + dx)*invx;          << 
335                                                << 
336   G4double invy = (v.y() == 0) ? DBL_MAX : -1. << 
337   G4double dy = std::copysign(fDy,invy);       << 
338   G4double tymin = std::max(txmin,(p.y() - dy) << 
339   G4double tymax = std::min(txmax,(p.y() + dy) << 
340                                                << 
341   G4double invz = (v.z() == 0) ? DBL_MAX : -1. << 
342   G4double dz = std::copysign(fDz,invz);       << 
343   G4double tmin = std::max(tymin,(p.z() - dz)* << 
344   G4double tmax = std::min(tymax,(p.z() + dz)* << 
345                                                   538 
346   if (tmax <= tmin + delta) return kInfinity;  << 539   // Will we intersect?
347   return (tmin < delta) ? 0. : tmin;           << 540   // If safx/y/z is >-tol/2 the point is outside/on the box's x/y/z extent.
                                                   >> 541   // If both p.x/y/z and v.x/y/z repectively are both positive/negative,
                                                   >> 542   // travel is in a direction away from the shape.
                                                   >> 543 
                                                   >> 544   if (    ((p.x()*v.x() >= 0.0) && safx > -kCarTolerance*0.5) 
                                                   >> 545        || ((p.y()*v.y() >= 0.0) && safy > -kCarTolerance*0.5)
                                                   >> 546        || ((p.z()*v.z() >= 0.0) && safz > -kCarTolerance*0.5)   ) 
                                                   >> 547   {
                                                   >> 548     return kInfinity ;  // travel away or parallel within tolerance
                                                   >> 549   }
                                                   >> 550 
                                                   >> 551   // Compute min / max distances for x/y/z travel:
                                                   >> 552   // X Planes
                                                   >> 553 
                                                   >> 554   if ( v.x())
                                                   >> 555   {
                                                   >> 556     stmp = 1.0/std::fabs(v.x()) ;
                                                   >> 557 
                                                   >> 558     if (safx >= 0.0)
                                                   >> 559     {
                                                   >> 560       smin = safx*stmp ;
                                                   >> 561       smax = (fDx+std::fabs(p.x()))*stmp ;
                                                   >> 562     }
                                                   >> 563     else
                                                   >> 564     {
                                                   >> 565       if (v.x() > 0)  sOut = (fDx - p.x())*stmp ;
                                                   >> 566       if (v.x() < 0)  sOut = (fDx + p.x())*stmp ;
                                                   >> 567     }
                                                   >> 568   }
                                                   >> 569 
                                                   >> 570   // Y Planes
                                                   >> 571 
                                                   >> 572   if ( v.y()) 
                                                   >> 573   {
                                                   >> 574     stmp = 1.0/std::fabs(v.y()) ;
                                                   >> 575 
                                                   >> 576     if (safy >= 0.0)
                                                   >> 577     {
                                                   >> 578       sminy = safy*stmp ;
                                                   >> 579       smaxy = (fDy+std::fabs(p.y()))*stmp ;
                                                   >> 580 
                                                   >> 581       if (sminy > smin) smin=sminy ;
                                                   >> 582       if (smaxy < smax) smax=smaxy ;
                                                   >> 583 
                                                   >> 584       if (smin >= smax-kCarTolerance*0.5)
                                                   >> 585       {
                                                   >> 586         return kInfinity ;  // touch XY corner
                                                   >> 587       }
                                                   >> 588     }
                                                   >> 589     else
                                                   >> 590     {
                                                   >> 591       if (v.y() > 0)  sOuty = (fDy - p.y())*stmp ;
                                                   >> 592       if (v.y() < 0)  sOuty = (fDy + p.y())*stmp ;
                                                   >> 593       if( sOuty < sOut ) sOut = sOuty ;
                                                   >> 594     }     
                                                   >> 595   }
                                                   >> 596 
                                                   >> 597   // Z planes
                                                   >> 598 
                                                   >> 599   if ( v.z() )
                                                   >> 600   {
                                                   >> 601     stmp = 1.0/std::fabs(v.z()) ;
                                                   >> 602 
                                                   >> 603     if ( safz >= 0.0)
                                                   >> 604     {
                                                   >> 605       sminz = safz*stmp ;
                                                   >> 606       smaxz = (fDz+std::fabs(p.z()))*stmp ;
                                                   >> 607 
                                                   >> 608       if (sminz > smin) smin = sminz ;
                                                   >> 609       if (smaxz < smax) smax = smaxz ;
                                                   >> 610 
                                                   >> 611       if (smin >= smax-kCarTolerance*0.5)
                                                   >> 612       { 
                                                   >> 613         return kInfinity ;    // touch ZX or ZY corners
                                                   >> 614       }
                                                   >> 615     }
                                                   >> 616     else
                                                   >> 617     {
                                                   >> 618       if (v.z() > 0)  sOutz = (fDz - p.z())*stmp ;
                                                   >> 619       if (v.z() < 0)  sOutz = (fDz + p.z())*stmp ;
                                                   >> 620       if( sOutz < sOut ) sOut = sOutz ;
                                                   >> 621     }
                                                   >> 622   }
                                                   >> 623 
                                                   >> 624   if ( sOut <= smin + 0.5*kCarTolerance) // travel over edge
                                                   >> 625   {
                                                   >> 626     return kInfinity ;
                                                   >> 627   }
                                                   >> 628   if (smin < 0.5*kCarTolerance)  smin = 0.0 ;
                                                   >> 629 
                                                   >> 630   return smin ;
348 }                                                 631 }
349                                                   632 
350 //////////////////////////////////////////////    633 //////////////////////////////////////////////////////////////////////////
351 //                                             << 634 // 
352 // Appoximate distance to box.                    635 // Appoximate distance to box.
353 // Returns largest perpendicular distance to t    636 // Returns largest perpendicular distance to the closest x/y/z sides of
354 // the box, which is the most fast estimation     637 // the box, which is the most fast estimation of the shortest distance to box
355 // - If inside return 0                           638 // - If inside return 0
356                                                   639 
357 G4double G4Box::DistanceToIn(const G4ThreeVect    640 G4double G4Box::DistanceToIn(const G4ThreeVector& p) const
358 {                                                 641 {
359   G4double dist = std::max(std::max(           << 642   G4double safex, safey, safez, safe = 0.0 ;
360                   std::abs(p.x())-fDx,         << 643 
361                   std::abs(p.y())-fDy),        << 644   safex = std::fabs(p.x()) - fDx ;
362                   std::abs(p.z())-fDz);        << 645   safey = std::fabs(p.y()) - fDy ;
363   return (dist > 0) ? dist : 0.;               << 646   safez = std::fabs(p.z()) - fDz ;
                                                   >> 647 
                                                   >> 648   if (safex > safe) safe = safex ;
                                                   >> 649   if (safey > safe) safe = safey ;
                                                   >> 650   if (safez > safe) safe = safez ;
                                                   >> 651 
                                                   >> 652   return safe ;
364 }                                                 653 }
365                                                   654 
366 ////////////////////////////////////////////// << 655 /////////////////////////////////////////////////////////////////////////
367 //                                                656 //
368 // Calculate distance to surface of the box fr << 657 // Calcluate distance to surface of box from inside
369 // find normal at exit point, if required      << 658 // by calculating distances to box's x/y/z planes.
370 // - when leaving the surface, return 0        << 659 // Smallest distance is exact distance to exiting.
                                                   >> 660 // - Eliminate one side of each pair by considering direction of v
                                                   >> 661 // - when leaving a surface & v.close, return 0
371                                                   662 
372 G4double G4Box::DistanceToOut( const G4ThreeVe << 663 G4double G4Box::DistanceToOut( const G4ThreeVector& p,const G4ThreeVector& v,
373                                const G4ThreeVe << 
374                                const G4bool ca    664                                const G4bool calcNorm,
375                                G4bool* validNo << 665                                      G4bool *validNorm,G4ThreeVector *n) const
376 {                                                 666 {
377   // Check if point is on the surface and trav << 667   ESide side = kUndefined ;
378   //                                           << 668   G4double pdist,stmp,snxt;
379   if ((std::abs(p.x()) - fDx) >= -delta && p.x << 669 
                                                   >> 670   if (calcNorm) *validNorm = true ; // All normals are valid
                                                   >> 671 
                                                   >> 672   if (v.x() > 0)   // X planes  
380   {                                               673   {
381     if (calcNorm)                              << 674     pdist = fDx - p.x() ;
                                                   >> 675 
                                                   >> 676     if (pdist > kCarTolerance*0.5)
                                                   >> 677     {
                                                   >> 678       snxt = pdist/v.x() ;
                                                   >> 679       side = kPX ;
                                                   >> 680     }
                                                   >> 681     else
382     {                                             682     {
383       *validNorm = true;                       << 683       if (calcNorm) *n    = G4ThreeVector(1,0,0) ;
384       n->set((p.x() < 0) ? -1. : 1., 0., 0.);  << 684       return         snxt = 0 ;
385     }                                             685     }
386     return 0.;                                 << 
387   }                                               686   }
388   if ((std::abs(p.y()) - fDy) >= -delta && p.y << 687   else if (v.x() < 0) 
389   {                                               688   {
390     if (calcNorm)                              << 689     pdist = fDx + p.x() ;
                                                   >> 690 
                                                   >> 691     if (pdist > kCarTolerance*0.5)
                                                   >> 692     {
                                                   >> 693       snxt = -pdist/v.x() ;
                                                   >> 694       side = kMX ;
                                                   >> 695     }
                                                   >> 696     else
391     {                                             697     {
392       *validNorm = true;                       << 698       if (calcNorm) *n   = G4ThreeVector(-1,0,0) ;
393       n->set(0., (p.y() < 0) ? -1. : 1., 0.);  << 699       return        snxt = 0 ;
394     }                                             700     }
395     return 0.;                                 << 
396   }                                               701   }
397   if ((std::abs(p.z()) - fDz) >= -delta && p.z << 702   else snxt = kInfinity ;
                                                   >> 703 
                                                   >> 704   if ( v.y() > 0 )   // Y planes  
398   {                                               705   {
399     if (calcNorm)                              << 706     pdist=fDy-p.y();
                                                   >> 707 
                                                   >> 708     if (pdist>kCarTolerance*0.5)
                                                   >> 709     {
                                                   >> 710       stmp=pdist/v.y();
                                                   >> 711 
                                                   >> 712       if (stmp<snxt)
                                                   >> 713       {
                                                   >> 714         snxt=stmp;
                                                   >> 715         side=kPY;
                                                   >> 716       }
                                                   >> 717     }
                                                   >> 718     else
400     {                                             719     {
401       *validNorm = true;                       << 720       if (calcNorm) *n    = G4ThreeVector(0,1,0) ;
402       n->set(0., 0., (p.z() < 0) ? -1. : 1.);  << 721       return         snxt = 0 ;
403     }                                             722     }
404     return 0.;                                 << 
405   }                                               723   }
                                                   >> 724   else if ( v.y() < 0 ) 
                                                   >> 725   {
                                                   >> 726     pdist = fDy + p.y() ;
406                                                   727 
407   // Find intersection                         << 728     if (pdist > kCarTolerance*0.5)
408   //                                           << 729     {
409   G4double vx = v.x();                         << 730       stmp=-pdist/v.y();
410   G4double tx = (vx == 0) ? DBL_MAX : (std::co << 
411                                                   731 
412   G4double vy = v.y();                         << 732       if (stmp<snxt)
413   G4double ty = (vy == 0) ? tx : (std::copysig << 733       {
414   G4double txy = std::min(tx,ty);              << 734         snxt=stmp;
                                                   >> 735         side=kMY;
                                                   >> 736       }
                                                   >> 737     }
                                                   >> 738     else
                                                   >> 739     {
                                                   >> 740       if (calcNorm) *n    = G4ThreeVector(0,-1,0) ;
                                                   >> 741       return         snxt = 0 ;
                                                   >> 742     }
                                                   >> 743   }
                                                   >> 744   if (v.z()>0)        // Z planes 
                                                   >> 745   {
                                                   >> 746     pdist=fDz-p.z();
415                                                   747 
416   G4double vz = v.z();                         << 748     if (pdist > kCarTolerance*0.5)
417   G4double tz = (vz == 0) ? txy : (std::copysi << 749     {
418   G4double tmax = std::min(txy,tz);            << 750       stmp=pdist/v.z();
419                                                   751 
420   // Set normal, if required, and return dista << 752       if (stmp < snxt)
421   //                                           << 753       {
422   if (calcNorm)                                << 754         snxt=stmp;
                                                   >> 755         side=kPZ;
                                                   >> 756       }
                                                   >> 757     }
                                                   >> 758     else
                                                   >> 759     {
                                                   >> 760       if (calcNorm) *n    = G4ThreeVector(0,0,1) ;
                                                   >> 761       return         snxt = 0 ;
                                                   >> 762     }
                                                   >> 763   }
                                                   >> 764   else if (v.z()<0) 
423   {                                               765   {
424     *validNorm = true;                         << 766     pdist = fDz + p.z() ;
425     if (tmax == tx)      n->set((v.x() < 0) ?  << 767 
426     else if (tmax == ty) n->set(0., (v.y() < 0 << 768     if (pdist > kCarTolerance*0.5)
427     else                 n->set(0., 0., (v.z() << 769     {
                                                   >> 770       stmp=-pdist/v.z();
                                                   >> 771 
                                                   >> 772       if (stmp < snxt)
                                                   >> 773       {
                                                   >> 774         snxt=stmp;
                                                   >> 775         side=kMZ;
                                                   >> 776       }
                                                   >> 777     }
                                                   >> 778     else
                                                   >> 779     {
                                                   >> 780       if (calcNorm) *n    = G4ThreeVector(0,0,-1) ;
                                                   >> 781       return         snxt = 0 ;
                                                   >> 782     }
                                                   >> 783   }
                                                   >> 784   if (calcNorm)
                                                   >> 785   {      
                                                   >> 786     switch (side)
                                                   >> 787     {
                                                   >> 788       case kPX:
                                                   >> 789         *n=G4ThreeVector(1,0,0);
                                                   >> 790         break;
                                                   >> 791       case kMX:
                                                   >> 792         *n=G4ThreeVector(-1,0,0);
                                                   >> 793         break;
                                                   >> 794       case kPY:
                                                   >> 795         *n=G4ThreeVector(0,1,0);
                                                   >> 796         break;
                                                   >> 797       case kMY:
                                                   >> 798         *n=G4ThreeVector(0,-1,0);
                                                   >> 799         break;
                                                   >> 800       case kPZ:
                                                   >> 801         *n=G4ThreeVector(0,0,1);
                                                   >> 802         break;
                                                   >> 803       case kMZ:
                                                   >> 804         *n=G4ThreeVector(0,0,-1);
                                                   >> 805         break;
                                                   >> 806       default:
                                                   >> 807         G4cout.precision(16);
                                                   >> 808         G4cout << G4endl;
                                                   >> 809         DumpInfo();
                                                   >> 810         G4cout << "Position:"  << G4endl << G4endl;
                                                   >> 811         G4cout << "p.x() = "   << p.x()/mm << " mm" << G4endl;
                                                   >> 812         G4cout << "p.y() = "   << p.y()/mm << " mm" << G4endl;
                                                   >> 813         G4cout << "p.z() = "   << p.z()/mm << " mm" << G4endl << G4endl;
                                                   >> 814         G4cout << "Direction:" << G4endl << G4endl;
                                                   >> 815         G4cout << "v.x() = "   << v.x() << G4endl;
                                                   >> 816         G4cout << "v.y() = "   << v.y() << G4endl;
                                                   >> 817         G4cout << "v.z() = "   << v.z() << G4endl << G4endl;
                                                   >> 818         G4cout << "Proposed distance :" << G4endl << G4endl;
                                                   >> 819         G4cout << "snxt = "    << snxt/mm << " mm" << G4endl << G4endl;
                                                   >> 820         G4Exception("G4Box::DistanceToOut(p,v,..)","Notification",JustWarning,
                                                   >> 821                     "Undefined side for valid surface normal to solid.");
                                                   >> 822         break;
                                                   >> 823     }
428   }                                               824   }
429   return tmax;                                 << 825   return snxt;
430 }                                                 826 }
431                                                   827 
432 //////////////////////////////////////////////    828 ////////////////////////////////////////////////////////////////////////////
433 //                                                829 //
434 // Calculate exact shortest distance to any bo    830 // Calculate exact shortest distance to any boundary from inside
435 // - if outside return 0                       << 831 // - If outside return 0
436                                                   832 
437 G4double G4Box::DistanceToOut(const G4ThreeVec    833 G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
438 {                                                 834 {
                                                   >> 835   G4double safx1,safx2,safy1,safy2,safz1,safz2,safe=0.0;
                                                   >> 836 
439 #ifdef G4CSGDEBUG                                 837 #ifdef G4CSGDEBUG
440   if( Inside(p) == kOutside )                     838   if( Inside(p) == kOutside )
441   {                                               839   {
442     std::ostringstream message;                << 840      G4cout.precision(16) ;
443     G4int oldprc = message.precision(16);      << 841      G4cout << G4endl ;
444     message << "Point p is outside (!?) of sol << 842      DumpInfo();
445     message << "Position:\n";                  << 843      G4cout << "Position:"  << G4endl << G4endl ;
446     message << "   p.x() = " << p.x()/mm << "  << 844      G4cout << "p.x() = "   << p.x()/mm << " mm" << G4endl ;
447     message << "   p.y() = " << p.y()/mm << "  << 845      G4cout << "p.y() = "   << p.y()/mm << " mm" << G4endl ;
448     message << "   p.z() = " << p.z()/mm << "  << 846      G4cout << "p.z() = "   << p.z()/mm << " mm" << G4endl << G4endl ;
449     G4cout.precision(oldprc);                  << 847      G4Exception("G4Box::DistanceToOut(p)", "Notification", JustWarning, 
450     G4Exception("G4Box::DistanceToOut(p)", "Ge << 848                  "Point p is outside !?" );
451                 JustWarning, message );        << 
452     DumpInfo();                                << 
453   }                                               849   }
454 #endif                                            850 #endif
455   G4double dist = std::min(std::min(           << 851 
456                   fDx-std::abs(p.x()),         << 852   safx1 = fDx - p.x() ;
457                   fDy-std::abs(p.y())),        << 853   safx2 = fDx + p.x() ;
458                   fDz-std::abs(p.z()));        << 854   safy1 = fDy - p.y() ;
459   return (dist > 0) ? dist : 0.;               << 855   safy2 = fDy + p.y() ;
                                                   >> 856   safz1 = fDz - p.z() ;
                                                   >> 857   safz2 = fDz + p.z() ;  
                                                   >> 858   
                                                   >> 859   // shortest Dist to any boundary now MIN(safx1,safx2,safy1..)
                                                   >> 860 
                                                   >> 861   if (safx2 < safx1) safe = safx2 ;
                                                   >> 862   else               safe = safx1 ;
                                                   >> 863   if (safy1 < safe)  safe = safy1 ;
                                                   >> 864   if (safy2 < safe)  safe = safy2 ;
                                                   >> 865   if (safz1 < safe)  safe = safz1 ;
                                                   >> 866   if (safz2 < safe)  safe = safz2 ;
                                                   >> 867 
                                                   >> 868   if (safe < 0) safe = 0 ;
                                                   >> 869   return safe ;  
460 }                                                 870 }
461                                                   871 
462 ////////////////////////////////////////////// << 872 ////////////////////////////////////////////////////////////////////////
463 //                                                873 //
464 // GetEntityType                               << 874 // Create a List containing the transformed vertices
465                                                << 875 // Ordering [0-3] -fDz cross section
466 G4GeometryType G4Box::GetEntityType() const    << 876 //          [4-7] +fDz cross section such that [0] is below [4],
467 {                                              << 877 //                                             [1] below [5] etc.
468   return {"G4Box"};                            << 878 // Note:
                                                   >> 879 //  Caller has deletion resposibility
                                                   >> 880 
                                                   >> 881 G4ThreeVectorList*
                                                   >> 882 G4Box::CreateRotatedVertices(const G4AffineTransform& pTransform) const
                                                   >> 883 {
                                                   >> 884   G4ThreeVectorList* vertices = new G4ThreeVectorList();
                                                   >> 885   vertices->reserve(8);
                                                   >> 886 
                                                   >> 887   if (vertices)
                                                   >> 888   {
                                                   >> 889     G4ThreeVector vertex0(-fDx,-fDy,-fDz) ;
                                                   >> 890     G4ThreeVector vertex1(fDx,-fDy,-fDz) ;
                                                   >> 891     G4ThreeVector vertex2(fDx,fDy,-fDz) ;
                                                   >> 892     G4ThreeVector vertex3(-fDx,fDy,-fDz) ;
                                                   >> 893     G4ThreeVector vertex4(-fDx,-fDy,fDz) ;
                                                   >> 894     G4ThreeVector vertex5(fDx,-fDy,fDz) ;
                                                   >> 895     G4ThreeVector vertex6(fDx,fDy,fDz) ;
                                                   >> 896     G4ThreeVector vertex7(-fDx,fDy,fDz) ;
                                                   >> 897 
                                                   >> 898     vertices->push_back(pTransform.TransformPoint(vertex0));
                                                   >> 899     vertices->push_back(pTransform.TransformPoint(vertex1));
                                                   >> 900     vertices->push_back(pTransform.TransformPoint(vertex2));
                                                   >> 901     vertices->push_back(pTransform.TransformPoint(vertex3));
                                                   >> 902     vertices->push_back(pTransform.TransformPoint(vertex4));
                                                   >> 903     vertices->push_back(pTransform.TransformPoint(vertex5));
                                                   >> 904     vertices->push_back(pTransform.TransformPoint(vertex6));
                                                   >> 905     vertices->push_back(pTransform.TransformPoint(vertex7));
                                                   >> 906   }
                                                   >> 907   else
                                                   >> 908   {
                                                   >> 909     DumpInfo();
                                                   >> 910     G4Exception("G4Box::CreateRotatedVertices()",
                                                   >> 911                 "FatalError", FatalException,
                                                   >> 912                 "Error in allocation of vertices. Out of memory !");
                                                   >> 913   }
                                                   >> 914   return vertices;
469 }                                                 915 }
470                                                   916 
471 //////////////////////////////////////////////    917 //////////////////////////////////////////////////////////////////////////
472 //                                                918 //
473 // IsFaceted                                   << 919 // GetEntityType
474                                                   920 
475 G4bool G4Box::IsFaceted() const                << 921 G4GeometryType G4Box::GetEntityType() const
476 {                                                 922 {
477   return true;                                 << 923   return G4String("G4Box");
478 }                                                 924 }
479                                                   925 
480 //////////////////////////////////////////////    926 //////////////////////////////////////////////////////////////////////////
481 //                                                927 //
482 // Stream object contents to an output stream     928 // Stream object contents to an output stream
483                                                   929 
484 std::ostream& G4Box::StreamInfo(std::ostream&     930 std::ostream& G4Box::StreamInfo(std::ostream& os) const
485 {                                                 931 {
486   G4long oldprc = os.precision(16);            << 
487   os << "-------------------------------------    932   os << "-----------------------------------------------------------\n"
488      << "    *** Dump for solid - " << GetName    933      << "    *** Dump for solid - " << GetName() << " ***\n"
489      << "    =================================    934      << "    ===================================================\n"
490      << "Solid type: G4Box\n"                  << 935      << " Solid type: G4Box\n"
491      << "Parameters: \n"                       << 936      << " Parameters: \n"
492      << "   half length X: " << fDx/mm << " mm << 937      << "    half length X: " << fDx/mm << " mm \n"
493      << "   half length Y: " << fDy/mm << " mm << 938      << "    half length Y: " << fDy/mm << " mm \n"
494      << "   half length Z: " << fDz/mm << " mm << 939      << "    half length Z: " << fDz/mm << " mm \n"
495      << "-------------------------------------    940      << "-----------------------------------------------------------\n";
496   os.precision(oldprc);                        << 941 
497   return os;                                      942   return os;
498 }                                                 943 }
499                                                   944 
500 //////////////////////////////////////////////    945 //////////////////////////////////////////////////////////////////////////
501 //                                                946 //
502 // Return a point randomly and uniformly selec << 947 // Methods for visualisation
503                                                   948 
504 G4ThreeVector G4Box::GetPointOnSurface() const << 949 void G4Box::DescribeYourselfTo (G4VGraphicsScene& scene) const 
505 {                                                 950 {
506   G4double sxy = fDx*fDy, sxz = fDx*fDz, syz = << 951   scene.AddSolid (*this);
507   G4double select = (sxy + sxz + syz)*G4QuickR << 
508   G4double u = 2.*G4QuickRand() - 1.;          << 
509   G4double v = 2.*G4QuickRand() - 1.;          << 
510                                                << 
511   if (select < sxy)                            << 
512     return { u*fDx, v*fDy, ((select < 0.5*sxy) << 
513   else if (select < sxy + sxz)                 << 
514     return { u*fDx, ((select < sxy + 0.5*sxz)  << 
515   else                                         << 
516     return { ((select < sxy + sxz + 0.5*syz) ? << 
517 }                                                 952 }
518                                                   953 
519 ////////////////////////////////////////////// << 954 G4VisExtent G4Box::GetExtent() const 
520 //                                             << 
521 // Make a clone of the object                  << 
522 //                                             << 
523 G4VSolid* G4Box::Clone() const                 << 
524 {                                                 955 {
525   return new G4Box(*this);                     << 956   return G4VisExtent (-fDx, fDx, -fDy, fDy, -fDz, fDz);
526 }                                                 957 }
527                                                   958 
528 ////////////////////////////////////////////// << 959 G4Polyhedron* G4Box::CreatePolyhedron () const 
529 //                                             << 
530 // Methods for visualisation                   << 
531                                                << 
532 void G4Box::DescribeYourselfTo (G4VGraphicsSce << 
533 {                                                 960 {
534   scene.AddSolid (*this);                      << 961   return new G4PolyhedronBox (fDx, fDy, fDz);
535 }                                                 962 }
536                                                   963 
537 G4VisExtent G4Box::GetExtent() const           << 964 G4NURBS* G4Box::CreateNURBS () const 
538 {                                                 965 {
539   return { -fDx, fDx, -fDy, fDy, -fDz, fDz };  << 966   return new G4NURBSbox (fDx, fDy, fDz);
540 }                                                 967 }
                                                   >> 968     
                                                   >> 969 /////////////////////////////////////////////////////////////////////////////
                                                   >> 970 //
                                                   >> 971 // Return a point (G4ThreeVector) randomly and uniformly selected on the solid surface
541                                                   972 
542 G4Polyhedron* G4Box::CreatePolyhedron () const << 973 G4ThreeVector G4Box::GetPointOnSurface() const
543 {                                                 974 {
544   return new G4PolyhedronBox (fDx, fDy, fDz);  << 975   G4double px, py, pz, select, sumS;
                                                   >> 976   G4double Sxy = fDx*fDy, Sxz = fDx*fDz, Syz = fDy*fDz;
                                                   >> 977 
                                                   >> 978   sumS   = Sxy + Sxz + Syz;
                                                   >> 979   select = sumS*G4UniformRand();
                                                   >> 980  
                                                   >> 981   if( select < Sxy )
                                                   >> 982   {
                                                   >> 983     px = -fDx +2*fDx*G4UniformRand();
                                                   >> 984     py = -fDy +2*fDy*G4UniformRand();
                                                   >> 985 
                                                   >> 986     if(G4UniformRand() > 0.5) pz =  fDz;
                                                   >> 987     else                      pz = -fDz;
                                                   >> 988   }
                                                   >> 989   else if ( ( select - Sxy ) < Sxz ) 
                                                   >> 990   {
                                                   >> 991     px = -fDx +2*fDx*G4UniformRand();
                                                   >> 992     pz = -fDz +2*fDz*G4UniformRand();
                                                   >> 993 
                                                   >> 994     if(G4UniformRand() > 0.5) py =  fDy;
                                                   >> 995     else                      py = -fDy;
                                                   >> 996   }
                                                   >> 997   else  
                                                   >> 998   {
                                                   >> 999     py = -fDy +2*fDy*G4UniformRand();
                                                   >> 1000     pz = -fDz +2*fDz*G4UniformRand();
                                                   >> 1001 
                                                   >> 1002     if(G4UniformRand() > 0.5) px =  fDx;
                                                   >> 1003     else                      px = -fDx;
                                                   >> 1004   } 
                                                   >> 1005   return G4ThreeVector(px,py,pz);
545 }                                                 1006 }
546 #endif                                         << 1007 
547                                                   1008