Geant4 Cross Reference

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


  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 // $Id: G4Para.cc 69788 2013-05-15 12:06:57Z gcosmo $
                                                   >>  28 //
                                                   >>  29 // class G4Para
                                                   >>  30 //
 26 // Implementation for G4Para class                 31 // Implementation for G4Para class
 27 //                                                 32 //
 28 // 21.03.95 P.Kent: Modified for `tolerant' ge <<  33 // History:
                                                   >>  34 //
                                                   >>  35 // 23.10.05 V.Grichine: bug fixed in DistanceToOut(p,v,...) for the v.x()<0 case 
                                                   >>  36 // 28.04.05 V.Grichine: new SurfaceNormal according to J. Apostolakis proposal 
                                                   >>  37 // 30.11.04 V.Grichine: modifications in SurfaceNormal for edges/vertices and
                                                   >>  38 //                      in constructor with vertices
                                                   >>  39 // 14.02.02 V.Grichine: bug fixed in Inside according to proposal of D.Wright
                                                   >>  40 // 18.11.99 V.Grichine: kUndef was added to ESide
 29 // 31.10.96 V.Grichine: Modifications accordin     41 // 31.10.96 V.Grichine: Modifications according G4Box/Tubs before to commit
 30 // 28.04.05 V.Grichine: new SurfaceNormal acco <<  42 // 21.03.95 P.Kent: Modified for `tolerant' geom
 31 // 29.05.17 E.Tcherniaev: complete revision, s <<  43 //
 32 //////////////////////////////////////////////     44 ////////////////////////////////////////////////////////////////////////////
 33                                                    45 
 34 #include "G4Para.hh"                               46 #include "G4Para.hh"
 35                                                    47 
 36 #if !defined(G4GEOM_USE_UPARA)                 << 
 37                                                << 
 38 #include "G4VoxelLimits.hh"                        48 #include "G4VoxelLimits.hh"
 39 #include "G4AffineTransform.hh"                    49 #include "G4AffineTransform.hh"
 40 #include "G4BoundingEnvelope.hh"               << 
 41 #include "Randomize.hh"                            50 #include "Randomize.hh"
 42                                                    51 
 43 #include "G4VPVParameterisation.hh"                52 #include "G4VPVParameterisation.hh"
 44                                                    53 
 45 #include "G4VGraphicsScene.hh"                     54 #include "G4VGraphicsScene.hh"
                                                   >>  55 #include "G4Polyhedron.hh"
                                                   >>  56 #include "G4NURBS.hh"
                                                   >>  57 #include "G4NURBSbox.hh"
 46                                                    58 
 47 using namespace CLHEP;                             59 using namespace CLHEP;
 48                                                    60 
 49 ////////////////////////////////////////////// <<  61 // Private enum: Not for external use 
                                                   >>  62     
                                                   >>  63 enum ESide {kUndef,kPX,kMX,kPY,kMY,kPZ,kMZ};
                                                   >>  64 
                                                   >>  65 // used internally for normal routine
                                                   >>  66 
                                                   >>  67 enum ENSide {kNZ,kNX,kNY};
                                                   >>  68 
                                                   >>  69 /////////////////////////////////////////////////////////////////////
                                                   >>  70 //
                                                   >>  71 // Constructor - check and set half-widths
                                                   >>  72 
                                                   >>  73 void G4Para::SetAllParameters( G4double pDx, G4double pDy, G4double pDz, 
                                                   >>  74                                G4double pAlpha, G4double pTheta, G4double pPhi )
                                                   >>  75 {
                                                   >>  76   if ( pDx > 0 && pDy > 0 && pDz > 0 )
                                                   >>  77   {
                                                   >>  78     fDx         = pDx;
                                                   >>  79     fDy         = pDy;
                                                   >>  80     fDz         = pDz;
                                                   >>  81     fTalpha     = std::tan(pAlpha);
                                                   >>  82     fTthetaCphi = std::tan(pTheta)*std::cos(pPhi);
                                                   >>  83     fTthetaSphi = std::tan(pTheta)*std::sin(pPhi);
                                                   >>  84   }
                                                   >>  85   else
                                                   >>  86   {
                                                   >>  87     std::ostringstream message;
                                                   >>  88     message << "Invalid Length Parameters for Solid: " << GetName() << G4endl
                                                   >>  89             << "        pDx, pDy, pDz = "
                                                   >>  90             << pDx << ", " << pDy << ", " << pDz;
                                                   >>  91     G4Exception("G4Para::SetAllParameters()", "GeomSolids0002",
                                                   >>  92                 FatalException, message);
                                                   >>  93   }
                                                   >>  94   fCubicVolume = 0.;
                                                   >>  95   fSurfaceArea = 0.;
                                                   >>  96   fpPolyhedron = 0;
                                                   >>  97 }
                                                   >>  98 
                                                   >>  99 ///////////////////////////////////////////////////////////////////////////
 50 //                                                100 //
 51 //  Constructor - set & check half widths      << 
 52                                                   101 
 53 G4Para::G4Para(const G4String& pName,             102 G4Para::G4Para(const G4String& pName,
 54                      G4double pDx, G4double pD    103                      G4double pDx, G4double pDy, G4double pDz,
 55                      G4double pAlpha, G4double    104                      G4double pAlpha, G4double pTheta, G4double pPhi)
 56   : G4CSGSolid(pName), halfCarTolerance(0.5*kC << 105   : G4CSGSolid(pName)
 57 {                                                 106 {
 58   SetAllParameters(pDx, pDy, pDz, pAlpha, pThe << 107   if ((pDx<=0) || (pDy<=0) || (pDz<=0))
 59   fRebuildPolyhedron = false;  // default valu << 108   {
                                                   >> 109     std::ostringstream message;
                                                   >> 110     message << "Invalid Length Parameters for Solid: " << GetName() << G4endl
                                                   >> 111             << "        pDx, pDy, pDz = "
                                                   >> 112             << pDx << ", " << pDy << ", " << pDz;
                                                   >> 113     G4Exception("G4Para::G4Para()", "GeomSolids0002",
                                                   >> 114                 FatalException, message);
                                                   >> 115   }
                                                   >> 116   SetAllParameters( pDx, pDy, pDz, pAlpha, pTheta, pPhi);
 60 }                                                 117 }
 61                                                   118 
 62 ////////////////////////////////////////////// << 119 ////////////////////////////////////////////////////////////////////////
 63 //                                                120 //
 64 // Constructor - design of trapezoid based on  << 121 // Constructor - Design of trapezoid based on 8 G4ThreeVector parameters, 
                                                   >> 122 // which are its vertices. Checking of planarity with preparation of 
                                                   >> 123 // fPlanes[] and than calculation of other members
 65                                                   124 
 66 G4Para::G4Para( const G4String& pName,            125 G4Para::G4Para( const G4String& pName,
 67                 const G4ThreeVector pt[8] )       126                 const G4ThreeVector pt[8] )
 68   : G4CSGSolid(pName), halfCarTolerance(0.5*kC << 127   : G4CSGSolid(pName)
 69 {                                                 128 {
 70   // Find dimensions and trigonometric values  << 129   if (!( pt[0].z()<0 && pt[0].z()==pt[1].z() && pt[0].z()==pt[2].z() &&
 71   //                                           << 130          pt[0].z()==pt[3].z() && pt[4].z()>0 && pt[4].z()==pt[5].z() &&
 72   fDx = (pt[3].x() - pt[2].x())*0.5;           << 131          pt[4].z()==pt[6].z() && pt[4].z()==pt[7].z()           &&
 73   fDy = (pt[2].y() - pt[1].y())*0.5;           << 132         (pt[0].z()+pt[4].z())==0                                &&
 74   fDz = pt[7].z();                             << 133          pt[0].y()==pt[1].y() && pt[2].y()==pt[3].y()           &&
 75   CheckParameters(); // check dimensions       << 134          pt[4].y()==pt[5].y() && pt[6].y()==pt[7].y()           &&
 76                                                << 135        ( pt[0].y() + pt[2].y() + pt[4].y() + pt[6].y() ) == 0   && 
 77   fTalpha = (pt[2].x() + pt[3].x() - pt[1].x() << 136        ( pt[0].x() + pt[1].x() + pt[4].x() + pt[5].x() ) == 0) )
 78   fTthetaCphi = (pt[4].x() + fDy*fTalpha + fDx << 137   {
 79   fTthetaSphi = (pt[4].y() + fDy)/fDz;         << 138     std::ostringstream message;
 80   MakePlanes();                                << 139     message << "Invalid vertice coordinates for Solid: " << GetName();
 81                                                << 140     G4Exception("G4Para::G4Para()", "GeomSolids0002",
 82   // Recompute vertices                        << 141                 FatalException, message);
 83   //                                           << 142   }    
 84   G4ThreeVector v[8];                          << 143   fDx = ((pt[3]).x()-(pt[2]).x())*0.5;
 85   G4double DyTalpha = fDy*fTalpha;             << 144   fDy = ((pt[2]).y()-(pt[1]).y())*0.5;
 86   G4double DzTthetaSphi = fDz*fTthetaSphi;     << 145   fDz = (pt[7]).z();
 87   G4double DzTthetaCphi = fDz*fTthetaCphi;     << 146   fTalpha = ((pt[2]).x()+(pt[3]).x()-(pt[1]).x()-(pt[0]).x())*0.25/fDy ;
 88   v[0].set(-DzTthetaCphi-DyTalpha-fDx, -DzTthe << 147   fTthetaCphi = ((pt[4]).x()+fDy*fTalpha+fDx)/fDz ;
 89   v[1].set(-DzTthetaCphi-DyTalpha+fDx, -DzTthe << 148   fTthetaSphi = ((pt[4]).y()+fDy)/fDz ;
 90   v[2].set(-DzTthetaCphi+DyTalpha-fDx, -DzTthe << 149   fCubicVolume = 0.;
 91   v[3].set(-DzTthetaCphi+DyTalpha+fDx, -DzTthe << 150   fSurfaceArea = 0.;
 92   v[4].set( DzTthetaCphi-DyTalpha-fDx,  DzTthe << 151   fpPolyhedron = 0;
 93   v[5].set( DzTthetaCphi-DyTalpha+fDx,  DzTthe << 
 94   v[6].set( DzTthetaCphi+DyTalpha-fDx,  DzTthe << 
 95   v[7].set( DzTthetaCphi+DyTalpha+fDx,  DzTthe << 
 96                                                << 
 97   // Compare with original vertices            << 
 98   //                                           << 
 99   for (G4int i=0; i<8; ++i)                    << 
100   {                                            << 
101     G4double delx = std::abs(pt[i].x() - v[i]. << 
102     G4double dely = std::abs(pt[i].y() - v[i]. << 
103     G4double delz = std::abs(pt[i].z() - v[i]. << 
104     G4double discrepancy = std::max(std::max(d << 
105     if (discrepancy > 0.1*kCarTolerance)       << 
106     {                                          << 
107       std::ostringstream message;              << 
108       G4long oldprc = message.precision(16);   << 
109       message << "Invalid vertice coordinates  << 
110               << "\nVertix #" << i << ", discr << 
111               << "\n  original   : " << pt[i]  << 
112               << "\n  recomputed : " << v[i];  << 
113       G4cout.precision(oldprc);                << 
114       G4Exception("G4Para::G4Para()", "GeomSol << 
115                   FatalException, message);    << 
116                                                << 
117     }                                          << 
118   }                                            << 
119 }                                                 152 }
120                                                   153 
121 ////////////////////////////////////////////// << 154 ///////////////////////////////////////////////////////////////////////
122 //                                                155 //
123 // Fake default constructor - sets only member    156 // Fake default constructor - sets only member data and allocates memory
124 //                            for usage restri << 157 //                            for usage restricted to object persistency.
125                                                << 158 //
126 G4Para::G4Para( __void__& a )                     159 G4Para::G4Para( __void__& a )
127   : G4CSGSolid(a), halfCarTolerance(0.5*kCarTo << 160   : G4CSGSolid(a), fDx(0.), fDy(0.), fDz(0.),
                                                   >> 161     fTalpha(0.), fTthetaCphi(0.), fTthetaSphi(0.)
128 {                                                 162 {
129   SetAllParameters(1., 1., 1., 0., 0., 0.);    << 
130   fRebuildPolyhedron = false; // default value << 
131 }                                                 163 }
132                                                   164 
133 //////////////////////////////////////////////    165 //////////////////////////////////////////////////////////////////////////
134 //                                                166 //
135 // Destructor                                  << 
136                                                   167 
137 G4Para::~G4Para() = default;                   << 168 G4Para::~G4Para()
                                                   >> 169 {
                                                   >> 170 }
138                                                   171 
139 //////////////////////////////////////////////    172 //////////////////////////////////////////////////////////////////////////
140 //                                                173 //
141 // Copy constructor                               174 // Copy constructor
142                                                   175 
143 G4Para::G4Para(const G4Para& rhs)                 176 G4Para::G4Para(const G4Para& rhs)
144   : G4CSGSolid(rhs), halfCarTolerance(rhs.half << 177   : G4CSGSolid(rhs), fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz),
145     fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz),  << 178     fTalpha(rhs.fTalpha), fTthetaCphi(rhs.fTthetaCphi),
146     fTthetaCphi(rhs.fTthetaCphi),fTthetaSphi(r << 179     fTthetaSphi(rhs.fTthetaSphi)
147 {                                                 180 {
148   for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs << 
149 }                                                 181 }
150                                                   182 
151 //////////////////////////////////////////////    183 //////////////////////////////////////////////////////////////////////////
152 //                                                184 //
153 // Assignment operator                            185 // Assignment operator
154                                                   186 
155 G4Para& G4Para::operator = (const G4Para& rhs) << 187 G4Para& G4Para::operator = (const G4Para& rhs) 
156 {                                                 188 {
157    // Check assignment to self                    189    // Check assignment to self
158    //                                             190    //
159    if (this == &rhs)  { return *this; }           191    if (this == &rhs)  { return *this; }
160                                                   192 
161    // Copy base class data                        193    // Copy base class data
162    //                                             194    //
163    G4CSGSolid::operator=(rhs);                    195    G4CSGSolid::operator=(rhs);
164                                                   196 
165    // Copy data                                   197    // Copy data
166    //                                             198    //
167    halfCarTolerance = rhs.halfCarTolerance;    << 199    fDx = rhs.fDx; fDy = rhs.fDy; fDz = rhs.fDz;
168    fDx = rhs.fDx;                              << 200    fTalpha = rhs.fTalpha; fTthetaCphi = rhs.fTthetaCphi;
169    fDy = rhs.fDy;                              << 
170    fDz = rhs.fDz;                              << 
171    fTalpha = rhs.fTalpha;                      << 
172    fTthetaCphi = rhs.fTthetaCphi;              << 
173    fTthetaSphi = rhs.fTthetaSphi;                 201    fTthetaSphi = rhs.fTthetaSphi;
174    for (G4int i=0; i<4; ++i) { fPlanes[i] = rh << 
175                                                   202 
176    return *this;                                  203    return *this;
177 }                                                 204 }
178                                                   205 
179 //////////////////////////////////////////////    206 //////////////////////////////////////////////////////////////////////////
180 //                                                207 //
181 // Set all parameters, as for constructor - se << 
182                                                << 
183 void G4Para::SetAllParameters(G4double pDx, G4 << 
184                               G4double pAlpha, << 
185 {                                              << 
186   // Reset data of the base class              << 
187   fCubicVolume = 0;                            << 
188   fSurfaceArea = 0;                            << 
189   fRebuildPolyhedron = true;                   << 
190                                                << 
191   // Set parameters                            << 
192   fDx = pDx;                                   << 
193   fDy = pDy;                                   << 
194   fDz = pDz;                                   << 
195   fTalpha = std::tan(pAlpha);                  << 
196   fTthetaCphi = std::tan(pTheta)*std::cos(pPhi << 
197   fTthetaSphi = std::tan(pTheta)*std::sin(pPhi << 
198                                                << 
199   CheckParameters();                           << 
200   MakePlanes();                                << 
201 }                                              << 
202                                                << 
203 ////////////////////////////////////////////// << 
204 //                                             << 
205 // Check dimensions                            << 
206                                                << 
207 void G4Para::CheckParameters()                 << 
208 {                                              << 
209   if (fDx < 2*kCarTolerance ||                 << 
210       fDy < 2*kCarTolerance ||                 << 
211       fDz < 2*kCarTolerance)                   << 
212   {                                            << 
213     std::ostringstream message;                << 
214     message << "Invalid (too small or negative << 
215             << GetName()                       << 
216             << "\n  X - " << fDx               << 
217             << "\n  Y - " << fDy               << 
218             << "\n  Z - " << fDz;              << 
219     G4Exception("G4Para::CheckParameters()", " << 
220                 FatalException, message);      << 
221   }                                            << 
222 }                                              << 
223                                                << 
224 ////////////////////////////////////////////// << 
225 //                                             << 
226 // Set side planes                             << 
227                                                << 
228 void G4Para::MakePlanes()                      << 
229 {                                              << 
230   G4ThreeVector vx(1, 0, 0);                   << 
231   G4ThreeVector vy(fTalpha, 1, 0);             << 
232   G4ThreeVector vz(fTthetaCphi, fTthetaSphi, 1 << 
233                                                << 
234   // Set -Y & +Y planes                        << 
235   //                                           << 
236   G4ThreeVector ynorm = (vx.cross(vz)).unit(); << 
237                                                << 
238   fPlanes[0].a = 0.;                           << 
239   fPlanes[0].b = ynorm.y();                    << 
240   fPlanes[0].c = ynorm.z();                    << 
241   fPlanes[0].d = fPlanes[0].b*fDy; // point (0 << 
242                                                << 
243   fPlanes[1].a =  0.;                          << 
244   fPlanes[1].b = -fPlanes[0].b;                << 
245   fPlanes[1].c = -fPlanes[0].c;                << 
246   fPlanes[1].d =  fPlanes[0].d;                << 
247                                                << 
248   // Set -X & +X planes                        << 
249   //                                           << 
250   G4ThreeVector xnorm = (vz.cross(vy)).unit(); << 
251                                                << 
252   fPlanes[2].a = xnorm.x();                    << 
253   fPlanes[2].b = xnorm.y();                    << 
254   fPlanes[2].c = xnorm.z();                    << 
255   fPlanes[2].d = fPlanes[2].a*fDx; // point (f << 
256                                                << 
257   fPlanes[3].a = -fPlanes[2].a;                << 
258   fPlanes[3].b = -fPlanes[2].b;                << 
259   fPlanes[3].c = -fPlanes[2].c;                << 
260   fPlanes[3].d =  fPlanes[2].d;                << 
261 }                                              << 
262                                                << 
263 ////////////////////////////////////////////// << 
264 //                                             << 
265 // Get volume                                  << 
266                                                << 
267 G4double G4Para::GetCubicVolume()              << 
268 {                                              << 
269   // It is like G4Box, since para transformati << 
270   if (fCubicVolume == 0)                       << 
271   {                                            << 
272     fCubicVolume = 8*fDx*fDy*fDz;              << 
273   }                                            << 
274   return fCubicVolume;                         << 
275 }                                              << 
276                                                << 
277 ////////////////////////////////////////////// << 
278 //                                             << 
279 // Get surface area                            << 
280                                                << 
281 G4double G4Para::GetSurfaceArea()              << 
282 {                                              << 
283   if(fSurfaceArea == 0)                        << 
284   {                                            << 
285     G4ThreeVector vx(fDx, 0, 0);               << 
286     G4ThreeVector vy(fDy*fTalpha, fDy, 0);     << 
287     G4ThreeVector vz(fDz*fTthetaCphi, fDz*fTth << 
288                                                << 
289     G4double sxy = fDx*fDy; // (vx.cross(vy)). << 
290     G4double sxz = (vx.cross(vz)).mag();       << 
291     G4double syz = (vy.cross(vz)).mag();       << 
292                                                << 
293     fSurfaceArea = 8*(sxy+sxz+syz);            << 
294   }                                            << 
295   return fSurfaceArea;                         << 
296 }                                              << 
297                                                << 
298 ////////////////////////////////////////////// << 
299 //                                             << 
300 // Dispatch to parameterisation for replicatio    208 // Dispatch to parameterisation for replication mechanism dimension
301 // computation & modification                  << 209 // computation & modification.
302                                                   210 
303 void G4Para::ComputeDimensions(      G4VPVPara    211 void G4Para::ComputeDimensions(      G4VPVParameterisation* p,
304                                 const G4int n,    212                                 const G4int n,
305                                 const G4VPhysi    213                                 const G4VPhysicalVolume* pRep )
306 {                                                 214 {
307   p->ComputeDimensions(*this,n,pRep);             215   p->ComputeDimensions(*this,n,pRep);
308 }                                                 216 }
309                                                   217 
310 ////////////////////////////////////////////// << 
311 //                                             << 
312 // Get bounding box                            << 
313                                                << 
314 void G4Para::BoundingLimits(G4ThreeVector& pMi << 
315 {                                              << 
316   G4double dz = GetZHalfLength();              << 
317   G4double dx = GetXHalfLength();              << 
318   G4double dy = GetYHalfLength();              << 
319                                                << 
320   G4double x0 = dz*fTthetaCphi;                << 
321   G4double x1 = dy*GetTanAlpha();              << 
322   G4double xmin =                              << 
323     std::min(                                  << 
324     std::min(                                  << 
325     std::min(-x0-x1-dx,-x0+x1-dx),x0-x1-dx),x0 << 
326   G4double xmax =                              << 
327     std::max(                                  << 
328     std::max(                                  << 
329     std::max(-x0-x1+dx,-x0+x1+dx),x0-x1+dx),x0 << 
330                                                << 
331   G4double y0 = dz*fTthetaSphi;                << 
332   G4double ymin = std::min(-y0-dy,y0-dy);      << 
333   G4double ymax = std::max(-y0+dy,y0+dy);      << 
334                                                << 
335   pMin.set(xmin,ymin,-dz);                     << 
336   pMax.set(xmax,ymax, dz);                     << 
337                                                << 
338   // Check correctness of the bounding box     << 
339   //                                           << 
340   if (pMin.x() >= pMax.x() || pMin.y() >= pMax << 
341   {                                            << 
342     std::ostringstream message;                << 
343     message << "Bad bounding box (min >= max)  << 
344             << GetName() << " !"               << 
345             << "\npMin = " << pMin             << 
346             << "\npMax = " << pMax;            << 
347     G4Exception("G4Para::BoundingLimits()", "G << 
348                 JustWarning, message);         << 
349     DumpInfo();                                << 
350   }                                            << 
351 }                                              << 
352                                                   218 
353 ////////////////////////////////////////////// << 219 //////////////////////////////////////////////////////////////
354 //                                                220 //
355 // Calculate extent under transform and specif    221 // Calculate extent under transform and specified limit
356                                                   222 
357 G4bool G4Para::CalculateExtent( const EAxis pA    223 G4bool G4Para::CalculateExtent( const EAxis pAxis,
358                                 const G4VoxelL    224                                 const G4VoxelLimits& pVoxelLimit,
359                                 const G4Affine    225                                 const G4AffineTransform& pTransform,
360                                      G4double&    226                                      G4double& pMin, G4double& pMax ) const
361 {                                                 227 {
362   G4ThreeVector bmin, bmax;                    << 228   G4bool flag;
363   G4bool exist;                                << 
364                                                   229 
365   // Check bounding box (bbox)                 << 230   if (!pTransform.IsRotated())
366   //                                           << 231   {  
367   BoundingLimits(bmin,bmax);                   << 232     // Special case handling for unrotated trapezoids
368   G4BoundingEnvelope bbox(bmin,bmax);          << 233     // Compute z/x/y/ mins and maxs respecting limits, with early returns
369 #ifdef G4BBOX_EXTENT                           << 234     // if outside limits. Then switch() on pAxis
370   return bbox.CalculateExtent(pAxis,pVoxelLimi << 235 
371 #endif                                         << 236     G4int i ; 
372   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox << 237     G4double xoffset,xMin,xMax;
373   {                                            << 238     G4double yoffset,yMin,yMax;
374     return exist = pMin < pMax;                << 239     G4double zoffset,zMin,zMax;
375   }                                            << 240     G4double temp[8] ;       // some points for intersection with zMin/zMax
                                                   >> 241     
                                                   >> 242     xoffset=pTransform.NetTranslation().x();      
                                                   >> 243     yoffset=pTransform.NetTranslation().y();
                                                   >> 244     zoffset=pTransform.NetTranslation().z();
                                                   >> 245  
                                                   >> 246     G4ThreeVector pt[8];   // vertices after translation
                                                   >> 247     pt[0]=G4ThreeVector(xoffset-fDz*fTthetaCphi-fDy*fTalpha-fDx,
                                                   >> 248                         yoffset-fDz*fTthetaSphi-fDy,zoffset-fDz);
                                                   >> 249     pt[1]=G4ThreeVector(xoffset-fDz*fTthetaCphi-fDy*fTalpha+fDx,
                                                   >> 250                         yoffset-fDz*fTthetaSphi-fDy,zoffset-fDz);
                                                   >> 251     pt[2]=G4ThreeVector(xoffset-fDz*fTthetaCphi+fDy*fTalpha-fDx,
                                                   >> 252                         yoffset-fDz*fTthetaSphi+fDy,zoffset-fDz);
                                                   >> 253     pt[3]=G4ThreeVector(xoffset-fDz*fTthetaCphi+fDy*fTalpha+fDx,
                                                   >> 254                         yoffset-fDz*fTthetaSphi+fDy,zoffset-fDz);
                                                   >> 255     pt[4]=G4ThreeVector(xoffset+fDz*fTthetaCphi-fDy*fTalpha-fDx,
                                                   >> 256                         yoffset+fDz*fTthetaSphi-fDy,zoffset+fDz);
                                                   >> 257     pt[5]=G4ThreeVector(xoffset+fDz*fTthetaCphi-fDy*fTalpha+fDx,
                                                   >> 258                         yoffset+fDz*fTthetaSphi-fDy,zoffset+fDz);
                                                   >> 259     pt[6]=G4ThreeVector(xoffset+fDz*fTthetaCphi+fDy*fTalpha-fDx,
                                                   >> 260                         yoffset+fDz*fTthetaSphi+fDy,zoffset+fDz);
                                                   >> 261     pt[7]=G4ThreeVector(xoffset+fDz*fTthetaCphi+fDy*fTalpha+fDx,
                                                   >> 262                         yoffset+fDz*fTthetaSphi+fDy,zoffset+fDz);
                                                   >> 263     zMin=zoffset-fDz;
                                                   >> 264     zMax=zoffset+fDz;
                                                   >> 265     if ( pVoxelLimit.IsZLimited() )
                                                   >> 266     {
                                                   >> 267       if   ( (zMin>pVoxelLimit.GetMaxZExtent()+kCarTolerance)
                                                   >> 268           || (zMax<pVoxelLimit.GetMinZExtent()-kCarTolerance) )
                                                   >> 269       {
                                                   >> 270         return false;
                                                   >> 271       }
                                                   >> 272       else
                                                   >> 273       {
                                                   >> 274         if (zMin<pVoxelLimit.GetMinZExtent())
                                                   >> 275         {
                                                   >> 276           zMin=pVoxelLimit.GetMinZExtent();
                                                   >> 277         }
                                                   >> 278         if (zMax>pVoxelLimit.GetMaxZExtent())
                                                   >> 279         {
                                                   >> 280           zMax=pVoxelLimit.GetMaxZExtent();
                                                   >> 281         }
                                                   >> 282       }
                                                   >> 283     }
376                                                   284 
377   // Set bounding envelope (benv) and calculat << 285     temp[0] = pt[0].y()+(pt[4].y()-pt[0].y())
378   //                                           << 286                        *(zMin-pt[0].z())/(pt[4].z()-pt[0].z()) ;
379   G4double dz = GetZHalfLength();              << 287     temp[1] = pt[0].y()+(pt[4].y()-pt[0].y())
380   G4double dx = GetXHalfLength();              << 288                        *(zMax-pt[0].z())/(pt[4].z()-pt[0].z()) ;
381   G4double dy = GetYHalfLength();              << 289     temp[2] = pt[2].y()+(pt[6].y()-pt[2].y())
                                                   >> 290                        *(zMin-pt[2].z())/(pt[6].z()-pt[2].z()) ;
                                                   >> 291     temp[3] = pt[2].y()+(pt[6].y()-pt[2].y())
                                                   >> 292                        *(zMax-pt[2].z())/(pt[6].z()-pt[2].z()) ;        
                                                   >> 293     yMax = yoffset - std::fabs(fDz*fTthetaSphi) - fDy - fDy ;
                                                   >> 294     yMin = -yMax ;
                                                   >> 295     for(i=0;i<4;i++)
                                                   >> 296     {
                                                   >> 297       if(temp[i] > yMax) yMax = temp[i] ;
                                                   >> 298       if(temp[i] < yMin) yMin = temp[i] ;
                                                   >> 299     }
                                                   >> 300       
                                                   >> 301     if (pVoxelLimit.IsYLimited())
                                                   >> 302     {
                                                   >> 303       if ( (yMin>pVoxelLimit.GetMaxYExtent()+kCarTolerance)
                                                   >> 304         || (yMax<pVoxelLimit.GetMinYExtent()-kCarTolerance) )
                                                   >> 305       {
                                                   >> 306         return false;
                                                   >> 307       }
                                                   >> 308       else
                                                   >> 309       {
                                                   >> 310         if (yMin<pVoxelLimit.GetMinYExtent())
                                                   >> 311         {
                                                   >> 312           yMin=pVoxelLimit.GetMinYExtent();
                                                   >> 313         }
                                                   >> 314         if (yMax>pVoxelLimit.GetMaxYExtent())
                                                   >> 315         {
                                                   >> 316           yMax=pVoxelLimit.GetMaxYExtent();
                                                   >> 317         }
                                                   >> 318       }
                                                   >> 319     }
382                                                   320 
383   G4double x0 = dz*fTthetaCphi;                << 321     temp[0] = pt[0].x()+(pt[4].x()-pt[0].x())
384   G4double x1 = dy*GetTanAlpha();              << 322                        *(zMin-pt[0].z())/(pt[4].z()-pt[0].z()) ;
385   G4double y0 = dz*fTthetaSphi;                << 323     temp[1] = pt[0].x()+(pt[4].x()-pt[0].x())
                                                   >> 324                        *(zMax-pt[0].z())/(pt[4].z()-pt[0].z()) ;
                                                   >> 325     temp[2] = pt[2].x()+(pt[6].x()-pt[2].x())
                                                   >> 326                        *(zMin-pt[2].z())/(pt[6].z()-pt[2].z()) ;
                                                   >> 327     temp[3] = pt[2].x()+(pt[6].x()-pt[2].x())
                                                   >> 328                        *(zMax-pt[2].z())/(pt[6].z()-pt[2].z()) ;
                                                   >> 329     temp[4] = pt[3].x()+(pt[7].x()-pt[3].x())
                                                   >> 330                        *(zMin-pt[3].z())/(pt[7].z()-pt[3].z()) ;
                                                   >> 331     temp[5] = pt[3].x()+(pt[7].x()-pt[3].x())
                                                   >> 332                        *(zMax-pt[3].z())/(pt[7].z()-pt[3].z()) ;
                                                   >> 333     temp[6] = pt[1].x()+(pt[5].x()-pt[1].x())
                                                   >> 334                        *(zMin-pt[1].z())/(pt[5].z()-pt[1].z()) ;
                                                   >> 335     temp[7] = pt[1].x()+(pt[5].x()-pt[1].x())
                                                   >> 336                        *(zMax-pt[1].z())/(pt[5].z()-pt[1].z()) ;
                                                   >> 337 
                                                   >> 338     xMax = xoffset - std::fabs(fDz*fTthetaCphi) - fDx - fDx -fDx - fDx;
                                                   >> 339     xMin = -xMax ;
                                                   >> 340     for(i=0;i<8;i++)
                                                   >> 341     {
                                                   >> 342       if(temp[i] > xMax) xMax = temp[i] ;
                                                   >> 343       if(temp[i] < xMin) xMin = temp[i] ;
                                                   >> 344     }
                                                   >> 345       // xMax/Min = f(yMax/Min) ?
                                                   >> 346     if (pVoxelLimit.IsXLimited())
                                                   >> 347     {
                                                   >> 348       if ( (xMin>pVoxelLimit.GetMaxXExtent()+kCarTolerance)
                                                   >> 349         || (xMax<pVoxelLimit.GetMinXExtent()-kCarTolerance) )
                                                   >> 350       {
                                                   >> 351         return false;
                                                   >> 352       }
                                                   >> 353       else
                                                   >> 354       {
                                                   >> 355         if (xMin<pVoxelLimit.GetMinXExtent())
                                                   >> 356         {
                                                   >> 357           xMin=pVoxelLimit.GetMinXExtent();
                                                   >> 358         }
                                                   >> 359         if (xMax>pVoxelLimit.GetMaxXExtent())
                                                   >> 360         {
                                                   >> 361           xMax=pVoxelLimit.GetMaxXExtent();
                                                   >> 362         }
                                                   >> 363       }
                                                   >> 364     }
386                                                   365 
387   G4ThreeVectorList baseA(4), baseB(4);        << 366     switch (pAxis)
388   baseA[0].set(-x0-x1-dx,-y0-dy,-dz);          << 367     {
389   baseA[1].set(-x0-x1+dx,-y0-dy,-dz);          << 368       case kXAxis:
390   baseA[2].set(-x0+x1+dx,-y0+dy,-dz);          << 369         pMin=xMin;
391   baseA[3].set(-x0+x1-dx,-y0+dy,-dz);          << 370         pMax=xMax;
                                                   >> 371         break;
                                                   >> 372       case kYAxis:
                                                   >> 373         pMin=yMin;
                                                   >> 374         pMax=yMax;
                                                   >> 375         break;
                                                   >> 376       case kZAxis:
                                                   >> 377         pMin=zMin;
                                                   >> 378         pMax=zMax;
                                                   >> 379         break;
                                                   >> 380       default:
                                                   >> 381         break;
                                                   >> 382     }
392                                                   383 
393   baseB[0].set(+x0-x1-dx, y0-dy, dz);          << 384     pMin-=kCarTolerance;
394   baseB[1].set(+x0-x1+dx, y0-dy, dz);          << 385     pMax+=kCarTolerance;
395   baseB[2].set(+x0+x1+dx, y0+dy, dz);          << 386     flag = true;
396   baseB[3].set(+x0+x1-dx, y0+dy, dz);          << 387   }
                                                   >> 388   else
                                                   >> 389   {
                                                   >> 390     // General rotated case - create and clip mesh to boundaries
                                                   >> 391 
                                                   >> 392     G4bool existsAfterClip=false;
                                                   >> 393     G4ThreeVectorList *vertices;
397                                                   394 
398   std::vector<const G4ThreeVectorList *> polyg << 395     pMin=+kInfinity;
399   polygons[0] = &baseA;                        << 396     pMax=-kInfinity;
400   polygons[1] = &baseB;                        << 
401                                                   397 
402   G4BoundingEnvelope benv(bmin,bmax,polygons); << 398     // Calculate rotated vertex coordinates
403   exist = benv.CalculateExtent(pAxis,pVoxelLim << 399 
404   return exist;                                << 400     vertices=CreateRotatedVertices(pTransform);
                                                   >> 401     ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
                                                   >> 402     ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax);
                                                   >> 403     ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
                                                   >> 404       
                                                   >> 405     if (pMin!=kInfinity||pMax!=-kInfinity)
                                                   >> 406     {
                                                   >> 407       existsAfterClip=true;
                                                   >> 408         
                                                   >> 409       // Add 2*tolerance to avoid precision troubles
                                                   >> 410       //
                                                   >> 411       pMin-=kCarTolerance;
                                                   >> 412       pMax+=kCarTolerance;
                                                   >> 413     }
                                                   >> 414     else
                                                   >> 415     {
                                                   >> 416       // Check for case where completely enveloping clipping volume
                                                   >> 417       // If point inside then we are confident that the solid completely
                                                   >> 418       // envelopes the clipping volume. Hence set min/max extents according
                                                   >> 419       // to clipping volume extents along the specified axis.
                                                   >> 420        
                                                   >> 421       G4ThreeVector clipCentre(
                                                   >> 422         (pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
                                                   >> 423         (pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
                                                   >> 424         (pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
                                                   >> 425         
                                                   >> 426       if (Inside(pTransform.Inverse().TransformPoint(clipCentre))!=kOutside)
                                                   >> 427       {
                                                   >> 428         existsAfterClip=true;
                                                   >> 429         pMin=pVoxelLimit.GetMinExtent(pAxis);
                                                   >> 430         pMax=pVoxelLimit.GetMaxExtent(pAxis);
                                                   >> 431       }
                                                   >> 432     }
                                                   >> 433     delete vertices ;          //  'new' in the function called
                                                   >> 434     flag = existsAfterClip ;
                                                   >> 435   }
                                                   >> 436   return flag;
405 }                                                 437 }
406                                                   438 
407 ////////////////////////////////////////////// << 439 /////////////////////////////////////////////////////////////////////////////
408 //                                             << 
409 // Determine where is point p, inside/on_surfa << 
410 //                                                440 //
                                                   >> 441 // Check in p is inside/on surface/outside solid
411                                                   442 
412 EInside G4Para::Inside( const G4ThreeVector& p    443 EInside G4Para::Inside( const G4ThreeVector& p ) const
413 {                                                 444 {
414   G4double xx = fPlanes[2].a*p.x()+fPlanes[2]. << 445   G4double xt, yt, yt1;
415   G4double dx = std::abs(xx) + fPlanes[2].d;   << 446   EInside  in = kOutside;
416                                                   447 
417   G4double yy = fPlanes[0].b*p.y()+fPlanes[0]. << 448   yt1 = p.y() - fTthetaSphi*p.z();
418   G4double dy = std::abs(yy) + fPlanes[0].d;   << 449   yt  = std::fabs(yt1) ;
419   G4double dxy = std::max(dx,dy);              << 
420                                                   450 
421   G4double dz = std::abs(p.z())-fDz;           << 451   // xt = std::fabs( p.x() - fTthetaCphi*p.z() - fTalpha*yt );
422   G4double dist = std::max(dxy,dz);            << 
423                                                   452 
424   if (dist > halfCarTolerance) return kOutside << 453   xt = std::fabs( p.x() - fTthetaCphi*p.z() - fTalpha*yt1 );
425   return (dist > -halfCarTolerance) ? kSurface << 454 
                                                   >> 455   if ( std::fabs( p.z() ) <= fDz - kCarTolerance*0.5)
                                                   >> 456   {
                                                   >> 457     if (yt <= fDy - kCarTolerance*0.5)
                                                   >> 458     {
                                                   >> 459       if      ( xt <= fDx - kCarTolerance*0.5 ) in = kInside;
                                                   >> 460       else if ( xt <= fDx + kCarTolerance*0.5 ) in = kSurface;
                                                   >> 461     }
                                                   >> 462     else if ( yt <= fDy + kCarTolerance*0.5)
                                                   >> 463     {
                                                   >> 464       if ( xt <= fDx + kCarTolerance*0.5 ) in = kSurface;  
                                                   >> 465     }
                                                   >> 466   }
                                                   >> 467   else  if ( std::fabs(p.z()) <= fDz + kCarTolerance*0.5 )
                                                   >> 468   {
                                                   >> 469     if ( yt <= fDy + kCarTolerance*0.5)
                                                   >> 470     {
                                                   >> 471       if ( xt <= fDx + kCarTolerance*0.5 ) in = kSurface;  
                                                   >> 472     }
                                                   >> 473   }
                                                   >> 474   return in;
426 }                                                 475 }
427                                                   476 
428 ////////////////////////////////////////////// << 477 ///////////////////////////////////////////////////////////////////////////
429 //                                                478 //
430 // Determine side where point is, and return c << 479 // Calculate side nearest to p, and return normal
                                                   >> 480 // If 2+ sides equidistant, first side's normal returned (arbitrarily)
431                                                   481 
432 G4ThreeVector G4Para::SurfaceNormal( const G4T    482 G4ThreeVector G4Para::SurfaceNormal( const G4ThreeVector& p ) const
433 {                                                 483 {
434   G4int nsurf = 0; // number of surfaces where << 484   G4ThreeVector norm, sumnorm(0.,0.,0.);
                                                   >> 485   G4int noSurfaces = 0; 
                                                   >> 486   G4double distx,disty,distz;
                                                   >> 487   G4double newpx,newpy,xshift;
                                                   >> 488   G4double calpha,salpha;      // Sin/Cos(alpha) - needed to recalc G4Parameter
                                                   >> 489   G4double tntheta,cosntheta;  // tan and cos of normal's theta component
                                                   >> 490   G4double ycomp;
                                                   >> 491   G4double delta = 0.5*kCarTolerance;
                                                   >> 492 
                                                   >> 493   newpx  = p.x()-fTthetaCphi*p.z();
                                                   >> 494   newpy  = p.y()-fTthetaSphi*p.z();
                                                   >> 495 
                                                   >> 496   calpha = 1/std::sqrt(1+fTalpha*fTalpha);
                                                   >> 497   if (fTalpha) {salpha = -calpha*fTalpha;} // NOTE: using MINUS std::sin(alpha)
                                                   >> 498   else         {salpha = 0.;}
                                                   >> 499   
                                                   >> 500   //  xshift = newpx*calpha+newpy*salpha;
                                                   >> 501   xshift = newpx - newpy*fTalpha;
435                                                   502 
436   // Check Z faces                             << 503   //  distx  = std::fabs(std::fabs(xshift)-fDx*calpha);
437   //                                           << 504   distx  = std::fabs(std::fabs(xshift)-fDx);
438   G4double nz = 0;                             << 505   disty  = std::fabs(std::fabs(newpy)-fDy);
439   G4double dz = std::abs(p.z()) - fDz;         << 506   distz  = std::fabs(std::fabs(p.z())-fDz);
440   if (std::abs(dz) <= halfCarTolerance)        << 
441   {                                            << 
442     nz = (p.z() < 0) ? -1 : 1;                 << 
443     ++nsurf;                                   << 
444   }                                            << 
445                                                   507 
446   // Check Y faces                             << 508   tntheta   = fTthetaCphi*calpha + fTthetaSphi*salpha;
447   //                                           << 509   cosntheta = 1/std::sqrt(1+tntheta*tntheta);
448   G4double ny = 0;                             << 510   ycomp     = 1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
449   G4double yy = fPlanes[0].b*p.y()+fPlanes[0]. << 511 
450   if (std::abs(fPlanes[0].d + yy) <= halfCarTo << 512   G4ThreeVector nX  = G4ThreeVector( calpha*cosntheta,
451   {                                            << 513                                      salpha*cosntheta,
452     ny  = fPlanes[0].b;                        << 514                                     -tntheta*cosntheta);
453     nz += fPlanes[0].c;                        << 515   G4ThreeVector nY  = G4ThreeVector( 0, ycomp,-fTthetaSphi*ycomp);
454     ++nsurf;                                   << 516   G4ThreeVector nZ  = G4ThreeVector( 0, 0,  1.0);
455   }                                            << 517 
456   else if (std::abs(fPlanes[1].d - yy) <= half << 518   if (distx <= delta)      
457   {                                               519   {
458     ny  = fPlanes[1].b;                        << 520     noSurfaces ++;
459     nz += fPlanes[1].c;                        << 521     if ( xshift >= 0.) {sumnorm += nX;}
460     ++nsurf;                                   << 522     else               {sumnorm -= nX;}
461   }                                               523   }
462                                                << 524   if (disty <= delta)
463   // Check X faces                             << 
464   //                                           << 
465   G4double nx = 0;                             << 
466   G4double xx = fPlanes[2].a*p.x()+fPlanes[2]. << 
467   if (std::abs(fPlanes[2].d + xx) <= halfCarTo << 
468   {                                               525   {
469     nx  = fPlanes[2].a;                        << 526     noSurfaces ++;
470     ny += fPlanes[2].b;                        << 527     if ( newpy >= 0.)  {sumnorm += nY;}
471     nz += fPlanes[2].c;                        << 528     else               {sumnorm -= nY;}
472     ++nsurf;                                   << 
473   }                                               529   }
474   else if (std::abs(fPlanes[3].d - xx) <= half << 530   if (distz <= delta)  
475   {                                               531   {
476     nx  = fPlanes[3].a;                        << 532     noSurfaces ++;
477     ny += fPlanes[3].b;                        << 533     if ( p.z() >= 0.)  {sumnorm += nZ;}
478     nz += fPlanes[3].c;                        << 534     else               {sumnorm -= nZ;}
479     ++nsurf;                                   << 
480   }                                               535   }
481                                                << 536   if ( noSurfaces == 0 )
482   // Return normal                             << 
483   //                                           << 
484   if (nsurf == 1)      return {nx,ny,nz};      << 
485   else if (nsurf != 0) return G4ThreeVector(nx << 
486   else                                         << 
487   {                                               537   {
488     // Point is not on the surface             << 
489     //                                         << 
490 #ifdef G4CSGDEBUG                                 538 #ifdef G4CSGDEBUG
491     std::ostringstream message;                << 
492     G4int oldprc = message.precision(16);      << 
493     message << "Point p is not on surface (!?) << 
494             << GetName() << G4endl;            << 
495     message << "Position:\n";                  << 
496     message << "   p.x() = " << p.x()/mm << "  << 
497     message << "   p.y() = " << p.y()/mm << "  << 
498     message << "   p.z() = " << p.z()/mm << "  << 
499     G4cout.precision(oldprc) ;                 << 
500     G4Exception("G4Para::SurfaceNormal(p)", "G    539     G4Exception("G4Para::SurfaceNormal(p)", "GeomSolids1002",
501                 JustWarning, message );        << 540                 JustWarning, "Point p is not on surface !?" );
502     DumpInfo();                                << 541 #endif 
503 #endif                                         << 542      norm = ApproxSurfaceNormal(p);
504     return ApproxSurfaceNormal(p);             << 
505   }                                               543   }
                                                   >> 544   else if ( noSurfaces == 1 ) {norm = sumnorm;}
                                                   >> 545   else                        {norm = sumnorm.unit();}
                                                   >> 546 
                                                   >> 547   return norm;
506 }                                                 548 }
507                                                   549 
508 ////////////////////////////////////////////// << 550 
                                                   >> 551 ////////////////////////////////////////////////////////////////////////
509 //                                                552 //
510 // Algorithm for SurfaceNormal() following the    553 // Algorithm for SurfaceNormal() following the original specification
511 // for points not on the surface                  554 // for points not on the surface
512                                                   555 
513 G4ThreeVector G4Para::ApproxSurfaceNormal( con    556 G4ThreeVector G4Para::ApproxSurfaceNormal( const G4ThreeVector& p ) const
514 {                                                 557 {
515   G4double dist = -DBL_MAX;                    << 558   ENSide  side;
516   G4int iside = 0;                             << 559   G4ThreeVector norm;
517   for (G4int i=0; i<4; ++i)                    << 560   G4double distx,disty,distz;
                                                   >> 561   G4double newpx,newpy,xshift;
                                                   >> 562   G4double calpha,salpha;  // Sin/Cos(alpha) - needed to recalc G4Parameter 
                                                   >> 563   G4double tntheta,cosntheta;  // tan and cos of normal's theta component
                                                   >> 564   G4double ycomp;
                                                   >> 565 
                                                   >> 566   newpx=p.x()-fTthetaCphi*p.z();
                                                   >> 567   newpy=p.y()-fTthetaSphi*p.z();
                                                   >> 568 
                                                   >> 569   calpha=1/std::sqrt(1+fTalpha*fTalpha);
                                                   >> 570   if (fTalpha)
518   {                                               571   {
519     G4double d = fPlanes[i].a*p.x() +          << 572     salpha=-calpha/fTalpha;  // NOTE: actually use MINUS std::sin(alpha)
520                  fPlanes[i].b*p.y() +          << 
521                  fPlanes[i].c*p.z() + fPlanes[ << 
522     if (d > dist) { dist = d; iside = i; }     << 
523   }                                               573   }
                                                   >> 574   else
                                                   >> 575   {
                                                   >> 576     salpha=0;
                                                   >> 577   }
                                                   >> 578 
                                                   >> 579   xshift=newpx*calpha+newpy*salpha;
524                                                   580 
525   G4double distz = std::abs(p.z()) - fDz;      << 581   distx=std::fabs(std::fabs(xshift)-fDx*calpha);
526   if (dist > distz)                            << 582   disty=std::fabs(std::fabs(newpy)-fDy);
527     return { fPlanes[iside].a, fPlanes[iside]. << 583   distz=std::fabs(std::fabs(p.z())-fDz);
                                                   >> 584     
                                                   >> 585   if (distx<disty)
                                                   >> 586   {
                                                   >> 587     if (distx<distz) {side=kNX;}
                                                   >> 588     else {side=kNZ;}
                                                   >> 589   }
528   else                                            590   else
529     return { 0, 0, (G4double)((p.z() < 0) ? -1 << 591   {
                                                   >> 592     if (disty<distz) {side=kNY;}
                                                   >> 593     else {side=kNZ;}
                                                   >> 594   }
                                                   >> 595 
                                                   >> 596   switch (side)
                                                   >> 597   {
                                                   >> 598     case kNX:
                                                   >> 599       tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
                                                   >> 600       if (xshift<0)
                                                   >> 601       {
                                                   >> 602         cosntheta=-1/std::sqrt(1+tntheta*tntheta);
                                                   >> 603       }
                                                   >> 604       else
                                                   >> 605       {
                                                   >> 606         cosntheta=1/std::sqrt(1+tntheta*tntheta);
                                                   >> 607       }
                                                   >> 608       norm=G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
                                                   >> 609       break;
                                                   >> 610     case kNY:
                                                   >> 611       if (newpy<0)
                                                   >> 612       {
                                                   >> 613         ycomp=-1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
                                                   >> 614       }
                                                   >> 615       else
                                                   >> 616       {
                                                   >> 617         ycomp=1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
                                                   >> 618       }
                                                   >> 619       norm=G4ThreeVector(0,ycomp,-fTthetaSphi*ycomp);
                                                   >> 620       break;
                                                   >> 621     case kNZ:           // Closest to Z
                                                   >> 622       if (p.z()>=0)
                                                   >> 623       {
                                                   >> 624         norm=G4ThreeVector(0,0,1);
                                                   >> 625       }
                                                   >> 626       else
                                                   >> 627       {
                                                   >> 628         norm=G4ThreeVector(0,0,-1);
                                                   >> 629       }
                                                   >> 630       break;
                                                   >> 631   }
                                                   >> 632   return norm;
530 }                                                 633 }
531                                                   634 
532 ////////////////////////////////////////////// << 635 //////////////////////////////////////////////////////////////////////////////
533 //                                                636 //
534 // Calculate distance to shape from outside       637 // Calculate distance to shape from outside
535 //  - return kInfinity if no intersection      << 638 // - return kInfinity if no intersection
536                                                << 639 //
537 G4double G4Para::DistanceToIn(const G4ThreeVec << 640 // ALGORITHM:
538                               const G4ThreeVec << 641 // For each component, calculate pair of minimum and maximum intersection
539 {                                              << 642 // values for which the particle is in the extent of the shape
540   // Z intersections                           << 643 // - The smallest (MAX minimum) allowed distance of the pairs is intersect
                                                   >> 644 // - Z plane intersectin uses tolerance
                                                   >> 645 // - XZ YZ planes use logic & *SLIGHTLY INCORRECT* tolerance
                                                   >> 646 //   (this saves at least 1 sqrt, 1 multiply and 1 divide... in applicable
                                                   >> 647 //    cases)
                                                   >> 648 // - Note: XZ and YZ planes each divide space into four regions,
                                                   >> 649 //   characterised by ss1 ss2
                                                   >> 650 
                                                   >> 651 G4double G4Para::DistanceToIn( const G4ThreeVector& p,
                                                   >> 652                                const G4ThreeVector& v ) const
                                                   >> 653 {
                                                   >> 654   G4double snxt;    // snxt = default return value
                                                   >> 655   G4double smin,smax;
                                                   >> 656   G4double tmin,tmax;
                                                   >> 657   G4double yt,vy,xt,vx;
                                                   >> 658   G4double max;
541   //                                              659   //
542   if ((std::abs(p.z()) - fDz) >= -halfCarToler << 660   // Z Intersection range
543     return kInfinity;                          << 
544   G4double invz = (-v.z() == 0) ? DBL_MAX : -1 << 
545   G4double dz = (invz < 0) ? fDz : -fDz;       << 
546   G4double tzmin = (p.z() + dz)*invz;          << 
547   G4double tzmax = (p.z() - dz)*invz;          << 
548                                                << 
549   // Y intersections                           << 
550   //                                              661   //
551   G4double tmin0 = tzmin, tmax0 = tzmax;       << 662   if (v.z()>0)
552   G4double cos0 = fPlanes[0].b*v.y() + fPlanes << 663   {
553   G4double disy = fPlanes[0].b*p.y() + fPlanes << 664     max=fDz-p.z();
554   G4double dis0 = fPlanes[0].d + disy;         << 665     if (max>kCarTolerance*0.5)
555   if (dis0 >= -halfCarTolerance)               << 666     {
                                                   >> 667       smax=max/v.z();
                                                   >> 668       smin=(-fDz-p.z())/v.z();
                                                   >> 669     }
                                                   >> 670     else
                                                   >> 671     {
                                                   >> 672       return snxt=kInfinity;
                                                   >> 673     }
                                                   >> 674   }
                                                   >> 675   else if (v.z()<0)
556   {                                               676   {
557     if (cos0 >= 0) return kInfinity;           << 677     max=-fDz-p.z();
558     G4double tmp  = -dis0/cos0;                << 678     if (max<-kCarTolerance*0.5)
559     if (tmin0 < tmp) tmin0 = tmp;              << 679     {
                                                   >> 680       smax=max/v.z();
                                                   >> 681       smin=(fDz-p.z())/v.z();
                                                   >> 682     }
                                                   >> 683     else
                                                   >> 684     {
                                                   >> 685       return snxt=kInfinity;
                                                   >> 686     }
560   }                                               687   }
561   else if (cos0 > 0)                           << 688   else
562   {                                               689   {
563     G4double tmp  = -dis0/cos0;                << 690     if (std::fabs(p.z())<=fDz) // Inside
564     if (tmax0 > tmp) tmax0 = tmp;              << 691     {
                                                   >> 692       smin=0;
                                                   >> 693       smax=kInfinity;
                                                   >> 694     }
                                                   >> 695     else
                                                   >> 696     {
                                                   >> 697       return snxt=kInfinity;
                                                   >> 698     }
565   }                                               699   }
                                                   >> 700     
                                                   >> 701   //
                                                   >> 702   // Y G4Parallel planes intersection
                                                   >> 703   //
566                                                   704 
567   G4double tmin1 = tmin0, tmax1 = tmax0;       << 705   yt=p.y()-fTthetaSphi*p.z();
568   G4double cos1 = -cos0;                       << 706   vy=v.y()-fTthetaSphi*v.z();
569   G4double dis1 = fPlanes[1].d - disy;         << 707 
570   if (dis1 >= -halfCarTolerance)               << 708   if (vy>0)
571   {                                               709   {
572     if (cos1 >= 0) return kInfinity;           << 710     max=fDy-yt;
573     G4double tmp  = -dis1/cos1;                << 711     if (max>kCarTolerance*0.5)
574     if (tmin1 < tmp) tmin1 = tmp;              << 712     {
                                                   >> 713       tmax=max/vy;
                                                   >> 714       tmin=(-fDy-yt)/vy;
                                                   >> 715     }
                                                   >> 716     else
                                                   >> 717     {
                                                   >> 718       return snxt=kInfinity;
                                                   >> 719     }
575   }                                               720   }
576   else if (cos1 > 0)                           << 721   else if (vy<0)
577   {                                               722   {
578     G4double tmp  = -dis1/cos1;                << 723     max=-fDy-yt;
579     if (tmax1 > tmp) tmax1 = tmp;              << 724     if (max<-kCarTolerance*0.5)
                                                   >> 725     {
                                                   >> 726       tmax=max/vy;
                                                   >> 727       tmin=(fDy-yt)/vy;
                                                   >> 728     }
                                                   >> 729     else
                                                   >> 730     {
                                                   >> 731       return snxt=kInfinity;
                                                   >> 732     }
                                                   >> 733   }
                                                   >> 734   else
                                                   >> 735   {
                                                   >> 736     if (std::fabs(yt)<=fDy)
                                                   >> 737     {
                                                   >> 738       tmin=0;
                                                   >> 739       tmax=kInfinity;
                                                   >> 740     }
                                                   >> 741     else
                                                   >> 742     {
                                                   >> 743       return snxt=kInfinity;
                                                   >> 744     }
580   }                                               745   }
581                                                   746 
582   // X intersections                           << 747   // Re-Calc valid intersection range
583   //                                              748   //
584   G4double tmin2 = tmin1, tmax2 = tmax1;       << 749   if (tmin>smin) smin=tmin;
585   G4double cos2 = fPlanes[2].a*v.x() + fPlanes << 750   if (tmax<smax) smax=tmax;
586   G4double disx = fPlanes[2].a*p.x() + fPlanes << 751   if (smax<=smin)
587   G4double dis2 = fPlanes[2].d + disx;         << 
588   if (dis2 >= -halfCarTolerance)               << 
589   {                                               752   {
590     if (cos2 >= 0) return kInfinity;           << 753     return snxt=kInfinity;
591     G4double tmp  = -dis2/cos2;                << 
592     if (tmin2 < tmp) tmin2 = tmp;              << 
593   }                                               754   }
594   else if (cos2 > 0)                           << 755   else
595   {                                               756   {
596     G4double tmp  = -dis2/cos2;                << 757     //
597     if (tmax2 > tmp) tmax2 = tmp;              << 758     // X G4Parallel planes intersection
                                                   >> 759     //
                                                   >> 760     xt=p.x()-fTthetaCphi*p.z()-fTalpha*yt;
                                                   >> 761     vx=v.x()-fTthetaCphi*v.z()-fTalpha*vy;
                                                   >> 762     if (vx>0)
                                                   >> 763     {
                                                   >> 764       max=fDx-xt;
                                                   >> 765       if (max>kCarTolerance*0.5)
                                                   >> 766       {
                                                   >> 767         tmax=max/vx;
                                                   >> 768         tmin=(-fDx-xt)/vx;
                                                   >> 769       }
                                                   >> 770       else
                                                   >> 771       {
                                                   >> 772         return snxt=kInfinity;
                                                   >> 773       }
                                                   >> 774     }
                                                   >> 775     else if (vx<0)
                                                   >> 776     {
                                                   >> 777       max=-fDx-xt;
                                                   >> 778       if (max<-kCarTolerance*0.5)
                                                   >> 779       {
                                                   >> 780         tmax=max/vx;
                                                   >> 781         tmin=(fDx-xt)/vx;
                                                   >> 782       }
                                                   >> 783       else
                                                   >> 784       {
                                                   >> 785         return snxt=kInfinity;
                                                   >> 786       }
                                                   >> 787     }
                                                   >> 788     else
                                                   >> 789     {
                                                   >> 790       if (std::fabs(xt)<=fDx)
                                                   >> 791       {
                                                   >> 792         tmin=0;
                                                   >> 793         tmax=kInfinity;
                                                   >> 794       }
                                                   >> 795       else
                                                   >> 796       {
                                                   >> 797         return snxt=kInfinity;
                                                   >> 798       }
                                                   >> 799     }
                                                   >> 800     if (tmin>smin) smin=tmin;
                                                   >> 801     if (tmax<smax) smax=tmax;
598   }                                               802   }
599                                                   803 
600   G4double tmin3 = tmin2, tmax3 = tmax2;       << 804   if (smax>0&&smin<smax)
601   G4double cos3 = -cos2;                       << 
602   G4double dis3 = fPlanes[3].d - disx;         << 
603   if (dis3 >= -halfCarTolerance)               << 
604   {                                               805   {
605     if (cos3 >= 0) return kInfinity;           << 806     if (smin>0)
606     G4double tmp  = -dis3/cos3;                << 807     {
607     if (tmin3 < tmp) tmin3 = tmp;              << 808       snxt=smin;
                                                   >> 809     }
                                                   >> 810     else
                                                   >> 811     {
                                                   >> 812       snxt=0;
                                                   >> 813     }
608   }                                               814   }
609   else if (cos3 > 0)                           << 815   else
610   {                                               816   {
611     G4double tmp  = -dis3/cos3;                << 817     snxt=kInfinity;
612     if (tmax3 > tmp) tmax3 = tmp;              << 
613   }                                               818   }
614                                                << 819   return snxt;
615   // Find distance                             << 
616   //                                           << 
617   G4double tmin = tmin3, tmax = tmax3;         << 
618   if (tmax <= tmin + halfCarTolerance) return  << 
619   return (tmin < halfCarTolerance ) ? 0. : tmi << 
620 }                                                 820 }
621                                                   821 
622 ////////////////////////////////////////////// << 822 ////////////////////////////////////////////////////////////////////////////
623 //                                                823 //
624 // Calculate exact shortest distance to any bo    824 // Calculate exact shortest distance to any boundary from outside
625 // - returns 0 is point inside                 << 825 // - Returns 0 is point inside
626                                                   826 
627 G4double G4Para::DistanceToIn( const G4ThreeVe    827 G4double G4Para::DistanceToIn( const G4ThreeVector& p ) const
628 {                                                 828 {
629   G4double xx = fPlanes[2].a*p.x()+fPlanes[2]. << 829   G4double safe=0.0;
630   G4double dx = std::abs(xx) + fPlanes[2].d;   << 830   G4double distz1,distz2,disty1,disty2,distx1,distx2;
                                                   >> 831   G4double trany,cosy,tranx,cosx;
631                                                   832 
632   G4double yy = fPlanes[0].b*p.y()+fPlanes[0]. << 833   // Z planes
633   G4double dy = std::abs(yy) + fPlanes[0].d;   << 834   //
634   G4double dxy = std::max(dx,dy);              << 835   distz1=p.z()-fDz;
                                                   >> 836   distz2=-fDz-p.z();
                                                   >> 837   if (distz1>distz2)
                                                   >> 838   {
                                                   >> 839     safe=distz1;
                                                   >> 840   }
                                                   >> 841   else
                                                   >> 842   {
                                                   >> 843     safe=distz2;
                                                   >> 844   }
                                                   >> 845 
                                                   >> 846   trany=p.y()-fTthetaSphi*p.z(); // Transformed y into `box' system
635                                                   847 
636   G4double dz = std::abs(p.z())-fDz;           << 848   // Transformed x into `box' system
637   G4double dist = std::max(dxy,dz);            << 849   //
                                                   >> 850   cosy=1.0/std::sqrt(1.0+fTthetaSphi*fTthetaSphi);
                                                   >> 851   disty1=(trany-fDy)*cosy;
                                                   >> 852   disty2=(-fDy-trany)*cosy;
                                                   >> 853     
                                                   >> 854   if (disty1>safe) safe=disty1;
                                                   >> 855   if (disty2>safe) safe=disty2;
638                                                   856 
639   return (dist > 0) ? dist : 0.;               << 857   tranx=p.x()-fTthetaCphi*p.z()-fTalpha*trany;
                                                   >> 858   cosx=1.0/std::sqrt(1.0+fTalpha*fTalpha+fTthetaCphi*fTthetaCphi);
                                                   >> 859   distx1=(tranx-fDx)*cosx;
                                                   >> 860   distx2=(-fDx-tranx)*cosx;
                                                   >> 861     
                                                   >> 862   if (distx1>safe) safe=distx1;
                                                   >> 863   if (distx2>safe) safe=distx2;
                                                   >> 864     
                                                   >> 865   if (safe<0) safe=0;
                                                   >> 866   return safe;  
640 }                                                 867 }
641                                                   868 
642 //////////////////////////////////////////////    869 //////////////////////////////////////////////////////////////////////////
643 //                                                870 //
644 // Calculate distance to surface of shape from << 871 // Calculate distance to surface of shape from inside
645 // find normal at exit point                   << 872 // Calculate distance to x/y/z planes - smallest is exiting distance
646 // - when leaving the surface, return 0        << 
647                                                   873 
648 G4double G4Para::DistanceToOut(const G4ThreeVe    874 G4double G4Para::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
649                                const G4bool ca    875                                const G4bool calcNorm,
650                                      G4bool* v << 876                                G4bool *validNorm, G4ThreeVector *n) const
651 {                                                 877 {
652   // Z intersections                           << 878   ESide side = kUndef;
                                                   >> 879   G4double snxt;    // snxt = return value
                                                   >> 880   G4double max,tmax;
                                                   >> 881   G4double yt,vy,xt,vx;
                                                   >> 882 
                                                   >> 883   G4double ycomp,calpha,salpha,tntheta,cosntheta;
                                                   >> 884 
                                                   >> 885   //
                                                   >> 886   // Z Intersections
653   //                                              887   //
654   if ((std::abs(p.z()) - fDz) >= -halfCarToler << 888 
                                                   >> 889   if (v.z()>0)
655   {                                               890   {
656     if (calcNorm)                              << 891     max=fDz-p.z();
                                                   >> 892     if (max>kCarTolerance*0.5)
                                                   >> 893     {
                                                   >> 894       snxt=max/v.z();
                                                   >> 895       side=kPZ;
                                                   >> 896     }
                                                   >> 897     else
657     {                                             898     {
658       *validNorm = true;                       << 899       if (calcNorm)
659       n->set(0, 0, (p.z() < 0) ? -1 : 1);      << 900       {
                                                   >> 901         *validNorm=true;
                                                   >> 902         *n=G4ThreeVector(0,0,1);
                                                   >> 903       }
                                                   >> 904       return snxt=0;
660     }                                             905     }
661     return 0.;                                 << 
662   }                                               906   }
663   G4double vz = v.z();                         << 907   else if (v.z()<0)
664   G4double tmax = (vz == 0) ? DBL_MAX : (std:: << 
665   G4int iside = (vz < 0) ? -4 : -2; // little  << 
666                                                << 
667   // Y intersections                           << 
668   //                                           << 
669   G4double cos0 = fPlanes[0].b*v.y() + fPlanes << 
670   if (cos0 > 0)                                << 
671   {                                               908   {
672     G4double dis0 = fPlanes[0].b*p.y() + fPlan << 909     max=-fDz-p.z();
673     if (dis0 >= -halfCarTolerance)             << 910     if (max<-kCarTolerance*0.5)
                                                   >> 911     {
                                                   >> 912       snxt=max/v.z();
                                                   >> 913       side=kMZ;
                                                   >> 914     }
                                                   >> 915     else
674     {                                             916     {
675       if (calcNorm)                               917       if (calcNorm)
676       {                                           918       {
677         *validNorm = true;                     << 919         *validNorm=true;
678         n->set(0, fPlanes[0].b, fPlanes[0].c); << 920         *n=G4ThreeVector(0,0,-1);
679       }                                           921       }
680       return 0.;                               << 922       return snxt=0;
681     }                                             923     }
682     G4double tmp = -dis0/cos0;                 << 
683     if (tmax > tmp) { tmax = tmp; iside = 0; } << 
684   }                                               924   }
                                                   >> 925   else
                                                   >> 926   {
                                                   >> 927     snxt=kInfinity;
                                                   >> 928   }
                                                   >> 929     
                                                   >> 930   //
                                                   >> 931   // Y plane intersection
                                                   >> 932   //
                                                   >> 933 
                                                   >> 934   yt=p.y()-fTthetaSphi*p.z();
                                                   >> 935   vy=v.y()-fTthetaSphi*v.z();
685                                                   936 
686   G4double cos1 = -cos0;                       << 937   if (vy>0)
687   if (cos1 > 0)                                << 938   {
                                                   >> 939     max=fDy-yt;
                                                   >> 940     if (max>kCarTolerance*0.5)
                                                   >> 941     {
                                                   >> 942       tmax=max/vy;
                                                   >> 943       if (tmax<snxt)
                                                   >> 944       {
                                                   >> 945         snxt=tmax;
                                                   >> 946         side=kPY;
                                                   >> 947       }
                                                   >> 948     }
                                                   >> 949     else
                                                   >> 950     {
                                                   >> 951       if (calcNorm)
                                                   >> 952       {      
                                                   >> 953         *validNorm=true; // Leaving via plus Y
                                                   >> 954         ycomp=1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
                                                   >> 955         *n=G4ThreeVector(0,ycomp,-fTthetaSphi*ycomp);
                                                   >> 956       }
                                                   >> 957       return snxt=0;
                                                   >> 958     }
                                                   >> 959   }
                                                   >> 960   else if (vy<0)
688   {                                               961   {
689     G4double dis1 = fPlanes[1].b*p.y() + fPlan << 962     max=-fDy-yt;
690     if (dis1 >= -halfCarTolerance)             << 963     if (max<-kCarTolerance*0.5)
                                                   >> 964     {
                                                   >> 965       tmax=max/vy;
                                                   >> 966       if (tmax<snxt)
                                                   >> 967       {
                                                   >> 968         snxt=tmax;
                                                   >> 969         side=kMY;
                                                   >> 970       }
                                                   >> 971     }
                                                   >> 972     else
691     {                                             973     {
692       if (calcNorm)                               974       if (calcNorm)
693       {                                           975       {
694         *validNorm = true;                     << 976         *validNorm=true; // Leaving via minus Y
695         n->set(0, fPlanes[1].b, fPlanes[1].c); << 977         ycomp=-1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
                                                   >> 978         *n=G4ThreeVector(0,ycomp,-fTthetaSphi*ycomp);
696       }                                           979       }
697       return 0.;                               << 980       return snxt=0;
698     }                                             981     }
699     G4double tmp = -dis1/cos1;                 << 
700     if (tmax > tmp) { tmax = tmp; iside = 1; } << 
701   }                                               982   }
702                                                   983 
703   // X intersections                           << 
704   //                                              984   //
705   G4double cos2 = fPlanes[2].a*v.x() + fPlanes << 985   // X plane intersection
706   if (cos2 > 0)                                << 986   //
                                                   >> 987 
                                                   >> 988   xt=p.x()-fTthetaCphi*p.z()-fTalpha*yt;
                                                   >> 989   vx=v.x()-fTthetaCphi*v.z()-fTalpha*vy;
                                                   >> 990   if (vx>0)
707   {                                               991   {
708     G4double dis2 = fPlanes[2].a*p.x()+fPlanes << 992     max=fDx-xt;
709     if (dis2 >= -halfCarTolerance)             << 993     if (max>kCarTolerance*0.5)
                                                   >> 994     {
                                                   >> 995       tmax=max/vx;
                                                   >> 996       if (tmax<snxt)
                                                   >> 997       {
                                                   >> 998         snxt=tmax;
                                                   >> 999         side=kPX;
                                                   >> 1000       }
                                                   >> 1001     }
                                                   >> 1002     else
710     {                                             1003     {
711       if (calcNorm)                               1004       if (calcNorm)
712       {                                           1005       {
713          *validNorm = true;                    << 1006         *validNorm=true; // Leaving via plus X
714          n->set(fPlanes[2].a, fPlanes[2].b, fP << 1007         calpha=1/std::sqrt(1+fTalpha*fTalpha);
                                                   >> 1008         if (fTalpha)
                                                   >> 1009         {
                                                   >> 1010           salpha=-calpha/fTalpha;  // NOTE: actually use MINUS std::sin(alpha)
                                                   >> 1011         }
                                                   >> 1012         else
                                                   >> 1013         {
                                                   >> 1014           salpha=0;
                                                   >> 1015         }
                                                   >> 1016         tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
                                                   >> 1017         cosntheta=1/std::sqrt(1+tntheta*tntheta);
                                                   >> 1018         *n=G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
715       }                                           1019       }
716       return 0.;                               << 1020       return snxt=0;
717     }                                             1021     }
718     G4double tmp = -dis2/cos2;                 << 
719     if (tmax > tmp) { tmax = tmp; iside = 2; } << 
720   }                                               1022   }
721                                                << 1023   else if (vx<0)
722   G4double cos3 = -cos2;                       << 
723   if (cos3 > 0)                                << 
724   {                                               1024   {
725     G4double dis3 = fPlanes[3].a*p.x()+fPlanes << 1025     max=-fDx-xt;
726     if (dis3 >= -halfCarTolerance)             << 1026     if (max<-kCarTolerance*0.5)
                                                   >> 1027     {
                                                   >> 1028       tmax=max/vx;
                                                   >> 1029       if (tmax<snxt)
                                                   >> 1030       {
                                                   >> 1031         snxt=tmax;
                                                   >> 1032         side=kMX;
                                                   >> 1033       }
                                                   >> 1034     }
                                                   >> 1035     else
727     {                                             1036     {
728       if (calcNorm)                               1037       if (calcNorm)
729       {                                           1038       {
730          *validNorm = true;                    << 1039         *validNorm=true; // Leaving via minus X
731          n->set(fPlanes[3].a, fPlanes[3].b, fP << 1040         calpha=1/std::sqrt(1+fTalpha*fTalpha);
                                                   >> 1041         if (fTalpha)
                                                   >> 1042         {
                                                   >> 1043           salpha=-calpha/fTalpha;  // NOTE: actually use MINUS std::sin(alpha)
                                                   >> 1044         }
                                                   >> 1045         else
                                                   >> 1046         {
                                                   >> 1047           salpha=0;
                                                   >> 1048         }
                                                   >> 1049         tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
                                                   >> 1050         cosntheta=-1/std::sqrt(1+tntheta*tntheta);
                                                   >> 1051         *n=G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
732       }                                           1052       }
733       return 0.;                               << 1053       return snxt=0;
734     }                                             1054     }
735     G4double tmp = -dis3/cos3;                 << 
736     if (tmax > tmp) { tmax = tmp; iside = 3; } << 
737   }                                               1055   }
738                                                   1056 
739   // Set normal, if required, and return dista << 1057   if (calcNorm)
740   //                                           << 
741   if (calcNorm)                                << 
742   {                                               1058   {
743     *validNorm = true;                         << 1059     *validNorm=true;
744     if (iside < 0)                             << 1060     switch (side)
745       n->set(0, 0, iside + 3); // (-4+3)=-1, ( << 1061     {
746     else                                       << 1062       case kMZ:
747       n->set(fPlanes[iside].a, fPlanes[iside]. << 1063         *n=G4ThreeVector(0,0,-1);
                                                   >> 1064         break;
                                                   >> 1065       case kPZ:
                                                   >> 1066         *n=G4ThreeVector(0,0,1);
                                                   >> 1067         break;
                                                   >> 1068       case kMY:
                                                   >> 1069         ycomp=-1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
                                                   >> 1070         *n=G4ThreeVector(0,ycomp,-fTthetaSphi*ycomp);
                                                   >> 1071         break;        
                                                   >> 1072       case kPY:
                                                   >> 1073         ycomp=1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
                                                   >> 1074         *n=G4ThreeVector(0,ycomp,-fTthetaSphi*ycomp);
                                                   >> 1075         break;        
                                                   >> 1076       case kMX:
                                                   >> 1077         calpha=1/std::sqrt(1+fTalpha*fTalpha);
                                                   >> 1078         if (fTalpha)
                                                   >> 1079         {
                                                   >> 1080           salpha=-calpha/fTalpha;  // NOTE: actually use MINUS std::sin(alpha)
                                                   >> 1081         }
                                                   >> 1082         else
                                                   >> 1083         {
                                                   >> 1084           salpha=0;
                                                   >> 1085         }
                                                   >> 1086         tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
                                                   >> 1087         cosntheta=-1/std::sqrt(1+tntheta*tntheta);
                                                   >> 1088         *n=G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
                                                   >> 1089         break;
                                                   >> 1090       case kPX:
                                                   >> 1091         calpha=1/std::sqrt(1+fTalpha*fTalpha);
                                                   >> 1092         if (fTalpha)
                                                   >> 1093         {
                                                   >> 1094           salpha=-calpha/fTalpha;  // NOTE: actually use MINUS std::sin(alpha)
                                                   >> 1095         }
                                                   >> 1096         else
                                                   >> 1097         {
                                                   >> 1098           salpha=0;
                                                   >> 1099         }
                                                   >> 1100         tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
                                                   >> 1101         cosntheta=1/std::sqrt(1+tntheta*tntheta);
                                                   >> 1102         *n=G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
                                                   >> 1103         break;
                                                   >> 1104       default:
                                                   >> 1105         DumpInfo();
                                                   >> 1106         G4Exception("G4Para::DistanceToOut(p,v,..)",
                                                   >> 1107                     "GeomSolids1002",JustWarning,
                                                   >> 1108                     "Undefined side for valid surface normal to solid.");
                                                   >> 1109         break;
                                                   >> 1110     }
748   }                                               1111   }
749   return tmax;                                 << 1112   return snxt;
750 }                                                 1113 }
751                                                   1114 
752 ////////////////////////////////////////////// << 1115 /////////////////////////////////////////////////////////////////////////////
753 //                                                1116 //
754 // Calculate exact shortest distance to any bo    1117 // Calculate exact shortest distance to any boundary from inside
755 // - returns 0 is point outside                << 1118 // - Returns 0 is point outside
756                                                   1119 
757 G4double G4Para::DistanceToOut( const G4ThreeV    1120 G4double G4Para::DistanceToOut( const G4ThreeVector& p ) const
758 {                                                 1121 {
                                                   >> 1122   G4double safe=0.0;
                                                   >> 1123   G4double distz1,distz2,disty1,disty2,distx1,distx2;
                                                   >> 1124   G4double trany,cosy,tranx,cosx;
                                                   >> 1125 
759 #ifdef G4CSGDEBUG                                 1126 #ifdef G4CSGDEBUG
760   if( Inside(p) == kOutside )                     1127   if( Inside(p) == kOutside )
761   {                                               1128   {
762     std::ostringstream message;                << 1129      G4int oldprc = G4cout.precision(16) ;
763     G4int oldprc = message.precision(16);      << 1130      G4cout << G4endl ;
764     message << "Point p is outside (!?) of sol << 1131      DumpInfo();
765     message << "Position:\n";                  << 1132      G4cout << "Position:"  << G4endl << G4endl ;
766     message << "   p.x() = " << p.x()/mm << "  << 1133      G4cout << "p.x() = "   << p.x()/mm << " mm" << G4endl ;
767     message << "   p.y() = " << p.y()/mm << "  << 1134      G4cout << "p.y() = "   << p.y()/mm << " mm" << G4endl ;
768     message << "   p.z() = " << p.z()/mm << "  << 1135      G4cout << "p.z() = "   << p.z()/mm << " mm" << G4endl << G4endl ;
769     G4cout.precision(oldprc) ;                 << 1136      G4cout.precision(oldprc) ;
770     G4Exception("G4Para::DistanceToOut(p)", "G << 1137      G4Exception("G4Para::DistanceToOut(p)", "GeomSolids1002",
771                 JustWarning, message );        << 1138                  JustWarning, "Point p is outside !?" );
772     DumpInfo();                                << 1139   }
773     }                                          << 
774 #endif                                            1140 #endif
775   G4double xx = fPlanes[2].a*p.x()+fPlanes[2]. << 
776   G4double dx = std::abs(xx) + fPlanes[2].d;   << 
777                                                   1141 
778   G4double yy = fPlanes[0].b*p.y()+fPlanes[0]. << 1142   // Z planes
779   G4double dy = std::abs(yy) + fPlanes[0].d;   << 1143   //
780   G4double dxy = std::max(dx,dy);              << 1144   distz1=fDz-p.z();
                                                   >> 1145   distz2=fDz+p.z();
                                                   >> 1146   if (distz1<distz2)
                                                   >> 1147   {
                                                   >> 1148     safe=distz1;
                                                   >> 1149   }
                                                   >> 1150   else
                                                   >> 1151   {
                                                   >> 1152     safe=distz2;
                                                   >> 1153   }
                                                   >> 1154 
                                                   >> 1155   trany=p.y()-fTthetaSphi*p.z(); // Transformed y into `box' system
781                                                   1156 
782   G4double dz = std::abs(p.z())-fDz;           << 1157   // Transformed x into `box' system
783   G4double dist = std::max(dxy,dz);            << 1158   //
                                                   >> 1159   cosy=1.0/std::sqrt(1.0+fTthetaSphi*fTthetaSphi);
                                                   >> 1160   disty1=(fDy-trany)*cosy;
                                                   >> 1161   disty2=(fDy+trany)*cosy;
                                                   >> 1162     
                                                   >> 1163   if (disty1<safe) safe=disty1;
                                                   >> 1164   if (disty2<safe) safe=disty2;
784                                                   1165 
785   return (dist < 0) ? -dist : 0.;              << 1166   tranx=p.x()-fTthetaCphi*p.z()-fTalpha*trany;
                                                   >> 1167   cosx=1.0/std::sqrt(1.0+fTalpha*fTalpha+fTthetaCphi*fTthetaCphi);
                                                   >> 1168   distx1=(fDx-tranx)*cosx;
                                                   >> 1169   distx2=(fDx+tranx)*cosx;
                                                   >> 1170     
                                                   >> 1171   if (distx1<safe) safe=distx1;
                                                   >> 1172   if (distx2<safe) safe=distx2;
                                                   >> 1173     
                                                   >> 1174   if (safe<0) safe=0;
                                                   >> 1175   return safe;  
786 }                                                 1176 }
787                                                   1177 
788 ////////////////////////////////////////////// << 1178 ////////////////////////////////////////////////////////////////////////////////
789 //                                                1179 //
790 // GetEntityType                               << 1180 // Create a List containing the transformed vertices
791                                                << 1181 // Ordering [0-3] -fDz cross section
792 G4GeometryType G4Para::GetEntityType() const   << 1182 //          [4-7] +fDz cross section such that [0] is below [4],
793 {                                              << 1183 //                                             [1] below [5] etc.
794   return {"G4Para"};                           << 1184 // Note:
                                                   >> 1185 //  Caller has deletion resposibility
                                                   >> 1186 
                                                   >> 1187 G4ThreeVectorList*
                                                   >> 1188 G4Para::CreateRotatedVertices( const G4AffineTransform& pTransform ) const
                                                   >> 1189 {
                                                   >> 1190   G4ThreeVectorList *vertices;
                                                   >> 1191   vertices=new G4ThreeVectorList();
                                                   >> 1192   if (vertices)
                                                   >> 1193   {
                                                   >> 1194     vertices->reserve(8);
                                                   >> 1195     G4ThreeVector vertex0(-fDz*fTthetaCphi-fDy*fTalpha-fDx,
                                                   >> 1196                           -fDz*fTthetaSphi-fDy, -fDz);
                                                   >> 1197     G4ThreeVector vertex1(-fDz*fTthetaCphi-fDy*fTalpha+fDx,
                                                   >> 1198                           -fDz*fTthetaSphi-fDy, -fDz);
                                                   >> 1199     G4ThreeVector vertex2(-fDz*fTthetaCphi+fDy*fTalpha-fDx,
                                                   >> 1200                           -fDz*fTthetaSphi+fDy, -fDz);
                                                   >> 1201     G4ThreeVector vertex3(-fDz*fTthetaCphi+fDy*fTalpha+fDx,
                                                   >> 1202                           -fDz*fTthetaSphi+fDy, -fDz);
                                                   >> 1203     G4ThreeVector vertex4(+fDz*fTthetaCphi-fDy*fTalpha-fDx,
                                                   >> 1204                           +fDz*fTthetaSphi-fDy, +fDz);
                                                   >> 1205     G4ThreeVector vertex5(+fDz*fTthetaCphi-fDy*fTalpha+fDx,
                                                   >> 1206                           +fDz*fTthetaSphi-fDy, +fDz);
                                                   >> 1207     G4ThreeVector vertex6(+fDz*fTthetaCphi+fDy*fTalpha-fDx,
                                                   >> 1208                           +fDz*fTthetaSphi+fDy, +fDz);
                                                   >> 1209     G4ThreeVector vertex7(+fDz*fTthetaCphi+fDy*fTalpha+fDx,
                                                   >> 1210                           +fDz*fTthetaSphi+fDy, +fDz);
                                                   >> 1211 
                                                   >> 1212     vertices->push_back(pTransform.TransformPoint(vertex0));
                                                   >> 1213     vertices->push_back(pTransform.TransformPoint(vertex1));
                                                   >> 1214     vertices->push_back(pTransform.TransformPoint(vertex2));
                                                   >> 1215     vertices->push_back(pTransform.TransformPoint(vertex3));
                                                   >> 1216     vertices->push_back(pTransform.TransformPoint(vertex4));
                                                   >> 1217     vertices->push_back(pTransform.TransformPoint(vertex5));
                                                   >> 1218     vertices->push_back(pTransform.TransformPoint(vertex6));
                                                   >> 1219     vertices->push_back(pTransform.TransformPoint(vertex7));
                                                   >> 1220   }
                                                   >> 1221   else
                                                   >> 1222   {
                                                   >> 1223     DumpInfo();
                                                   >> 1224     G4Exception("G4Para::CreateRotatedVertices()",
                                                   >> 1225                 "GeomSolids0003", FatalException,
                                                   >> 1226                 "Error in allocation of vertices. Out of memory !");
                                                   >> 1227   }
                                                   >> 1228   return vertices;
795 }                                                 1229 }
796                                                   1230 
797 //////////////////////////////////////////////    1231 //////////////////////////////////////////////////////////////////////////
798 //                                                1232 //
799 // IsFaceted                                   << 1233 // GetEntityType
800                                                   1234 
801 G4bool G4Para::IsFaceted() const               << 1235 G4GeometryType G4Para::GetEntityType() const
802 {                                                 1236 {
803   return true;                                 << 1237   return G4String("G4Para");
804 }                                                 1238 }
805                                                   1239 
806 //////////////////////////////////////////////    1240 //////////////////////////////////////////////////////////////////////////
807 //                                                1241 //
808 // Make a clone of the object                     1242 // Make a clone of the object
809 //                                                1243 //
810 G4VSolid* G4Para::Clone() const                   1244 G4VSolid* G4Para::Clone() const
811 {                                                 1245 {
812   return new G4Para(*this);                       1246   return new G4Para(*this);
813 }                                                 1247 }
814                                                   1248 
815 //////////////////////////////////////////////    1249 //////////////////////////////////////////////////////////////////////////
816 //                                                1250 //
817 // Stream object contents to an output stream     1251 // Stream object contents to an output stream
818                                                   1252 
819 std::ostream& G4Para::StreamInfo( std::ostream    1253 std::ostream& G4Para::StreamInfo( std::ostream& os ) const
820 {                                                 1254 {
821   G4double alpha = std::atan(fTalpha);         << 1255   G4int oldprc = os.precision(16);
822   G4double theta = std::atan(std::sqrt(fTtheta << 
823                                        fTtheta << 
824   G4double phi   = std::atan2(fTthetaSphi,fTth << 
825                                                << 
826   G4long oldprc = os.precision(16);            << 
827   os << "-------------------------------------    1256   os << "-----------------------------------------------------------\n"
828      << "    *** Dump for solid - " << GetName    1257      << "    *** Dump for solid - " << GetName() << " ***\n"
829      << "    =================================    1258      << "    ===================================================\n"
830      << " Solid type: G4Para\n"                   1259      << " Solid type: G4Para\n"
831      << " Parameters:\n"                       << 1260      << " Parameters: \n"
832      << "    half length X: " << fDx/mm << " m << 1261      << "    half length X: " << fDx/mm << " mm \n"
833      << "    half length Y: " << fDy/mm << " m << 1262      << "    half length Y: " << fDy/mm << " mm \n"
834      << "    half length Z: " << fDz/mm << " m << 1263      << "    half length Z: " << fDz/mm << " mm \n"
835      << "    alpha: " << alpha/degree << "degr << 1264      << "    std::tan(alpha)         : " << fTalpha/degree << " degrees \n"
836      << "    theta: " << theta/degree << "degr << 1265      << "    std::tan(theta)*std::cos(phi): " << fTthetaCphi/degree
837      << "    phi: " << phi/degree << "degrees\ << 1266      << " degrees \n"
                                                   >> 1267      << "    std::tan(theta)*std::sin(phi): " << fTthetaSphi/degree
                                                   >> 1268      << " degrees \n"
838      << "-------------------------------------    1269      << "-----------------------------------------------------------\n";
839   os.precision(oldprc);                           1270   os.precision(oldprc);
840                                                   1271 
841   return os;                                      1272   return os;
842 }                                                 1273 }
843                                                   1274 
844 ////////////////////////////////////////////// << 1275 //////////////////////////////////////////////////////////////////////////////
                                                   >> 1276 //
                                                   >> 1277 // GetPointOnPlane
                                                   >> 1278 // Auxiliary method for Get Point on Surface
845 //                                                1279 //
846 // Return a point randomly and uniformly selec << 
847                                                   1280 
848 G4ThreeVector G4Para::GetPointOnSurface() cons << 1281 G4ThreeVector G4Para::GetPointOnPlane(G4ThreeVector p0, G4ThreeVector p1, 
                                                   >> 1282                                       G4ThreeVector p2, G4ThreeVector p3, 
                                                   >> 1283                                       G4double& area) const
849 {                                                 1284 {
850   G4double DyTalpha = fDy*fTalpha;             << 1285   G4double lambda1, lambda2, chose, aOne, aTwo;
851   G4double DzTthetaSphi = fDz*fTthetaSphi;     << 1286   G4ThreeVector t, u, v, w, Area, normal;
852   G4double DzTthetaCphi = fDz*fTthetaCphi;     << 
853                                                << 
854   // Set vertices                              << 
855   //                                           << 
856   G4ThreeVector pt[8];                         << 
857   pt[0].set(-DzTthetaCphi-DyTalpha-fDx, -DzTth << 
858   pt[1].set(-DzTthetaCphi-DyTalpha+fDx, -DzTth << 
859   pt[2].set(-DzTthetaCphi+DyTalpha-fDx, -DzTth << 
860   pt[3].set(-DzTthetaCphi+DyTalpha+fDx, -DzTth << 
861   pt[4].set( DzTthetaCphi-DyTalpha-fDx,  DzTth << 
862   pt[5].set( DzTthetaCphi-DyTalpha+fDx,  DzTth << 
863   pt[6].set( DzTthetaCphi+DyTalpha-fDx,  DzTth << 
864   pt[7].set( DzTthetaCphi+DyTalpha+fDx,  DzTth << 
865                                                << 
866   // Set areas (-Z, -Y, +Y, -X, +X, +Z)        << 
867   //                                           << 
868   G4ThreeVector vx(fDx, 0, 0);                 << 
869   G4ThreeVector vy(DyTalpha, fDy, 0);          << 
870   G4ThreeVector vz(DzTthetaCphi, DzTthetaSphi, << 
871                                                << 
872   G4double sxy = fDx*fDy; // (vx.cross(vy)).ma << 
873   G4double sxz = (vx.cross(vz)).mag();         << 
874   G4double syz = (vy.cross(vz)).mag();         << 
875                                                   1287   
876   G4double sface[6] = { sxy, syz, syz, sxz, sx << 1288   t = p1 - p0;
877   for (G4int i=1; i<6; ++i) { sface[i] += sfac << 1289   u = p2 - p1;
                                                   >> 1290   v = p3 - p2;
                                                   >> 1291   w = p0 - p3;
                                                   >> 1292 
                                                   >> 1293   Area = G4ThreeVector(w.y()*v.z() - w.z()*v.y(),
                                                   >> 1294                        w.z()*v.x() - w.x()*v.z(),
                                                   >> 1295                        w.x()*v.y() - w.y()*v.x());
                                                   >> 1296   
                                                   >> 1297   aOne = 0.5*Area.mag();
                                                   >> 1298   
                                                   >> 1299   Area = G4ThreeVector(t.y()*u.z() - t.z()*u.y(),
                                                   >> 1300                        t.z()*u.x() - t.x()*u.z(),
                                                   >> 1301                        t.x()*u.y() - t.y()*u.x());
                                                   >> 1302   
                                                   >> 1303   aTwo = 0.5*Area.mag();
                                                   >> 1304   
                                                   >> 1305   area = aOne + aTwo;
                                                   >> 1306   
                                                   >> 1307   chose = RandFlat::shoot(0.,aOne+aTwo);
878                                                   1308 
879   // Select face                               << 1309   if( (chose>=0.) && (chose < aOne) )
880   //                                           << 1310   {
881   G4double select = sface[5]*G4UniformRand();  << 1311     lambda1 = RandFlat::shoot(0.,1.);
882   G4int k = 5;                                 << 1312     lambda2 = RandFlat::shoot(0.,lambda1);
883   if (select <= sface[4]) k = 4;               << 1313     return (p2+lambda1*v+lambda2*w);    
884   if (select <= sface[3]) k = 3;               << 1314   }
885   if (select <= sface[2]) k = 2;               << 1315 
886   if (select <= sface[1]) k = 1;               << 1316   // else
887   if (select <= sface[0]) k = 0;               << 1317 
888                                                << 1318   lambda1 = RandFlat::shoot(0.,1.);
889   // Generate point                            << 1319   lambda2 = RandFlat::shoot(0.,lambda1);
890   //                                           << 1320   return (p0+lambda1*t+lambda2*u);    
891   G4int ip[6][3] = {{0,1,2}, {0,4,1}, {2,3,6}, << 
892   G4double u = G4UniformRand();                << 
893   G4double v = G4UniformRand();                << 
894   return (1.-u-v)*pt[ip[k][0]] + u*pt[ip[k][1] << 
895 }                                                 1321 }
896                                                   1322 
897 ////////////////////////////////////////////// << 1323 /////////////////////////////////////////////////////////////////////////
                                                   >> 1324 //
                                                   >> 1325 // GetPointOnSurface
                                                   >> 1326 //
                                                   >> 1327 // Return a point (G4ThreeVector) randomly and uniformly
                                                   >> 1328 // selected on the solid surface
                                                   >> 1329 
                                                   >> 1330 G4ThreeVector G4Para::GetPointOnSurface() const
                                                   >> 1331 {
                                                   >> 1332   G4ThreeVector One, Two, Three, Four, Five, Six;
                                                   >> 1333   G4ThreeVector pt[8] ;
                                                   >> 1334   G4double chose, aOne, aTwo, aThree, aFour, aFive, aSix;
                                                   >> 1335 
                                                   >> 1336   pt[0] = G4ThreeVector(-fDz*fTthetaCphi-fDy*fTalpha-fDx,
                                                   >> 1337                         -fDz*fTthetaSphi-fDy, -fDz);
                                                   >> 1338   pt[1] = G4ThreeVector(-fDz*fTthetaCphi-fDy*fTalpha+fDx,
                                                   >> 1339                         -fDz*fTthetaSphi-fDy, -fDz);
                                                   >> 1340   pt[2] = G4ThreeVector(-fDz*fTthetaCphi+fDy*fTalpha-fDx,
                                                   >> 1341                         -fDz*fTthetaSphi+fDy, -fDz);
                                                   >> 1342   pt[3] = G4ThreeVector(-fDz*fTthetaCphi+fDy*fTalpha+fDx,
                                                   >> 1343                         -fDz*fTthetaSphi+fDy, -fDz);
                                                   >> 1344   pt[4] = G4ThreeVector(+fDz*fTthetaCphi-fDy*fTalpha-fDx,
                                                   >> 1345                         +fDz*fTthetaSphi-fDy, +fDz);
                                                   >> 1346   pt[5] = G4ThreeVector(+fDz*fTthetaCphi-fDy*fTalpha+fDx,
                                                   >> 1347                         +fDz*fTthetaSphi-fDy, +fDz);
                                                   >> 1348   pt[6] = G4ThreeVector(+fDz*fTthetaCphi+fDy*fTalpha-fDx,
                                                   >> 1349                         +fDz*fTthetaSphi+fDy, +fDz);
                                                   >> 1350   pt[7] = G4ThreeVector(+fDz*fTthetaCphi+fDy*fTalpha+fDx,
                                                   >> 1351                         +fDz*fTthetaSphi+fDy, +fDz);
                                                   >> 1352 
                                                   >> 1353   // make sure we provide the points in a clockwise fashion
                                                   >> 1354 
                                                   >> 1355   One   = GetPointOnPlane(pt[0],pt[1],pt[3],pt[2], aOne);
                                                   >> 1356   Two   = GetPointOnPlane(pt[4],pt[5],pt[7],pt[6], aTwo);
                                                   >> 1357   Three = GetPointOnPlane(pt[6],pt[7],pt[3],pt[2], aThree);
                                                   >> 1358   Four  = GetPointOnPlane(pt[4],pt[5],pt[1],pt[0], aFour); 
                                                   >> 1359   Five  = GetPointOnPlane(pt[0],pt[2],pt[6],pt[4], aFive);
                                                   >> 1360   Six   = GetPointOnPlane(pt[1],pt[3],pt[7],pt[5], aSix);
                                                   >> 1361 
                                                   >> 1362   chose = RandFlat::shoot(0.,aOne+aTwo+aThree+aFour+aFive+aSix);
                                                   >> 1363   
                                                   >> 1364   if( (chose>=0.) && (chose<aOne) )                    
                                                   >> 1365     { return One; }
                                                   >> 1366   else if(chose>=aOne && chose<aOne+aTwo)  
                                                   >> 1367     { return Two; }
                                                   >> 1368   else if(chose>=aOne+aTwo && chose<aOne+aTwo+aThree)
                                                   >> 1369     { return Three; }
                                                   >> 1370   else if(chose>=aOne+aTwo+aThree && chose<aOne+aTwo+aThree+aFour)
                                                   >> 1371     { return Four; }
                                                   >> 1372   else if(chose>=aOne+aTwo+aThree+aFour && chose<aOne+aTwo+aThree+aFour+aFive)
                                                   >> 1373     { return Five; }
                                                   >> 1374   return Six;
                                                   >> 1375 }
                                                   >> 1376 
                                                   >> 1377 ////////////////////////////////////////////////////////////////////////////
898 //                                                1378 //
899 // Methods for visualisation                      1379 // Methods for visualisation
900                                                   1380 
901 void G4Para::DescribeYourselfTo ( G4VGraphicsS    1381 void G4Para::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
902 {                                                 1382 {
903   scene.AddSolid (*this);                         1383   scene.AddSolid (*this);
904 }                                                 1384 }
905                                                   1385 
906 G4Polyhedron* G4Para::CreatePolyhedron () cons    1386 G4Polyhedron* G4Para::CreatePolyhedron () const
907 {                                                 1387 {
908   G4double phi = std::atan2(fTthetaSphi, fTthe    1388   G4double phi = std::atan2(fTthetaSphi, fTthetaCphi);
909   G4double alpha = std::atan(fTalpha);            1389   G4double alpha = std::atan(fTalpha);
910   G4double theta = std::atan(std::sqrt(fTtheta << 1390   G4double theta = std::atan(std::sqrt(fTthetaCphi*fTthetaCphi
911                                        fTtheta << 1391                             +fTthetaSphi*fTthetaSphi));
912                                                   1392     
913   return new G4PolyhedronPara(fDx, fDy, fDz, a    1393   return new G4PolyhedronPara(fDx, fDy, fDz, alpha, theta, phi);
914 }                                                 1394 }
915 #endif                                         << 1395 
                                                   >> 1396 G4NURBS* G4Para::CreateNURBS () const
                                                   >> 1397 {
                                                   >> 1398   // return new G4NURBSbox (fDx, fDy, fDz);
                                                   >> 1399   return 0 ;
                                                   >> 1400 }
916                                                   1401