Geant4 Cross Reference

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


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                    <<   3 // * DISCLAIMER                                                       *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th <<   5 // * The following disclaimer summarizes all the specific disclaimers *
  6 // * the Geant4 Collaboration.  It is provided <<   6 // * of contributors to this software. The specific disclaimers,which *
  7 // * conditions of the Geant4 Software License <<   7 // * govern, are listed with their locations in:                      *
  8 // * LICENSE and available at  http://cern.ch/ <<   8 // *   http://cern.ch/geant4/license                                  *
  9 // * include a list of copyright holders.      << 
 10 // *                                                9 // *                                                                  *
 11 // * Neither the authors of this software syst     10 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     11 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     12 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     13 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  <<  14 // * use.                                                             *
 16 // * for the full disclaimer and the limitatio << 
 17 // *                                               15 // *                                                                  *
 18 // * This  code  implementation is the result  <<  16 // * This  code  implementation is the  intellectual property  of the *
 19 // * technical work of the GEANT4 collaboratio <<  17 // * GEANT4 collaboration.                                            *
 20 // * By using,  copying,  modifying or  distri <<  18 // * By copying,  distributing  or modifying the Program (or any work *
 21 // * any work based  on the software)  you  ag <<  19 // * based  on  the Program)  you indicate  your  acceptance of  this *
 22 // * use  in  resulting  scientific  publicati <<  20 // * statement, and all its terms.                                    *
 23 // * acceptance of all terms of the Geant4 Sof << 
 24 // *******************************************     21 // ********************************************************************
 25 //                                                 22 //
                                                   >>  23 //
                                                   >>  24 // $Id: G4Trap.cc,v 1.37 2005/06/08 16:14:25 gcosmo Exp $
                                                   >>  25 // GEANT4 tag $Name: geant4-07-01 $
                                                   >>  26 //
                                                   >>  27 // class G4Trap
                                                   >>  28 //
 26 // Implementation for G4Trap class                 29 // Implementation for G4Trap class
 27 //                                                 30 //
 28 // 21.03.95 P.Kent: Modified for `tolerant' ge <<  31 // History:
                                                   >>  32 //
                                                   >>  33 // 28.04.05 V.Grichine: new SurfaceNormal according to J. Apostolakis proposal 
                                                   >>  34 // 26.04.05 V.Grichine: new SurfaceNormal is default 
                                                   >>  35 // 19.04.05 V.Grichine: bug fixed in G4Trap("name",G4ThreeVector[8] vp)
                                                   >>  36 // 12.12.04 V.Grichine: SurfaceNormal with edges/vertices 
                                                   >>  37 // 15.11.04 V.Grichine: bug fixed in G4Trap("name",G4ThreeVector[8] vp)
                                                   >>  38 // 13.12.99 V.Grichine: bug fixed in DistanceToIn(p,v)
                                                   >>  39 // 19.11.99 V.Grichine: kUndef was added to Eside enum
                                                   >>  40 // 04.06.99 S.Giani: Fixed CalculateExtent in rotated case. 
                                                   >>  41 // 08.12.97 J.Allison: Added "nominal" constructor and method SetAllParameters.
                                                   >>  42 // 01.11.96 V.Grichine: Costructor for Right Angular Wedge from STEP, G4Trd/Para
 29 // 09.09.96 V.Grichine: Final modifications be     43 // 09.09.96 V.Grichine: Final modifications before to commit
 30 // 08.12.97 J.Allison: Added "nominal" constru <<  44 // 21.03.95 P.Kent: Modified for `tolerant' geometry
 31 // 28.04.05 V.Grichine: new SurfaceNormal acco <<  45 //
 32 // 18.04.17 E.Tcherniaev: complete revision, s <<  46 //////////////////////////////////////////////////////////////////////////////////// 
 33 // ------------------------------------------- << 
 34                                                    47 
 35 #include "G4Trap.hh"                               48 #include "G4Trap.hh"
 36                                                << 
 37 #if !defined(G4GEOM_USE_UTRAP)                 << 
 38                                                << 
 39 #include "globals.hh"                              49 #include "globals.hh"
 40 #include "G4GeomTools.hh"                      << 
 41                                                    50 
 42 #include "G4VoxelLimits.hh"                        51 #include "G4VoxelLimits.hh"
 43 #include "G4AffineTransform.hh"                    52 #include "G4AffineTransform.hh"
 44 #include "G4BoundingEnvelope.hh"               << 
 45                                                    53 
 46 #include "G4VPVParameterisation.hh"                54 #include "G4VPVParameterisation.hh"
 47                                                    55 
 48 #include "G4QuickRand.hh"                      << 
 49                                                << 
 50 #include "G4VGraphicsScene.hh"                     56 #include "G4VGraphicsScene.hh"
 51 #include "G4Polyhedron.hh"                         57 #include "G4Polyhedron.hh"
                                                   >>  58 #include "G4NURBS.hh"
                                                   >>  59 #include "G4NURBSbox.hh"
                                                   >>  60 
                                                   >>  61 ////////////////////////////////////////////////////////////////////////
                                                   >>  62 //
                                                   >>  63 // Accuracy of coplanarity
                                                   >>  64 
                                                   >>  65 const G4double kCoplanar_Tolerance = 1E-4 ;
                                                   >>  66 
                                                   >>  67 //////////////////////////////////////////////////////////////////////////
                                                   >>  68 //
                                                   >>  69 // Private enum: Not for external use 
                                                   >>  70     
                                                   >>  71 enum Eside {kUndef,ks0,ks1,ks2,ks3,kPZ,kMZ};
                                                   >>  72 
                                                   >>  73 ////////////////////////////////////////////////////////////////////////
                                                   >>  74 //
                                                   >>  75 // Destructor
 52                                                    76 
 53 using namespace CLHEP;                         <<  77 G4Trap::~G4Trap()
                                                   >>  78 {
                                                   >>  79 }
 54                                                    80 
 55 //////////////////////////////////////////////     81 //////////////////////////////////////////////////////////////////////////
 56 //                                                 82 //
 57 // Constructor - check and set half-widths as  <<  83 // Constructor - check and set half-widths as well as angles: 
 58 // final check of coplanarity                      84 // final check of coplanarity
 59                                                    85 
 60 G4Trap::G4Trap( const G4String& pName,             86 G4Trap::G4Trap( const G4String& pName,
 61                       G4double pDz,                87                       G4double pDz,
 62                       G4double pTheta, G4doubl     88                       G4double pTheta, G4double pPhi,
 63                       G4double pDy1, G4double      89                       G4double pDy1, G4double pDx1, G4double pDx2,
 64                       G4double pAlp1,              90                       G4double pAlp1,
 65                       G4double pDy2, G4double      91                       G4double pDy2, G4double pDx3, G4double pDx4,
 66                       G4double pAlp2 )         <<  92                       G4double pAlp2)
 67   : G4CSGSolid(pName), halfCarTolerance(0.5*kC <<  93   : G4CSGSolid(pName)
 68 {                                                  94 {
 69   fDz = pDz;                                   <<  95   if ( pDz > 0 && pDy1 > 0 && pDx1 > 0 && 
 70   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi <<  96        pDx2 > 0 && pDy2 > 0 && pDx3 > 0 && pDx4 > 0 )
 71   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi <<  97   {
 72                                                <<  98     fDz=pDz;
 73   fDy1 = pDy1; fDx1 = pDx1; fDx2 = pDx2; fTalp <<  99     fTthetaCphi=std::tan(pTheta)*std::cos(pPhi);
 74   fDy2 = pDy2; fDx3 = pDx3; fDx4 = pDx4; fTalp << 100     fTthetaSphi=std::tan(pTheta)*std::sin(pPhi);
                                                   >> 101       
                                                   >> 102     fDy1=pDy1;
                                                   >> 103     fDx1=pDx1;
                                                   >> 104     fDx2=pDx2;
                                                   >> 105     fTalpha1=std::tan(pAlp1);
                                                   >> 106      
                                                   >> 107     fDy2=pDy2;
                                                   >> 108     fDx3=pDx3;
                                                   >> 109     fDx4=pDx4;
                                                   >> 110     fTalpha2=std::tan(pAlp2);
 75                                                   111 
 76   CheckParameters();                           << 112     MakePlanes();
 77   MakePlanes();                                << 113   }
                                                   >> 114   else
                                                   >> 115   {
                                                   >> 116     G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl
                                                   >> 117            << "        Invalid dimensions !" << G4endl
                                                   >> 118            << "          X - "
                                                   >> 119            << pDx1 << ", " << pDx2 << ", " << pDx3 << ", " << pDx4 << G4endl
                                                   >> 120            << "          Y - " << pDy1 << ", " << pDy2 << G4endl
                                                   >> 121            << "          Z - " << pDz << G4endl;
                                                   >> 122     G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 123                 "Invalid length G4Trap parameters.");
                                                   >> 124   }
 78 }                                                 125 }
 79                                                   126 
 80 ////////////////////////////////////////////// << 127 ////////////////////////////////////////////////////////////////////////////
 81 //                                                128 //
 82 // Constructor - Design of trapezoid based on  << 129 // Constructor - Design of trapezoid based on 8 G4ThreeVector parameters, 
 83 // which are its vertices. Checking of planari << 130 // which are its vertices. Checking of planarity with preparation of 
 84 // fPlanes[] and than calculation of other mem    131 // fPlanes[] and than calculation of other members
 85                                                   132 
 86 G4Trap::G4Trap( const G4String& pName,            133 G4Trap::G4Trap( const G4String& pName,
 87                 const G4ThreeVector pt[8] )       134                 const G4ThreeVector pt[8] )
 88   : G4CSGSolid(pName), halfCarTolerance(0.5*kC << 135   : G4CSGSolid(pName)
 89 {                                                 136 {
 90   // Start with check of centering - the cente    137   // Start with check of centering - the center of gravity trap line
 91   // should cross the origin of frame             138   // should cross the origin of frame
 92   //                                           << 
 93   if (  pt[0].z() >= 0                         << 
 94         || pt[0].z() != pt[1].z()              << 
 95         || pt[0].z() != pt[2].z()              << 
 96         || pt[0].z() != pt[3].z()              << 
 97                                                << 
 98         || pt[4].z() <= 0                      << 
 99         || pt[4].z() != pt[5].z()              << 
100         || pt[4].z() != pt[6].z()              << 
101         || pt[4].z() != pt[7].z()              << 
102                                                << 
103         || std::fabs( pt[0].z() + pt[4].z() )  << 
104                                                << 
105         || pt[0].y() != pt[1].y()              << 
106         || pt[2].y() != pt[3].y()              << 
107         || pt[4].y() != pt[5].y()              << 
108         || pt[6].y() != pt[7].y()              << 
109                                                << 
110         || std::fabs(pt[0].y()+pt[2].y()+pt[4] << 
111         || std::fabs(pt[0].x()+pt[1].x()+pt[4] << 
112                      pt[2].x()+pt[3].x()+pt[6] << 
113   {                                            << 
114     std::ostringstream message;                << 
115     message << "Invalid vertice coordinates fo << 
116     G4Exception("G4Trap::G4Trap()", "GeomSolid << 
117                 FatalException, message);      << 
118   }                                            << 
119                                                   139 
120   // Set parameters                            << 140   if (   pt[0].z() < 0 
121   //                                           << 141       && pt[0].z() == pt[1].z() && pt[0].z() == pt[2].z() && pt[0].z() == pt[3].z()
122   fDz = (pt[7]).z();                           << 142       && pt[4].z() > 0 
123                                                << 143       && pt[4].z() == pt[5].z() && pt[4].z() == pt[6].z() && pt[4].z() == pt[7].z()
124   fDy1     = ((pt[2]).y()-(pt[1]).y())*0.5;    << 144       && ( pt[0].z() + pt[4].z() ) == 0
125   fDx1     = ((pt[1]).x()-(pt[0]).x())*0.5;    << 145       && pt[0].y() == pt[1].y() && pt[2].y() == pt[3].y()
126   fDx2     = ((pt[3]).x()-(pt[2]).x())*0.5;    << 146       && pt[4].y() == pt[5].y() && pt[6].y() == pt[7].y()
127   fTalpha1 = ((pt[2]).x()+(pt[3]).x()-(pt[1]). << 147       && ( pt[0].y() + pt[2].y() + pt[4].y() + pt[6].y() ) == 0 
128                                                << 148       && ( pt[0].x() + pt[1].x() + pt[4].x() + pt[5].x() + 
129   fDy2     = ((pt[6]).y()-(pt[5]).y())*0.5;    << 149            pt[2].x() + pt[3].x() + pt[6].x() + pt[7].x() ) == 0 )
130   fDx3     = ((pt[5]).x()-(pt[4]).x())*0.5;    << 150   {
131   fDx4     = ((pt[7]).x()-(pt[6]).x())*0.5;    << 151     G4bool good;
132   fTalpha2 = ((pt[6]).x()+(pt[7]).x()-(pt[5]). << 152     
                                                   >> 153     // Bottom side with normal approx. -Y
                                                   >> 154     
                                                   >> 155     good = MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
                                                   >> 156 
                                                   >> 157     if (!good)
                                                   >> 158     {
                                                   >> 159       DumpInfo();
                                                   >> 160       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 161                   "Face at ~-Y not planar.");
                                                   >> 162     }
                                                   >> 163 
                                                   >> 164     // Top side with normal approx. +Y
                                                   >> 165     
                                                   >> 166     good = MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
                                                   >> 167 
                                                   >> 168     if (!good)
                                                   >> 169     {
                                                   >> 170       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 171       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 172                   "Face at ~+Y not planar.");
                                                   >> 173     }
                                                   >> 174 
                                                   >> 175     // Front side with normal approx. -X
                                                   >> 176     
                                                   >> 177     good = MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
                                                   >> 178 
                                                   >> 179     if (!good)
                                                   >> 180     {
                                                   >> 181       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 182       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 183                   "Face at ~-X not planar.");
                                                   >> 184     }
                                                   >> 185 
                                                   >> 186     // Back side iwth normal approx. +X
                                                   >> 187     
                                                   >> 188     good = MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
                                                   >> 189     if (!good)
                                                   >> 190     {
                                                   >> 191       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 192       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 193                   "Face at ~+X not planar.");
                                                   >> 194     }
                                                   >> 195     fDz = (pt[7]).z() ;
                                                   >> 196       
                                                   >> 197     fDy1     = ((pt[2]).y()-(pt[1]).y())*0.5;
                                                   >> 198     fDx1     = ((pt[1]).x()-(pt[0]).x())*0.5;
                                                   >> 199     fDx2     = ((pt[3]).x()-(pt[2]).x())*0.5;
                                                   >> 200     fTalpha1 = ((pt[2]).x()+(pt[3]).x()-(pt[1]).x()-(pt[0]).x())*0.25/fDy1;
                                                   >> 201 
                                                   >> 202     fDy2     = ((pt[6]).y()-(pt[5]).y())*0.5;
                                                   >> 203     fDx3     = ((pt[5]).x()-(pt[4]).x())*0.5;
                                                   >> 204     fDx4     = ((pt[7]).x()-(pt[6]).x())*0.5;
                                                   >> 205     fTalpha2 = ((pt[6]).x()+(pt[7]).x()-(pt[5]).x()-(pt[4]).x())*0.25/fDy2;
133                                                   206 
134   fTthetaCphi = ((pt[4]).x()+fDy2*fTalpha2+fDx << 207     fTthetaCphi = ((pt[4]).x()+fDy2*fTalpha2+fDx3)/fDz;
135   fTthetaSphi = ((pt[4]).y()+fDy2)/fDz;        << 208     fTthetaSphi = ((pt[4]).y()+fDy2)/fDz;
136                                                << 209   }
137   CheckParameters();                           << 210   else
138   MakePlanes(pt);                              << 211   {
                                                   >> 212     G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 213     G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 214                   "Invalid vertice coordinates.");
                                                   >> 215   }
139 }                                                 216 }
140                                                   217 
141 ////////////////////////////////////////////// << 218 //////////////////////////////////////////////////////////////////////////////
142 //                                                219 //
143 // Constructor for Right Angular Wedge from ST    220 // Constructor for Right Angular Wedge from STEP
144                                                   221 
145 G4Trap::G4Trap( const G4String& pName,            222 G4Trap::G4Trap( const G4String& pName,
146                       G4double pZ,                223                       G4double pZ,
147                       G4double pY,                224                       G4double pY,
148                       G4double pX, G4double pL    225                       G4double pX, G4double pLTX )
149   : G4CSGSolid(pName), halfCarTolerance(0.5*kC << 226   : G4CSGSolid(pName) 
                                                   >> 227          
150 {                                                 228 {
151   fDz  = 0.5*pZ; fTthetaCphi = 0; fTthetaSphi  << 229   G4bool good;
152   fDy1 = 0.5*pY; fDx1 = 0.5*pX; fDx2 = 0.5*pLT << 230 
153   fDy2 = fDy1;   fDx3 = fDx1;   fDx4 = fDx2;   << 231   if ( pZ>0 && pY>0 && pX>0 && pLTX>0 && pLTX<=pX )
                                                   >> 232   {
                                                   >> 233     fDz = 0.5*pZ ;
                                                   >> 234     fTthetaCphi = 0 ;
                                                   >> 235     fTthetaSphi = 0 ;
                                                   >> 236 
                                                   >> 237     fDy1 = 0.5*pY;
                                                   >> 238     fDx1 = 0.5*pX ;
                                                   >> 239     fDx2 = 0.5*pLTX;
                                                   >> 240     fTalpha1 =  0.5*(pLTX - pX)/pY;
                                                   >> 241 
                                                   >> 242     fDy2 = fDy1 ;
                                                   >> 243     fDx3 = fDx1;
                                                   >> 244     fDx4 = fDx2 ;
                                                   >> 245     fTalpha2 = fTalpha1 ;
                                                   >> 246 
                                                   >> 247     G4ThreeVector pt[8] ;
                                                   >> 248 
                                                   >> 249     pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
                                                   >> 250                         -fDz*fTthetaSphi-fDy1,-fDz);
                                                   >> 251     pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
                                                   >> 252                         -fDz*fTthetaSphi-fDy1,-fDz);
                                                   >> 253     pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
                                                   >> 254                         -fDz*fTthetaSphi+fDy1,-fDz);
                                                   >> 255     pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
                                                   >> 256                         -fDz*fTthetaSphi+fDy1,-fDz);
                                                   >> 257     pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
                                                   >> 258                         +fDz*fTthetaSphi-fDy2,+fDz);
                                                   >> 259     pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
                                                   >> 260                         +fDz*fTthetaSphi-fDy2,+fDz);
                                                   >> 261     pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
                                                   >> 262                         +fDz*fTthetaSphi+fDy2,+fDz);
                                                   >> 263     pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
                                                   >> 264                         +fDz*fTthetaSphi+fDy2,+fDz);
                                                   >> 265 
                                                   >> 266     // Bottom side with normal approx. -Y
                                                   >> 267     //
                                                   >> 268     good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
                                                   >> 269     if (!good)
                                                   >> 270     {
                                                   >> 271       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 272       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 273                   "Face at ~-Y not planar.");
                                                   >> 274     }
                                                   >> 275 
                                                   >> 276     // Top side with normal approx. +Y
                                                   >> 277     //
                                                   >> 278     good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
                                                   >> 279     if (!good)
                                                   >> 280     {
                                                   >> 281       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 282       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 283                   "Face at ~+Y not planar.");
                                                   >> 284     }
                                                   >> 285 
                                                   >> 286     // Front side with normal approx. -X
                                                   >> 287     //
                                                   >> 288     good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
                                                   >> 289     if (!good)
                                                   >> 290     {
                                                   >> 291       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 292       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 293                   "Face at ~-X not planar.");
                                                   >> 294     }
154                                                   295 
155   CheckParameters();                           << 296     // Back side iwth normal approx. +X
156   MakePlanes();                                << 297     //
                                                   >> 298     good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
                                                   >> 299     if (!good)
                                                   >> 300     {
                                                   >> 301       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 302       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 303                   "Face at ~+X not planar.");
                                                   >> 304     }
                                                   >> 305   }
                                                   >> 306     else
                                                   >> 307   {
                                                   >> 308     G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 309     G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 310                 "Invalid length G4Trap parameters.");
                                                   >> 311   }
157 }                                                 312 }
158                                                   313 
159 ////////////////////////////////////////////// << 314 ///////////////////////////////////////////////////////////////////////////////
160 //                                                315 //
161 // Constructor for G4Trd                          316 // Constructor for G4Trd
162                                                   317 
163 G4Trap::G4Trap( const G4String& pName,            318 G4Trap::G4Trap( const G4String& pName,
164                       G4double pDx1,  G4double    319                       G4double pDx1,  G4double pDx2,
165                       G4double pDy1,  G4double    320                       G4double pDy1,  G4double pDy2,
166                       G4double pDz )              321                       G4double pDz )
167   : G4CSGSolid(pName), halfCarTolerance(0.5*kC << 322   : G4CSGSolid(pName)
168 {                                                 323 {
169   fDz  = pDz;  fTthetaCphi = 0; fTthetaSphi =  << 324   G4bool good;
170   fDy1 = pDy1; fDx1 = pDx1; fDx2 = pDx1; fTalp << 325 
171   fDy2 = pDy2; fDx3 = pDx2; fDx4 = pDx2; fTalp << 326   if ( pDz>0 && pDy1>0 && pDx1>0 && pDx2>0 && pDy2>0 )
                                                   >> 327   {
                                                   >> 328     fDz = pDz;
                                                   >> 329     fTthetaCphi = 0 ;
                                                   >> 330     fTthetaSphi = 0 ;
                                                   >> 331       
                                                   >> 332     fDy1 = pDy1 ;
                                                   >> 333     fDx1 = pDx1 ;
                                                   >> 334     fDx2 = pDx1 ;
                                                   >> 335     fTalpha1 = 0 ;
                                                   >> 336      
                                                   >> 337     fDy2 = pDy2 ;
                                                   >> 338     fDx3 = pDx2 ;
                                                   >> 339     fDx4 = pDx2 ;
                                                   >> 340     fTalpha2 = 0 ;
                                                   >> 341 
                                                   >> 342     G4ThreeVector pt[8] ;
                                                   >> 343      
                                                   >> 344     pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
                                                   >> 345                         -fDz*fTthetaSphi-fDy1,-fDz);
                                                   >> 346     pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
                                                   >> 347                         -fDz*fTthetaSphi-fDy1,-fDz);
                                                   >> 348     pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
                                                   >> 349                         -fDz*fTthetaSphi+fDy1,-fDz);
                                                   >> 350     pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
                                                   >> 351                         -fDz*fTthetaSphi+fDy1,-fDz);
                                                   >> 352     pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
                                                   >> 353                         +fDz*fTthetaSphi-fDy2,+fDz);
                                                   >> 354     pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
                                                   >> 355                         +fDz*fTthetaSphi-fDy2,+fDz);
                                                   >> 356     pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
                                                   >> 357                         +fDz*fTthetaSphi+fDy2,+fDz);
                                                   >> 358     pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
                                                   >> 359                         +fDz*fTthetaSphi+fDy2,+fDz);
                                                   >> 360 
                                                   >> 361     // Bottom side with normal approx. -Y
                                                   >> 362     //
                                                   >> 363     good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
                                                   >> 364     if (!good)
                                                   >> 365     {
                                                   >> 366       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 367       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 368                   "Face at ~-Y not planar.");
                                                   >> 369     }
                                                   >> 370 
                                                   >> 371     // Top side with normal approx. +Y
                                                   >> 372     //
                                                   >> 373     good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
                                                   >> 374     if (!good)
                                                   >> 375     {
                                                   >> 376       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 377       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 378                   "Face at ~+Y not planar.");
                                                   >> 379     }
172                                                   380 
173   CheckParameters();                           << 381     // Front side with normal approx. -X
174   MakePlanes();                                << 382     //
                                                   >> 383     good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
                                                   >> 384     if (!good)
                                                   >> 385     {
                                                   >> 386       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 387       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 388                   "Face at ~-X not planar.");
                                                   >> 389     }
                                                   >> 390 
                                                   >> 391     // Back side iwth normal approx. +X
                                                   >> 392     //
                                                   >> 393     good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
                                                   >> 394     if (!good)
                                                   >> 395     {
                                                   >> 396       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 397       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 398                   "Face at ~+X not planar.");
                                                   >> 399     }
                                                   >> 400   }
                                                   >> 401   else
                                                   >> 402   {
                                                   >> 403     G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 404     G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 405                 "Invalid length G4Trap parameters.");
                                                   >> 406   }
175 }                                                 407 }
176                                                   408 
177 ////////////////////////////////////////////// << 409 ////////////////////////////////////////////////////////////////////////////
178 //                                                410 //
179 // Constructor for G4Para                         411 // Constructor for G4Para
180                                                   412 
181 G4Trap::G4Trap( const G4String& pName,            413 G4Trap::G4Trap( const G4String& pName,
182                       G4double pDx, G4double p    414                       G4double pDx, G4double pDy,
183                       G4double pDz,               415                       G4double pDz,
184                       G4double pAlpha,            416                       G4double pAlpha,
185                       G4double pTheta, G4doubl << 417                       G4double pTheta, G4double pPhi)
186   : G4CSGSolid(pName), halfCarTolerance(0.5*kC << 418   : G4CSGSolid(pName)       
187 {                                                 419 {
188   fDz = pDz;                                   << 420   G4bool good;
189   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi << 421 
190   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi << 422   if ( pDz>0 && pDy>0 && pDx>0 )
                                                   >> 423   {
                                                   >> 424     fDz = pDz ;
                                                   >> 425     fTthetaCphi = std::tan(pTheta)*std::cos(pPhi) ;
                                                   >> 426     fTthetaSphi = std::tan(pTheta)*std::sin(pPhi) ;
                                                   >> 427      
                                                   >> 428     fDy1 = pDy ;
                                                   >> 429     fDx1 = pDx ;
                                                   >> 430     fDx2 = pDx ;
                                                   >> 431     fTalpha1 = std::tan(pAlpha) ;
                                                   >> 432     
                                                   >> 433     fDy2 = pDy ;
                                                   >> 434     fDx3 = pDx ;
                                                   >> 435     fDx4 = pDx ;
                                                   >> 436     fTalpha2 = fTalpha1 ;
                                                   >> 437 
                                                   >> 438     G4ThreeVector pt[8] ;
                                                   >> 439      
                                                   >> 440     pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
                                                   >> 441                         -fDz*fTthetaSphi-fDy1,-fDz);
                                                   >> 442     pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
                                                   >> 443                         -fDz*fTthetaSphi-fDy1,-fDz);
                                                   >> 444     pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
                                                   >> 445                         -fDz*fTthetaSphi+fDy1,-fDz);
                                                   >> 446     pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
                                                   >> 447                         -fDz*fTthetaSphi+fDy1,-fDz);
                                                   >> 448     pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
                                                   >> 449                         +fDz*fTthetaSphi-fDy2,+fDz);
                                                   >> 450     pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
                                                   >> 451                         +fDz*fTthetaSphi-fDy2,+fDz);
                                                   >> 452     pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
                                                   >> 453                         +fDz*fTthetaSphi+fDy2,+fDz);
                                                   >> 454     pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
                                                   >> 455                         +fDz*fTthetaSphi+fDy2,+fDz);
                                                   >> 456 
                                                   >> 457     // Bottom side with normal approx. -Y
                                                   >> 458     //
                                                   >> 459     good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
                                                   >> 460     if (!good)
                                                   >> 461     {
                                                   >> 462       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 463       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 464                   "Face at ~-Y not planar.");
                                                   >> 465     }
191                                                   466 
192   fDy1 = pDy; fDx1 = pDx; fDx2 = pDx; fTalpha1 << 467     // Top side with normal approx. +Y
193   fDy2 = pDy; fDx3 = pDx; fDx4 = pDx; fTalpha2 << 468     //
                                                   >> 469     good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
                                                   >> 470     if (!good)
                                                   >> 471     {
                                                   >> 472       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 473       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 474                   "Face at ~+Y not planar.");
                                                   >> 475     }
194                                                   476 
195   CheckParameters();                           << 477     // Front side with normal approx. -X
196   MakePlanes();                                << 478     //
                                                   >> 479     good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
                                                   >> 480     if (!good)
                                                   >> 481     {
                                                   >> 482       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 483       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 484                   "Face at ~-X not planar.");
                                                   >> 485     }
                                                   >> 486 
                                                   >> 487     // Back side iwth normal approx. +X
                                                   >> 488     //
                                                   >> 489     good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
                                                   >> 490     if (!good)
                                                   >> 491     {
                                                   >> 492       G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 493       G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 494                   "Face at ~+X not planar.");
                                                   >> 495     }
                                                   >> 496   }
                                                   >> 497   else
                                                   >> 498   {
                                                   >> 499     G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
                                                   >> 500     G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
                                                   >> 501                 "Invalid length G4Trap parameters.");
                                                   >> 502   }
197 }                                                 503 }
198                                                   504 
199 ////////////////////////////////////////////// << 505 ///////////////////////////////////////////////////////////////////////////
200 //                                                506 //
201 // Nominal constructor for G4Trap whose parame    507 // Nominal constructor for G4Trap whose parameters are to be set by
202 // a G4VParamaterisation later.  Check and set    508 // a G4VParamaterisation later.  Check and set half-widths as well as
203 // angles: final check of coplanarity             509 // angles: final check of coplanarity
204                                                   510 
205 G4Trap::G4Trap( const G4String& pName )           511 G4Trap::G4Trap( const G4String& pName )
206   : G4CSGSolid (pName), halfCarTolerance(0.5*k << 512   : G4CSGSolid (pName),
207     fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.), << 513     fDz         (1.),
208     fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.) << 514     fTthetaCphi (0.),
209     fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.) << 515     fTthetaSphi (0.),
210 {                                              << 516     fDy1        (1.),
211   MakePlanes();                                << 517     fDx1        (1.),
212 }                                              << 518     fDx2        (1.),
213                                                << 519     fTalpha1    (0.),
214 ////////////////////////////////////////////// << 520     fDy2        (1.),
215 //                                             << 521     fDx3        (1.),
216 // Fake default constructor - sets only member << 522     fDx4        (1.),
217 //                            for usage restri << 523     fTalpha2    (0.)
218 //                                             << 
219 G4Trap::G4Trap( __void__& a )                  << 
220   : G4CSGSolid(a), halfCarTolerance(0.5*kCarTo << 
221     fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.), << 
222     fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.) << 
223     fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.) << 
224 {                                              << 
225   MakePlanes();                                << 
226 }                                              << 
227                                                << 
228 ////////////////////////////////////////////// << 
229 //                                             << 
230 // Destructor                                  << 
231                                                << 
232 G4Trap::~G4Trap() = default;                   << 
233                                                << 
234 ////////////////////////////////////////////// << 
235 //                                             << 
236 // Copy constructor                            << 
237                                                << 
238 G4Trap::G4Trap(const G4Trap& rhs)              << 
239   : G4CSGSolid(rhs), halfCarTolerance(rhs.half << 
240     fDz(rhs.fDz), fTthetaCphi(rhs.fTthetaCphi) << 
241     fDy1(rhs.fDy1), fDx1(rhs.fDx1), fDx2(rhs.f << 
242     fDy2(rhs.fDy2), fDx3(rhs.fDx3), fDx4(rhs.f << 
243 {                                              << 
244   for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs << 
245   for (G4int i=0; i<6; ++i) { fAreas[i] = rhs. << 
246   fTrapType = rhs.fTrapType;                   << 
247 }                                              << 
248                                                << 
249 ////////////////////////////////////////////// << 
250 //                                             << 
251 // Assignment operator                         << 
252                                                << 
253 G4Trap& G4Trap::operator = (const G4Trap& rhs) << 
254 {                                                 524 {
255   // Check assignment to self                  << 525  MakePlanes();
256   //                                           << 
257   if (this == &rhs)  { return *this; }         << 
258                                                << 
259   // Copy base class data                      << 
260   //                                           << 
261   G4CSGSolid::operator=(rhs);                  << 
262                                                << 
263   // Copy data                                 << 
264   //                                           << 
265   halfCarTolerance = rhs.halfCarTolerance;     << 
266   fDz = rhs.fDz; fTthetaCphi = rhs.fTthetaCphi << 
267   fDy1 = rhs.fDy1; fDx1 = rhs.fDx1; fDx2 = rhs << 
268   fDy2 = rhs.fDy2; fDx3 = rhs.fDx3; fDx4 = rhs << 
269   for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs << 
270   for (G4int i=0; i<6; ++i) { fAreas[i] = rhs. << 
271   fTrapType = rhs.fTrapType;                   << 
272   return *this;                                << 
273 }                                                 526 }
274                                                   527 
275 ////////////////////////////////////////////// << 528 ///////////////////////////////////////////////////////////////////////
276 //                                                529 //
277 // Set all parameters, as for constructor - ch    530 // Set all parameters, as for constructor - check and set half-widths
278 // as well as angles: final check of coplanari    531 // as well as angles: final check of coplanarity
279                                                   532 
280 void G4Trap::SetAllParameters ( G4double pDz,     533 void G4Trap::SetAllParameters ( G4double pDz,
281                                 G4double pThet    534                                 G4double pTheta,
282                                 G4double pPhi,    535                                 G4double pPhi,
283                                 G4double pDy1,    536                                 G4double pDy1,
284                                 G4double pDx1,    537                                 G4double pDx1,
285                                 G4double pDx2,    538                                 G4double pDx2,
286                                 G4double pAlp1    539                                 G4double pAlp1,
287                                 G4double pDy2,    540                                 G4double pDy2,
288                                 G4double pDx3,    541                                 G4double pDx3,
289                                 G4double pDx4,    542                                 G4double pDx4,
290                                 G4double pAlp2    543                                 G4double pAlp2 )
291 {                                                 544 {
292   // Reset data of the base class              << 545   fCubicVolume= 0.;
293   fCubicVolume = 0;                            << 546   fpPolyhedron = 0;
294   fSurfaceArea = 0;                            << 547   if ( pDz>0 && pDy1>0 && pDx1>0 && pDx2>0 && pDy2>0 && pDx3>0 && pDx4>0 )
295   fRebuildPolyhedron = true;                   << 548   {
296                                                << 549     fDz=pDz;
297   // Set parameters                            << 550     fTthetaCphi=std::tan(pTheta)*std::cos(pPhi);
298   fDz = pDz;                                   << 551     fTthetaSphi=std::tan(pTheta)*std::sin(pPhi);
299   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi << 552      
300   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi << 553     fDy1=pDy1;
301                                                << 554     fDx1=pDx1;
302   fDy1 = pDy1; fDx1 = pDx1; fDx2 = pDx2; fTalp << 555     fDx2=pDx2;
303   fDy2 = pDy2; fDx3 = pDx3; fDx4 = pDx4; fTalp << 556     fTalpha1=std::tan(pAlp1);
                                                   >> 557     
                                                   >> 558     fDy2=pDy2;
                                                   >> 559     fDx3=pDx3;
                                                   >> 560     fDx4=pDx4;
                                                   >> 561     fTalpha2=std::tan(pAlp2);
304                                                   562 
305   CheckParameters();                           << 563     MakePlanes();
306   MakePlanes();                                << 564   }
307 }                                              << 565   else
308                                                << 566   {
309 ////////////////////////////////////////////// << 567     G4cerr << "ERROR - G4Trap()::SetAllParameters(): " << GetName() << G4endl
310 //                                             << 568            << "        Invalid dimensions !" << G4endl
311 // Check length parameters                     << 569            << "          X - "
312                                                << 570            << pDx1 << ", " << pDx2 << ", " << pDx3 << ", " << pDx4 << G4endl
313 void G4Trap::CheckParameters()                 << 571            << "          Y - " << pDy1 << ", " << pDy2 << G4endl
314 {                                              << 572            << "          Z - " << pDz << G4endl;
315   if (fDz<=0 ||                                << 573     G4Exception("G4Trap::SetAllParameters()", "InvalidSetup",
316       fDy1<=0 || fDx1<=0 || fDx2<=0 ||         << 574                 FatalException, "Invalid Length Parameters.");
317       fDy2<=0 || fDx3<=0 || fDx4<=0)           << 
318   {                                            << 
319     std::ostringstream message;                << 
320     message << "Invalid Length Parameters for  << 
321             << "\n  X - " <<fDx1<<", "<<fDx2<< << 
322             << "\n  Y - " <<fDy1<<", "<<fDy2   << 
323             << "\n  Z - " <<fDz;               << 
324     G4Exception("G4Trap::CheckParameters()", " << 
325                 FatalException, message);      << 
326   }                                               575   }
327 }                                                 576 }
328                                                   577 
329 //////////////////////////////////////////////    578 //////////////////////////////////////////////////////////////////////////
330 //                                                579 //
331 // Compute vertices and set side planes        << 580 // Checking of coplanarity
332                                                << 581 
333 void G4Trap::MakePlanes()                      << 582 G4bool G4Trap::MakePlanes()
334 {                                              << 583 {
335   G4double DzTthetaCphi = fDz*fTthetaCphi;     << 584   G4bool good = true;
336   G4double DzTthetaSphi = fDz*fTthetaSphi;     << 585 
337   G4double Dy1Talpha1   = fDy1*fTalpha1;       << 586   G4ThreeVector pt[8] ;
338   G4double Dy2Talpha2   = fDy2*fTalpha2;       << 587      
339                                                << 588   pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
340   G4ThreeVector pt[8] =                        << 589                       -fDz*fTthetaSphi-fDy1,-fDz);
341   {                                            << 590   pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
342     G4ThreeVector(-DzTthetaCphi-Dy1Talpha1-fDx << 591                       -fDz*fTthetaSphi-fDy1,-fDz);
343     G4ThreeVector(-DzTthetaCphi-Dy1Talpha1+fDx << 592   pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
344     G4ThreeVector(-DzTthetaCphi+Dy1Talpha1-fDx << 593                       -fDz*fTthetaSphi+fDy1,-fDz);
345     G4ThreeVector(-DzTthetaCphi+Dy1Talpha1+fDx << 594   pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
346     G4ThreeVector( DzTthetaCphi-Dy2Talpha2-fDx << 595                       -fDz*fTthetaSphi+fDy1,-fDz);
347     G4ThreeVector( DzTthetaCphi-Dy2Talpha2+fDx << 596   pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
348     G4ThreeVector( DzTthetaCphi+Dy2Talpha2-fDx << 597                       +fDz*fTthetaSphi-fDy2,+fDz);
349     G4ThreeVector( DzTthetaCphi+Dy2Talpha2+fDx << 598   pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
350   };                                           << 599                       +fDz*fTthetaSphi-fDy2,+fDz);
351                                                << 600   pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
352   MakePlanes(pt);                              << 601                       +fDz*fTthetaSphi+fDy2,+fDz);
353 }                                              << 602   pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
354                                                << 603                       +fDz*fTthetaSphi+fDy2,+fDz);
355 ////////////////////////////////////////////// << 
356 //                                             << 
357 // Set side planes, check planarity            << 
358                                                   604 
359 void G4Trap::MakePlanes(const G4ThreeVector pt << 605   // Bottom side with normal approx. -Y
360 {                                              << 606   //
361   constexpr G4int iface[4][4] = { {0,4,5,1}, { << 607   good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]) ;
362   const static G4String side[4] = { "~-Y", "~+ << 608   if (!good)
                                                   >> 609   {
                                                   >> 610     G4cerr << "ERROR - G4Trap()::MakePlanes(): " << GetName() << G4endl;
                                                   >> 611     G4Exception("G4Trap::MakePlanes()", "InvalidSetup", FatalException,
                                                   >> 612                 "Face at ~-Y not planar.");
                                                   >> 613   }
363                                                   614 
364   for (G4int i=0; i<4; ++i)                    << 615   // Top side with normal approx. +Y
                                                   >> 616   //
                                                   >> 617   good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
                                                   >> 618   if (!good)
365   {                                               619   {
366     if (MakePlane(pt[iface[i][0]],             << 620     G4cerr << "ERROR - G4Trap()::MakePlanes(): " << GetName() << G4endl;
367                   pt[iface[i][1]],             << 621     G4Exception("G4Trap::MakePlanes()", "InvalidSetup", FatalException,
368                   pt[iface[i][2]],             << 622                 "Face at ~+Y not planar.");
369                   pt[iface[i][3]],             << 623   }
370                   fPlanes[i])) continue;       << 
371                                                   624 
372     // Non planar side face                    << 625   // Front side with normal approx. -X
373     G4ThreeVector normal(fPlanes[i].a,fPlanes[ << 626   //
374     G4double dmax = 0;                         << 627   good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
375     for (G4int k=0; k<4; ++k)                  << 628   if (!good)
376     {                                          << 629   {
377       G4double dist = normal.dot(pt[iface[i][k << 630     G4cerr << "ERROR - G4Trap()::MakePlanes(): " << GetName() << G4endl;
378       if (std::abs(dist) > std::abs(dmax)) dma << 631     G4Exception("G4Trap::MakePlanes()", "InvalidSetup", FatalException,
379     }                                          << 632                 "Face at ~-X not planar.");
380     std::ostringstream message;                << 633   }
381     message << "Side face " << side[i] << " is << 634    
382             << GetName() << "\nDiscrepancy: "  << 635   // Back side iwth normal approx. +X
383     StreamInfo(message);                       << 636   //
384     G4Exception("G4Trap::MakePlanes()", "GeomS << 637   good = MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
385                 FatalException, message);      << 638   if ( !good )
                                                   >> 639   {
                                                   >> 640     G4cerr << "ERROR - G4Trap()::MakePlanes(): " << GetName() << G4endl;
                                                   >> 641     G4Exception("G4Trap::MakePlanes()", "InvalidSetup", FatalException,
                                                   >> 642                 "Face at ~+X not planar");
386   }                                               643   }
387                                                   644 
388   // Re-compute parameters                     << 645   return good;
389   SetCachedValues();                           << 
390 }                                                 646 }
391                                                   647 
392 ////////////////////////////////////////////// << 648 //////////////////////////////////////////////////////////////////////////////
393 //                                                649 //
394 // Calculate the coef's of the plane p1->p2->p    650 // Calculate the coef's of the plane p1->p2->p3->p4->p1
395 // where the ThreeVectors 1-4 are in anti-cloc << 651 // where the ThreeVectors 1-4 are in anti-clockwise order when viewed from
396 // from infront of the plane (i.e. from normal << 652 // infront of the plane (i.e. from normal direction).
397 //                                                653 //
398 // Return true if the points are coplanar, fal << 654 // Return true if the ThreeVectors are coplanar + set coef;s
                                                   >> 655 //        false if ThreeVectors are not coplanar
399                                                   656 
400 G4bool G4Trap::MakePlane( const G4ThreeVector&    657 G4bool G4Trap::MakePlane( const G4ThreeVector& p1,
401                           const G4ThreeVector&    658                           const G4ThreeVector& p2,
402                           const G4ThreeVector&    659                           const G4ThreeVector& p3,
403                           const G4ThreeVector&    660                           const G4ThreeVector& p4,
404                                 TrapSidePlane&    661                                 TrapSidePlane& plane )
405 {                                                 662 {
406   G4ThreeVector normal = ((p4 - p2).cross(p3 - << 663   G4double a, b, c, s;
407   if (std::abs(normal.x()) < DBL_EPSILON) norm << 664   G4ThreeVector v12, v13, v14, Vcross;
408   if (std::abs(normal.y()) < DBL_EPSILON) norm << 
409   if (std::abs(normal.z()) < DBL_EPSILON) norm << 
410   normal = normal.unit();                      << 
411                                                << 
412   G4ThreeVector centre = (p1 + p2 + p3 + p4)*0 << 
413   plane.a =  normal.x();                       << 
414   plane.b =  normal.y();                       << 
415   plane.c =  normal.z();                       << 
416   plane.d = -normal.dot(centre);               << 
417                                                << 
418   // compute distances and check planarity     << 
419   G4double d1 = std::abs(normal.dot(p1) + plan << 
420   G4double d2 = std::abs(normal.dot(p2) + plan << 
421   G4double d3 = std::abs(normal.dot(p3) + plan << 
422   G4double d4 = std::abs(normal.dot(p4) + plan << 
423   G4double dmax = std::max(std::max(std::max(d << 
424                                                   665 
425   return dmax <= 1000 * kCarTolerance;         << 666   G4bool good;
426 }                                              << 
427                                                << 
428 ////////////////////////////////////////////// << 
429 //                                             << 
430 // Recompute parameters using planes           << 
431                                                << 
432 void G4Trap::SetCachedValues()                 << 
433 {                                              << 
434   // Set indeces                               << 
435   constexpr  G4int iface[6][4] =               << 
436       { {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2, << 
437                                                << 
438   // Get vertices                              << 
439   G4ThreeVector pt[8];                         << 
440   GetVertices(pt);                             << 
441                                                << 
442   // Set face areas                            << 
443   for (G4int i=0; i<6; ++i)                    << 
444   {                                            << 
445     fAreas[i] = G4GeomTools::QuadAreaNormal(pt << 
446                                             pt << 
447                                             pt << 
448                                             pt << 
449   }                                            << 
450   for (G4int i=1; i<6; ++i) { fAreas[i] += fAr << 
451                                                << 
452   // Define type of trapezoid                  << 
453   fTrapType = 0;                               << 
454   if (fPlanes[0].b  == -1 && fPlanes[1].b == 1 << 
455       std::abs(fPlanes[0].a) < DBL_EPSILON &&  << 
456       std::abs(fPlanes[0].c) < DBL_EPSILON &&  << 
457       std::abs(fPlanes[1].a) < DBL_EPSILON &&  << 
458       std::abs(fPlanes[1].c) < DBL_EPSILON)    << 
459   {                                            << 
460     fTrapType = 1; // YZ section is a rectangl << 
461     if (std::abs(fPlanes[2].a + fPlanes[3].a)  << 
462         std::abs(fPlanes[2].c - fPlanes[3].c)  << 
463         fPlanes[2].b == 0 &&                   << 
464         fPlanes[3].b == 0)                     << 
465     {                                          << 
466       fTrapType = 2; // ... and XZ section is  << 
467       fPlanes[2].a = -fPlanes[3].a;            << 
468       fPlanes[2].c =  fPlanes[3].c;            << 
469     }                                          << 
470     if (std::abs(fPlanes[2].a + fPlanes[3].a)  << 
471         std::abs(fPlanes[2].b - fPlanes[3].b)  << 
472         fPlanes[2].c == 0 &&                   << 
473         fPlanes[3].c == 0)                     << 
474     {                                          << 
475       fTrapType = 3; // ... and XY section is  << 
476       fPlanes[2].a = -fPlanes[3].a;            << 
477       fPlanes[2].b =  fPlanes[3].b;            << 
478     }                                          << 
479   }                                            << 
480 }                                              << 
481                                                   667 
482 ////////////////////////////////////////////// << 668   v12    = p2 - p1;
483 //                                             << 669   v13    = p3 - p1;
484 // Get volume                                  << 670   v14    = p4 - p1;
                                                   >> 671   Vcross = v12.cross(v13);
485                                                   672 
486 G4double G4Trap::GetCubicVolume()              << 673   if (std::fabs(Vcross.dot(v14)/(Vcross.mag()*v14.mag())) > kCoplanar_Tolerance)
487 {                                              << 
488   if (fCubicVolume == 0)                       << 
489   {                                               674   {
490     G4ThreeVector pt[8];                       << 675     good = false;
491     GetVertices(pt);                           << 
492                                                << 
493     G4double dz  = pt[4].z() - pt[0].z();      << 
494     G4double dy1 = pt[2].y() - pt[0].y();      << 
495     G4double dx1 = pt[1].x() - pt[0].x();      << 
496     G4double dx2 = pt[3].x() - pt[2].x();      << 
497     G4double dy2 = pt[6].y() - pt[4].y();      << 
498     G4double dx3 = pt[5].x() - pt[4].x();      << 
499     G4double dx4 = pt[7].x() - pt[6].x();      << 
500                                                << 
501     fCubicVolume = ((dx1 + dx2 + dx3 + dx4)*(d << 
502                     (dx4 + dx3 - dx2 - dx1)*(d << 
503   }                                               676   }
504   return fCubicVolume;                         << 677   else
505 }                                              << 
506                                                << 
507 ////////////////////////////////////////////// << 
508 //                                             << 
509 // Get surface area                            << 
510                                                << 
511 G4double G4Trap::GetSurfaceArea()              << 
512 {                                              << 
513   if (fSurfaceArea == 0)                       << 
514   {                                               678   {
515     G4ThreeVector pt[8];                       << 679     // a,b,c correspond to the x/y/z components of the
516     G4int iface [6][4] =                       << 680     // normal vector to the plane
517       { {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2, << 681      
518                                                << 682     //  a  = (p2.y()-p1.y())*(p1.z()+p2.z())+(p3.y()-p2.y())*(p2.z()+p3.z());
519     GetVertices(pt);                           << 683     //  a += (p4.y()-p3.y())*(p3.z()+p4.z())+(p1.y()-p4.y())*(p4.z()+p1.z()); // ?   
520     for (const auto & i : iface)               << 684     // b  = (p2.z()-p1.z())*(p1.x()+p2.x())+(p3.z()-p2.z())*(p2.x()+p3.x());
                                                   >> 685     // b += (p4.z()-p3.z())*(p3.x()+p4.x())+(p1.z()-p4.z())*(p4.x()+p1.x()); // ?      
                                                   >> 686     // c  = (p2.x()-p1.x())*(p1.y()+p2.y())+(p3.x()-p2.x())*(p2.y()+p3.y());
                                                   >> 687     // c += (p4.x()-p3.x())*(p3.y()+p4.y())+(p1.x()-p4.x())*(p4.y()+p1.y()); // ?
                                                   >> 688 
                                                   >> 689     // Let create diagonals 4-2 and 3-1 than (4-2)x(3-1) provides
                                                   >> 690     // vector perpendicular to the plane directed to outside !!!
                                                   >> 691     // and a,b,c, = f(1,2,3,4) external relative to trap normal
                                                   >> 692 
                                                   >> 693     a = +(p4.y() - p2.y())*(p3.z() - p1.z())
                                                   >> 694         - (p3.y() - p1.y())*(p4.z() - p2.z());
                                                   >> 695 
                                                   >> 696     b = -(p4.x() - p2.x())*(p3.z() - p1.z())
                                                   >> 697         + (p3.x() - p1.x())*(p4.z() - p2.z());
                                                   >> 698  
                                                   >> 699     c = +(p4.x() - p2.x())*(p3.y() - p1.y())
                                                   >> 700         - (p3.x() - p1.x())*(p4.y() - p2.y());
                                                   >> 701 
                                                   >> 702     s = std::sqrt( a*a + b*b + c*c ); // so now vector plane.(a,b,c) is unit 
                                                   >> 703 
                                                   >> 704     if( s > 0 )
                                                   >> 705     {
                                                   >> 706       plane.a = a/s;
                                                   >> 707       plane.b = b/s;
                                                   >> 708       plane.c = c/s;
                                                   >> 709     }
                                                   >> 710     else
521     {                                             711     {
522       fSurfaceArea += G4GeomTools::QuadAreaNor << 712       G4cerr << "ERROR - G4Trap()::MakePlane(): " << GetName() << G4endl;
523                                                << 713       G4Exception("G4Trap::MakePlanes()", "InvalidSetup", FatalException,
524                                                << 714                   "Invalid parameters: norm.mod() <= 0") ;
525                                                << 
526     }                                             715     }
                                                   >> 716     // Calculate D: p1 in in plane so D=-n.p1.Vect()
                                                   >> 717     
                                                   >> 718     plane.d = -( plane.a*p1.x() + plane.b*p1.y() + plane.c*p1.z() );
                                                   >> 719 
                                                   >> 720     good = true;
527   }                                               721   }
528   return fSurfaceArea;                         << 722   return good;
529 }                                                 723 }
530                                                   724 
531 ////////////////////////////////////////////// << 725 //////////////////////////////////////////////////////////////////////////////
532 //                                                726 //
533 // Dispatch to parameterisation for replicatio    727 // Dispatch to parameterisation for replication mechanism dimension
534 // computation & modification.                    728 // computation & modification.
535                                                   729 
536 void G4Trap::ComputeDimensions(       G4VPVPar    730 void G4Trap::ComputeDimensions(       G4VPVParameterisation* p,
537                                 const G4int n,    731                                 const G4int n,
538                                 const G4VPhysi    732                                 const G4VPhysicalVolume* pRep )
539 {                                                 733 {
540   p->ComputeDimensions(*this,n,pRep);             734   p->ComputeDimensions(*this,n,pRep);
541 }                                                 735 }
542                                                   736 
543 ////////////////////////////////////////////// << 
544 //                                             << 
545 // Get bounding box                            << 
546                                                << 
547 void G4Trap::BoundingLimits(G4ThreeVector& pMi << 
548 {                                              << 
549   G4ThreeVector pt[8];                         << 
550   GetVertices(pt);                             << 
551                                                << 
552   G4double xmin = kInfinity, xmax = -kInfinity << 
553   G4double ymin = kInfinity, ymax = -kInfinity << 
554   for (const auto & i : pt)                    << 
555   {                                            << 
556     G4double x = i.x();                        << 
557     if (x < xmin) xmin = x;                    << 
558     if (x > xmax) xmax = x;                    << 
559     G4double y = i.y();                        << 
560     if (y < ymin) ymin = y;                    << 
561     if (y > ymax) ymax = y;                    << 
562   }                                            << 
563                                                << 
564   G4double dz   = GetZHalfLength();            << 
565   pMin.set(xmin,ymin,-dz);                     << 
566   pMax.set(xmax,ymax, dz);                     << 
567                                                   737 
568   // Check correctness of the bounding box     << 738 ////////////////////////////////////////////////////////////////////////
569   //                                           << 
570   if (pMin.x() >= pMax.x() || pMin.y() >= pMax << 
571   {                                            << 
572     std::ostringstream message;                << 
573     message << "Bad bounding box (min >= max)  << 
574             << GetName() << " !"               << 
575             << "\npMin = " << pMin             << 
576             << "\npMax = " << pMax;            << 
577     G4Exception("G4Trap::BoundingLimits()", "G << 
578                 JustWarning, message);         << 
579     DumpInfo();                                << 
580   }                                            << 
581 }                                              << 
582                                                << 
583 ////////////////////////////////////////////// << 
584 //                                                739 //
585 // Calculate extent under transform and specif    740 // Calculate extent under transform and specified limit
586                                                   741 
587 G4bool G4Trap::CalculateExtent( const EAxis pA    742 G4bool G4Trap::CalculateExtent( const EAxis pAxis,
588                                 const G4VoxelL    743                                 const G4VoxelLimits& pVoxelLimit,
589                                 const G4Affine    744                                 const G4AffineTransform& pTransform,
590                                       G4double    745                                       G4double& pMin, G4double& pMax) const
591 {                                                 746 {
592   G4ThreeVector bmin, bmax;                    << 747   G4double xMin, xMax, yMin, yMax, zMin, zMax;
593   G4bool exist;                                << 748   G4bool flag;
594                                                   749 
595   // Check bounding box (bbox)                 << 750   if (!pTransform.IsRotated())
596   //                                           << 751   {  
597   BoundingLimits(bmin,bmax);                   << 752     // Special case handling for unrotated trapezoids
598   G4BoundingEnvelope bbox(bmin,bmax);          << 753     // Compute z/x/y/ mins and maxs respecting limits, with early returns
599 #ifdef G4BBOX_EXTENT                           << 754     // if outside limits. Then switch() on pAxis
600   return bbox.CalculateExtent(pAxis,pVoxelLimi << 755 
601 #endif                                         << 756     G4int i ; 
602   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox << 757     G4double xoffset;
603   {                                            << 758     G4double yoffset;
604     return exist = pMin < pMax;                << 759     G4double zoffset;
                                                   >> 760     G4double temp[8] ;     // some points for intersection with zMin/zMax
                                                   >> 761     G4ThreeVector pt[8];   // vertices after translation
                                                   >> 762     
                                                   >> 763     xoffset=pTransform.NetTranslation().x();      
                                                   >> 764     yoffset=pTransform.NetTranslation().y();
                                                   >> 765     zoffset=pTransform.NetTranslation().z();
                                                   >> 766  
                                                   >> 767     pt[0]=G4ThreeVector(xoffset-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
                                                   >> 768                         yoffset-fDz*fTthetaSphi-fDy1,zoffset-fDz);
                                                   >> 769     pt[1]=G4ThreeVector(xoffset-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
                                                   >> 770                         yoffset-fDz*fTthetaSphi-fDy1,zoffset-fDz);
                                                   >> 771     pt[2]=G4ThreeVector(xoffset-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
                                                   >> 772                         yoffset-fDz*fTthetaSphi+fDy1,zoffset-fDz);
                                                   >> 773     pt[3]=G4ThreeVector(xoffset-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
                                                   >> 774                         yoffset-fDz*fTthetaSphi+fDy1,zoffset-fDz);
                                                   >> 775     pt[4]=G4ThreeVector(xoffset+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
                                                   >> 776                         yoffset+fDz*fTthetaSphi-fDy2,zoffset+fDz);
                                                   >> 777     pt[5]=G4ThreeVector(xoffset+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
                                                   >> 778                         yoffset+fDz*fTthetaSphi-fDy2,zoffset+fDz);
                                                   >> 779     pt[6]=G4ThreeVector(xoffset+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
                                                   >> 780                         yoffset+fDz*fTthetaSphi+fDy2,zoffset+fDz);
                                                   >> 781     pt[7]=G4ThreeVector(xoffset+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
                                                   >> 782                         yoffset+fDz*fTthetaSphi+fDy2,zoffset+fDz);
                                                   >> 783     zMin=zoffset-fDz;
                                                   >> 784     zMax=zoffset+fDz;
                                                   >> 785 
                                                   >> 786     if ( pVoxelLimit.IsZLimited() )
                                                   >> 787     {
                                                   >> 788       if ( (zMin > pVoxelLimit.GetMaxZExtent() + kCarTolerance)
                                                   >> 789         || (zMax < pVoxelLimit.GetMinZExtent() - kCarTolerance) )
                                                   >> 790       {
                                                   >> 791         return false;
                                                   >> 792       }
                                                   >> 793       else
                                                   >> 794       {
                                                   >> 795         if ( zMin < pVoxelLimit.GetMinZExtent() )
                                                   >> 796         {
                                                   >> 797           zMin = pVoxelLimit.GetMinZExtent() ;
                                                   >> 798         }
                                                   >> 799         if ( zMax > pVoxelLimit.GetMaxZExtent() )
                                                   >> 800         {
                                                   >> 801           zMax = pVoxelLimit.GetMaxZExtent() ;
                                                   >> 802         }
                                                   >> 803       }
                                                   >> 804     }
                                                   >> 805     temp[0] = pt[0].y()+(pt[4].y()-pt[0].y())*(zMin-pt[0].z())
                                                   >> 806                        /(pt[4].z()-pt[0].z()) ;
                                                   >> 807     temp[1] = pt[0].y()+(pt[4].y()-pt[0].y())*(zMax-pt[0].z())
                                                   >> 808                        /(pt[4].z()-pt[0].z()) ;
                                                   >> 809     temp[2] = pt[2].y()+(pt[6].y()-pt[2].y())*(zMin-pt[2].z())
                                                   >> 810                        /(pt[6].z()-pt[2].z()) ;
                                                   >> 811     temp[3] = pt[2].y()+(pt[6].y()-pt[2].y())*(zMax-pt[2].z())
                                                   >> 812                        /(pt[6].z()-pt[2].z()) ;
                                                   >> 813 
                                                   >> 814     yMax = yoffset - std::fabs(fDz*fTthetaSphi) - fDy1 - fDy2 ;
                                                   >> 815     yMin = -yMax ;
                                                   >> 816 
                                                   >> 817     for( i = 0 ; i < 4 ; i++ )
                                                   >> 818     {
                                                   >> 819       if( temp[i] > yMax ) yMax = temp[i] ;
                                                   >> 820       if( temp[i] < yMin ) yMin = temp[i] ;
                                                   >> 821     }    
                                                   >> 822     if ( pVoxelLimit.IsYLimited() )
                                                   >> 823     {
                                                   >> 824       if ( (yMin > pVoxelLimit.GetMaxYExtent() + kCarTolerance)
                                                   >> 825         || (yMax < pVoxelLimit.GetMinYExtent() - kCarTolerance) )
                                                   >> 826       {
                                                   >> 827         return false;
                                                   >> 828       }
                                                   >> 829       else
                                                   >> 830       {
                                                   >> 831         if ( yMin < pVoxelLimit.GetMinYExtent() )
                                                   >> 832         {
                                                   >> 833           yMin = pVoxelLimit.GetMinYExtent() ;
                                                   >> 834         }
                                                   >> 835         if ( yMax > pVoxelLimit.GetMaxYExtent() )
                                                   >> 836         {
                                                   >> 837           yMax = pVoxelLimit.GetMaxYExtent() ;
                                                   >> 838         }
                                                   >> 839       }
                                                   >> 840     }
                                                   >> 841     temp[0] = pt[0].x()+(pt[4].x()-pt[0].x())
                                                   >> 842                        *(zMin-pt[0].z())/(pt[4].z()-pt[0].z()) ;
                                                   >> 843     temp[1] = pt[0].x()+(pt[4].x()-pt[0].x())
                                                   >> 844                        *(zMax-pt[0].z())/(pt[4].z()-pt[0].z()) ;
                                                   >> 845     temp[2] = pt[2].x()+(pt[6].x()-pt[2].x())
                                                   >> 846                        *(zMin-pt[2].z())/(pt[6].z()-pt[2].z()) ;
                                                   >> 847     temp[3] = pt[2].x()+(pt[6].x()-pt[2].x())
                                                   >> 848                        *(zMax-pt[2].z())/(pt[6].z()-pt[2].z()) ;
                                                   >> 849     temp[4] = pt[3].x()+(pt[7].x()-pt[3].x())
                                                   >> 850                        *(zMin-pt[3].z())/(pt[7].z()-pt[3].z()) ;
                                                   >> 851     temp[5] = pt[3].x()+(pt[7].x()-pt[3].x())
                                                   >> 852                        *(zMax-pt[3].z())/(pt[7].z()-pt[3].z()) ;
                                                   >> 853     temp[6] = pt[1].x()+(pt[5].x()-pt[1].x())
                                                   >> 854                        *(zMin-pt[1].z())/(pt[5].z()-pt[1].z()) ;
                                                   >> 855     temp[7] = pt[1].x()+(pt[5].x()-pt[1].x())
                                                   >> 856                        *(zMax-pt[1].z())/(pt[5].z()-pt[1].z()) ;
                                                   >> 857       
                                                   >> 858     xMax = xoffset - std::fabs(fDz*fTthetaCphi) - fDx1 - fDx2 -fDx3 - fDx4 ;
                                                   >> 859     xMin = -xMax ;
                                                   >> 860 
                                                   >> 861     for( i = 0 ; i < 8 ; i++ )
                                                   >> 862     {
                                                   >> 863       if( temp[i] > xMax) xMax = temp[i] ;
                                                   >> 864       if( temp[i] < xMin) xMin = temp[i] ;
                                                   >> 865     }                                            
                                                   >> 866     if (pVoxelLimit.IsXLimited())   // xMax/Min = f(yMax/Min) ?
                                                   >> 867     {
                                                   >> 868       if ( (xMin > pVoxelLimit.GetMaxXExtent() + kCarTolerance)
                                                   >> 869         || (xMax < pVoxelLimit.GetMinXExtent() - kCarTolerance) )
                                                   >> 870       {
                                                   >> 871         return false;
                                                   >> 872       }
                                                   >> 873       else
                                                   >> 874       {
                                                   >> 875         if ( xMin < pVoxelLimit.GetMinXExtent() )
                                                   >> 876         {
                                                   >> 877           xMin = pVoxelLimit.GetMinXExtent() ;
                                                   >> 878         }
                                                   >> 879         if ( xMax > pVoxelLimit.GetMaxXExtent() )
                                                   >> 880         {
                                                   >> 881           xMax = pVoxelLimit.GetMaxXExtent() ;
                                                   >> 882         }
                                                   >> 883       }
                                                   >> 884     }
                                                   >> 885     switch (pAxis)
                                                   >> 886     {
                                                   >> 887       case kXAxis:
                                                   >> 888         pMin=xMin;
                                                   >> 889         pMax=xMax;
                                                   >> 890         break;
                                                   >> 891 
                                                   >> 892       case kYAxis:
                                                   >> 893         pMin=yMin;
                                                   >> 894         pMax=yMax;
                                                   >> 895         break;
                                                   >> 896 
                                                   >> 897       case kZAxis:
                                                   >> 898         pMin=zMin;
                                                   >> 899         pMax=zMax;
                                                   >> 900         break;
                                                   >> 901 
                                                   >> 902       default:
                                                   >> 903         break;
                                                   >> 904     }
                                                   >> 905     pMin -= kCarTolerance;
                                                   >> 906     pMax += kCarTolerance;
                                                   >> 907 
                                                   >> 908     flag = true;
605   }                                               909   }
                                                   >> 910   else    // General rotated case -
                                                   >> 911   {
                                                   >> 912     G4bool existsAfterClip = false ;
                                                   >> 913     G4ThreeVectorList*       vertices;
                                                   >> 914     pMin                   = +kInfinity;
                                                   >> 915     pMax                   = -kInfinity;
                                                   >> 916       
                                                   >> 917     // Calculate rotated vertex coordinates. Operator 'new' is called
                                                   >> 918 
                                                   >> 919     vertices = CreateRotatedVertices(pTransform);
                                                   >> 920       
                                                   >> 921     xMin = +kInfinity; yMin = +kInfinity; zMin = +kInfinity;
                                                   >> 922     xMax = -kInfinity; yMax = -kInfinity; zMax = -kInfinity;
                                                   >> 923       
                                                   >> 924     for( G4int nv = 0 ; nv < 8 ; nv++ )
                                                   >> 925     { 
                                                   >> 926       if( (*vertices)[nv].x() > xMax ) xMax = (*vertices)[nv].x();
                                                   >> 927       if( (*vertices)[nv].y() > yMax ) yMax = (*vertices)[nv].y();
                                                   >> 928       if( (*vertices)[nv].z() > zMax ) zMax = (*vertices)[nv].z();
                                                   >> 929       
                                                   >> 930       if( (*vertices)[nv].x() < xMin ) xMin = (*vertices)[nv].x();
                                                   >> 931       if( (*vertices)[nv].y() < yMin ) yMin = (*vertices)[nv].y();
                                                   >> 932       if( (*vertices)[nv].z() < zMin ) zMin = (*vertices)[nv].z();
                                                   >> 933     }
                                                   >> 934     if ( pVoxelLimit.IsZLimited() )
                                                   >> 935     {
                                                   >> 936       if ( (zMin > pVoxelLimit.GetMaxZExtent() + kCarTolerance)
                                                   >> 937         || (zMax < pVoxelLimit.GetMinZExtent() - kCarTolerance) )
                                                   >> 938       {
                                                   >> 939         delete vertices ;    //  'new' in the function called
                                                   >> 940         return false;
                                                   >> 941       }
                                                   >> 942       else
                                                   >> 943       {
                                                   >> 944         if ( zMin < pVoxelLimit.GetMinZExtent() )
                                                   >> 945         {
                                                   >> 946           zMin = pVoxelLimit.GetMinZExtent() ;
                                                   >> 947         }
                                                   >> 948         if ( zMax > pVoxelLimit.GetMaxZExtent() )
                                                   >> 949         {
                                                   >> 950           zMax = pVoxelLimit.GetMaxZExtent() ;
                                                   >> 951         }
                                                   >> 952       }
                                                   >> 953     } 
                                                   >> 954     if ( pVoxelLimit.IsYLimited() )
                                                   >> 955     {
                                                   >> 956       if ( (yMin > pVoxelLimit.GetMaxYExtent() + kCarTolerance)
                                                   >> 957         || (yMax < pVoxelLimit.GetMinYExtent() - kCarTolerance) )
                                                   >> 958       {
                                                   >> 959         delete vertices ;    //  'new' in the function called
                                                   >> 960         return false;
                                                   >> 961       }
                                                   >> 962       else
                                                   >> 963       {
                                                   >> 964         if ( yMin < pVoxelLimit.GetMinYExtent() )
                                                   >> 965         {
                                                   >> 966           yMin = pVoxelLimit.GetMinYExtent() ;
                                                   >> 967         }
                                                   >> 968         if ( yMax > pVoxelLimit.GetMaxYExtent() )
                                                   >> 969         {
                                                   >> 970           yMax = pVoxelLimit.GetMaxYExtent() ;
                                                   >> 971         }
                                                   >> 972       }
                                                   >> 973     }
                                                   >> 974     if ( pVoxelLimit.IsXLimited() )
                                                   >> 975     {
                                                   >> 976       if ( (xMin > pVoxelLimit.GetMaxXExtent() + kCarTolerance)
                                                   >> 977         || (xMax < pVoxelLimit.GetMinXExtent() - kCarTolerance) )
                                                   >> 978       {
                                                   >> 979         delete vertices ;    //  'new' in the function called
                                                   >> 980         return false ;
                                                   >> 981       } 
                                                   >> 982       else
                                                   >> 983       {
                                                   >> 984         if ( xMin < pVoxelLimit.GetMinXExtent() )
                                                   >> 985         {
                                                   >> 986           xMin = pVoxelLimit.GetMinXExtent() ;
                                                   >> 987         }
                                                   >> 988         if ( xMax > pVoxelLimit.GetMaxXExtent() )
                                                   >> 989         {
                                                   >> 990           xMax = pVoxelLimit.GetMaxXExtent() ;
                                                   >> 991         }
                                                   >> 992       }
                                                   >> 993     }
                                                   >> 994     switch (pAxis)
                                                   >> 995     {
                                                   >> 996       case kXAxis:
                                                   >> 997         pMin=xMin;
                                                   >> 998         pMax=xMax;
                                                   >> 999         break;
606                                                   1000 
607   // Set bounding envelope (benv) and calculat << 1001       case kYAxis:
608   //                                           << 1002         pMin=yMin;
609   G4ThreeVector pt[8];                         << 1003         pMax=yMax;
610   GetVertices(pt);                             << 1004         break;
                                                   >> 1005 
                                                   >> 1006       case kZAxis:
                                                   >> 1007         pMin=zMin;
                                                   >> 1008         pMax=zMax;
                                                   >> 1009         break;
611                                                   1010 
612   G4ThreeVectorList baseA(4), baseB(4);        << 1011       default:
613   baseA[0] = pt[0];                            << 1012         break;
614   baseA[1] = pt[1];                            << 1013     }
615   baseA[2] = pt[3];                            << 1014     if ( (pMin != kInfinity) || (pMax != -kInfinity) )
616   baseA[3] = pt[2];                            << 1015     {
617                                                << 1016       existsAfterClip=true;
618   baseB[0] = pt[4];                            << 1017         
619   baseB[1] = pt[5];                            << 1018       // Add tolerance to avoid precision troubles
620   baseB[2] = pt[7];                            << 1019       //
621   baseB[3] = pt[6];                            << 1020       pMin -= kCarTolerance ;
622                                                << 1021       pMax += kCarTolerance ;      
623   std::vector<const G4ThreeVectorList *> polyg << 1022     }
624   polygons[0] = &baseA;                        << 1023     delete vertices ;          //  'new' in the function called
625   polygons[1] = &baseB;                        << 1024     flag = existsAfterClip ;
626                                                << 1025   }
627   G4BoundingEnvelope benv(bmin,bmax,polygons); << 1026   return flag;
628   exist = benv.CalculateExtent(pAxis,pVoxelLim << 
629   return exist;                                << 
630 }                                                 1027 }
631                                                   1028 
632 ////////////////////////////////////////////// << 1029 
                                                   >> 1030 ////////////////////////////////////////////////////////////////////////
633 //                                                1031 //
634 // Return whether point is inside/outside/on_s << 1032 // Return whether point inside/outside/on surface, using tolerance
635                                                   1033 
636 EInside G4Trap::Inside( const G4ThreeVector& p    1034 EInside G4Trap::Inside( const G4ThreeVector& p ) const
637 {                                                 1035 {
638   switch (fTrapType)                           << 1036   EInside in;
                                                   >> 1037   G4double Dist;
                                                   >> 1038   G4int i;
                                                   >> 1039   if ( std::fabs(p.z()) <= fDz-kCarTolerance*0.5)
639   {                                               1040   {
640     case 0: // General case                    << 1041     in = kInside;
                                                   >> 1042 
                                                   >> 1043     for ( i = 0;i < 4;i++ )
                                                   >> 1044     {
                                                   >> 1045       Dist = fPlanes[i].a*p.x() + fPlanes[i].b*p.y()
                                                   >> 1046             +fPlanes[i].c*p.z() + fPlanes[i].d;
                                                   >> 1047 
                                                   >> 1048       if      (Dist >  kCarTolerance*0.5)  return in = kOutside;
                                                   >> 1049       else if (Dist > -kCarTolerance*0.5)         in = kSurface;
                                                   >> 1050        
                                                   >> 1051     }
                                                   >> 1052   }
                                                   >> 1053   else if (std::fabs(p.z()) <= fDz+kCarTolerance*0.5)
                                                   >> 1054   {
                                                   >> 1055     in = kSurface;
                                                   >> 1056 
                                                   >> 1057     for ( i = 0; i < 4; i++ )
641     {                                             1058     {
642       G4double dz = std::abs(p.z())-fDz;       << 1059       Dist =  fPlanes[i].a*p.x() + fPlanes[i].b*p.y()
643       G4double dy1 = fPlanes[0].b*p.y()+fPlane << 1060              +fPlanes[i].c*p.z() + fPlanes[i].d;
644       G4double dy2 = fPlanes[1].b*p.y()+fPlane << 
645       G4double dy = std::max(dz,std::max(dy1,d << 
646                                                << 
647       G4double dx1 = fPlanes[2].a*p.x()+fPlane << 
648                    + fPlanes[2].c*p.z()+fPlane << 
649       G4double dx2 = fPlanes[3].a*p.x()+fPlane << 
650                    + fPlanes[3].c*p.z()+fPlane << 
651       G4double dist = std::max(dy,std::max(dx1 << 
652                                                << 
653       return (dist > halfCarTolerance) ? kOuts << 
654         ((dist > -halfCarTolerance) ? kSurface << 
655     }                                          << 
656     case 1: // YZ section is a rectangle       << 
657     {                                          << 
658       G4double dz = std::abs(p.z())-fDz;       << 
659       G4double dy = std::max(dz,std::abs(p.y() << 
660       G4double dx1 = fPlanes[2].a*p.x()+fPlane << 
661                    + fPlanes[2].c*p.z()+fPlane << 
662       G4double dx2 = fPlanes[3].a*p.x()+fPlane << 
663                    + fPlanes[3].c*p.z()+fPlane << 
664       G4double dist = std::max(dy,std::max(dx1 << 
665                                                << 
666       return (dist > halfCarTolerance) ? kOuts << 
667         ((dist > -halfCarTolerance) ? kSurface << 
668     }                                          << 
669     case 2: // YZ section is a rectangle and   << 
670     {       // XZ section is an isosceles trap << 
671       G4double dz = std::abs(p.z())-fDz;       << 
672       G4double dy = std::max(dz,std::abs(p.y() << 
673       G4double dx = fPlanes[3].a*std::abs(p.x( << 
674                   + fPlanes[3].c*p.z()+fPlanes << 
675       G4double dist = std::max(dy,dx);         << 
676                                                << 
677       return (dist > halfCarTolerance) ? kOuts << 
678         ((dist > -halfCarTolerance) ? kSurface << 
679     }                                          << 
680     case 3: // YZ section is a rectangle and   << 
681     {       // XY section is an isosceles trap << 
682       G4double dz = std::abs(p.z())-fDz;       << 
683       G4double dy = std::max(dz,std::abs(p.y() << 
684       G4double dx = fPlanes[3].a*std::abs(p.x( << 
685                   + fPlanes[3].b*p.y()+fPlanes << 
686       G4double dist = std::max(dy,dx);         << 
687                                                   1061 
688       return (dist > halfCarTolerance) ? kOuts << 1062       if (Dist > kCarTolerance*0.5)        return in = kOutside;      
689         ((dist > -halfCarTolerance) ? kSurface << 
690     }                                             1063     }
691   }                                               1064   }
692   return kOutside;                             << 1065   else  in = kOutside;
                                                   >> 1066   
                                                   >> 1067   return in;
693 }                                                 1068 }
694                                                   1069 
695 ////////////////////////////////////////////// << 1070 /////////////////////////////////////////////////////////////////////////////
696 //                                                1071 //
697 // Determine side, and return corresponding no << 1072 // Calculate side nearest to p, and return normal
                                                   >> 1073 // If 2+ sides equidistant, first side's normal returned (arbitrarily)
698                                                   1074 
699 G4ThreeVector G4Trap::SurfaceNormal( const G4T    1075 G4ThreeVector G4Trap::SurfaceNormal( const G4ThreeVector& p ) const
700 {                                                 1076 {
701   G4double nx = 0, ny = 0, nz = 0;             << 1077   G4int i, imin = 0, noSurfaces = 0;
702   G4double dz = std::abs(p.z()) - fDz;         << 1078   G4double dist, distz, distx, disty, distmx, distmy, safe = kInfinity;
703   nz = std::copysign(G4double(std::abs(dz) <=  << 1079   G4double delta    = 0.5*kCarTolerance;
                                                   >> 1080   G4ThreeVector norm, sumnorm(0.,0.,0.);
704                                                   1081 
705   switch (fTrapType)                           << 1082   for (i = 0; i < 4; i++)
706   {                                               1083   {
707     case 0: // General case                    << 1084     dist =  std::fabs(fPlanes[i].a*p.x() + fPlanes[i].b*p.y()
708     {                                          << 1085           + fPlanes[i].c*p.z() + fPlanes[i].d);
709       for (G4int i=0; i<2; ++i)                << 1086     if ( dist < safe )
710       {                                        << 
711         G4double dy = fPlanes[i].b*p.y() + fPl << 
712         if (std::abs(dy) > halfCarTolerance) c << 
713         ny  = fPlanes[i].b;                    << 
714         nz += fPlanes[i].c;                    << 
715         break;                                 << 
716       }                                        << 
717       for (G4int i=2; i<4; ++i)                << 
718       {                                        << 
719         G4double dx = fPlanes[i].a*p.x() +     << 
720                       fPlanes[i].b*p.y() + fPl << 
721         if (std::abs(dx) > halfCarTolerance) c << 
722         nx  = fPlanes[i].a;                    << 
723         ny += fPlanes[i].b;                    << 
724         nz += fPlanes[i].c;                    << 
725         break;                                 << 
726       }                                        << 
727       break;                                   << 
728     }                                          << 
729     case 1: // YZ section - rectangle          << 
730     {                                          << 
731       G4double dy = std::abs(p.y()) + fPlanes[ << 
732       ny = std::copysign(G4double(std::abs(dy) << 
733       for (G4int i=2; i<4; ++i)                << 
734       {                                        << 
735         G4double dx = fPlanes[i].a*p.x() +     << 
736                       fPlanes[i].b*p.y() + fPl << 
737         if (std::abs(dx) > halfCarTolerance) c << 
738         nx  = fPlanes[i].a;                    << 
739         ny += fPlanes[i].b;                    << 
740         nz += fPlanes[i].c;                    << 
741         break;                                 << 
742       }                                        << 
743       break;                                   << 
744     }                                          << 
745     case 2: // YZ section - rectangle, XZ sect << 
746     {                                             1087     {
747       G4double dy = std::abs(p.y()) + fPlanes[ << 1088       safe = dist;
748       ny = std::copysign(G4double(std::abs(dy) << 1089       imin = i;
749       G4double dx = fPlanes[3].a*std::abs(p.x( << 
750                     fPlanes[3].c*p.z() + fPlan << 
751       G4double k = std::abs(dx) <= halfCarTole << 
752       nx  = std::copysign(k, p.x())*fPlanes[3] << 
753       nz += k*fPlanes[3].c;                    << 
754       break;                                   << 
755     }                                          << 
756     case 3: // YZ section - rectangle, XY sect << 
757     {                                          << 
758       G4double dy = std::abs(p.y()) + fPlanes[ << 
759       ny = std::copysign(G4double(std::abs(dy) << 
760       G4double dx = fPlanes[3].a*std::abs(p.x( << 
761                     fPlanes[3].b*p.y() + fPlan << 
762       G4double k = std::abs(dx) <= halfCarTole << 
763       nx  = std::copysign(k, p.x())*fPlanes[3] << 
764       ny += k*fPlanes[3].b;                    << 
765       break;                                   << 
766     }                                             1090     }
767   }                                               1091   }
                                                   >> 1092   distz  = std::fabs( std::fabs( p.z() ) - fDz );
768                                                   1093 
769   // Return normal                             << 1094   distmy = std::fabs( fPlanes[0].a*p.x() + fPlanes[0].b*p.y()
770   //                                           << 1095                     + fPlanes[0].c*p.z() + fPlanes[0].d      );
771   G4double mag2 = nx*nx + ny*ny + nz*nz;       << 1096 
772   if (mag2 == 1)      return { nx,ny,nz };     << 1097   disty  = std::fabs( fPlanes[1].a*p.x() + fPlanes[1].b*p.y()
773   else if (mag2 != 0) return G4ThreeVector(nx, << 1098                     + fPlanes[1].c*p.z() + fPlanes[1].d      );
774   else                                         << 1099 
                                                   >> 1100   distmx = std::fabs( fPlanes[2].a*p.x() + fPlanes[2].b*p.y()
                                                   >> 1101                     + fPlanes[2].c*p.z() + fPlanes[2].d      );
                                                   >> 1102 
                                                   >> 1103   distx  = std::fabs( fPlanes[3].a*p.x() + fPlanes[3].b*p.y()
                                                   >> 1104                     + fPlanes[3].c*p.z() + fPlanes[3].d      );
                                                   >> 1105 
                                                   >> 1106   G4ThreeVector nX  = G4ThreeVector(fPlanes[3].a,fPlanes[3].b,fPlanes[3].c);
                                                   >> 1107   G4ThreeVector nmX = G4ThreeVector(fPlanes[2].a,fPlanes[2].b,fPlanes[2].c);
                                                   >> 1108   G4ThreeVector nY  = G4ThreeVector(fPlanes[1].a,fPlanes[1].b,fPlanes[1].c);
                                                   >> 1109   G4ThreeVector nmY = G4ThreeVector(fPlanes[0].a,fPlanes[0].b,fPlanes[0].c);
                                                   >> 1110   G4ThreeVector nZ  = G4ThreeVector(0.,0.,1.0);
                                                   >> 1111 
                                                   >> 1112   if (distx <= delta)      
                                                   >> 1113   {
                                                   >> 1114     noSurfaces ++;
                                                   >> 1115     sumnorm += nX;     
                                                   >> 1116   }
                                                   >> 1117   if (distmx <= delta)      
                                                   >> 1118   {
                                                   >> 1119     noSurfaces ++;
                                                   >> 1120     sumnorm += nmX;      
                                                   >> 1121   }
                                                   >> 1122   if (disty <= delta)
                                                   >> 1123   {
                                                   >> 1124     noSurfaces ++;
                                                   >> 1125     sumnorm += nY;  
                                                   >> 1126   }
                                                   >> 1127   if (distmy <= delta)
                                                   >> 1128   {
                                                   >> 1129     noSurfaces ++;
                                                   >> 1130     sumnorm += nmY;  
                                                   >> 1131   }
                                                   >> 1132   if (distz <= delta)  
                                                   >> 1133   {
                                                   >> 1134     noSurfaces ++;
                                                   >> 1135     if ( p.z() >= 0.)  sumnorm += nZ;
                                                   >> 1136     else               sumnorm -= nZ; 
                                                   >> 1137   }
                                                   >> 1138   if ( noSurfaces == 0 )
775   {                                               1139   {
776     // Point is not on the surface             << 
777     //                                         << 
778 #ifdef G4CSGDEBUG                                 1140 #ifdef G4CSGDEBUG
779     std::ostringstream message;                << 1141     G4Exception("G4Trap::SurfaceNormal(p)", "Notification", JustWarning, 
780     G4long oldprc = message.precision(16);     << 1142                 "Point p is not on surface !?" );
781     message << "Point p is not on surface (!?) << 1143 #endif 
782             << GetName() << G4endl;            << 1144      norm = ApproxSurfaceNormal(p);
783     message << "Position:\n";                  << 
784     message << "   p.x() = " << p.x()/mm << "  << 
785     message << "   p.y() = " << p.y()/mm << "  << 
786     message << "   p.z() = " << p.z()/mm << "  << 
787     G4cout.precision(oldprc) ;                 << 
788     G4Exception("G4Trap::SurfaceNormal(p)", "G << 
789                 JustWarning, message );        << 
790     DumpInfo();                                << 
791 #endif                                         << 
792     return ApproxSurfaceNormal(p);             << 
793   }                                               1145   }
                                                   >> 1146   else if ( noSurfaces == 1 ) norm = sumnorm;
                                                   >> 1147   else                        norm = sumnorm.unit();
                                                   >> 1148   return norm;
794 }                                                 1149 }
795                                                   1150 
796 ////////////////////////////////////////////// << 1151 ////////////////////////////////////////////////////////////////////////////////////
797 //                                                1152 //
798 // Algorithm for SurfaceNormal() following the    1153 // Algorithm for SurfaceNormal() following the original specification
799 // for points not on the surface                  1154 // for points not on the surface
800                                                   1155 
801 G4ThreeVector G4Trap::ApproxSurfaceNormal( con    1156 G4ThreeVector G4Trap::ApproxSurfaceNormal( const G4ThreeVector& p ) const
802 {                                                 1157 {
803   G4double dist = -DBL_MAX;                    << 1158   G4double safe=kInfinity,Dist,safez;
804   G4int iside = 0;                             << 1159   G4int i,imin=0;
805   for (G4int i=0; i<4; ++i)                    << 1160   for (i=0;i<4;i++)
806   {                                            << 1161   {
807     G4double d = fPlanes[i].a*p.x() +          << 1162     Dist=std::fabs(fPlanes[i].a*p.x()+fPlanes[i].b*p.y()
808                  fPlanes[i].b*p.y() +          << 1163         +fPlanes[i].c*p.z()+fPlanes[i].d);
809                  fPlanes[i].c*p.z() + fPlanes[ << 1164     if (Dist<safe)
810     if (d > dist) { dist = d; iside = i; }     << 1165     {
                                                   >> 1166       safe=Dist;
                                                   >> 1167       imin=i;
                                                   >> 1168     }
                                                   >> 1169   }
                                                   >> 1170   safez=std::fabs(std::fabs(p.z())-fDz);
                                                   >> 1171   if (safe<safez)
                                                   >> 1172   {
                                                   >> 1173     return G4ThreeVector(fPlanes[imin].a,fPlanes[imin].b,fPlanes[imin].c);
811   }                                               1174   }
812                                                << 
813   G4double distz = std::abs(p.z()) - fDz;      << 
814   if (dist > distz)                            << 
815     return { fPlanes[iside].a, fPlanes[iside]. << 
816   else                                            1175   else
817     return { 0, 0, (G4double)((p.z() < 0) ? -1 << 1176   {
                                                   >> 1177     if (p.z()>0)
                                                   >> 1178     {
                                                   >> 1179       return G4ThreeVector(0,0,1);
                                                   >> 1180     }
                                                   >> 1181     else
                                                   >> 1182     {
                                                   >> 1183       return G4ThreeVector(0,0,-1);
                                                   >> 1184     }
                                                   >> 1185   }
818 }                                                 1186 }
819                                                   1187 
820 ////////////////////////////////////////////// << 1188 ////////////////////////////////////////////////////////////////////////////
                                                   >> 1189 //
                                                   >> 1190 // Calculate distance to shape from outside - return kInfinity if no intersection
821 //                                                1191 //
822 // Calculate distance to shape from outside    << 1192 // ALGORITHM:
823 //  - return kInfinity if no intersection      << 1193 // For each component, calculate pair of minimum and maximum intersection
                                                   >> 1194 // values for which the particle is in the extent of the shape
                                                   >> 1195 // - The smallest (MAX minimum) allowed distance of the pairs is intersect
824                                                   1196 
825 G4double G4Trap::DistanceToIn(const G4ThreeVec << 1197 G4double G4Trap::DistanceToIn( const G4ThreeVector& p,
826                               const G4ThreeVec << 1198                                const G4ThreeVector& v ) const
827 {                                                 1199 {
828   // Z intersections                           << 
829   //                                           << 
830   if ((std::abs(p.z()) - fDz) >= -halfCarToler << 
831     return kInfinity;                          << 
832   G4double invz = (-v.z() == 0) ? DBL_MAX : -1 << 
833   G4double dz = (invz < 0) ? fDz : -fDz;       << 
834   G4double tzmin = (p.z() + dz)*invz;          << 
835   G4double tzmax = (p.z() - dz)*invz;          << 
836                                                   1200 
837   // Y intersections                           << 1201   G4double snxt;    // snxt = default return value
                                                   >> 1202   G4double max,smax,smin;
                                                   >> 1203   G4double pdist,Comp,vdist;
                                                   >> 1204   G4int i;
                                                   >> 1205   //
                                                   >> 1206   // Z Intersection range
838   //                                              1207   //
839   G4double tymin = 0, tymax = DBL_MAX;         << 1208   if ( v.z() > 0 )
840   G4int i = 0;                                 << 
841   for ( ; i<2; ++i)                            << 
842   {                                               1209   {
843     G4double cosa = fPlanes[i].b*v.y() + fPlan << 1210     max = fDz - p.z() ;
844     G4double dist = fPlanes[i].b*p.y() + fPlan << 1211     if (max > 0.5*kCarTolerance)
845     if (dist >= -halfCarTolerance)             << 
846     {                                             1212     {
847       if (cosa >= 0) return kInfinity;         << 1213       smax = max/v.z();
848       G4double tmp  = -dist/cosa;              << 1214       smin = (-fDz-p.z())/v.z();
849       if (tymin < tmp) tymin = tmp;            << 
850     }                                             1215     }
851     else if (cosa > 0)                         << 1216     else
852     {                                             1217     {
853       G4double tmp  = -dist/cosa;              << 1218       return snxt=kInfinity;
854       if (tymax > tmp) tymax = tmp;            << 
855     }                                             1219     }
856   }                                               1220   }
857                                                << 1221   else if (v.z() < 0 )
858   // Z intersections                           << 1222   {
859   //                                           << 1223     max = - fDz - p.z() ;
860   G4double txmin = 0, txmax = DBL_MAX;         << 1224     if (max < -0.5*kCarTolerance )
861   for ( ; i<4; ++i)                            << 1225     {
                                                   >> 1226       smax=max/v.z();
                                                   >> 1227       smin=(fDz-p.z())/v.z();
                                                   >> 1228     }
                                                   >> 1229     else
                                                   >> 1230     {
                                                   >> 1231       return snxt=kInfinity;
                                                   >> 1232     }
                                                   >> 1233   }
                                                   >> 1234   else
862   {                                               1235   {
863     G4double cosa = fPlanes[i].a*v.x()+fPlanes << 1236     if (std::fabs(p.z())<fDz - 0.5*kCarTolerance) // Inside was <=fDz
864     G4double dist = fPlanes[i].a*p.x()+fPlanes << 
865                     fPlanes[i].d;              << 
866     if (dist >= -halfCarTolerance)             << 
867     {                                             1237     {
868       if (cosa >= 0) return kInfinity;         << 1238       smin=0;
869       G4double tmp  = -dist/cosa;              << 1239       smax=kInfinity;
870       if (txmin < tmp) txmin = tmp;            << 
871     }                                             1240     }
872     else if (cosa > 0)                         << 1241     else
873     {                                             1242     {
874       G4double tmp  = -dist/cosa;              << 1243       return snxt=kInfinity;
875       if (txmax > tmp) txmax = tmp;            << 
876     }                                             1244     }
877   }                                               1245   }
878                                                   1246 
879   // Find distance                             << 1247   for (i=0;i<4;i++)
                                                   >> 1248   {
                                                   >> 1249     pdist=fPlanes[i].a*p.x()+fPlanes[i].b*p.y()
                                                   >> 1250          +fPlanes[i].c*p.z()+fPlanes[i].d;
                                                   >> 1251     Comp=fPlanes[i].a*v.x()+fPlanes[i].b*v.y()+fPlanes[i].c*v.z();
                                                   >> 1252     if ( pdist >= -0.5*kCarTolerance )      // was >0
                                                   >> 1253     {
                                                   >> 1254       //
                                                   >> 1255       // Outside the plane -> this is an extent entry distance
                                                   >> 1256       //
                                                   >> 1257       if (Comp >= 0)   // was >0
                                                   >> 1258       {
                                                   >> 1259         return snxt=kInfinity ;
                                                   >> 1260       }
                                                   >> 1261       else 
                                                   >> 1262       {
                                                   >> 1263         vdist=-pdist/Comp;
                                                   >> 1264         if (vdist>smin)
                                                   >> 1265         {
                                                   >> 1266           if (vdist<smax)
                                                   >> 1267           {
                                                   >> 1268             smin = vdist;
                                                   >> 1269           }
                                                   >> 1270           else
                                                   >> 1271           {
                                                   >> 1272             return snxt=kInfinity;
                                                   >> 1273           }
                                                   >> 1274         }
                                                   >> 1275       }
                                                   >> 1276     }
                                                   >> 1277     else
                                                   >> 1278     {
                                                   >> 1279       //
                                                   >> 1280       // Inside the plane -> couble  be an extent exit distance (smax)
                                                   >> 1281       //
                                                   >> 1282       if (Comp>0)  // Will leave extent
                                                   >> 1283       {
                                                   >> 1284         vdist=-pdist/Comp;
                                                   >> 1285         if (vdist<smax)
                                                   >> 1286         {
                                                   >> 1287           if (vdist>smin)
                                                   >> 1288           {
                                                   >> 1289             smax=vdist;
                                                   >> 1290           }
                                                   >> 1291           else
                                                   >> 1292           {
                                                   >> 1293             return snxt=kInfinity;
                                                   >> 1294           }
                                                   >> 1295         }  
                                                   >> 1296       }
                                                   >> 1297     }
                                                   >> 1298   }
880   //                                              1299   //
881   G4double tmin = std::max(std::max(txmin,tymi << 1300   // Checks in non z plane intersections ensure smin<smax
882   G4double tmax = std::min(std::min(txmax,tyma << 1301   //
883                                                << 1302   if (smin >=0 )
884   if (tmax <= tmin + halfCarTolerance) return  << 1303   {
885   return (tmin < halfCarTolerance ) ? 0. : tmi << 1304     snxt = smin ;
                                                   >> 1305   }
                                                   >> 1306   else
                                                   >> 1307   {
                                                   >> 1308     snxt = 0 ;
                                                   >> 1309   }
                                                   >> 1310   return snxt;
886 }                                                 1311 }
887                                                   1312 
888 ////////////////////////////////////////////// << 1313 ///////////////////////////////////////////////////////////////////////////
889 //                                                1314 //
890 // Calculate exact shortest distance to any bo    1315 // Calculate exact shortest distance to any boundary from outside
891 // This is the best fast estimation of the sho    1316 // This is the best fast estimation of the shortest distance to trap
892 // - return 0 if point is inside               << 1317 // - Returns 0 is ThreeVector inside
893                                                   1318 
894 G4double G4Trap::DistanceToIn( const G4ThreeVe    1319 G4double G4Trap::DistanceToIn( const G4ThreeVector& p ) const
895 {                                                 1320 {
896   switch (fTrapType)                           << 1321   G4double safe=0.0,Dist;
                                                   >> 1322   G4int i;
                                                   >> 1323   safe=std::fabs(p.z())-fDz;
                                                   >> 1324   for (i=0;i<4;i++)
897   {                                               1325   {
898     case 0: // General case                    << 1326     Dist=fPlanes[i].a*p.x()+fPlanes[i].b*p.y()
899     {                                          << 1327         +fPlanes[i].c*p.z()+fPlanes[i].d;
900       G4double dz = std::abs(p.z())-fDz;       << 1328     if (Dist > safe) safe=Dist;
901       G4double dy1 = fPlanes[0].b*p.y()+fPlane << 
902       G4double dy2 = fPlanes[1].b*p.y()+fPlane << 
903       G4double dy = std::max(dz,std::max(dy1,d << 
904                                                << 
905       G4double dx1 = fPlanes[2].a*p.x()+fPlane << 
906                    + fPlanes[2].c*p.z()+fPlane << 
907       G4double dx2 = fPlanes[3].a*p.x()+fPlane << 
908                    + fPlanes[3].c*p.z()+fPlane << 
909       G4double dist = std::max(dy,std::max(dx1 << 
910       return (dist > 0) ? dist : 0.;           << 
911     }                                          << 
912     case 1: // YZ section is a rectangle       << 
913     {                                          << 
914       G4double dz = std::abs(p.z())-fDz;       << 
915       G4double dy = std::max(dz,std::abs(p.y() << 
916       G4double dx1 = fPlanes[2].a*p.x()+fPlane << 
917                    + fPlanes[2].c*p.z()+fPlane << 
918       G4double dx2 = fPlanes[3].a*p.x()+fPlane << 
919                    + fPlanes[3].c*p.z()+fPlane << 
920       G4double dist = std::max(dy,std::max(dx1 << 
921       return (dist > 0) ? dist : 0.;           << 
922     }                                          << 
923     case 2: // YZ section is a rectangle and   << 
924     {       // XZ section is an isosceles trap << 
925       G4double dz = std::abs(p.z())-fDz;       << 
926       G4double dy = std::max(dz,std::abs(p.y() << 
927       G4double dx = fPlanes[3].a*std::abs(p.x( << 
928                   + fPlanes[3].c*p.z()+fPlanes << 
929       G4double dist = std::max(dy,dx);         << 
930       return (dist > 0) ? dist : 0.;           << 
931     }                                          << 
932     case 3: // YZ section is a rectangle and   << 
933     {       // XY section is an isosceles trap << 
934       G4double dz = std::abs(p.z())-fDz;       << 
935       G4double dy = std::max(dz,std::abs(p.y() << 
936       G4double dx = fPlanes[3].a*std::abs(p.x( << 
937                   + fPlanes[3].b*p.y()+fPlanes << 
938       G4double dist = std::max(dy,dx);         << 
939       return (dist > 0) ? dist : 0.;           << 
940     }                                          << 
941   }                                               1329   }
942   return 0.;                                   << 1330   if (safe<0) safe=0;
                                                   >> 1331   return safe;  
943 }                                                 1332 }
944                                                   1333 
945 ////////////////////////////////////////////// << 1334 /////////////////////////////////////////////////////////////////////////////////
946 //                                                1335 //
947 // Calculate distance to surface of shape from << 1336 // Calculate distance to surface of shape from inside
948 // find normal at exit point, if required      << 1337 // Calculate distance to x/y/z planes - smallest is exiting distance
949 // - when leaving the surface, return 0        << 
950                                                   1338 
951 G4double G4Trap::DistanceToOut(const G4ThreeVe    1339 G4double G4Trap::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
952                                const G4bool ca    1340                                const G4bool calcNorm,
953                                      G4bool* v << 1341                                      G4bool *validNorm, G4ThreeVector *n) const
954 {                                                 1342 {
955   // Z intersections                           << 1343   Eside side = kUndef;
                                                   >> 1344   G4double snxt;    // snxt = return value
                                                   >> 1345   G4double pdist,Comp,vdist,max;
                                                   >> 1346   //
                                                   >> 1347   // Z Intersections
956   //                                              1348   //
957   if ((std::abs(p.z()) - fDz) >= -halfCarToler << 1349   if (v.z()>0)
958   {                                               1350   {
959     if (calcNorm)                              << 1351     max=fDz-p.z();
                                                   >> 1352     if (max>kCarTolerance/2)
960     {                                             1353     {
961       *validNorm = true;                       << 1354       snxt=max/v.z();
962       n->set(0, 0, (p.z() < 0) ? -1 : 1);      << 1355       side=kPZ;
963     }                                             1356     }
964     return 0;                                  << 1357     else
                                                   >> 1358     {
                                                   >> 1359       if (calcNorm)
                                                   >> 1360       {
                                                   >> 1361         *validNorm=true;
                                                   >> 1362         *n=G4ThreeVector(0,0,1);
                                                   >> 1363       }
                                                   >> 1364       return snxt=0;
                                                   >> 1365     }
                                                   >> 1366   }
                                                   >> 1367   else if (v.z()<0)
                                                   >> 1368   {
                                                   >> 1369     max=-fDz-p.z();
                                                   >> 1370     if (max<-kCarTolerance/2)
                                                   >> 1371     {
                                                   >> 1372       snxt=max/v.z();
                                                   >> 1373       side=kMZ;
                                                   >> 1374     }
                                                   >> 1375     else
                                                   >> 1376     {
                                                   >> 1377       if (calcNorm)
                                                   >> 1378       {
                                                   >> 1379         *validNorm=true;
                                                   >> 1380         *n=G4ThreeVector(0,0,-1);
                                                   >> 1381       }
                                                   >> 1382       return snxt=0;
                                                   >> 1383     }
                                                   >> 1384   }
                                                   >> 1385   else
                                                   >> 1386   {
                                                   >> 1387     snxt=kInfinity;
965   }                                               1388   }
966   G4double vz = v.z();                         << 
967   G4double tmax = (vz == 0) ? DBL_MAX : (std:: << 
968   G4int iside = (vz < 0) ? -4 : -2; // little  << 
969                                                   1389 
970   // Y intersections                           << 
971   //                                              1390   //
972   G4int i = 0;                                 << 1391   // Intersections with planes[0] (expanded because of setting enum)
973   for ( ; i<2; ++i)                            << 1392   //
                                                   >> 1393   pdist=fPlanes[0].a*p.x()+fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
                                                   >> 1394   Comp=fPlanes[0].a*v.x()+fPlanes[0].b*v.y()+fPlanes[0].c*v.z();
                                                   >> 1395   if (pdist>0)
974   {                                               1396   {
975     G4double cosa = fPlanes[i].b*v.y() + fPlan << 1397     // Outside the plane
976     if (cosa > 0)                              << 1398     if (Comp>0)
977     {                                             1399     {
978       G4double dist = fPlanes[i].b*p.y() + fPl << 1400       // Leaving immediately
979       if (dist >= -halfCarTolerance)           << 1401       if (calcNorm)
980       {                                           1402       {
981         if (calcNorm)                          << 1403         *validNorm=true;
982         {                                      << 1404         *n=G4ThreeVector(fPlanes[0].a,fPlanes[0].b,fPlanes[0].c);
983           *validNorm = true;                   << 1405       }
984           n->set(0, fPlanes[i].b, fPlanes[i].c << 1406       return snxt=0;
985         }                                      << 1407     }
986         return 0;                              << 1408   }
                                                   >> 1409   else if (pdist<-kCarTolerance/2)
                                                   >> 1410   {
                                                   >> 1411     // Inside the plane
                                                   >> 1412     if (Comp>0)
                                                   >> 1413     {
                                                   >> 1414       // Will leave extent
                                                   >> 1415       vdist=-pdist/Comp;
                                                   >> 1416       if (vdist<snxt)
                                                   >> 1417       {
                                                   >> 1418         snxt=vdist;
                                                   >> 1419         side=ks0;
987       }                                           1420       }
988       G4double tmp = -dist/cosa;               << 1421     }
989       if (tmax > tmp) { tmax = tmp; iside = i; << 1422   }
                                                   >> 1423   else
                                                   >> 1424   {
                                                   >> 1425     // On surface
                                                   >> 1426     if (Comp>0)
                                                   >> 1427     {
                                                   >> 1428       if (calcNorm)
                                                   >> 1429       {
                                                   >> 1430         *validNorm=true;
                                                   >> 1431         *n=G4ThreeVector(fPlanes[0].a,fPlanes[0].b,fPlanes[0].c);
                                                   >> 1432       }
                                                   >> 1433       return snxt=0;
990     }                                             1434     }
991   }                                               1435   }
992                                                   1436 
993   // X intersections                           << 
994   //                                              1437   //
995   for ( ; i<4; ++i)                            << 1438   // Intersections with planes[1] (expanded because of setting enum)
                                                   >> 1439   //
                                                   >> 1440   pdist=fPlanes[1].a*p.x()+fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
                                                   >> 1441   Comp=fPlanes[1].a*v.x()+fPlanes[1].b*v.y()+fPlanes[1].c*v.z();
                                                   >> 1442   if (pdist>0)
996   {                                               1443   {
997     G4double cosa = fPlanes[i].a*v.x()+fPlanes << 1444     // Outside the plane
998     if (cosa > 0)                              << 1445     if (Comp>0)
999     {                                             1446     {
1000       G4double dist = fPlanes[i].a*p.x() +    << 1447       // Leaving immediately
1001                       fPlanes[i].b*p.y() + fP << 1448       if (calcNorm)
1002       if (dist >= -halfCarTolerance)          << 
1003       {                                          1449       {
1004         if (calcNorm)                         << 1450         *validNorm=true;
1005         {                                     << 1451         *n=G4ThreeVector(fPlanes[1].a,fPlanes[1].b,fPlanes[1].c);
1006            *validNorm = true;                 << 1452       }
1007            n->set(fPlanes[i].a, fPlanes[i].b, << 1453       return snxt=0;
1008         }                                     << 1454     }
1009         return 0;                             << 1455   }
                                                   >> 1456   else if (pdist<-kCarTolerance/2)
                                                   >> 1457   {
                                                   >> 1458     // Inside the plane
                                                   >> 1459     if (Comp>0)
                                                   >> 1460     {
                                                   >> 1461       // Will leave extent
                                                   >> 1462       vdist=-pdist/Comp;
                                                   >> 1463       if (vdist<snxt)
                                                   >> 1464       {
                                                   >> 1465         snxt=vdist;
                                                   >> 1466         side=ks1;
                                                   >> 1467       }
                                                   >> 1468     }
                                                   >> 1469   }
                                                   >> 1470   else
                                                   >> 1471   {
                                                   >> 1472     // On surface
                                                   >> 1473     if (Comp>0)
                                                   >> 1474     {
                                                   >> 1475       if (calcNorm)
                                                   >> 1476       {
                                                   >> 1477         *validNorm=true;
                                                   >> 1478         *n=G4ThreeVector(fPlanes[1].a,fPlanes[1].b,fPlanes[1].c);
                                                   >> 1479       }
                                                   >> 1480       return snxt=0;
                                                   >> 1481     }
                                                   >> 1482   }
                                                   >> 1483 
                                                   >> 1484   //
                                                   >> 1485   // Intersections with planes[2] (expanded because of setting enum)
                                                   >> 1486   //
                                                   >> 1487   pdist=fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z()+fPlanes[2].d;
                                                   >> 1488   Comp=fPlanes[2].a*v.x()+fPlanes[2].b*v.y()+fPlanes[2].c*v.z();
                                                   >> 1489   if (pdist>0)
                                                   >> 1490   {
                                                   >> 1491     // Outside the plane
                                                   >> 1492     if (Comp>0)
                                                   >> 1493     {
                                                   >> 1494       // Leaving immediately
                                                   >> 1495       if (calcNorm)
                                                   >> 1496       {
                                                   >> 1497         *validNorm=true;
                                                   >> 1498         *n=G4ThreeVector(fPlanes[2].a,fPlanes[2].b,fPlanes[2].c);
                                                   >> 1499       }
                                                   >> 1500       return snxt=0;
                                                   >> 1501     }
                                                   >> 1502   }
                                                   >> 1503   else if (pdist<-kCarTolerance/2)
                                                   >> 1504   {
                                                   >> 1505     // Inside the plane
                                                   >> 1506     if (Comp>0)
                                                   >> 1507     {
                                                   >> 1508       // Will leave extent
                                                   >> 1509       vdist=-pdist/Comp;
                                                   >> 1510       if (vdist<snxt)
                                                   >> 1511       {
                                                   >> 1512         snxt=vdist;
                                                   >> 1513         side=ks2;
                                                   >> 1514       }
                                                   >> 1515     }
                                                   >> 1516   }
                                                   >> 1517   else
                                                   >> 1518   {
                                                   >> 1519     // On surface
                                                   >> 1520     if (Comp>0)
                                                   >> 1521     {
                                                   >> 1522       if (calcNorm)
                                                   >> 1523       {
                                                   >> 1524         *validNorm=true;
                                                   >> 1525         *n=G4ThreeVector(fPlanes[2].a,fPlanes[2].b,fPlanes[2].c);
1010       }                                          1526       }
1011       G4double tmp = -dist/cosa;              << 1527       return snxt=0;
1012       if (tmax > tmp) { tmax = tmp; iside = i << 
1013     }                                            1528     }
1014   }                                              1529   }
1015                                                  1530 
1016   // Set normal, if required, and return dist << 
1017   //                                             1531   //
                                                   >> 1532   // Intersections with planes[3] (expanded because of setting enum)
                                                   >> 1533   //
                                                   >> 1534   pdist=fPlanes[3].a*p.x()+fPlanes[3].b*p.y()+fPlanes[3].c*p.z()+fPlanes[3].d;
                                                   >> 1535   Comp=fPlanes[3].a*v.x()+fPlanes[3].b*v.y()+fPlanes[3].c*v.z();
                                                   >> 1536   if (pdist>0)
                                                   >> 1537   {
                                                   >> 1538     // Outside the plane
                                                   >> 1539     if (Comp>0)
                                                   >> 1540     {
                                                   >> 1541       // Leaving immediately
                                                   >> 1542       if (calcNorm)
                                                   >> 1543       {
                                                   >> 1544         *validNorm=true;
                                                   >> 1545         *n=G4ThreeVector(fPlanes[3].a,fPlanes[3].b,fPlanes[3].c);
                                                   >> 1546       }
                                                   >> 1547       return snxt=0;
                                                   >> 1548     }
                                                   >> 1549   }
                                                   >> 1550   else if (pdist<-kCarTolerance/2)
                                                   >> 1551   {
                                                   >> 1552     // Inside the plane
                                                   >> 1553     if (Comp>0)
                                                   >> 1554     {
                                                   >> 1555       // Will leave extent
                                                   >> 1556       vdist=-pdist/Comp;
                                                   >> 1557       if (vdist<snxt)
                                                   >> 1558       {
                                                   >> 1559         snxt=vdist;
                                                   >> 1560         side=ks3;
                                                   >> 1561       }
                                                   >> 1562     }
                                                   >> 1563   }
                                                   >> 1564   else
                                                   >> 1565   {
                                                   >> 1566     // On surface
                                                   >> 1567     if (Comp>0)
                                                   >> 1568     {
                                                   >> 1569       if (calcNorm)
                                                   >> 1570       {
                                                   >> 1571         *validNorm=true;
                                                   >> 1572         *n=G4ThreeVector(fPlanes[3].a,fPlanes[3].b,fPlanes[3].c);
                                                   >> 1573       }
                                                   >> 1574       return snxt=0;
                                                   >> 1575     }
                                                   >> 1576   }
                                                   >> 1577 
                                                   >> 1578   // set normal
1018   if (calcNorm)                                  1579   if (calcNorm)
1019   {                                              1580   {
1020     *validNorm = true;                        << 1581     *validNorm=true;
1021     if (iside < 0)                            << 1582     switch(side)
1022       n->set(0, 0, iside + 3); // (-4+3)=-1,  << 1583     {
1023     else                                      << 1584       case ks0:
1024       n->set(fPlanes[iside].a, fPlanes[iside] << 1585         *n=G4ThreeVector(fPlanes[0].a,fPlanes[0].b,fPlanes[0].c);
                                                   >> 1586         break;
                                                   >> 1587       case ks1:
                                                   >> 1588         *n=G4ThreeVector(fPlanes[1].a,fPlanes[1].b,fPlanes[1].c);
                                                   >> 1589         break;
                                                   >> 1590       case ks2:
                                                   >> 1591         *n=G4ThreeVector(fPlanes[2].a,fPlanes[2].b,fPlanes[2].c);
                                                   >> 1592         break;
                                                   >> 1593       case ks3:
                                                   >> 1594         *n=G4ThreeVector(fPlanes[3].a,fPlanes[3].b,fPlanes[3].c);
                                                   >> 1595         break;
                                                   >> 1596       case kMZ:
                                                   >> 1597         *n=G4ThreeVector(0,0,-1);
                                                   >> 1598         break;
                                                   >> 1599       case kPZ:
                                                   >> 1600         *n=G4ThreeVector(0,0,1);
                                                   >> 1601         break;
                                                   >> 1602       default:
                                                   >> 1603         G4cout.precision(16);
                                                   >> 1604         G4cout << G4endl;
                                                   >> 1605         DumpInfo();
                                                   >> 1606         G4cout << "Position:"  << G4endl << G4endl;
                                                   >> 1607         G4cout << "p.x() = "   << p.x()/mm << " mm" << G4endl;
                                                   >> 1608         G4cout << "p.y() = "   << p.y()/mm << " mm" << G4endl;
                                                   >> 1609         G4cout << "p.z() = "   << p.z()/mm << " mm" << G4endl << G4endl;
                                                   >> 1610         G4cout << "Direction:" << G4endl << G4endl;
                                                   >> 1611         G4cout << "v.x() = "   << v.x() << G4endl;
                                                   >> 1612         G4cout << "v.y() = "   << v.y() << G4endl;
                                                   >> 1613         G4cout << "v.z() = "   << v.z() << G4endl << G4endl;
                                                   >> 1614         G4cout << "Proposed distance :" << G4endl << G4endl;
                                                   >> 1615         G4cout << "snxt = "    << snxt/mm << " mm" << G4endl << G4endl;
                                                   >> 1616         G4Exception("G4Trap::DistanceToOut(p,v,..)","Notification",JustWarning,
                                                   >> 1617                     "Undefined side for valid surface normal to solid.");
                                                   >> 1618         break;
                                                   >> 1619     }
1025   }                                              1620   }
1026   return tmax;                                << 1621   return snxt;
1027 }                                                1622 }
1028                                                  1623 
1029 ///////////////////////////////////////////// << 1624 //////////////////////////////////////////////////////////////////////////////
1030 //                                               1625 //
1031 // Calculate exact shortest distance to any b    1626 // Calculate exact shortest distance to any boundary from inside
1032 // - Returns 0 is ThreeVector outside            1627 // - Returns 0 is ThreeVector outside
1033                                                  1628 
1034 G4double G4Trap::DistanceToOut( const G4Three    1629 G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
1035 {                                                1630 {
                                                   >> 1631   G4double safe=0.0,Dist;
                                                   >> 1632   G4int i;
                                                   >> 1633 
1036 #ifdef G4CSGDEBUG                                1634 #ifdef G4CSGDEBUG
1037   if( Inside(p) == kOutside )                    1635   if( Inside(p) == kOutside )
1038   {                                              1636   {
1039     std::ostringstream message;               << 1637      G4cout.precision(16) ;
1040     G4long oldprc = message.precision(16);    << 1638      G4cout << G4endl ;
1041     message << "Point p is outside (!?) of so << 1639      DumpInfo();
1042     message << "Position:\n";                 << 1640      G4cout << "Position:"  << G4endl << G4endl ;
1043     message << "   p.x() = " << p.x()/mm << " << 1641      G4cout << "p.x() = "   << p.x()/mm << " mm" << G4endl ;
1044     message << "   p.y() = " << p.y()/mm << " << 1642      G4cout << "p.y() = "   << p.y()/mm << " mm" << G4endl ;
1045     message << "   p.z() = " << p.z()/mm << " << 1643      G4cout << "p.z() = "   << p.z()/mm << " mm" << G4endl << G4endl ;
1046     G4cout.precision(oldprc);                 << 1644      G4Exception("G4Trap::DistanceToOut(p)",
1047     G4Exception("G4Trap::DistanceToOut(p)", " << 1645                  "Notification", JustWarning, "Point p is outside !?" );
1048                 JustWarning, message );       << 
1049     DumpInfo();                               << 
1050   }                                              1646   }
1051 #endif                                           1647 #endif
1052   switch (fTrapType)                          << 1648 
                                                   >> 1649   safe=fDz-std::fabs(p.z());
                                                   >> 1650   if (safe<0) safe=0;
                                                   >> 1651   else
1053   {                                              1652   {
1054     case 0: // General case                   << 1653     for (i=0;i<4;i++)
1055     {                                            1654     {
1056       G4double dz = std::abs(p.z())-fDz;      << 1655       Dist=-(fPlanes[i].a*p.x()+fPlanes[i].b*p.y()
1057       G4double dy1 = fPlanes[0].b*p.y()+fPlan << 1656             +fPlanes[i].c*p.z()+fPlanes[i].d);
1058       G4double dy2 = fPlanes[1].b*p.y()+fPlan << 1657       if (Dist<safe) safe=Dist;
1059       G4double dy = std::max(dz,std::max(dy1, << 1658     }
1060                                               << 1659     if (safe<0) safe=0;
1061       G4double dx1 = fPlanes[2].a*p.x()+fPlan << 1660   }
1062                    + fPlanes[2].c*p.z()+fPlan << 1661   return safe;  
1063       G4double dx2 = fPlanes[3].a*p.x()+fPlan << 
1064                    + fPlanes[3].c*p.z()+fPlan << 
1065       G4double dist = std::max(dy,std::max(dx << 
1066       return (dist < 0) ? -dist : 0.;         << 
1067     }                                         << 
1068     case 1: // YZ section is a rectangle      << 
1069     {                                         << 
1070       G4double dz = std::abs(p.z())-fDz;      << 
1071       G4double dy = std::max(dz,std::abs(p.y( << 
1072       G4double dx1 = fPlanes[2].a*p.x()+fPlan << 
1073                    + fPlanes[2].c*p.z()+fPlan << 
1074       G4double dx2 = fPlanes[3].a*p.x()+fPlan << 
1075                    + fPlanes[3].c*p.z()+fPlan << 
1076       G4double dist = std::max(dy,std::max(dx << 
1077       return (dist < 0) ? -dist : 0.;         << 
1078     }                                         << 
1079     case 2: // YZ section is a rectangle and  << 
1080     {       // XZ section is an isosceles tra << 
1081       G4double dz = std::abs(p.z())-fDz;      << 
1082       G4double dy = std::max(dz,std::abs(p.y( << 
1083       G4double dx = fPlanes[3].a*std::abs(p.x << 
1084                   + fPlanes[3].c*p.z()+fPlane << 
1085       G4double dist = std::max(dy,dx);        << 
1086       return (dist < 0) ? -dist : 0.;         << 
1087     }                                         << 
1088     case 3: // YZ section is a rectangle and  << 
1089     {       // XY section is an isosceles tra << 
1090       G4double dz = std::abs(p.z())-fDz;      << 
1091       G4double dy = std::max(dz,std::abs(p.y( << 
1092       G4double dx = fPlanes[3].a*std::abs(p.x << 
1093                   + fPlanes[3].b*p.y()+fPlane << 
1094       G4double dist = std::max(dy,dx);        << 
1095       return (dist < 0) ? -dist : 0.;         << 
1096     }                                         << 
1097   }                                           << 
1098   return 0.;                                  << 
1099 }                                                1662 }
1100                                                  1663 
1101 /////////////////////////////////////////////    1664 //////////////////////////////////////////////////////////////////////////
1102 //                                               1665 //
1103 // GetEntityType                              << 1666 // Create a List containing the transformed vertices
1104                                               << 1667 // Ordering [0-3] -fDz cross section
1105 G4GeometryType G4Trap::GetEntityType() const  << 1668 //          [4-7] +fDz cross section such that [0] is below [4],
1106 {                                             << 1669 //                                             [1] below [5] etc.
1107   return {"G4Trap"};                          << 1670 // Note:
                                                   >> 1671 //  Caller has deletion resposibility
                                                   >> 1672 
                                                   >> 1673 G4ThreeVectorList*
                                                   >> 1674 G4Trap::CreateRotatedVertices( const G4AffineTransform& pTransform ) const
                                                   >> 1675 {
                                                   >> 1676   G4ThreeVectorList *vertices;
                                                   >> 1677   vertices=new G4ThreeVectorList();
                                                   >> 1678   vertices->reserve(8);
                                                   >> 1679   if (vertices)
                                                   >> 1680   {
                                                   >> 1681     G4ThreeVector vertex0(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
                                                   >> 1682                           -fDz*fTthetaSphi-fDy1,-fDz);
                                                   >> 1683     G4ThreeVector vertex1(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
                                                   >> 1684                           -fDz*fTthetaSphi-fDy1,-fDz);
                                                   >> 1685     G4ThreeVector vertex2(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
                                                   >> 1686                           -fDz*fTthetaSphi+fDy1,-fDz);
                                                   >> 1687     G4ThreeVector vertex3(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
                                                   >> 1688                           -fDz*fTthetaSphi+fDy1,-fDz);
                                                   >> 1689     G4ThreeVector vertex4(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
                                                   >> 1690                           +fDz*fTthetaSphi-fDy2,+fDz);
                                                   >> 1691     G4ThreeVector vertex5(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
                                                   >> 1692                           +fDz*fTthetaSphi-fDy2,+fDz);
                                                   >> 1693     G4ThreeVector vertex6(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
                                                   >> 1694                           +fDz*fTthetaSphi+fDy2,+fDz);
                                                   >> 1695     G4ThreeVector vertex7(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
                                                   >> 1696                           +fDz*fTthetaSphi+fDy2,+fDz);
                                                   >> 1697 
                                                   >> 1698     vertices->push_back(pTransform.TransformPoint(vertex0));
                                                   >> 1699     vertices->push_back(pTransform.TransformPoint(vertex1));
                                                   >> 1700     vertices->push_back(pTransform.TransformPoint(vertex2));
                                                   >> 1701     vertices->push_back(pTransform.TransformPoint(vertex3));
                                                   >> 1702     vertices->push_back(pTransform.TransformPoint(vertex4));
                                                   >> 1703     vertices->push_back(pTransform.TransformPoint(vertex5));
                                                   >> 1704     vertices->push_back(pTransform.TransformPoint(vertex6));
                                                   >> 1705     vertices->push_back(pTransform.TransformPoint(vertex7));
                                                   >> 1706   }
                                                   >> 1707   else
                                                   >> 1708   {
                                                   >> 1709     DumpInfo();
                                                   >> 1710     G4Exception("G4Trap::CreateRotatedVertices()",
                                                   >> 1711                 "FatalError", FatalException,
                                                   >> 1712                 "Error in allocation of vertices. Out of memory !");
                                                   >> 1713   }
                                                   >> 1714   return vertices;
1108 }                                                1715 }
1109                                                  1716 
1110 /////////////////////////////////////////////    1717 //////////////////////////////////////////////////////////////////////////
1111 //                                               1718 //
1112 // IsFaceted                                  << 1719 // GetEntityType
1113                                               << 
1114 G4bool G4Trap::IsFaceted() const              << 
1115 {                                             << 
1116   return true;                                << 
1117 }                                             << 
1118                                                  1720 
1119 ///////////////////////////////////////////// << 1721 G4GeometryType G4Trap::GetEntityType() const
1120 //                                            << 
1121 // Make a clone of the object                 << 
1122 //                                            << 
1123 G4VSolid* G4Trap::Clone() const               << 
1124 {                                                1722 {
1125   return new G4Trap(*this);                   << 1723   return G4String("G4Trap");
1126 }                                                1724 }
1127                                                  1725 
1128 /////////////////////////////////////////////    1726 //////////////////////////////////////////////////////////////////////////
1129 //                                               1727 //
1130 // Stream object contents to an output stream    1728 // Stream object contents to an output stream
1131                                                  1729 
1132 std::ostream& G4Trap::StreamInfo( std::ostrea    1730 std::ostream& G4Trap::StreamInfo( std::ostream& os ) const
1133 {                                                1731 {
1134   G4double phi    = GetPhi();                 << 
1135   G4double theta  = GetTheta();               << 
1136   G4double alpha1 = GetAlpha1();              << 
1137   G4double alpha2 = GetAlpha2();              << 
1138                                               << 
1139   G4long oldprc = os.precision(16);           << 
1140   os << "------------------------------------    1732   os << "-----------------------------------------------------------\n"
1141      << "    *** Dump for solid: " << GetName << 1733      << "    *** Dump for solid - " << GetName() << " ***\n"
1142      << "    ================================    1734      << "    ===================================================\n"
1143      << " Solid type: G4Trap\n"                  1735      << " Solid type: G4Trap\n"
1144      << " Parameters:\n"                      << 1736      << " Parameters: \n"
1145      << "    half length Z: " << fDz/mm << "  << 1737      << "    half length Z: " << fDz/mm << " mm \n"
1146      << "    half length Y, face -Dz: " << fD << 1738      << "    half length Y of face -fDz: " << fDy1/mm << " mm \n"
1147      << "    half length X, face -Dz, side -D << 1739      << "    half length X of side -fDy1, face -fDz: " << fDx1/mm << " mm \n"
1148      << "    half length X, face -Dz, side +D << 1740      << "    half length X of side +fDy1, face -fDz: " << fDx2/mm << " mm \n"
1149      << "    half length Y, face +Dz: " << fD << 1741      << "    half length Y of face +fDz: " << fDy2/mm << " mm \n"
1150      << "    half length X, face +Dz, side -D << 1742      << "    half length X of side -fDy2, face +fDz: " << fDx3/mm << " mm \n"
1151      << "    half length X, face +Dz, side +D << 1743      << "    half length X of side +fDy2, face +fDz: " << fDx4/mm << " mm \n"
1152      << "    theta: " << theta/degree << " de << 1744      << "    std::tan(theta)*std::cos(phi): " << fTthetaCphi/degree << " degrees \n"
1153      << "    phi:   " << phi/degree << " degr << 1745      << "    std::tan(theta)*std::sin(phi): " << fTthetaSphi/degree << " degrees \n"
1154      << "    alpha, face -Dz: " << alpha1/deg << 1746      << "    std::tan(alpha), -fDz: " << fTalpha1/degree << " degrees \n"
1155      << "    alpha, face +Dz: " << alpha2/deg << 1747      << "    std::tan(alpha), +fDz: " << fTalpha2/degree << " degrees \n"
                                                   >> 1748      << "    trap side plane equations:\n"
                                                   >> 1749      << "        " << fPlanes[0].a << " X + " << fPlanes[0].b << " Y + "
                                                   >> 1750                    << fPlanes[0].c << " Z + " << fPlanes[0].d << " = 0\n"
                                                   >> 1751      << "        " << fPlanes[1].a << " X + " << fPlanes[1].b << " Y + "
                                                   >> 1752                    << fPlanes[1].c << " Z + " << fPlanes[1].d << " = 0\n"
                                                   >> 1753      << "        " << fPlanes[2].a << " X + " << fPlanes[2].b << " Y + "
                                                   >> 1754                    << fPlanes[2].c << " Z + " << fPlanes[2].d << " = 0\n"
                                                   >> 1755      << "        " << fPlanes[3].a << " X + " << fPlanes[3].b << " Y + "
                                                   >> 1756                    << fPlanes[3].c << " Z + " << fPlanes[3].d << " = 0\n"
1156      << "------------------------------------    1757      << "-----------------------------------------------------------\n";
1157   os.precision(oldprc);                       << 
1158                                                  1758 
1159   return os;                                     1759   return os;
1160 }                                                1760 }
1161                                                  1761 
1162 ///////////////////////////////////////////// << 1762 ///////////////////////////////////////////////////////////////////////////////
1163 //                                            << 
1164 // Compute vertices from planes               << 
1165                                               << 
1166 void G4Trap::GetVertices(G4ThreeVector pt[8]) << 
1167 {                                             << 
1168   for (G4int i=0; i<8; ++i)                   << 
1169   {                                           << 
1170     G4int iy = (i==0 || i==1 || i==4 || i==5) << 
1171     G4int ix = (i==0 || i==2 || i==4 || i==6) << 
1172     G4double z = (i < 4) ? -fDz : fDz;        << 
1173     G4double y = -(fPlanes[iy].c*z + fPlanes[ << 
1174     G4double x = -(fPlanes[ix].b*y + fPlanes[ << 
1175                    + fPlanes[ix].d)/fPlanes[i << 
1176     pt[i].set(x,y,z);                         << 
1177   }                                           << 
1178 }                                             << 
1179                                               << 
1180 ///////////////////////////////////////////// << 
1181 //                                            << 
1182 // Generate random point on the surface       << 
1183                                               << 
1184 G4ThreeVector G4Trap::GetPointOnSurface() con << 
1185 {                                             << 
1186   // Set indeces                              << 
1187   constexpr G4int iface [6][4] =              << 
1188     { {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6 << 
1189                                               << 
1190   // Set vertices                             << 
1191   G4ThreeVector pt[8];                        << 
1192   GetVertices(pt);                            << 
1193                                               << 
1194   // Select face                              << 
1195   //                                          << 
1196   G4double select = fAreas[5]*G4QuickRand();  << 
1197   G4int k = 5;                                << 
1198   k -= (G4int)(select <= fAreas[4]);          << 
1199   k -= (G4int)(select <= fAreas[3]);          << 
1200   k -= (G4int)(select <= fAreas[2]);          << 
1201   k -= (G4int)(select <= fAreas[1]);          << 
1202   k -= (G4int)(select <= fAreas[0]);          << 
1203                                               << 
1204   // Select sub-triangle                      << 
1205   //                                          << 
1206   G4int i0 = iface[k][0];                     << 
1207   G4int i1 = iface[k][1];                     << 
1208   G4int i2 = iface[k][2];                     << 
1209   G4int i3 = iface[k][3];                     << 
1210   G4double s2 = G4GeomTools::TriangleAreaNorm << 
1211   if (select > fAreas[k] - s2) i0 = i2;       << 
1212                                               << 
1213   // Generate point                           << 
1214   //                                          << 
1215   G4double u = G4QuickRand();                 << 
1216   G4double v = G4QuickRand();                 << 
1217   if (u + v > 1.) { u = 1. - u; v = 1. - v; } << 
1218   return (1.-u-v)*pt[i0] + u*pt[i1] + v*pt[i3 << 
1219 }                                             << 
1220                                               << 
1221 ///////////////////////////////////////////// << 
1222 //                                               1763 //
1223 // Methods for visualisation                     1764 // Methods for visualisation
1224                                                  1765 
1225 void G4Trap::DescribeYourselfTo ( G4VGraphics    1766 void G4Trap::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
1226 {                                                1767 {
1227   scene.AddSolid (*this);                        1768   scene.AddSolid (*this);
1228 }                                                1769 }
1229                                                  1770 
1230 G4Polyhedron* G4Trap::CreatePolyhedron () con    1771 G4Polyhedron* G4Trap::CreatePolyhedron () const
1231 {                                                1772 {
1232   G4double phi = std::atan2(fTthetaSphi, fTth    1773   G4double phi = std::atan2(fTthetaSphi, fTthetaCphi);
1233   G4double alpha1 = std::atan(fTalpha1);         1774   G4double alpha1 = std::atan(fTalpha1);
1234   G4double alpha2 = std::atan(fTalpha2);         1775   G4double alpha2 = std::atan(fTalpha2);
1235   G4double theta = std::atan(std::sqrt(fTthet << 1776   G4double theta = std::atan(std::sqrt(fTthetaCphi*fTthetaCphi+fTthetaSphi*fTthetaSphi));
1236                                       +fTthet << 
1237                                                  1777 
1238   return new G4PolyhedronTrap(fDz, theta, phi    1778   return new G4PolyhedronTrap(fDz, theta, phi,
1239                               fDy1, fDx1, fDx    1779                               fDy1, fDx1, fDx2, alpha1,
1240                               fDy2, fDx3, fDx    1780                               fDy2, fDx3, fDx4, alpha2);
1241 }                                                1781 }
1242                                                  1782 
1243 #endif                                        << 1783 G4NURBS* G4Trap::CreateNURBS () const
                                                   >> 1784 {
                                                   >> 1785    // return new G4NURBSbox (fDx, fDy, fDz);
                                                   >> 1786    return 0 ;
                                                   >> 1787 }
1244                                                  1788