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


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