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 10.5.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
                                                   >>  26 //
                                                   >>  27 //
                                                   >>  28 // class G4Trap
                                                   >>  29 //
 26 // Implementation for G4Trap class                 30 // Implementation for G4Trap class
 27 //                                                 31 //
 28 // 21.03.95 P.Kent: Modified for `tolerant' ge <<  32 // History:
 29 // 09.09.96 V.Grichine: Final modifications be <<  33 //
 30 // 08.12.97 J.Allison: Added "nominal" constru << 
 31 // 28.04.05 V.Grichine: new SurfaceNormal acco << 
 32 // 18.04.17 E.Tcherniaev: complete revision, s     34 // 18.04.17 E.Tcherniaev: complete revision, speed-up
 33 // ------------------------------------------- <<  35 // 23.09.16 E.Tcherniaev: use G4BoundingEnvelope for CalculateExtent(),
                                                   >>  36 //                      removed CreateRotatedVertices()
                                                   >>  37 // 28.04.05 V.Grichine: new SurfaceNormal according to J. Apostolakis proposal 
                                                   >>  38 // 26.04.05 V.Grichine: new SurfaceNormal is default 
                                                   >>  39 // 19.04.05 V.Grichine: bug fixed in G4Trap("name",G4ThreeVector[8] vp)
                                                   >>  40 // 12.12.04 V.Grichine: SurfaceNormal with edges/vertices 
                                                   >>  41 // 15.11.04 V.Grichine: bug fixed in G4Trap("name",G4ThreeVector[8] vp)
                                                   >>  42 // 13.12.99 V.Grichine: bug fixed in DistanceToIn(p,v)
                                                   >>  43 // 19.11.99 V.Grichine: kUndef was added to Eside enum
                                                   >>  44 // 04.06.99 S.Giani: Fixed CalculateExtent in rotated case. 
                                                   >>  45 // 08.12.97 J.Allison: Added "nominal" constructor and method SetAllParameters.
                                                   >>  46 // 01.11.96 V.Grichine: Costructor for Right Angular Wedge from STEP, G4Trd/Para
                                                   >>  47 // 09.09.96 V.Grichine: Final modifications before to commit
                                                   >>  48 // 21.03.95 P.Kent: Modified for `tolerant' geometry
                                                   >>  49 //
                                                   >>  50 ///////////////////////////////////////////////////////////////////////////////
 34                                                    51 
 35 #include "G4Trap.hh"                               52 #include "G4Trap.hh"
 36                                                    53 
 37 #if !defined(G4GEOM_USE_UTRAP)                     54 #if !defined(G4GEOM_USE_UTRAP)
 38                                                    55 
 39 #include "globals.hh"                              56 #include "globals.hh"
 40 #include "G4GeomTools.hh"                          57 #include "G4GeomTools.hh"
 41                                                    58 
 42 #include "G4VoxelLimits.hh"                        59 #include "G4VoxelLimits.hh"
 43 #include "G4AffineTransform.hh"                    60 #include "G4AffineTransform.hh"
 44 #include "G4BoundingEnvelope.hh"                   61 #include "G4BoundingEnvelope.hh"
 45                                                    62 
 46 #include "G4VPVParameterisation.hh"                63 #include "G4VPVParameterisation.hh"
 47                                                    64 
 48 #include "G4QuickRand.hh"                      <<  65 #include "Randomize.hh"
 49                                                    66 
 50 #include "G4VGraphicsScene.hh"                     67 #include "G4VGraphicsScene.hh"
 51 #include "G4Polyhedron.hh"                         68 #include "G4Polyhedron.hh"
 52                                                    69 
 53 using namespace CLHEP;                             70 using namespace CLHEP;
 54                                                    71 
 55 //////////////////////////////////////////////     72 //////////////////////////////////////////////////////////////////////////
 56 //                                                 73 //
 57 // Constructor - check and set half-widths as  <<  74 // Constructor - check and set half-widths as well as angles: 
 58 // final check of coplanarity                      75 // final check of coplanarity
 59                                                    76 
 60 G4Trap::G4Trap( const G4String& pName,             77 G4Trap::G4Trap( const G4String& pName,
 61                       G4double pDz,                78                       G4double pDz,
 62                       G4double pTheta, G4doubl     79                       G4double pTheta, G4double pPhi,
 63                       G4double pDy1, G4double      80                       G4double pDy1, G4double pDx1, G4double pDx2,
 64                       G4double pAlp1,              81                       G4double pAlp1,
 65                       G4double pDy2, G4double      82                       G4double pDy2, G4double pDx3, G4double pDx4,
 66                       G4double pAlp2 )         <<  83                       G4double pAlp2)
 67   : G4CSGSolid(pName), halfCarTolerance(0.5*kC     84   : G4CSGSolid(pName), halfCarTolerance(0.5*kCarTolerance)
 68 {                                                  85 {
 69   fDz = pDz;                                       86   fDz = pDz;
 70   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi     87   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi);
 71   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi     88   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi);
 72                                                    89 
 73   fDy1 = pDy1; fDx1 = pDx1; fDx2 = pDx2; fTalp     90   fDy1 = pDy1; fDx1 = pDx1; fDx2 = pDx2; fTalpha1 = std::tan(pAlp1);
 74   fDy2 = pDy2; fDx3 = pDx3; fDx4 = pDx4; fTalp     91   fDy2 = pDy2; fDx3 = pDx3; fDx4 = pDx4; fTalpha2 = std::tan(pAlp2);
 75                                                    92 
 76   CheckParameters();                               93   CheckParameters();
 77   MakePlanes();                                    94   MakePlanes();
 78 }                                                  95 }
 79                                                    96 
 80 //////////////////////////////////////////////     97 //////////////////////////////////////////////////////////////////////////
 81 //                                                 98 //
 82 // Constructor - Design of trapezoid based on  <<  99 // Constructor - Design of trapezoid based on 8 G4ThreeVector parameters, 
 83 // which are its vertices. Checking of planari << 100 // which are its vertices. Checking of planarity with preparation of 
 84 // fPlanes[] and than calculation of other mem    101 // fPlanes[] and than calculation of other members
 85                                                   102 
 86 G4Trap::G4Trap( const G4String& pName,            103 G4Trap::G4Trap( const G4String& pName,
 87                 const G4ThreeVector pt[8] )       104                 const G4ThreeVector pt[8] )
 88   : G4CSGSolid(pName), halfCarTolerance(0.5*kC    105   : G4CSGSolid(pName), halfCarTolerance(0.5*kCarTolerance)
 89 {                                                 106 {
 90   // Start with check of centering - the cente    107   // Start with check of centering - the center of gravity trap line
 91   // should cross the origin of frame             108   // should cross the origin of frame
 92   //                                              109   //
 93   if (  pt[0].z() >= 0                         << 110   if (!(   pt[0].z() < 0
 94         || pt[0].z() != pt[1].z()              << 111         && pt[0].z() == pt[1].z()
 95         || pt[0].z() != pt[2].z()              << 112         && pt[0].z() == pt[2].z()
 96         || pt[0].z() != pt[3].z()              << 113         && pt[0].z() == pt[3].z()
 97                                                << 114 
 98         || pt[4].z() <= 0                      << 115         && pt[4].z() > 0
 99         || pt[4].z() != pt[5].z()              << 116         && pt[4].z() == pt[5].z()
100         || pt[4].z() != pt[6].z()              << 117         && pt[4].z() == pt[6].z()
101         || pt[4].z() != pt[7].z()              << 118         && pt[4].z() == pt[7].z()
102                                                << 119 
103         || std::fabs( pt[0].z() + pt[4].z() )  << 120         && std::fabs( pt[0].z() + pt[4].z() ) < kCarTolerance
104                                                << 121 
105         || pt[0].y() != pt[1].y()              << 122         && pt[0].y() == pt[1].y()
106         || pt[2].y() != pt[3].y()              << 123         && pt[2].y() == pt[3].y()
107         || pt[4].y() != pt[5].y()              << 124         && pt[4].y() == pt[5].y()
108         || pt[6].y() != pt[7].y()              << 125         && pt[6].y() == pt[7].y()
109                                                << 126 
110         || std::fabs(pt[0].y()+pt[2].y()+pt[4] << 127         && std::fabs(pt[0].y()+pt[2].y()+pt[4].y()+pt[6].y()) < kCarTolerance
111         || std::fabs(pt[0].x()+pt[1].x()+pt[4] << 128         && std::fabs(pt[0].x()+pt[1].x()+pt[4].x()+pt[5].x() +
112                      pt[2].x()+pt[3].x()+pt[6] << 129                      pt[2].x()+pt[3].x()+pt[6].x()+pt[7].x()) < kCarTolerance ))
113   {                                               130   {
114     std::ostringstream message;                   131     std::ostringstream message;
115     message << "Invalid vertice coordinates fo    132     message << "Invalid vertice coordinates for Solid: " << GetName();
116     G4Exception("G4Trap::G4Trap()", "GeomSolid    133     G4Exception("G4Trap::G4Trap()", "GeomSolids0002",
117                 FatalException, message);         134                 FatalException, message);
118   }                                               135   }
119                                                << 136     
120   // Set parameters                               137   // Set parameters
121   //                                              138   //
122   fDz = (pt[7]).z();                              139   fDz = (pt[7]).z();
123                                                << 140       
124   fDy1     = ((pt[2]).y()-(pt[1]).y())*0.5;       141   fDy1     = ((pt[2]).y()-(pt[1]).y())*0.5;
125   fDx1     = ((pt[1]).x()-(pt[0]).x())*0.5;       142   fDx1     = ((pt[1]).x()-(pt[0]).x())*0.5;
126   fDx2     = ((pt[3]).x()-(pt[2]).x())*0.5;       143   fDx2     = ((pt[3]).x()-(pt[2]).x())*0.5;
127   fTalpha1 = ((pt[2]).x()+(pt[3]).x()-(pt[1]).    144   fTalpha1 = ((pt[2]).x()+(pt[3]).x()-(pt[1]).x()-(pt[0]).x())*0.25/fDy1;
128                                                   145 
129   fDy2     = ((pt[6]).y()-(pt[5]).y())*0.5;       146   fDy2     = ((pt[6]).y()-(pt[5]).y())*0.5;
130   fDx3     = ((pt[5]).x()-(pt[4]).x())*0.5;       147   fDx3     = ((pt[5]).x()-(pt[4]).x())*0.5;
131   fDx4     = ((pt[7]).x()-(pt[6]).x())*0.5;       148   fDx4     = ((pt[7]).x()-(pt[6]).x())*0.5;
132   fTalpha2 = ((pt[6]).x()+(pt[7]).x()-(pt[5]).    149   fTalpha2 = ((pt[6]).x()+(pt[7]).x()-(pt[5]).x()-(pt[4]).x())*0.25/fDy2;
133                                                   150 
134   fTthetaCphi = ((pt[4]).x()+fDy2*fTalpha2+fDx    151   fTthetaCphi = ((pt[4]).x()+fDy2*fTalpha2+fDx3)/fDz;
135   fTthetaSphi = ((pt[4]).y()+fDy2)/fDz;           152   fTthetaSphi = ((pt[4]).y()+fDy2)/fDz;
136                                                   153 
137   CheckParameters();                              154   CheckParameters();
138   MakePlanes(pt);                                 155   MakePlanes(pt);
139 }                                                 156 }
140                                                   157 
141 //////////////////////////////////////////////    158 //////////////////////////////////////////////////////////////////////////
142 //                                                159 //
143 // Constructor for Right Angular Wedge from ST    160 // Constructor for Right Angular Wedge from STEP
144                                                   161 
145 G4Trap::G4Trap( const G4String& pName,            162 G4Trap::G4Trap( const G4String& pName,
146                       G4double pZ,                163                       G4double pZ,
147                       G4double pY,                164                       G4double pY,
148                       G4double pX, G4double pL    165                       G4double pX, G4double pLTX )
149   : G4CSGSolid(pName), halfCarTolerance(0.5*kC    166   : G4CSGSolid(pName), halfCarTolerance(0.5*kCarTolerance)
150 {                                                 167 {
151   fDz  = 0.5*pZ; fTthetaCphi = 0; fTthetaSphi     168   fDz  = 0.5*pZ; fTthetaCphi = 0; fTthetaSphi = 0;
152   fDy1 = 0.5*pY; fDx1 = 0.5*pX; fDx2 = 0.5*pLT    169   fDy1 = 0.5*pY; fDx1 = 0.5*pX; fDx2 = 0.5*pLTX; fTalpha1 = 0.5*(pLTX - pX)/pY;
153   fDy2 = fDy1;   fDx3 = fDx1;   fDx4 = fDx2;      170   fDy2 = fDy1;   fDx3 = fDx1;   fDx4 = fDx2;     fTalpha2 = fTalpha1;
154                                                   171 
155   CheckParameters();                              172   CheckParameters();
156   MakePlanes();                                   173   MakePlanes();
157 }                                                 174 }
158                                                   175 
159 //////////////////////////////////////////////    176 //////////////////////////////////////////////////////////////////////////
160 //                                                177 //
161 // Constructor for G4Trd                          178 // Constructor for G4Trd
162                                                   179 
163 G4Trap::G4Trap( const G4String& pName,            180 G4Trap::G4Trap( const G4String& pName,
164                       G4double pDx1,  G4double    181                       G4double pDx1,  G4double pDx2,
165                       G4double pDy1,  G4double    182                       G4double pDy1,  G4double pDy2,
166                       G4double pDz )              183                       G4double pDz )
167   : G4CSGSolid(pName), halfCarTolerance(0.5*kC    184   : G4CSGSolid(pName), halfCarTolerance(0.5*kCarTolerance), fTrapType(0)
168 {                                                 185 {
169   fDz  = pDz;  fTthetaCphi = 0; fTthetaSphi =     186   fDz  = pDz;  fTthetaCphi = 0; fTthetaSphi = 0;
170   fDy1 = pDy1; fDx1 = pDx1; fDx2 = pDx1; fTalp    187   fDy1 = pDy1; fDx1 = pDx1; fDx2 = pDx1; fTalpha1 = 0;
171   fDy2 = pDy2; fDx3 = pDx2; fDx4 = pDx2; fTalp    188   fDy2 = pDy2; fDx3 = pDx2; fDx4 = pDx2; fTalpha2 = 0;
172                                                   189 
173   CheckParameters();                              190   CheckParameters();
174   MakePlanes();                                   191   MakePlanes();
175 }                                                 192 }
176                                                   193 
177 //////////////////////////////////////////////    194 //////////////////////////////////////////////////////////////////////////
178 //                                                195 //
179 // Constructor for G4Para                         196 // Constructor for G4Para
180                                                   197 
181 G4Trap::G4Trap( const G4String& pName,            198 G4Trap::G4Trap( const G4String& pName,
182                       G4double pDx, G4double p    199                       G4double pDx, G4double pDy,
183                       G4double pDz,               200                       G4double pDz,
184                       G4double pAlpha,            201                       G4double pAlpha,
185                       G4double pTheta, G4doubl    202                       G4double pTheta, G4double pPhi )
186   : G4CSGSolid(pName), halfCarTolerance(0.5*kC    203   : G4CSGSolid(pName), halfCarTolerance(0.5*kCarTolerance)
187 {                                                 204 {
188   fDz = pDz;                                      205   fDz = pDz;
189   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi    206   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi);
190   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi    207   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi);
191                                                   208 
192   fDy1 = pDy; fDx1 = pDx; fDx2 = pDx; fTalpha1    209   fDy1 = pDy; fDx1 = pDx; fDx2 = pDx; fTalpha1 = std::tan(pAlpha);
193   fDy2 = pDy; fDx3 = pDx; fDx4 = pDx; fTalpha2    210   fDy2 = pDy; fDx3 = pDx; fDx4 = pDx; fTalpha2 = fTalpha1;
194                                                   211 
195   CheckParameters();                              212   CheckParameters();
196   MakePlanes();                                   213   MakePlanes();
197 }                                                 214 }
198                                                   215 
199 //////////////////////////////////////////////    216 //////////////////////////////////////////////////////////////////////////
200 //                                                217 //
201 // Nominal constructor for G4Trap whose parame    218 // Nominal constructor for G4Trap whose parameters are to be set by
202 // a G4VParamaterisation later.  Check and set    219 // a G4VParamaterisation later.  Check and set half-widths as well as
203 // angles: final check of coplanarity             220 // angles: final check of coplanarity
204                                                   221 
205 G4Trap::G4Trap( const G4String& pName )           222 G4Trap::G4Trap( const G4String& pName )
206   : G4CSGSolid (pName), halfCarTolerance(0.5*k    223   : G4CSGSolid (pName), halfCarTolerance(0.5*kCarTolerance),
207     fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.),    224     fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.),
208     fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.)    225     fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.),
209     fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.)    226     fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.)
210 {                                                 227 {
211   MakePlanes();                                   228   MakePlanes();
212 }                                                 229 }
213                                                   230 
214 //////////////////////////////////////////////    231 //////////////////////////////////////////////////////////////////////////
215 //                                                232 //
216 // Fake default constructor - sets only member    233 // Fake default constructor - sets only member data and allocates memory
217 //                            for usage restri    234 //                            for usage restricted to object persistency.
218 //                                                235 //
219 G4Trap::G4Trap( __void__& a )                     236 G4Trap::G4Trap( __void__& a )
220   : G4CSGSolid(a), halfCarTolerance(0.5*kCarTo    237   : G4CSGSolid(a), halfCarTolerance(0.5*kCarTolerance),
221     fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.),    238     fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.),
222     fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.)    239     fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.),
223     fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.)    240     fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.)
224 {                                                 241 {
225   MakePlanes();                                   242   MakePlanes();
226 }                                                 243 }
227                                                   244 
228 //////////////////////////////////////////////    245 //////////////////////////////////////////////////////////////////////////
229 //                                                246 //
230 // Destructor                                     247 // Destructor
231                                                   248 
232 G4Trap::~G4Trap() = default;                   << 249 G4Trap::~G4Trap()
                                                   >> 250 {
                                                   >> 251 }
233                                                   252 
234 //////////////////////////////////////////////    253 //////////////////////////////////////////////////////////////////////////
235 //                                                254 //
236 // Copy constructor                               255 // Copy constructor
237                                                   256 
238 G4Trap::G4Trap(const G4Trap& rhs)                 257 G4Trap::G4Trap(const G4Trap& rhs)
239   : G4CSGSolid(rhs), halfCarTolerance(rhs.half    258   : G4CSGSolid(rhs), halfCarTolerance(rhs.halfCarTolerance),
240     fDz(rhs.fDz), fTthetaCphi(rhs.fTthetaCphi)    259     fDz(rhs.fDz), fTthetaCphi(rhs.fTthetaCphi), fTthetaSphi(rhs.fTthetaSphi),
241     fDy1(rhs.fDy1), fDx1(rhs.fDx1), fDx2(rhs.f    260     fDy1(rhs.fDy1), fDx1(rhs.fDx1), fDx2(rhs.fDx2), fTalpha1(rhs.fTalpha1),
242     fDy2(rhs.fDy2), fDx3(rhs.fDx3), fDx4(rhs.f    261     fDy2(rhs.fDy2), fDx3(rhs.fDx3), fDx4(rhs.fDx4), fTalpha2(rhs.fTalpha2)
243 {                                                 262 {
244   for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs    263   for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
245   for (G4int i=0; i<6; ++i) { fAreas[i] = rhs. << 
246   fTrapType = rhs.fTrapType;                      264   fTrapType = rhs.fTrapType;
247 }                                                 265 }
248                                                   266 
249 //////////////////////////////////////////////    267 //////////////////////////////////////////////////////////////////////////
250 //                                                268 //
251 // Assignment operator                            269 // Assignment operator
252                                                   270 
253 G4Trap& G4Trap::operator = (const G4Trap& rhs) << 271 G4Trap& G4Trap::operator = (const G4Trap& rhs) 
254 {                                                 272 {
255   // Check assignment to self                     273   // Check assignment to self
256   //                                              274   //
257   if (this == &rhs)  { return *this; }            275   if (this == &rhs)  { return *this; }
258                                                   276 
259   // Copy base class data                         277   // Copy base class data
260   //                                              278   //
261   G4CSGSolid::operator=(rhs);                     279   G4CSGSolid::operator=(rhs);
262                                                   280 
263   // Copy data                                    281   // Copy data
264   //                                              282   //
265   halfCarTolerance = rhs.halfCarTolerance;        283   halfCarTolerance = rhs.halfCarTolerance;
266   fDz = rhs.fDz; fTthetaCphi = rhs.fTthetaCphi    284   fDz = rhs.fDz; fTthetaCphi = rhs.fTthetaCphi; fTthetaSphi = rhs.fTthetaSphi;
267   fDy1 = rhs.fDy1; fDx1 = rhs.fDx1; fDx2 = rhs    285   fDy1 = rhs.fDy1; fDx1 = rhs.fDx1; fDx2 = rhs.fDx2; fTalpha1 = rhs.fTalpha1;
268   fDy2 = rhs.fDy2; fDx3 = rhs.fDx3; fDx4 = rhs    286   fDy2 = rhs.fDy2; fDx3 = rhs.fDx3; fDx4 = rhs.fDx4; fTalpha2 = rhs.fTalpha2;
269   for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs    287   for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
270   for (G4int i=0; i<6; ++i) { fAreas[i] = rhs. << 
271   fTrapType = rhs.fTrapType;                      288   fTrapType = rhs.fTrapType;
272   return *this;                                   289   return *this;
273 }                                                 290 }
274                                                   291 
275 //////////////////////////////////////////////    292 //////////////////////////////////////////////////////////////////////////
276 //                                                293 //
277 // Set all parameters, as for constructor - ch    294 // Set all parameters, as for constructor - check and set half-widths
278 // as well as angles: final check of coplanari    295 // as well as angles: final check of coplanarity
279                                                   296 
280 void G4Trap::SetAllParameters ( G4double pDz,     297 void G4Trap::SetAllParameters ( G4double pDz,
281                                 G4double pThet    298                                 G4double pTheta,
282                                 G4double pPhi,    299                                 G4double pPhi,
283                                 G4double pDy1,    300                                 G4double pDy1,
284                                 G4double pDx1,    301                                 G4double pDx1,
285                                 G4double pDx2,    302                                 G4double pDx2,
286                                 G4double pAlp1    303                                 G4double pAlp1,
287                                 G4double pDy2,    304                                 G4double pDy2,
288                                 G4double pDx3,    305                                 G4double pDx3,
289                                 G4double pDx4,    306                                 G4double pDx4,
290                                 G4double pAlp2    307                                 G4double pAlp2 )
291 {                                                 308 {
292   // Reset data of the base class                 309   // Reset data of the base class
293   fCubicVolume = 0;                               310   fCubicVolume = 0;
294   fSurfaceArea = 0;                               311   fSurfaceArea = 0;
295   fRebuildPolyhedron = true;                      312   fRebuildPolyhedron = true;
296                                                   313 
297   // Set parameters                               314   // Set parameters
298   fDz = pDz;                                      315   fDz = pDz;
299   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi    316   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi);
300   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi    317   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi);
301                                                   318 
302   fDy1 = pDy1; fDx1 = pDx1; fDx2 = pDx2; fTalp    319   fDy1 = pDy1; fDx1 = pDx1; fDx2 = pDx2; fTalpha1 = std::tan(pAlp1);
303   fDy2 = pDy2; fDx3 = pDx3; fDx4 = pDx4; fTalp    320   fDy2 = pDy2; fDx3 = pDx3; fDx4 = pDx4; fTalpha2 = std::tan(pAlp2);
304                                                   321 
305   CheckParameters();                              322   CheckParameters();
306   MakePlanes();                                   323   MakePlanes();
307 }                                                 324 }
308                                                   325 
309 //////////////////////////////////////////////    326 //////////////////////////////////////////////////////////////////////////
310 //                                                327 //
311 // Check length parameters                        328 // Check length parameters
312                                                   329 
313 void G4Trap::CheckParameters()                    330 void G4Trap::CheckParameters()
314 {                                                 331 {
315   if (fDz<=0 ||                                   332   if (fDz<=0 ||
316       fDy1<=0 || fDx1<=0 || fDx2<=0 ||            333       fDy1<=0 || fDx1<=0 || fDx2<=0 ||
317       fDy2<=0 || fDx3<=0 || fDx4<=0)              334       fDy2<=0 || fDx3<=0 || fDx4<=0)
318   {                                               335   {
319     std::ostringstream message;                   336     std::ostringstream message;
320     message << "Invalid Length Parameters for     337     message << "Invalid Length Parameters for Solid: " << GetName()
321             << "\n  X - " <<fDx1<<", "<<fDx2<<    338             << "\n  X - " <<fDx1<<", "<<fDx2<<", "<<fDx3<<", "<<fDx4
322             << "\n  Y - " <<fDy1<<", "<<fDy2      339             << "\n  Y - " <<fDy1<<", "<<fDy2
323             << "\n  Z - " <<fDz;                  340             << "\n  Z - " <<fDz;
324     G4Exception("G4Trap::CheckParameters()", "    341     G4Exception("G4Trap::CheckParameters()", "GeomSolids0002",
325                 FatalException, message);         342                 FatalException, message);
326   }                                               343   }
327 }                                                 344 }
328                                                   345 
329 //////////////////////////////////////////////    346 //////////////////////////////////////////////////////////////////////////
330 //                                                347 //
331 // Compute vertices and set side planes           348 // Compute vertices and set side planes
332                                                   349 
333 void G4Trap::MakePlanes()                         350 void G4Trap::MakePlanes()
334 {                                                 351 {
335   G4double DzTthetaCphi = fDz*fTthetaCphi;        352   G4double DzTthetaCphi = fDz*fTthetaCphi;
336   G4double DzTthetaSphi = fDz*fTthetaSphi;        353   G4double DzTthetaSphi = fDz*fTthetaSphi;
337   G4double Dy1Talpha1   = fDy1*fTalpha1;          354   G4double Dy1Talpha1   = fDy1*fTalpha1;
338   G4double Dy2Talpha2   = fDy2*fTalpha2;          355   G4double Dy2Talpha2   = fDy2*fTalpha2;
339                                                   356 
340   G4ThreeVector pt[8] =                           357   G4ThreeVector pt[8] =
341   {                                               358   {
342     G4ThreeVector(-DzTthetaCphi-Dy1Talpha1-fDx    359     G4ThreeVector(-DzTthetaCphi-Dy1Talpha1-fDx1,-DzTthetaSphi-fDy1,-fDz),
343     G4ThreeVector(-DzTthetaCphi-Dy1Talpha1+fDx    360     G4ThreeVector(-DzTthetaCphi-Dy1Talpha1+fDx1,-DzTthetaSphi-fDy1,-fDz),
344     G4ThreeVector(-DzTthetaCphi+Dy1Talpha1-fDx    361     G4ThreeVector(-DzTthetaCphi+Dy1Talpha1-fDx2,-DzTthetaSphi+fDy1,-fDz),
345     G4ThreeVector(-DzTthetaCphi+Dy1Talpha1+fDx    362     G4ThreeVector(-DzTthetaCphi+Dy1Talpha1+fDx2,-DzTthetaSphi+fDy1,-fDz),
346     G4ThreeVector( DzTthetaCphi-Dy2Talpha2-fDx    363     G4ThreeVector( DzTthetaCphi-Dy2Talpha2-fDx3, DzTthetaSphi-fDy2, fDz),
347     G4ThreeVector( DzTthetaCphi-Dy2Talpha2+fDx    364     G4ThreeVector( DzTthetaCphi-Dy2Talpha2+fDx3, DzTthetaSphi-fDy2, fDz),
348     G4ThreeVector( DzTthetaCphi+Dy2Talpha2-fDx    365     G4ThreeVector( DzTthetaCphi+Dy2Talpha2-fDx4, DzTthetaSphi+fDy2, fDz),
349     G4ThreeVector( DzTthetaCphi+Dy2Talpha2+fDx    366     G4ThreeVector( DzTthetaCphi+Dy2Talpha2+fDx4, DzTthetaSphi+fDy2, fDz)
350   };                                              367   };
351                                                   368 
352   MakePlanes(pt);                                 369   MakePlanes(pt);
353 }                                                 370 }
354                                                   371 
355 //////////////////////////////////////////////    372 //////////////////////////////////////////////////////////////////////////
356 //                                                373 //
357 // Set side planes, check planarity               374 // Set side planes, check planarity
358                                                   375 
359 void G4Trap::MakePlanes(const G4ThreeVector pt    376 void G4Trap::MakePlanes(const G4ThreeVector pt[8])
360 {                                                 377 {
361   constexpr G4int iface[4][4] = { {0,4,5,1}, { << 378   G4int iface[4][4] = { {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3} };
362   const static G4String side[4] = { "~-Y", "~+ << 379   G4String side[4] = { "~-Y", "~+Y", "~-X", "~+X" };
363                                                   380 
364   for (G4int i=0; i<4; ++i)                       381   for (G4int i=0; i<4; ++i)
365   {                                               382   {
366     if (MakePlane(pt[iface[i][0]],                383     if (MakePlane(pt[iface[i][0]],
367                   pt[iface[i][1]],                384                   pt[iface[i][1]],
368                   pt[iface[i][2]],                385                   pt[iface[i][2]],
369                   pt[iface[i][3]],                386                   pt[iface[i][3]],
370                   fPlanes[i])) continue;          387                   fPlanes[i])) continue;
371                                                   388 
372     // Non planar side face                       389     // Non planar side face
373     G4ThreeVector normal(fPlanes[i].a,fPlanes[    390     G4ThreeVector normal(fPlanes[i].a,fPlanes[i].b,fPlanes[i].c);
374     G4double dmax = 0;                            391     G4double dmax = 0;
375     for (G4int k=0; k<4; ++k)                     392     for (G4int k=0; k<4; ++k)
376     {                                             393     {
377       G4double dist = normal.dot(pt[iface[i][k    394       G4double dist = normal.dot(pt[iface[i][k]]) + fPlanes[i].d;
378       if (std::abs(dist) > std::abs(dmax)) dma    395       if (std::abs(dist) > std::abs(dmax)) dmax = dist;
379     }                                             396     }
380     std::ostringstream message;                   397     std::ostringstream message;
381     message << "Side face " << side[i] << " is    398     message << "Side face " << side[i] << " is not planar for solid: "
382             << GetName() << "\nDiscrepancy: "     399             << GetName() << "\nDiscrepancy: " << dmax/mm << " mm\n";
383     StreamInfo(message);                          400     StreamInfo(message);
384     G4Exception("G4Trap::MakePlanes()", "GeomS    401     G4Exception("G4Trap::MakePlanes()", "GeomSolids0002",
385                 FatalException, message);         402                 FatalException, message);
386   }                                               403   }
387                                                   404 
388   // Re-compute parameters                     << 405   // Define type of trapezoid
389   SetCachedValues();                           << 406   fTrapType = 0;
                                                   >> 407   if (fPlanes[0].b  == -1 && fPlanes[1].b == 1 &&
                                                   >> 408       std::abs(fPlanes[0].a) < DBL_EPSILON &&
                                                   >> 409       std::abs(fPlanes[0].c) < DBL_EPSILON &&
                                                   >> 410       std::abs(fPlanes[1].a) < DBL_EPSILON &&
                                                   >> 411       std::abs(fPlanes[1].c) < DBL_EPSILON)
                                                   >> 412   {
                                                   >> 413     fTrapType = 1; // YZ section is a rectangle ...
                                                   >> 414     if (std::abs(fPlanes[2].a + fPlanes[3].a) < DBL_EPSILON &&
                                                   >> 415         std::abs(fPlanes[2].c - fPlanes[3].c) < DBL_EPSILON &&
                                                   >> 416         fPlanes[2].b == 0 &&
                                                   >> 417         fPlanes[3].b == 0)
                                                   >> 418     {
                                                   >> 419       fTrapType = 2; // ... and XZ section is a isosceles trapezoid
                                                   >> 420       fPlanes[2].a = -fPlanes[3].a;
                                                   >> 421       fPlanes[2].c =  fPlanes[3].c;
                                                   >> 422     }
                                                   >> 423     if (std::abs(fPlanes[2].a + fPlanes[3].a) < DBL_EPSILON &&
                                                   >> 424         std::abs(fPlanes[2].b - fPlanes[3].b) < DBL_EPSILON &&
                                                   >> 425         fPlanes[2].c == 0 &&
                                                   >> 426         fPlanes[3].c == 0)
                                                   >> 427     {
                                                   >> 428       fTrapType = 3; // ... and XY section is a isosceles trapezoid
                                                   >> 429       fPlanes[2].a = -fPlanes[3].a;
                                                   >> 430       fPlanes[2].b =  fPlanes[3].b;
                                                   >> 431     }
                                                   >> 432   }
390 }                                                 433 }
391                                                   434 
392 ////////////////////////////////////////////// << 435 ///////////////////////////////////////////////////////////////////////
393 //                                                436 //
394 // Calculate the coef's of the plane p1->p2->p    437 // Calculate the coef's of the plane p1->p2->p3->p4->p1
395 // where the ThreeVectors 1-4 are in anti-cloc    438 // where the ThreeVectors 1-4 are in anti-clockwise order when viewed
396 // from infront of the plane (i.e. from normal    439 // from infront of the plane (i.e. from normal direction).
397 //                                                440 //
398 // Return true if the points are coplanar, fal    441 // Return true if the points are coplanar, false otherwise
399                                                   442 
400 G4bool G4Trap::MakePlane( const G4ThreeVector&    443 G4bool G4Trap::MakePlane( const G4ThreeVector& p1,
401                           const G4ThreeVector&    444                           const G4ThreeVector& p2,
402                           const G4ThreeVector&    445                           const G4ThreeVector& p3,
403                           const G4ThreeVector&    446                           const G4ThreeVector& p4,
404                                 TrapSidePlane&    447                                 TrapSidePlane& plane )
405 {                                                 448 {
406   G4ThreeVector normal = ((p4 - p2).cross(p3 -    449   G4ThreeVector normal = ((p4 - p2).cross(p3 - p1)).unit();
407   if (std::abs(normal.x()) < DBL_EPSILON) norm << 450   if (std::abs(normal.x()) < DBL_EPSILON) normal.setX(0); 
408   if (std::abs(normal.y()) < DBL_EPSILON) norm << 451   if (std::abs(normal.y()) < DBL_EPSILON) normal.setY(0); 
409   if (std::abs(normal.z()) < DBL_EPSILON) norm << 452   if (std::abs(normal.z()) < DBL_EPSILON) normal.setZ(0); 
410   normal = normal.unit();                         453   normal = normal.unit();
411                                                   454 
412   G4ThreeVector centre = (p1 + p2 + p3 + p4)*0    455   G4ThreeVector centre = (p1 + p2 + p3 + p4)*0.25;
413   plane.a =  normal.x();                          456   plane.a =  normal.x();
414   plane.b =  normal.y();                          457   plane.b =  normal.y();
415   plane.c =  normal.z();                          458   plane.c =  normal.z();
416   plane.d = -normal.dot(centre);                  459   plane.d = -normal.dot(centre);
417                                                   460 
418   // compute distances and check planarity        461   // compute distances and check planarity
419   G4double d1 = std::abs(normal.dot(p1) + plan    462   G4double d1 = std::abs(normal.dot(p1) + plane.d);
420   G4double d2 = std::abs(normal.dot(p2) + plan    463   G4double d2 = std::abs(normal.dot(p2) + plane.d);
421   G4double d3 = std::abs(normal.dot(p3) + plan    464   G4double d3 = std::abs(normal.dot(p3) + plane.d);
422   G4double d4 = std::abs(normal.dot(p4) + plan    465   G4double d4 = std::abs(normal.dot(p4) + plane.d);
423   G4double dmax = std::max(std::max(std::max(d    466   G4double dmax = std::max(std::max(std::max(d1,d2),d3),d4);
424                                                << 467   
425   return dmax <= 1000 * kCarTolerance;         << 468   return (dmax > 1000 * kCarTolerance) ? false : true;
426 }                                                 469 }
427                                                   470 
428 ////////////////////////////////////////////// << 471 ///////////////////////////////////////////////////////////////////////
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                                                << 
482 ////////////////////////////////////////////// << 
483 //                                                472 //
484 // Get volume                                     473 // Get volume
485                                                   474 
486 G4double G4Trap::GetCubicVolume()                 475 G4double G4Trap::GetCubicVolume()
487 {                                                 476 {
488   if (fCubicVolume == 0)                          477   if (fCubicVolume == 0)
489   {                                               478   {
490     G4ThreeVector pt[8];                          479     G4ThreeVector pt[8];
491     GetVertices(pt);                              480     GetVertices(pt);
492                                                << 481  
493     G4double dz  = pt[4].z() - pt[0].z();         482     G4double dz  = pt[4].z() - pt[0].z();
494     G4double dy1 = pt[2].y() - pt[0].y();         483     G4double dy1 = pt[2].y() - pt[0].y();
495     G4double dx1 = pt[1].x() - pt[0].x();         484     G4double dx1 = pt[1].x() - pt[0].x();
496     G4double dx2 = pt[3].x() - pt[2].x();         485     G4double dx2 = pt[3].x() - pt[2].x();
497     G4double dy2 = pt[6].y() - pt[4].y();         486     G4double dy2 = pt[6].y() - pt[4].y();
498     G4double dx3 = pt[5].x() - pt[4].x();         487     G4double dx3 = pt[5].x() - pt[4].x();
499     G4double dx4 = pt[7].x() - pt[6].x();         488     G4double dx4 = pt[7].x() - pt[6].x();
500                                                   489 
501     fCubicVolume = ((dx1 + dx2 + dx3 + dx4)*(d    490     fCubicVolume = ((dx1 + dx2 + dx3 + dx4)*(dy1 + dy2) +
502                     (dx4 + dx3 - dx2 - dx1)*(d    491                     (dx4 + dx3 - dx2 - dx1)*(dy2 - dy1)/3)*dz*0.125;
503   }                                               492   }
504   return fCubicVolume;                            493   return fCubicVolume;
505 }                                                 494 }
506                                                   495 
507 ////////////////////////////////////////////// << 496 ///////////////////////////////////////////////////////////////////////
508 //                                                497 //
509 // Get surface area                               498 // Get surface area
510                                                   499 
511 G4double G4Trap::GetSurfaceArea()                 500 G4double G4Trap::GetSurfaceArea()
512 {                                                 501 {
513   if (fSurfaceArea == 0)                          502   if (fSurfaceArea == 0)
514   {                                               503   {
515     G4ThreeVector pt[8];                          504     G4ThreeVector pt[8];
516     G4int iface [6][4] =                          505     G4int iface [6][4] =
517       { {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,    506       { {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
518                                                   507 
519     GetVertices(pt);                              508     GetVertices(pt);
520     for (const auto & i : iface)               << 509     for (G4int i=0; i<6; ++i)
521     {                                             510     {
522       fSurfaceArea += G4GeomTools::QuadAreaNor << 511       fSurfaceArea += G4GeomTools::QuadAreaNormal(pt[iface[i][0]],
523                                                << 512                                                   pt[iface[i][1]],
524                                                << 513                                                   pt[iface[i][2]],
525                                                << 514                                                   pt[iface[i][3]]).mag();
526     }                                             515     }
527   }                                               516   }
528   return fSurfaceArea;                            517   return fSurfaceArea;
529 }                                                 518 }
530                                                   519 
531 ////////////////////////////////////////////// << 520 ///////////////////////////////////////////////////////////////////////
532 //                                                521 //
533 // Dispatch to parameterisation for replicatio    522 // Dispatch to parameterisation for replication mechanism dimension
534 // computation & modification.                    523 // computation & modification.
535                                                   524 
536 void G4Trap::ComputeDimensions(       G4VPVPar    525 void G4Trap::ComputeDimensions(       G4VPVParameterisation* p,
537                                 const G4int n,    526                                 const G4int n,
538                                 const G4VPhysi    527                                 const G4VPhysicalVolume* pRep )
539 {                                                 528 {
540   p->ComputeDimensions(*this,n,pRep);             529   p->ComputeDimensions(*this,n,pRep);
541 }                                                 530 }
542                                                   531 
543 ////////////////////////////////////////////// << 532 ///////////////////////////////////////////////////////////////////////
544 //                                                533 //
545 // Get bounding box                               534 // Get bounding box
546                                                   535 
547 void G4Trap::BoundingLimits(G4ThreeVector& pMi    536 void G4Trap::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
548 {                                                 537 {
549   G4ThreeVector pt[8];                            538   G4ThreeVector pt[8];
550   GetVertices(pt);                                539   GetVertices(pt);
551                                                   540 
552   G4double xmin = kInfinity, xmax = -kInfinity    541   G4double xmin = kInfinity, xmax = -kInfinity;
553   G4double ymin = kInfinity, ymax = -kInfinity    542   G4double ymin = kInfinity, ymax = -kInfinity;
554   for (const auto & i : pt)                    << 543   for (G4int i=0; i<8; ++i)
555   {                                               544   {
556     G4double x = i.x();                        << 545     G4double x = pt[i].x();
557     if (x < xmin) xmin = x;                       546     if (x < xmin) xmin = x;
558     if (x > xmax) xmax = x;                       547     if (x > xmax) xmax = x;
559     G4double y = i.y();                        << 548     G4double y = pt[i].y();
560     if (y < ymin) ymin = y;                       549     if (y < ymin) ymin = y;
561     if (y > ymax) ymax = y;                       550     if (y > ymax) ymax = y;
562   }                                               551   }
563                                                   552 
564   G4double dz   = GetZHalfLength();               553   G4double dz   = GetZHalfLength();
565   pMin.set(xmin,ymin,-dz);                        554   pMin.set(xmin,ymin,-dz);
566   pMax.set(xmax,ymax, dz);                        555   pMax.set(xmax,ymax, dz);
567                                                   556 
568   // Check correctness of the bounding box        557   // Check correctness of the bounding box
569   //                                              558   //
570   if (pMin.x() >= pMax.x() || pMin.y() >= pMax    559   if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
571   {                                               560   {
572     std::ostringstream message;                   561     std::ostringstream message;
573     message << "Bad bounding box (min >= max)     562     message << "Bad bounding box (min >= max) for solid: "
574             << GetName() << " !"                  563             << GetName() << " !"
575             << "\npMin = " << pMin                564             << "\npMin = " << pMin
576             << "\npMax = " << pMax;               565             << "\npMax = " << pMax;
577     G4Exception("G4Trap::BoundingLimits()", "G    566     G4Exception("G4Trap::BoundingLimits()", "GeomMgt0001",
578                 JustWarning, message);            567                 JustWarning, message);
579     DumpInfo();                                   568     DumpInfo();
580   }                                               569   }
581 }                                                 570 }
582                                                   571 
583 ////////////////////////////////////////////// << 572 ///////////////////////////////////////////////////////////////////////
584 //                                                573 //
585 // Calculate extent under transform and specif    574 // Calculate extent under transform and specified limit
586                                                   575 
587 G4bool G4Trap::CalculateExtent( const EAxis pA    576 G4bool G4Trap::CalculateExtent( const EAxis pAxis,
588                                 const G4VoxelL    577                                 const G4VoxelLimits& pVoxelLimit,
589                                 const G4Affine    578                                 const G4AffineTransform& pTransform,
590                                       G4double    579                                       G4double& pMin, G4double& pMax) const
591 {                                                 580 {
592   G4ThreeVector bmin, bmax;                       581   G4ThreeVector bmin, bmax;
593   G4bool exist;                                   582   G4bool exist;
594                                                   583 
595   // Check bounding box (bbox)                    584   // Check bounding box (bbox)
596   //                                              585   //
597   BoundingLimits(bmin,bmax);                      586   BoundingLimits(bmin,bmax);
598   G4BoundingEnvelope bbox(bmin,bmax);             587   G4BoundingEnvelope bbox(bmin,bmax);
599 #ifdef G4BBOX_EXTENT                              588 #ifdef G4BBOX_EXTENT
600   return bbox.CalculateExtent(pAxis,pVoxelLimi << 589   if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
601 #endif                                            590 #endif
602   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox    591   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
603   {                                               592   {
604     return exist = pMin < pMax;                << 593     return exist = (pMin < pMax) ? true : false;
605   }                                               594   }
606                                                   595 
607   // Set bounding envelope (benv) and calculat    596   // Set bounding envelope (benv) and calculate extent
608   //                                              597   //
609   G4ThreeVector pt[8];                            598   G4ThreeVector pt[8];
610   GetVertices(pt);                                599   GetVertices(pt);
611                                                   600 
612   G4ThreeVectorList baseA(4), baseB(4);           601   G4ThreeVectorList baseA(4), baseB(4);
613   baseA[0] = pt[0];                               602   baseA[0] = pt[0];
614   baseA[1] = pt[1];                               603   baseA[1] = pt[1];
615   baseA[2] = pt[3];                               604   baseA[2] = pt[3];
616   baseA[3] = pt[2];                               605   baseA[3] = pt[2];
617                                                   606 
618   baseB[0] = pt[4];                               607   baseB[0] = pt[4];
619   baseB[1] = pt[5];                               608   baseB[1] = pt[5];
620   baseB[2] = pt[7];                               609   baseB[2] = pt[7];
621   baseB[3] = pt[6];                               610   baseB[3] = pt[6];
622                                                   611 
623   std::vector<const G4ThreeVectorList *> polyg    612   std::vector<const G4ThreeVectorList *> polygons(2);
624   polygons[0] = &baseA;                           613   polygons[0] = &baseA;
625   polygons[1] = &baseB;                           614   polygons[1] = &baseB;
626                                                   615 
627   G4BoundingEnvelope benv(bmin,bmax,polygons);    616   G4BoundingEnvelope benv(bmin,bmax,polygons);
628   exist = benv.CalculateExtent(pAxis,pVoxelLim    617   exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
629   return exist;                                   618   return exist;
630 }                                                 619 }
631                                                   620 
632 ////////////////////////////////////////////// << 621 ///////////////////////////////////////////////////////////////////////
633 //                                                622 //
634 // Return whether point is inside/outside/on_s    623 // Return whether point is inside/outside/on_surface
635                                                   624 
636 EInside G4Trap::Inside( const G4ThreeVector& p    625 EInside G4Trap::Inside( const G4ThreeVector& p ) const
637 {                                                 626 {
                                                   >> 627   G4double dz = std::abs(p.z())-fDz;
                                                   >> 628   if (dz > halfCarTolerance) return kOutside;
                                                   >> 629 
638   switch (fTrapType)                              630   switch (fTrapType)
639   {                                               631   {
640     case 0: // General case                       632     case 0: // General case
641     {                                             633     {
642       G4double dz = std::abs(p.z())-fDz;       << 
643       G4double dy1 = fPlanes[0].b*p.y()+fPlane    634       G4double dy1 = fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
644       G4double dy2 = fPlanes[1].b*p.y()+fPlane    635       G4double dy2 = fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
645       G4double dy = std::max(dz,std::max(dy1,d    636       G4double dy = std::max(dz,std::max(dy1,dy2));
646                                                   637 
647       G4double dx1 = fPlanes[2].a*p.x()+fPlane    638       G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
648                    + fPlanes[2].c*p.z()+fPlane    639                    + fPlanes[2].c*p.z()+fPlanes[2].d;
649       G4double dx2 = fPlanes[3].a*p.x()+fPlane    640       G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
650                    + fPlanes[3].c*p.z()+fPlane    641                    + fPlanes[3].c*p.z()+fPlanes[3].d;
651       G4double dist = std::max(dy,std::max(dx1    642       G4double dist = std::max(dy,std::max(dx1,dx2));
652                                                   643 
653       return (dist > halfCarTolerance) ? kOuts << 644       if (dist > halfCarTolerance) return kOutside;
654         ((dist > -halfCarTolerance) ? kSurface << 645       return (dist > -halfCarTolerance) ? kSurface : kInside;
655     }                                             646     }
656     case 1: // YZ section is a rectangle          647     case 1: // YZ section is a rectangle
657     {                                             648     {
658       G4double dz = std::abs(p.z())-fDz;       << 
659       G4double dy = std::max(dz,std::abs(p.y()    649       G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
660       G4double dx1 = fPlanes[2].a*p.x()+fPlane    650       G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
661                    + fPlanes[2].c*p.z()+fPlane    651                    + fPlanes[2].c*p.z()+fPlanes[2].d;
662       G4double dx2 = fPlanes[3].a*p.x()+fPlane    652       G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
663                    + fPlanes[3].c*p.z()+fPlane    653                    + fPlanes[3].c*p.z()+fPlanes[3].d;
664       G4double dist = std::max(dy,std::max(dx1    654       G4double dist = std::max(dy,std::max(dx1,dx2));
665                                                   655 
666       return (dist > halfCarTolerance) ? kOuts << 656       if (dist > halfCarTolerance) return kOutside;
667         ((dist > -halfCarTolerance) ? kSurface << 657       return (dist > -halfCarTolerance) ? kSurface : kInside;
668     }                                             658     }
669     case 2: // YZ section is a rectangle and      659     case 2: // YZ section is a rectangle and
670     {       // XZ section is an isosceles trap    660     {       // XZ section is an isosceles trapezoid
671       G4double dz = std::abs(p.z())-fDz;       << 
672       G4double dy = std::max(dz,std::abs(p.y()    661       G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
673       G4double dx = fPlanes[3].a*std::abs(p.x(    662       G4double dx = fPlanes[3].a*std::abs(p.x())
674                   + fPlanes[3].c*p.z()+fPlanes    663                   + fPlanes[3].c*p.z()+fPlanes[3].d;
675       G4double dist = std::max(dy,dx);            664       G4double dist = std::max(dy,dx);
676                                                   665 
677       return (dist > halfCarTolerance) ? kOuts << 666       if (dist > halfCarTolerance) return kOutside;
678         ((dist > -halfCarTolerance) ? kSurface << 667       return (dist > -halfCarTolerance) ? kSurface : kInside;
679     }                                             668     }
680     case 3: // YZ section is a rectangle and      669     case 3: // YZ section is a rectangle and
681     {       // XY section is an isosceles trap    670     {       // XY section is an isosceles trapezoid
682       G4double dz = std::abs(p.z())-fDz;       << 
683       G4double dy = std::max(dz,std::abs(p.y()    671       G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
684       G4double dx = fPlanes[3].a*std::abs(p.x(    672       G4double dx = fPlanes[3].a*std::abs(p.x())
685                   + fPlanes[3].b*p.y()+fPlanes    673                   + fPlanes[3].b*p.y()+fPlanes[3].d;
686       G4double dist = std::max(dy,dx);            674       G4double dist = std::max(dy,dx);
687                                                   675 
688       return (dist > halfCarTolerance) ? kOuts << 676       if (dist > halfCarTolerance) return kOutside;
689         ((dist > -halfCarTolerance) ? kSurface << 677       return (dist > -halfCarTolerance) ? kSurface : kInside;
690     }                                             678     }
691   }                                               679   }
692   return kOutside;                             << 680   return kOutside; 
693 }                                                 681 }
694                                                   682 
695 ////////////////////////////////////////////// << 683 ///////////////////////////////////////////////////////////////////////
696 //                                                684 //
697 // Determine side, and return corresponding no    685 // Determine side, and return corresponding normal
698                                                   686 
699 G4ThreeVector G4Trap::SurfaceNormal( const G4T    687 G4ThreeVector G4Trap::SurfaceNormal( const G4ThreeVector& p ) const
700 {                                                 688 {
                                                   >> 689   G4int nsurf = 0; // number of surfaces where p is placed
701   G4double nx = 0, ny = 0, nz = 0;                690   G4double nx = 0, ny = 0, nz = 0;
702   G4double dz = std::abs(p.z()) - fDz;            691   G4double dz = std::abs(p.z()) - fDz;
703   nz = std::copysign(G4double(std::abs(dz) <=  << 692   if (std::abs(dz) <= halfCarTolerance)
                                                   >> 693   {
                                                   >> 694     nz = (p.z() < 0) ? -1 : 1;
                                                   >> 695     ++nsurf;
                                                   >> 696   }
704                                                   697 
705   switch (fTrapType)                              698   switch (fTrapType)
706   {                                               699   {
707     case 0: // General case                       700     case 0: // General case
708     {                                             701     {
709       for (G4int i=0; i<2; ++i)                   702       for (G4int i=0; i<2; ++i)
710       {                                           703       {
711         G4double dy = fPlanes[i].b*p.y() + fPl    704         G4double dy = fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
712         if (std::abs(dy) > halfCarTolerance) c    705         if (std::abs(dy) > halfCarTolerance) continue;
713         ny  = fPlanes[i].b;                       706         ny  = fPlanes[i].b;
714         nz += fPlanes[i].c;                       707         nz += fPlanes[i].c;
                                                   >> 708         ++nsurf;
715         break;                                    709         break;
716       }                                           710       }
717       for (G4int i=2; i<4; ++i)                   711       for (G4int i=2; i<4; ++i)
718       {                                           712       {
719         G4double dx = fPlanes[i].a*p.x() +        713         G4double dx = fPlanes[i].a*p.x() +
720                       fPlanes[i].b*p.y() + fPl    714                       fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
721         if (std::abs(dx) > halfCarTolerance) c    715         if (std::abs(dx) > halfCarTolerance) continue;
722         nx  = fPlanes[i].a;                       716         nx  = fPlanes[i].a;
723         ny += fPlanes[i].b;                       717         ny += fPlanes[i].b;
724         nz += fPlanes[i].c;                       718         nz += fPlanes[i].c;
                                                   >> 719         ++nsurf;
725         break;                                    720         break;
726       }                                           721       }
727       break;                                      722       break;
728     }                                             723     }
729     case 1: // YZ section - rectangle          << 724     case 1: // YZ section is a rectangle
730     {                                             725     {
731       G4double dy = std::abs(p.y()) + fPlanes[    726       G4double dy = std::abs(p.y()) + fPlanes[1].d;
732       ny = std::copysign(G4double(std::abs(dy) << 727       if (std::abs(dy) <= halfCarTolerance) ny = (p.y() < 0) ? -1 : 1;
733       for (G4int i=2; i<4; ++i)                   728       for (G4int i=2; i<4; ++i)
734       {                                           729       {
735         G4double dx = fPlanes[i].a*p.x() +        730         G4double dx = fPlanes[i].a*p.x() +
736                       fPlanes[i].b*p.y() + fPl    731                       fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
737         if (std::abs(dx) > halfCarTolerance) c    732         if (std::abs(dx) > halfCarTolerance) continue;
738         nx  = fPlanes[i].a;                       733         nx  = fPlanes[i].a;
739         ny += fPlanes[i].b;                       734         ny += fPlanes[i].b;
740         nz += fPlanes[i].c;                       735         nz += fPlanes[i].c;
                                                   >> 736         ++nsurf;
741         break;                                    737         break;
742       }                                           738       }
743       break;                                      739       break;
744     }                                             740     }
745     case 2: // YZ section - rectangle, XZ sect << 741     case 2: // YZ section is a rectangle and
746     {                                          << 742     {       // XZ section is an isosceles trapezoid
747       G4double dy = std::abs(p.y()) + fPlanes[    743       G4double dy = std::abs(p.y()) + fPlanes[1].d;
748       ny = std::copysign(G4double(std::abs(dy) << 744       if (std::abs(dy) <= halfCarTolerance) ny = (p.y() < 0) ? -1 : 1;
749       G4double dx = fPlanes[3].a*std::abs(p.x(    745       G4double dx = fPlanes[3].a*std::abs(p.x()) +
750                     fPlanes[3].c*p.z() + fPlan    746                     fPlanes[3].c*p.z() + fPlanes[3].d;
751       G4double k = std::abs(dx) <= halfCarTole << 747       if (std::abs(dx) <= halfCarTolerance)
752       nx  = std::copysign(k, p.x())*fPlanes[3] << 748       {
753       nz += k*fPlanes[3].c;                    << 749         nx  = (p.x() < 0) ? -fPlanes[3].a : fPlanes[3].a;
                                                   >> 750         nz += fPlanes[3].c;
                                                   >> 751         ++nsurf;
                                                   >> 752       }
754       break;                                      753       break;
755     }                                             754     }
756     case 3: // YZ section - rectangle, XY sect << 755     case 3: // YZ section is a rectangle and
757     {                                          << 756     {       // XY section is an isosceles trapezoid
758       G4double dy = std::abs(p.y()) + fPlanes[    757       G4double dy = std::abs(p.y()) + fPlanes[1].d;
759       ny = std::copysign(G4double(std::abs(dy) << 758       if (std::abs(dy) <= halfCarTolerance) ny = (p.y() < 0) ? -1 : 1;
760       G4double dx = fPlanes[3].a*std::abs(p.x(    759       G4double dx = fPlanes[3].a*std::abs(p.x()) +
761                     fPlanes[3].b*p.y() + fPlan    760                     fPlanes[3].b*p.y() + fPlanes[3].d;
762       G4double k = std::abs(dx) <= halfCarTole << 761       if (std::abs(dx) <= halfCarTolerance)
763       nx  = std::copysign(k, p.x())*fPlanes[3] << 762       {
764       ny += k*fPlanes[3].b;                    << 763         nx  = (p.x() < 0) ? -fPlanes[3].a : fPlanes[3].a;
                                                   >> 764         ny += fPlanes[3].b;
                                                   >> 765         ++nsurf;
                                                   >> 766       }
765       break;                                      767       break;
766     }                                             768     }
767   }                                               769   }
768                                                   770 
769   // Return normal                                771   // Return normal
770   //                                              772   //
771   G4double mag2 = nx*nx + ny*ny + nz*nz;       << 773   if (nsurf == 1)      return G4ThreeVector(nx,ny,nz);
772   if (mag2 == 1)      return { nx,ny,nz };     << 774   else if (nsurf != 0) return G4ThreeVector(nx,ny,nz).unit(); // edge or corner
773   else if (mag2 != 0) return G4ThreeVector(nx, << 
774   else                                            775   else
775   {                                               776   {
776     // Point is not on the surface                777     // Point is not on the surface
777     //                                            778     //
778 #ifdef G4CSGDEBUG                                 779 #ifdef G4CSGDEBUG
779     std::ostringstream message;                   780     std::ostringstream message;
780     G4long oldprc = message.precision(16);     << 781     G4int oldprc = message.precision(16);
781     message << "Point p is not on surface (!?)    782     message << "Point p is not on surface (!?) of solid: "
782             << GetName() << G4endl;               783             << GetName() << G4endl;
783     message << "Position:\n";                     784     message << "Position:\n";
784     message << "   p.x() = " << p.x()/mm << "     785     message << "   p.x() = " << p.x()/mm << " mm\n";
785     message << "   p.y() = " << p.y()/mm << "     786     message << "   p.y() = " << p.y()/mm << " mm\n";
786     message << "   p.z() = " << p.z()/mm << "     787     message << "   p.z() = " << p.z()/mm << " mm";
787     G4cout.precision(oldprc) ;                    788     G4cout.precision(oldprc) ;
788     G4Exception("G4Trap::SurfaceNormal(p)", "G    789     G4Exception("G4Trap::SurfaceNormal(p)", "GeomSolids1002",
789                 JustWarning, message );           790                 JustWarning, message );
790     DumpInfo();                                   791     DumpInfo();
791 #endif                                            792 #endif
792     return ApproxSurfaceNormal(p);                793     return ApproxSurfaceNormal(p);
793   }                                               794   }
794 }                                                 795 }
795                                                   796 
796 ////////////////////////////////////////////// << 797 ///////////////////////////////////////////////////////////////////////
797 //                                                798 //
798 // Algorithm for SurfaceNormal() following the    799 // Algorithm for SurfaceNormal() following the original specification
799 // for points not on the surface                  800 // for points not on the surface
800                                                   801 
801 G4ThreeVector G4Trap::ApproxSurfaceNormal( con    802 G4ThreeVector G4Trap::ApproxSurfaceNormal( const G4ThreeVector& p ) const
802 {                                                 803 {
803   G4double dist = -DBL_MAX;                       804   G4double dist = -DBL_MAX;
804   G4int iside = 0;                                805   G4int iside = 0;
805   for (G4int i=0; i<4; ++i)                       806   for (G4int i=0; i<4; ++i)
806   {                                               807   {
807     G4double d = fPlanes[i].a*p.x() +             808     G4double d = fPlanes[i].a*p.x() +
808                  fPlanes[i].b*p.y() +             809                  fPlanes[i].b*p.y() +
809                  fPlanes[i].c*p.z() + fPlanes[    810                  fPlanes[i].c*p.z() + fPlanes[i].d;
810     if (d > dist) { dist = d; iside = i; }        811     if (d > dist) { dist = d; iside = i; }
811   }                                               812   }
812                                                   813 
813   G4double distz = std::abs(p.z()) - fDz;         814   G4double distz = std::abs(p.z()) - fDz;
814   if (dist > distz)                               815   if (dist > distz)
815     return { fPlanes[iside].a, fPlanes[iside]. << 816     return G4ThreeVector(fPlanes[iside].a, fPlanes[iside].b, fPlanes[iside].c);
816   else                                            817   else
817     return { 0, 0, (G4double)((p.z() < 0) ? -1 << 818     return G4ThreeVector(0, 0, (p.z() < 0) ? -1 : 1);
818 }                                                 819 }
819                                                   820 
820 ////////////////////////////////////////////// << 821 ///////////////////////////////////////////////////////////////////////
821 //                                                822 //
822 // Calculate distance to shape from outside       823 // Calculate distance to shape from outside
823 //  - return kInfinity if no intersection         824 //  - return kInfinity if no intersection
824                                                   825 
825 G4double G4Trap::DistanceToIn(const G4ThreeVec    826 G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
826                               const G4ThreeVec    827                               const G4ThreeVector& v ) const
827 {                                                 828 {
828   // Z intersections                              829   // Z intersections
829   //                                              830   //
830   if ((std::abs(p.z()) - fDz) >= -halfCarToler    831   if ((std::abs(p.z()) - fDz) >= -halfCarTolerance && p.z()*v.z() >= 0)
831     return kInfinity;                             832     return kInfinity;
832   G4double invz = (-v.z() == 0) ? DBL_MAX : -1    833   G4double invz = (-v.z() == 0) ? DBL_MAX : -1./v.z();
833   G4double dz = (invz < 0) ? fDz : -fDz;       << 834   G4double dz = (invz < 0) ? fDz : -fDz; 
834   G4double tzmin = (p.z() + dz)*invz;             835   G4double tzmin = (p.z() + dz)*invz;
835   G4double tzmax = (p.z() - dz)*invz;             836   G4double tzmax = (p.z() - dz)*invz;
836                                                   837 
837   // Y intersections                              838   // Y intersections
838   //                                              839   //
839   G4double tymin = 0, tymax = DBL_MAX;            840   G4double tymin = 0, tymax = DBL_MAX;
840   G4int i = 0;                                    841   G4int i = 0;
841   for ( ; i<2; ++i)                               842   for ( ; i<2; ++i)
842   {                                            << 843   { 
843     G4double cosa = fPlanes[i].b*v.y() + fPlan    844     G4double cosa = fPlanes[i].b*v.y() + fPlanes[i].c*v.z();
844     G4double dist = fPlanes[i].b*p.y() + fPlan    845     G4double dist = fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
845     if (dist >= -halfCarTolerance)                846     if (dist >= -halfCarTolerance)
846     {                                             847     {
847       if (cosa >= 0) return kInfinity;            848       if (cosa >= 0) return kInfinity;
848       G4double tmp  = -dist/cosa;                 849       G4double tmp  = -dist/cosa;
849       if (tymin < tmp) tymin = tmp;               850       if (tymin < tmp) tymin = tmp;
850     }                                             851     }
851     else if (cosa > 0)                            852     else if (cosa > 0)
852     {                                             853     {
853       G4double tmp  = -dist/cosa;                 854       G4double tmp  = -dist/cosa;
854       if (tymax > tmp) tymax = tmp;               855       if (tymax > tmp) tymax = tmp;
855     }                                          << 856     } 
856   }                                               857   }
857                                                   858 
858   // Z intersections                              859   // Z intersections
859   //                                              860   //
860   G4double txmin = 0, txmax = DBL_MAX;            861   G4double txmin = 0, txmax = DBL_MAX;
861   for ( ; i<4; ++i)                               862   for ( ; i<4; ++i)
862   {                                            << 863   { 
863     G4double cosa = fPlanes[i].a*v.x()+fPlanes    864     G4double cosa = fPlanes[i].a*v.x()+fPlanes[i].b*v.y()+fPlanes[i].c*v.z();
864     G4double dist = fPlanes[i].a*p.x()+fPlanes    865     G4double dist = fPlanes[i].a*p.x()+fPlanes[i].b*p.y()+fPlanes[i].c*p.z() +
865                     fPlanes[i].d;                 866                     fPlanes[i].d;
866     if (dist >= -halfCarTolerance)                867     if (dist >= -halfCarTolerance)
867     {                                             868     {
868       if (cosa >= 0) return kInfinity;            869       if (cosa >= 0) return kInfinity;
869       G4double tmp  = -dist/cosa;                 870       G4double tmp  = -dist/cosa;
870       if (txmin < tmp) txmin = tmp;               871       if (txmin < tmp) txmin = tmp;
871     }                                             872     }
872     else if (cosa > 0)                            873     else if (cosa > 0)
873     {                                             874     {
874       G4double tmp  = -dist/cosa;                 875       G4double tmp  = -dist/cosa;
875       if (txmax > tmp) txmax = tmp;               876       if (txmax > tmp) txmax = tmp;
876     }                                          << 877     } 
877   }                                               878   }
878                                                   879 
879   // Find distance                                880   // Find distance
880   //                                              881   //
881   G4double tmin = std::max(std::max(txmin,tymi    882   G4double tmin = std::max(std::max(txmin,tymin),tzmin);
882   G4double tmax = std::min(std::min(txmax,tyma    883   G4double tmax = std::min(std::min(txmax,tymax),tzmax);
883                                                << 884      
884   if (tmax <= tmin + halfCarTolerance) return     885   if (tmax <= tmin + halfCarTolerance) return kInfinity; // touch or no hit
885   return (tmin < halfCarTolerance ) ? 0. : tmi    886   return (tmin < halfCarTolerance ) ? 0. : tmin;
886 }                                                 887 }
887                                                   888 
888 ////////////////////////////////////////////// << 889 ////////////////////////////////////////////////////////////////////////////
889 //                                                890 //
890 // Calculate exact shortest distance to any bo    891 // Calculate exact shortest distance to any boundary from outside
891 // This is the best fast estimation of the sho    892 // This is the best fast estimation of the shortest distance to trap
892 // - return 0 if point is inside                  893 // - return 0 if point is inside
893                                                   894 
894 G4double G4Trap::DistanceToIn( const G4ThreeVe    895 G4double G4Trap::DistanceToIn( const G4ThreeVector& p ) const
895 {                                                 896 {
896   switch (fTrapType)                              897   switch (fTrapType)
897   {                                               898   {
898     case 0: // General case                       899     case 0: // General case
899     {                                             900     {
900       G4double dz = std::abs(p.z())-fDz;          901       G4double dz = std::abs(p.z())-fDz;
901       G4double dy1 = fPlanes[0].b*p.y()+fPlane    902       G4double dy1 = fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
902       G4double dy2 = fPlanes[1].b*p.y()+fPlane    903       G4double dy2 = fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
903       G4double dy = std::max(dz,std::max(dy1,d    904       G4double dy = std::max(dz,std::max(dy1,dy2));
904                                                   905 
905       G4double dx1 = fPlanes[2].a*p.x()+fPlane    906       G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
906                    + fPlanes[2].c*p.z()+fPlane    907                    + fPlanes[2].c*p.z()+fPlanes[2].d;
907       G4double dx2 = fPlanes[3].a*p.x()+fPlane    908       G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
908                    + fPlanes[3].c*p.z()+fPlane    909                    + fPlanes[3].c*p.z()+fPlanes[3].d;
909       G4double dist = std::max(dy,std::max(dx1    910       G4double dist = std::max(dy,std::max(dx1,dx2));
910       return (dist > 0) ? dist : 0.;              911       return (dist > 0) ? dist : 0.;
911     }                                             912     }
912     case 1: // YZ section is a rectangle          913     case 1: // YZ section is a rectangle
913     {                                             914     {
914       G4double dz = std::abs(p.z())-fDz;          915       G4double dz = std::abs(p.z())-fDz;
915       G4double dy = std::max(dz,std::abs(p.y()    916       G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
916       G4double dx1 = fPlanes[2].a*p.x()+fPlane    917       G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
917                    + fPlanes[2].c*p.z()+fPlane    918                    + fPlanes[2].c*p.z()+fPlanes[2].d;
918       G4double dx2 = fPlanes[3].a*p.x()+fPlane    919       G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
919                    + fPlanes[3].c*p.z()+fPlane    920                    + fPlanes[3].c*p.z()+fPlanes[3].d;
920       G4double dist = std::max(dy,std::max(dx1    921       G4double dist = std::max(dy,std::max(dx1,dx2));
921       return (dist > 0) ? dist : 0.;              922       return (dist > 0) ? dist : 0.;
922     }                                             923     }
923     case 2: // YZ section is a rectangle and      924     case 2: // YZ section is a rectangle and
924     {       // XZ section is an isosceles trap    925     {       // XZ section is an isosceles trapezoid
925       G4double dz = std::abs(p.z())-fDz;          926       G4double dz = std::abs(p.z())-fDz;
926       G4double dy = std::max(dz,std::abs(p.y()    927       G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
927       G4double dx = fPlanes[3].a*std::abs(p.x(    928       G4double dx = fPlanes[3].a*std::abs(p.x())
928                   + fPlanes[3].c*p.z()+fPlanes    929                   + fPlanes[3].c*p.z()+fPlanes[3].d;
929       G4double dist = std::max(dy,dx);            930       G4double dist = std::max(dy,dx);
930       return (dist > 0) ? dist : 0.;              931       return (dist > 0) ? dist : 0.;
931     }                                             932     }
932     case 3: // YZ section is a rectangle and      933     case 3: // YZ section is a rectangle and
933     {       // XY section is an isosceles trap    934     {       // XY section is an isosceles trapezoid
934       G4double dz = std::abs(p.z())-fDz;          935       G4double dz = std::abs(p.z())-fDz;
935       G4double dy = std::max(dz,std::abs(p.y()    936       G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
936       G4double dx = fPlanes[3].a*std::abs(p.x(    937       G4double dx = fPlanes[3].a*std::abs(p.x())
937                   + fPlanes[3].b*p.y()+fPlanes    938                   + fPlanes[3].b*p.y()+fPlanes[3].d;
938       G4double dist = std::max(dy,dx);            939       G4double dist = std::max(dy,dx);
939       return (dist > 0) ? dist : 0.;              940       return (dist > 0) ? dist : 0.;
940     }                                             941     }
941   }                                               942   }
942   return 0.;                                      943   return 0.;
943 }                                                 944 }
944                                                   945 
945 ////////////////////////////////////////////// << 946 ////////////////////////////////////////////////////////////////////////////
946 //                                                947 //
947 // Calculate distance to surface of shape from    948 // Calculate distance to surface of shape from inside and
948 // find normal at exit point, if required         949 // find normal at exit point, if required
949 // - when leaving the surface, return 0           950 // - when leaving the surface, return 0
950                                                   951 
951 G4double G4Trap::DistanceToOut(const G4ThreeVe    952 G4double G4Trap::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
952                                const G4bool ca    953                                const G4bool calcNorm,
953                                      G4bool* v << 954                                      G4bool *validNorm, G4ThreeVector *n) const
954 {                                                 955 {
955   // Z intersections                              956   // Z intersections
956   //                                              957   //
957   if ((std::abs(p.z()) - fDz) >= -halfCarToler    958   if ((std::abs(p.z()) - fDz) >= -halfCarTolerance && p.z()*v.z() > 0)
958   {                                               959   {
959     if (calcNorm)                                 960     if (calcNorm)
960     {                                             961     {
961       *validNorm = true;                          962       *validNorm = true;
962       n->set(0, 0, (p.z() < 0) ? -1 : 1);         963       n->set(0, 0, (p.z() < 0) ? -1 : 1);
963     }                                             964     }
964     return 0;                                     965     return 0;
965   }                                               966   }
966   G4double vz = v.z();                            967   G4double vz = v.z();
967   G4double tmax = (vz == 0) ? DBL_MAX : (std::    968   G4double tmax = (vz == 0) ? DBL_MAX : (std::copysign(fDz,vz) - p.z())/vz;
968   G4int iside = (vz < 0) ? -4 : -2; // little     969   G4int iside = (vz < 0) ? -4 : -2; // little trick: (-4+3)=-1, (-2+3)=+1
969                                                   970 
970   // Y intersections                              971   // Y intersections
971   //                                              972   //
972   G4int i = 0;                                    973   G4int i = 0;
973   for ( ; i<2; ++i)                               974   for ( ; i<2; ++i)
974   {                                               975   {
975     G4double cosa = fPlanes[i].b*v.y() + fPlan    976     G4double cosa = fPlanes[i].b*v.y() + fPlanes[i].c*v.z();
976     if (cosa > 0)                                 977     if (cosa > 0)
977     {                                             978     {
978       G4double dist = fPlanes[i].b*p.y() + fPl    979       G4double dist = fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
979       if (dist >= -halfCarTolerance)              980       if (dist >= -halfCarTolerance)
980       {                                           981       {
981         if (calcNorm)                             982         if (calcNorm)
982         {                                         983         {
983           *validNorm = true;                      984           *validNorm = true;
984           n->set(0, fPlanes[i].b, fPlanes[i].c    985           n->set(0, fPlanes[i].b, fPlanes[i].c);
985         }                                         986         }
986         return 0;                                 987         return 0;
987       }                                           988       }
988       G4double tmp = -dist/cosa;                  989       G4double tmp = -dist/cosa;
989       if (tmax > tmp) { tmax = tmp; iside = i;    990       if (tmax > tmp) { tmax = tmp; iside = i; }
990     }                                             991     }
991   }                                               992   }
992                                                   993 
993   // X intersections                              994   // X intersections
994   //                                              995   //
995   for ( ; i<4; ++i)                               996   for ( ; i<4; ++i)
996   {                                               997   {
997     G4double cosa = fPlanes[i].a*v.x()+fPlanes    998     G4double cosa = fPlanes[i].a*v.x()+fPlanes[i].b*v.y()+fPlanes[i].c*v.z();
998     if (cosa > 0)                                 999     if (cosa > 0)
999     {                                             1000     {
1000       G4double dist = fPlanes[i].a*p.x() +       1001       G4double dist = fPlanes[i].a*p.x() +
1001                       fPlanes[i].b*p.y() + fP    1002                       fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
1002       if (dist >= -halfCarTolerance)             1003       if (dist >= -halfCarTolerance)
1003       {                                          1004       {
1004         if (calcNorm)                            1005         if (calcNorm)
1005         {                                        1006         {
1006            *validNorm = true;                    1007            *validNorm = true;
1007            n->set(fPlanes[i].a, fPlanes[i].b,    1008            n->set(fPlanes[i].a, fPlanes[i].b, fPlanes[i].c);
1008         }                                        1009         }
1009         return 0;                                1010         return 0;
1010       }                                          1011       }
1011       G4double tmp = -dist/cosa;                 1012       G4double tmp = -dist/cosa;
1012       if (tmax > tmp) { tmax = tmp; iside = i    1013       if (tmax > tmp) { tmax = tmp; iside = i; }
1013     }                                            1014     }
1014   }                                              1015   }
1015                                                  1016 
1016   // Set normal, if required, and return dist    1017   // Set normal, if required, and return distance
1017   //                                             1018   //
1018   if (calcNorm)                               << 1019   if (calcNorm) 
1019   {                                              1020   {
1020     *validNorm = true;                           1021     *validNorm = true;
1021     if (iside < 0)                               1022     if (iside < 0)
1022       n->set(0, 0, iside + 3); // (-4+3)=-1,     1023       n->set(0, 0, iside + 3); // (-4+3)=-1, (-2+3)=+1
1023     else                                         1024     else
1024       n->set(fPlanes[iside].a, fPlanes[iside]    1025       n->set(fPlanes[iside].a, fPlanes[iside].b, fPlanes[iside].c);
1025   }                                              1026   }
1026   return tmax;                                   1027   return tmax;
1027 }                                                1028 }
1028                                                  1029 
1029 ///////////////////////////////////////////// << 1030 ////////////////////////////////////////////////////////////////////////////
1030 //                                               1031 //
1031 // Calculate exact shortest distance to any b    1032 // Calculate exact shortest distance to any boundary from inside
1032 // - Returns 0 is ThreeVector outside            1033 // - Returns 0 is ThreeVector outside
1033                                                  1034 
1034 G4double G4Trap::DistanceToOut( const G4Three    1035 G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
1035 {                                                1036 {
1036 #ifdef G4CSGDEBUG                                1037 #ifdef G4CSGDEBUG
1037   if( Inside(p) == kOutside )                    1038   if( Inside(p) == kOutside )
1038   {                                              1039   {
1039     std::ostringstream message;                  1040     std::ostringstream message;
1040     G4long oldprc = message.precision(16);    << 1041     G4int oldprc = message.precision(16);
1041     message << "Point p is outside (!?) of so    1042     message << "Point p is outside (!?) of solid: " << GetName() << G4endl;
1042     message << "Position:\n";                    1043     message << "Position:\n";
1043     message << "   p.x() = " << p.x()/mm << "    1044     message << "   p.x() = " << p.x()/mm << " mm\n";
1044     message << "   p.y() = " << p.y()/mm << "    1045     message << "   p.y() = " << p.y()/mm << " mm\n";
1045     message << "   p.z() = " << p.z()/mm << "    1046     message << "   p.z() = " << p.z()/mm << " mm";
1046     G4cout.precision(oldprc);                 << 1047     G4cout.precision(oldprc) ;
1047     G4Exception("G4Trap::DistanceToOut(p)", "    1048     G4Exception("G4Trap::DistanceToOut(p)", "GeomSolids1002",
1048                 JustWarning, message );          1049                 JustWarning, message );
1049     DumpInfo();                                  1050     DumpInfo();
1050   }                                              1051   }
1051 #endif                                           1052 #endif
1052   switch (fTrapType)                             1053   switch (fTrapType)
1053   {                                              1054   {
1054     case 0: // General case                      1055     case 0: // General case
1055     {                                            1056     {
1056       G4double dz = std::abs(p.z())-fDz;         1057       G4double dz = std::abs(p.z())-fDz;
1057       G4double dy1 = fPlanes[0].b*p.y()+fPlan    1058       G4double dy1 = fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
1058       G4double dy2 = fPlanes[1].b*p.y()+fPlan    1059       G4double dy2 = fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
1059       G4double dy = std::max(dz,std::max(dy1,    1060       G4double dy = std::max(dz,std::max(dy1,dy2));
1060                                                  1061 
1061       G4double dx1 = fPlanes[2].a*p.x()+fPlan    1062       G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
1062                    + fPlanes[2].c*p.z()+fPlan    1063                    + fPlanes[2].c*p.z()+fPlanes[2].d;
1063       G4double dx2 = fPlanes[3].a*p.x()+fPlan    1064       G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
1064                    + fPlanes[3].c*p.z()+fPlan    1065                    + fPlanes[3].c*p.z()+fPlanes[3].d;
1065       G4double dist = std::max(dy,std::max(dx    1066       G4double dist = std::max(dy,std::max(dx1,dx2));
1066       return (dist < 0) ? -dist : 0.;            1067       return (dist < 0) ? -dist : 0.;
1067     }                                            1068     }
1068     case 1: // YZ section is a rectangle         1069     case 1: // YZ section is a rectangle
1069     {                                            1070     {
1070       G4double dz = std::abs(p.z())-fDz;         1071       G4double dz = std::abs(p.z())-fDz;
1071       G4double dy = std::max(dz,std::abs(p.y(    1072       G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
1072       G4double dx1 = fPlanes[2].a*p.x()+fPlan    1073       G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
1073                    + fPlanes[2].c*p.z()+fPlan    1074                    + fPlanes[2].c*p.z()+fPlanes[2].d;
1074       G4double dx2 = fPlanes[3].a*p.x()+fPlan    1075       G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
1075                    + fPlanes[3].c*p.z()+fPlan    1076                    + fPlanes[3].c*p.z()+fPlanes[3].d;
1076       G4double dist = std::max(dy,std::max(dx    1077       G4double dist = std::max(dy,std::max(dx1,dx2));
1077       return (dist < 0) ? -dist : 0.;            1078       return (dist < 0) ? -dist : 0.;
1078     }                                            1079     }
1079     case 2: // YZ section is a rectangle and     1080     case 2: // YZ section is a rectangle and
1080     {       // XZ section is an isosceles tra    1081     {       // XZ section is an isosceles trapezoid
1081       G4double dz = std::abs(p.z())-fDz;         1082       G4double dz = std::abs(p.z())-fDz;
1082       G4double dy = std::max(dz,std::abs(p.y(    1083       G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
1083       G4double dx = fPlanes[3].a*std::abs(p.x    1084       G4double dx = fPlanes[3].a*std::abs(p.x())
1084                   + fPlanes[3].c*p.z()+fPlane    1085                   + fPlanes[3].c*p.z()+fPlanes[3].d;
1085       G4double dist = std::max(dy,dx);           1086       G4double dist = std::max(dy,dx);
1086       return (dist < 0) ? -dist : 0.;            1087       return (dist < 0) ? -dist : 0.;
1087     }                                            1088     }
1088     case 3: // YZ section is a rectangle and     1089     case 3: // YZ section is a rectangle and
1089     {       // XY section is an isosceles tra    1090     {       // XY section is an isosceles trapezoid
1090       G4double dz = std::abs(p.z())-fDz;         1091       G4double dz = std::abs(p.z())-fDz;
1091       G4double dy = std::max(dz,std::abs(p.y(    1092       G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
1092       G4double dx = fPlanes[3].a*std::abs(p.x    1093       G4double dx = fPlanes[3].a*std::abs(p.x())
1093                   + fPlanes[3].b*p.y()+fPlane    1094                   + fPlanes[3].b*p.y()+fPlanes[3].d;
1094       G4double dist = std::max(dy,dx);           1095       G4double dist = std::max(dy,dx);
1095       return (dist < 0) ? -dist : 0.;            1096       return (dist < 0) ? -dist : 0.;
1096     }                                            1097     }
1097   }                                              1098   }
1098   return 0.;                                     1099   return 0.;
1099 }                                                1100 }
1100                                                  1101 
1101 ///////////////////////////////////////////// << 1102 ////////////////////////////////////////////////////////////////////////////
1102 //                                               1103 //
1103 // GetEntityType                                 1104 // GetEntityType
1104                                                  1105 
1105 G4GeometryType G4Trap::GetEntityType() const     1106 G4GeometryType G4Trap::GetEntityType() const
1106 {                                                1107 {
1107   return {"G4Trap"};                          << 1108   return G4String("G4Trap");
1108 }                                             << 
1109                                               << 
1110 ///////////////////////////////////////////// << 
1111 //                                            << 
1112 // IsFaceted                                  << 
1113                                               << 
1114 G4bool G4Trap::IsFaceted() const              << 
1115 {                                             << 
1116   return true;                                << 
1117 }                                                1109 }
1118                                                  1110 
1119 /////////////////////////////////////////////    1111 //////////////////////////////////////////////////////////////////////////
1120 //                                               1112 //
1121 // Make a clone of the object                    1113 // Make a clone of the object
1122 //                                               1114 //
1123 G4VSolid* G4Trap::Clone() const                  1115 G4VSolid* G4Trap::Clone() const
1124 {                                                1116 {
1125   return new G4Trap(*this);                      1117   return new G4Trap(*this);
1126 }                                                1118 }
1127                                                  1119 
1128 /////////////////////////////////////////////    1120 //////////////////////////////////////////////////////////////////////////
1129 //                                               1121 //
1130 // Stream object contents to an output stream    1122 // Stream object contents to an output stream
1131                                                  1123 
1132 std::ostream& G4Trap::StreamInfo( std::ostrea    1124 std::ostream& G4Trap::StreamInfo( std::ostream& os ) const
1133 {                                                1125 {
1134   G4double phi    = GetPhi();                 << 1126   G4double phi    = std::atan2(fTthetaSphi,fTthetaCphi);
1135   G4double theta  = GetTheta();               << 1127   G4double theta  = std::atan(std::sqrt(fTthetaCphi*fTthetaCphi
1136   G4double alpha1 = GetAlpha1();              << 1128                                        +fTthetaSphi*fTthetaSphi));
1137   G4double alpha2 = GetAlpha2();              << 1129   G4double alpha1 = std::atan(fTalpha1);
                                                   >> 1130   G4double alpha2 = std::atan(fTalpha2);
                                                   >> 1131   G4String signDegree = "\u00B0"; 
1138                                                  1132 
1139   G4long oldprc = os.precision(16);           << 1133   G4int oldprc = os.precision(16);
1140   os << "------------------------------------    1134   os << "-----------------------------------------------------------\n"
1141      << "    *** Dump for solid: " << GetName    1135      << "    *** Dump for solid: " << GetName() << " ***\n"
1142      << "    ================================    1136      << "    ===================================================\n"
1143      << " Solid type: G4Trap\n"                  1137      << " Solid type: G4Trap\n"
1144      << " Parameters:\n"                         1138      << " Parameters:\n"
1145      << "    half length Z: " << fDz/mm << "     1139      << "    half length Z: " << fDz/mm << " mm\n"
1146      << "    half length Y, face -Dz: " << fD    1140      << "    half length Y, face -Dz: " << fDy1/mm << " mm\n"
1147      << "    half length X, face -Dz, side -D    1141      << "    half length X, face -Dz, side -Dy1: " << fDx1/mm << " mm\n"
1148      << "    half length X, face -Dz, side +D    1142      << "    half length X, face -Dz, side +Dy1: " << fDx2/mm << " mm\n"
1149      << "    half length Y, face +Dz: " << fD    1143      << "    half length Y, face +Dz: " << fDy2/mm << " mm\n"
1150      << "    half length X, face +Dz, side -D    1144      << "    half length X, face +Dz, side -Dy2: " << fDx3/mm << " mm\n"
1151      << "    half length X, face +Dz, side +D    1145      << "    half length X, face +Dz, side +Dy2: " << fDx4/mm << " mm\n"
1152      << "    theta: " << theta/degree << " de << 1146      << "    theta: " << theta/degree << signDegree << "\n"
1153      << "    phi:   " << phi/degree << " degr << 1147      << "    phi: " << phi/degree << signDegree << "\n"
1154      << "    alpha, face -Dz: " << alpha1/deg << 1148      << "    alpha, face -Dz: " << alpha1/degree << signDegree << "\n"
1155      << "    alpha, face +Dz: " << alpha2/deg << 1149      << "    alpha, face +Dz: " << alpha2/degree << signDegree << "\n"
1156      << "------------------------------------    1150      << "-----------------------------------------------------------\n";
1157   os.precision(oldprc);                          1151   os.precision(oldprc);
1158                                                  1152 
1159   return os;                                     1153   return os;
1160 }                                                1154 }
1161                                                  1155 
1162 /////////////////////////////////////////////    1156 //////////////////////////////////////////////////////////////////////////
1163 //                                               1157 //
1164 // Compute vertices from planes                  1158 // Compute vertices from planes
1165                                                  1159 
1166 void G4Trap::GetVertices(G4ThreeVector pt[8])    1160 void G4Trap::GetVertices(G4ThreeVector pt[8]) const
1167 {                                                1161 {
1168   for (G4int i=0; i<8; ++i)                      1162   for (G4int i=0; i<8; ++i)
1169   {                                              1163   {
1170     G4int iy = (i==0 || i==1 || i==4 || i==5)    1164     G4int iy = (i==0 || i==1 || i==4 || i==5) ? 0 : 1;
1171     G4int ix = (i==0 || i==2 || i==4 || i==6)    1165     G4int ix = (i==0 || i==2 || i==4 || i==6) ? 2 : 3;
1172     G4double z = (i < 4) ? -fDz : fDz;           1166     G4double z = (i < 4) ? -fDz : fDz;
1173     G4double y = -(fPlanes[iy].c*z + fPlanes[    1167     G4double y = -(fPlanes[iy].c*z + fPlanes[iy].d)/fPlanes[iy].b;
1174     G4double x = -(fPlanes[ix].b*y + fPlanes[    1168     G4double x = -(fPlanes[ix].b*y + fPlanes[ix].c*z
1175                    + fPlanes[ix].d)/fPlanes[i    1169                    + fPlanes[ix].d)/fPlanes[ix].a;
1176     pt[i].set(x,y,z);                            1170     pt[i].set(x,y,z);
1177   }                                              1171   }
1178 }                                                1172 }
1179                                                  1173 
1180 ///////////////////////////////////////////// << 1174 /////////////////////////////////////////////////////////////////////////
1181 //                                               1175 //
1182 // Generate random point on the surface          1176 // Generate random point on the surface
1183                                                  1177 
1184 G4ThreeVector G4Trap::GetPointOnSurface() con    1178 G4ThreeVector G4Trap::GetPointOnSurface() const
1185 {                                                1179 {
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];                           1180   G4ThreeVector pt[8];
                                                   >> 1181   G4int iface [6][4] =
                                                   >> 1182     { {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} }; 
                                                   >> 1183   G4double sface[6];
                                                   >> 1184 
1192   GetVertices(pt);                               1185   GetVertices(pt);
                                                   >> 1186   G4double stotal = 0;
                                                   >> 1187   for (G4int i=0; i<6; ++i)
                                                   >> 1188   {
                                                   >> 1189     G4double ss = G4GeomTools::QuadAreaNormal(pt[iface[i][0]],
                                                   >> 1190                                               pt[iface[i][1]],
                                                   >> 1191                                               pt[iface[i][2]],
                                                   >> 1192                                               pt[iface[i][3]]).mag();
                                                   >> 1193     stotal  += ss;
                                                   >> 1194     sface[i] = stotal;
                                                   >> 1195   }
1193                                                  1196 
1194   // Select face                                 1197   // Select face
1195   //                                             1198   //
1196   G4double select = fAreas[5]*G4QuickRand();  << 1199   G4double select = stotal*G4UniformRand();
1197   G4int k = 5;                                   1200   G4int k = 5;
1198   k -= (G4int)(select <= fAreas[4]);          << 1201   if (select <= sface[4]) k = 4;
1199   k -= (G4int)(select <= fAreas[3]);          << 1202   if (select <= sface[3]) k = 3;
1200   k -= (G4int)(select <= fAreas[2]);          << 1203   if (select <= sface[2]) k = 2;
1201   k -= (G4int)(select <= fAreas[1]);          << 1204   if (select <= sface[1]) k = 1;
1202   k -= (G4int)(select <= fAreas[0]);          << 1205   if (select <= sface[0]) k = 0;
1203                                                  1206 
1204   // Select sub-triangle                         1207   // Select sub-triangle
1205   //                                             1208   //
1206   G4int i0 = iface[k][0];                        1209   G4int i0 = iface[k][0];
1207   G4int i1 = iface[k][1];                        1210   G4int i1 = iface[k][1];
1208   G4int i2 = iface[k][2];                        1211   G4int i2 = iface[k][2];
1209   G4int i3 = iface[k][3];                        1212   G4int i3 = iface[k][3];
                                                   >> 1213   G4double s1 = G4GeomTools::TriangleAreaNormal(pt[i0],pt[i1],pt[i3]).mag();
1210   G4double s2 = G4GeomTools::TriangleAreaNorm    1214   G4double s2 = G4GeomTools::TriangleAreaNormal(pt[i2],pt[i1],pt[i3]).mag();
1211   if (select > fAreas[k] - s2) i0 = i2;       << 1215   if ((s1+s2)*G4UniformRand() > s1) i0 = i2;
1212                                                  1216 
1213   // Generate point                              1217   // Generate point
1214   //                                             1218   //
1215   G4double u = G4QuickRand();                 << 1219   G4double u = G4UniformRand();
1216   G4double v = G4QuickRand();                 << 1220   G4double v = G4UniformRand();
1217   if (u + v > 1.) { u = 1. - u; v = 1. - v; }    1221   if (u + v > 1.) { u = 1. - u; v = 1. - v; }
1218   return (1.-u-v)*pt[i0] + u*pt[i1] + v*pt[i3    1222   return (1.-u-v)*pt[i0] + u*pt[i1] + v*pt[i3];
1219 }                                                1223 }
1220                                                  1224 
1221 /////////////////////////////////////////////    1225 //////////////////////////////////////////////////////////////////////////
1222 //                                               1226 //
1223 // Methods for visualisation                     1227 // Methods for visualisation
1224                                                  1228 
1225 void G4Trap::DescribeYourselfTo ( G4VGraphics    1229 void G4Trap::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
1226 {                                                1230 {
1227   scene.AddSolid (*this);                        1231   scene.AddSolid (*this);
1228 }                                                1232 }
1229                                                  1233 
1230 G4Polyhedron* G4Trap::CreatePolyhedron () con    1234 G4Polyhedron* G4Trap::CreatePolyhedron () const
1231 {                                                1235 {
1232   G4double phi = std::atan2(fTthetaSphi, fTth    1236   G4double phi = std::atan2(fTthetaSphi, fTthetaCphi);
1233   G4double alpha1 = std::atan(fTalpha1);         1237   G4double alpha1 = std::atan(fTalpha1);
1234   G4double alpha2 = std::atan(fTalpha2);         1238   G4double alpha2 = std::atan(fTalpha2);
1235   G4double theta = std::atan(std::sqrt(fTthet    1239   G4double theta = std::atan(std::sqrt(fTthetaCphi*fTthetaCphi
1236                                       +fTthet    1240                                       +fTthetaSphi*fTthetaSphi));
1237                                                  1241 
1238   return new G4PolyhedronTrap(fDz, theta, phi    1242   return new G4PolyhedronTrap(fDz, theta, phi,
1239                               fDy1, fDx1, fDx    1243                               fDy1, fDx1, fDx2, alpha1,
1240                               fDy2, fDx3, fDx    1244                               fDy2, fDx3, fDx4, alpha2);
1241 }                                                1245 }
1242                                                  1246 
1243 #endif                                           1247 #endif
1244                                                  1248