Import Geant4 10.7.0 source tree
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
#include "G4VoxelLimits.hh"
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
@@ -140,13 +140,13 @@ void G4Box::SetXHalfLength(G4double dx)
|
||||
fCubicVolume = 0.;
|
||||
fSurfaceArea = 0.;
|
||||
fRebuildPolyhedron = true;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set Y dimension
|
||||
|
||||
void G4Box::SetYHalfLength(G4double dy)
|
||||
void G4Box::SetYHalfLength(G4double dy)
|
||||
{
|
||||
if(dy > 2*kCarTolerance) // limit to thickness of surfaces
|
||||
{
|
||||
@@ -163,7 +163,7 @@ void G4Box::SetYHalfLength(G4double dy)
|
||||
fCubicVolume = 0.;
|
||||
fSurfaceArea = 0.;
|
||||
fRebuildPolyhedron = true;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -186,7 +186,7 @@ void G4Box::SetZHalfLength(G4double dz)
|
||||
fCubicVolume = 0.;
|
||||
fSurfaceArea = 0.;
|
||||
fRebuildPolyhedron = true;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -252,8 +252,8 @@ EInside G4Box::Inside(const G4ThreeVector& p) const
|
||||
std::abs(p.x())-fDx,
|
||||
std::abs(p.y())-fDy),
|
||||
std::abs(p.z())-fDz);
|
||||
if (dist > delta) return kOutside;
|
||||
return (dist > -delta) ? kSurface : kInside;
|
||||
return (dist > delta) ? kOutside :
|
||||
((dist > -delta) ? kSurface : kInside);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -278,7 +278,7 @@ G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
|
||||
else
|
||||
{
|
||||
// Point is not on the surface
|
||||
//
|
||||
//
|
||||
#ifdef G4CSGDEBUG
|
||||
std::ostringstream message;
|
||||
G4int oldprc = message.precision(16);
|
||||
@@ -353,7 +353,7 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// Appoximate distance to box.
|
||||
// Returns largest perpendicular distance to the closest x/y/z sides of
|
||||
// the box, which is the most fast estimation of the shortest distance to box
|
||||
@@ -361,9 +361,10 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,
|
||||
|
||||
G4double G4Box::DistanceToIn(const G4ThreeVector& p) const
|
||||
{
|
||||
G4double dist = std::max(std::max(std::abs(p.x())-fDx,
|
||||
std::abs(p.y())-fDy),
|
||||
std::abs(p.z())-fDz);
|
||||
G4double dist = std::max(std::max(
|
||||
std::abs(p.x())-fDx,
|
||||
std::abs(p.y())-fDy),
|
||||
std::abs(p.z())-fDz);
|
||||
return (dist > 0) ? dist : 0.;
|
||||
}
|
||||
|
||||
@@ -456,9 +457,10 @@ G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
|
||||
DumpInfo();
|
||||
}
|
||||
#endif
|
||||
G4double dist = std::min(std::min(fDx-std::abs(p.x()),
|
||||
fDy-std::abs(p.y())),
|
||||
fDz-std::abs(p.z()));
|
||||
G4double dist = std::min(std::min(
|
||||
fDx-std::abs(p.x()),
|
||||
fDy-std::abs(p.y())),
|
||||
fDz-std::abs(p.z()));
|
||||
return (dist > 0) ? dist : 0.;
|
||||
}
|
||||
|
||||
@@ -493,29 +495,27 @@ std::ostream& G4Box::StreamInfo(std::ostream& os) const
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GetPointOnSurface
|
||||
//
|
||||
// Return a point (G4ThreeVector) randomly and uniformly selected
|
||||
// on the solid surface
|
||||
// Return a point randomly and uniformly selected on the surface
|
||||
|
||||
G4ThreeVector G4Box::GetPointOnSurface() const
|
||||
{
|
||||
G4double sxy = fDx*fDy, sxz = fDx*fDz, syz = fDy*fDz;
|
||||
G4double select = (sxy + sxz + syz)*G4UniformRand();
|
||||
G4double select = (sxy + sxz + syz)*G4QuickRand();
|
||||
G4double u = 2.*G4QuickRand() - 1.;
|
||||
G4double v = 2.*G4QuickRand() - 1.;
|
||||
|
||||
if (select < sxy)
|
||||
return G4ThreeVector((2.*G4UniformRand() - 1.)*fDx,
|
||||
(2.*G4UniformRand() - 1.)*fDy,
|
||||
(select < 0.5*sxy) ? -fDz : fDz);
|
||||
|
||||
if (select < sxy + sxz)
|
||||
return G4ThreeVector((2.*G4UniformRand() - 1.)*fDx,
|
||||
(select < sxy + 0.5*sxz) ? -fDy : fDy,
|
||||
(2.*G4UniformRand() - 1.)*fDz);
|
||||
return G4ThreeVector(u*fDx,
|
||||
v*fDy,
|
||||
((select < 0.5*sxy) ? -fDz : fDz));
|
||||
else if (select < sxy + sxz)
|
||||
return G4ThreeVector(u*fDx,
|
||||
((select < sxy + 0.5*sxz) ? -fDy : fDy),
|
||||
v*fDz);
|
||||
else
|
||||
return G4ThreeVector((select < sxy + sxz + 0.5*syz) ? -fDx : fDx,
|
||||
(2.*G4UniformRand() - 1.)*fDy,
|
||||
(2.*G4UniformRand() - 1.)*fDz);
|
||||
return G4ThreeVector(((select < sxy + sxz + 0.5*syz) ? -fDx : fDx),
|
||||
u*fDy,
|
||||
v*fDz);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "G4CSGSolid.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4RandomTools.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
@@ -45,7 +44,7 @@ namespace
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor
|
||||
// - Base class constructor
|
||||
// - Base class constructor
|
||||
|
||||
G4CSGSolid::G4CSGSolid(const G4String& name) :
|
||||
G4VSolid(name)
|
||||
@@ -67,7 +66,7 @@ G4CSGSolid::G4CSGSolid( __void__& a )
|
||||
// Destructor
|
||||
//
|
||||
|
||||
G4CSGSolid::~G4CSGSolid()
|
||||
G4CSGSolid::~G4CSGSolid()
|
||||
{
|
||||
delete fpPolyhedron; fpPolyhedron = nullptr;
|
||||
}
|
||||
@@ -87,7 +86,7 @@ G4CSGSolid::G4CSGSolid(const G4CSGSolid& rhs)
|
||||
//
|
||||
// Assignment operator
|
||||
|
||||
G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
|
||||
G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -105,11 +104,13 @@ G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
|
||||
delete fpPolyhedron; fpPolyhedron = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4CSGSolid::GetRadiusInRing(G4double rmin, G4double rmax) const
|
||||
{
|
||||
return G4RandomRadiusInRing(rmin, rmax);
|
||||
G4double k = G4QuickRand();
|
||||
return (rmin <= 0) ? rmax*std::sqrt(k)
|
||||
: std::sqrt(k*rmax*rmax + (1. - k)*rmin*rmin);
|
||||
}
|
||||
|
||||
std::ostream& G4CSGSolid::StreamInfo(std::ostream& os) const
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,7 @@
|
||||
// 21.03.95 P.Kent: Modified for `tolerant' geometry
|
||||
// 09.09.96 V.Grichine: Final modifications before to commit
|
||||
// 08.12.97 J.Allison: Added "nominal" constructor and method SetAllParameters
|
||||
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
|
||||
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
|
||||
// 18.04.17 E.Tcherniaev: complete revision, speed-up
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4VGraphicsScene.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
@@ -54,7 +54,7 @@ using namespace CLHEP;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor - check and set half-widths as well as angles:
|
||||
// Constructor - check and set half-widths as well as angles:
|
||||
// final check of coplanarity
|
||||
|
||||
G4Trap::G4Trap( const G4String& pName,
|
||||
@@ -79,8 +79,8 @@ G4Trap::G4Trap( const G4String& pName,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor - Design of trapezoid based on 8 G4ThreeVector parameters,
|
||||
// which are its vertices. Checking of planarity with preparation of
|
||||
// Constructor - Design of trapezoid based on 8 G4ThreeVector parameters,
|
||||
// which are its vertices. Checking of planarity with preparation of
|
||||
// fPlanes[] and than calculation of other members
|
||||
|
||||
G4Trap::G4Trap( const G4String& pName,
|
||||
@@ -116,11 +116,11 @@ G4Trap::G4Trap( const G4String& pName,
|
||||
G4Exception("G4Trap::G4Trap()", "GeomSolids0002",
|
||||
FatalException, message);
|
||||
}
|
||||
|
||||
|
||||
// Set parameters
|
||||
//
|
||||
fDz = (pt[7]).z();
|
||||
|
||||
|
||||
fDy1 = ((pt[2]).y()-(pt[1]).y())*0.5;
|
||||
fDx1 = ((pt[1]).x()-(pt[0]).x())*0.5;
|
||||
fDx2 = ((pt[3]).x()-(pt[2]).x())*0.5;
|
||||
@@ -244,6 +244,7 @@ G4Trap::G4Trap(const G4Trap& rhs)
|
||||
fDy2(rhs.fDy2), fDx3(rhs.fDx3), fDx4(rhs.fDx4), fTalpha2(rhs.fTalpha2)
|
||||
{
|
||||
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
|
||||
for (G4int i=0; i<6; ++i) { fAreas[i] = rhs.fAreas[i]; }
|
||||
fTrapType = rhs.fTrapType;
|
||||
}
|
||||
|
||||
@@ -251,7 +252,7 @@ G4Trap::G4Trap(const G4Trap& rhs)
|
||||
//
|
||||
// Assignment operator
|
||||
|
||||
G4Trap& G4Trap::operator = (const G4Trap& rhs)
|
||||
G4Trap& G4Trap::operator = (const G4Trap& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -268,6 +269,7 @@ G4Trap& G4Trap::operator = (const G4Trap& rhs)
|
||||
fDy1 = rhs.fDy1; fDx1 = rhs.fDx1; fDx2 = rhs.fDx2; fTalpha1 = rhs.fTalpha1;
|
||||
fDy2 = rhs.fDy2; fDx3 = rhs.fDx3; fDx4 = rhs.fDx4; fTalpha2 = rhs.fTalpha2;
|
||||
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
|
||||
for (G4int i=0; i<6; ++i) { fAreas[i] = rhs.fAreas[i]; }
|
||||
fTrapType = rhs.fTrapType;
|
||||
return *this;
|
||||
}
|
||||
@@ -358,8 +360,8 @@ void G4Trap::MakePlanes()
|
||||
|
||||
void G4Trap::MakePlanes(const G4ThreeVector pt[8])
|
||||
{
|
||||
G4int iface[4][4] = { {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3} };
|
||||
G4String side[4] = { "~-Y", "~+Y", "~-X", "~+X" };
|
||||
constexpr G4int iface[4][4] = { {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3} };
|
||||
const static G4String side[4] = { "~-Y", "~+Y", "~-X", "~+X" };
|
||||
|
||||
for (G4int i=0; i<4; ++i)
|
||||
{
|
||||
@@ -385,6 +387,70 @@ void G4Trap::MakePlanes(const G4ThreeVector pt[8])
|
||||
FatalException, message);
|
||||
}
|
||||
|
||||
// Re-compute parameters
|
||||
SetCachedValues();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate the coef's of the plane p1->p2->p3->p4->p1
|
||||
// where the ThreeVectors 1-4 are in anti-clockwise order when viewed
|
||||
// from infront of the plane (i.e. from normal direction).
|
||||
//
|
||||
// Return true if the points are coplanar, false otherwise
|
||||
|
||||
G4bool G4Trap::MakePlane( const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3,
|
||||
const G4ThreeVector& p4,
|
||||
TrapSidePlane& plane )
|
||||
{
|
||||
G4ThreeVector normal = ((p4 - p2).cross(p3 - p1)).unit();
|
||||
if (std::abs(normal.x()) < DBL_EPSILON) normal.setX(0);
|
||||
if (std::abs(normal.y()) < DBL_EPSILON) normal.setY(0);
|
||||
if (std::abs(normal.z()) < DBL_EPSILON) normal.setZ(0);
|
||||
normal = normal.unit();
|
||||
|
||||
G4ThreeVector centre = (p1 + p2 + p3 + p4)*0.25;
|
||||
plane.a = normal.x();
|
||||
plane.b = normal.y();
|
||||
plane.c = normal.z();
|
||||
plane.d = -normal.dot(centre);
|
||||
|
||||
// compute distances and check planarity
|
||||
G4double d1 = std::abs(normal.dot(p1) + plane.d);
|
||||
G4double d2 = std::abs(normal.dot(p2) + plane.d);
|
||||
G4double d3 = std::abs(normal.dot(p3) + plane.d);
|
||||
G4double d4 = std::abs(normal.dot(p4) + plane.d);
|
||||
G4double dmax = std::max(std::max(std::max(d1,d2),d3),d4);
|
||||
|
||||
return (dmax > 1000 * kCarTolerance) ? false : true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Recompute parameters using planes
|
||||
|
||||
void G4Trap::SetCachedValues()
|
||||
{
|
||||
// Set indeces
|
||||
constexpr G4int iface[6][4] =
|
||||
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
|
||||
|
||||
// Get vertices
|
||||
G4ThreeVector pt[8];
|
||||
GetVertices(pt);
|
||||
|
||||
// Set face areas
|
||||
for (G4int i=0; i<6; ++i)
|
||||
{
|
||||
fAreas[i] = G4GeomTools::QuadAreaNormal(pt[iface[i][0]],
|
||||
pt[iface[i][1]],
|
||||
pt[iface[i][2]],
|
||||
pt[iface[i][3]]).mag();
|
||||
}
|
||||
for (G4int i=1; i<6; ++i) { fAreas[i] += fAreas[i - 1]; }
|
||||
|
||||
// Define type of trapezoid
|
||||
fTrapType = 0;
|
||||
if (fPlanes[0].b == -1 && fPlanes[1].b == 1 &&
|
||||
@@ -415,43 +481,7 @@ void G4Trap::MakePlanes(const G4ThreeVector pt[8])
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate the coef's of the plane p1->p2->p3->p4->p1
|
||||
// where the ThreeVectors 1-4 are in anti-clockwise order when viewed
|
||||
// from infront of the plane (i.e. from normal direction).
|
||||
//
|
||||
// Return true if the points are coplanar, false otherwise
|
||||
|
||||
G4bool G4Trap::MakePlane( const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3,
|
||||
const G4ThreeVector& p4,
|
||||
TrapSidePlane& plane )
|
||||
{
|
||||
G4ThreeVector normal = ((p4 - p2).cross(p3 - p1)).unit();
|
||||
if (std::abs(normal.x()) < DBL_EPSILON) normal.setX(0);
|
||||
if (std::abs(normal.y()) < DBL_EPSILON) normal.setY(0);
|
||||
if (std::abs(normal.z()) < DBL_EPSILON) normal.setZ(0);
|
||||
normal = normal.unit();
|
||||
|
||||
G4ThreeVector centre = (p1 + p2 + p3 + p4)*0.25;
|
||||
plane.a = normal.x();
|
||||
plane.b = normal.y();
|
||||
plane.c = normal.z();
|
||||
plane.d = -normal.dot(centre);
|
||||
|
||||
// compute distances and check planarity
|
||||
G4double d1 = std::abs(normal.dot(p1) + plane.d);
|
||||
G4double d2 = std::abs(normal.dot(p2) + plane.d);
|
||||
G4double d3 = std::abs(normal.dot(p3) + plane.d);
|
||||
G4double d4 = std::abs(normal.dot(p4) + plane.d);
|
||||
G4double dmax = std::max(std::max(std::max(d1,d2),d3),d4);
|
||||
|
||||
return (dmax > 1000 * kCarTolerance) ? false : true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get volume
|
||||
|
||||
@@ -461,7 +491,7 @@ G4double G4Trap::GetCubicVolume()
|
||||
{
|
||||
G4ThreeVector pt[8];
|
||||
GetVertices(pt);
|
||||
|
||||
|
||||
G4double dz = pt[4].z() - pt[0].z();
|
||||
G4double dy1 = pt[2].y() - pt[0].y();
|
||||
G4double dx1 = pt[1].x() - pt[0].x();
|
||||
@@ -476,7 +506,7 @@ G4double G4Trap::GetCubicVolume()
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get surface area
|
||||
|
||||
@@ -500,7 +530,7 @@ G4double G4Trap::GetSurfaceArea()
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dispatch to parameterisation for replication mechanism dimension
|
||||
// computation & modification.
|
||||
@@ -512,7 +542,7 @@ void G4Trap::ComputeDimensions( G4VPVParameterisation* p,
|
||||
p->ComputeDimensions(*this,n,pRep);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get bounding box
|
||||
|
||||
@@ -552,7 +582,7 @@ void G4Trap::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate extent under transform and specified limit
|
||||
|
||||
@@ -601,7 +631,7 @@ G4bool G4Trap::CalculateExtent( const EAxis pAxis,
|
||||
return exist;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return whether point is inside/outside/on_surface
|
||||
|
||||
@@ -661,10 +691,10 @@ EInside G4Trap::Inside( const G4ThreeVector& p ) const
|
||||
((dist > -halfCarTolerance) ? kSurface : kInside);
|
||||
}
|
||||
}
|
||||
return kOutside;
|
||||
return kOutside;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Determine side, and return corresponding normal
|
||||
|
||||
@@ -765,7 +795,7 @@ G4ThreeVector G4Trap::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Algorithm for SurfaceNormal() following the original specification
|
||||
// for points not on the surface
|
||||
@@ -789,7 +819,7 @@ G4ThreeVector G4Trap::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
return G4ThreeVector(0, 0, (p.z() < 0) ? -1 : 1);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate distance to shape from outside
|
||||
// - return kInfinity if no intersection
|
||||
@@ -802,7 +832,7 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
|
||||
if ((std::abs(p.z()) - fDz) >= -halfCarTolerance && p.z()*v.z() >= 0)
|
||||
return kInfinity;
|
||||
G4double invz = (-v.z() == 0) ? DBL_MAX : -1./v.z();
|
||||
G4double dz = (invz < 0) ? fDz : -fDz;
|
||||
G4double dz = (invz < 0) ? fDz : -fDz;
|
||||
G4double tzmin = (p.z() + dz)*invz;
|
||||
G4double tzmax = (p.z() - dz)*invz;
|
||||
|
||||
@@ -811,7 +841,7 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
|
||||
G4double tymin = 0, tymax = DBL_MAX;
|
||||
G4int i = 0;
|
||||
for ( ; i<2; ++i)
|
||||
{
|
||||
{
|
||||
G4double cosa = fPlanes[i].b*v.y() + fPlanes[i].c*v.z();
|
||||
G4double dist = fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
|
||||
if (dist >= -halfCarTolerance)
|
||||
@@ -824,14 +854,14 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
|
||||
{
|
||||
G4double tmp = -dist/cosa;
|
||||
if (tymax > tmp) tymax = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Z intersections
|
||||
//
|
||||
G4double txmin = 0, txmax = DBL_MAX;
|
||||
for ( ; i<4; ++i)
|
||||
{
|
||||
{
|
||||
G4double cosa = fPlanes[i].a*v.x()+fPlanes[i].b*v.y()+fPlanes[i].c*v.z();
|
||||
G4double dist = fPlanes[i].a*p.x()+fPlanes[i].b*p.y()+fPlanes[i].c*p.z() +
|
||||
fPlanes[i].d;
|
||||
@@ -845,19 +875,19 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
|
||||
{
|
||||
G4double tmp = -dist/cosa;
|
||||
if (txmax > tmp) txmax = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find distance
|
||||
//
|
||||
G4double tmin = std::max(std::max(txmin,tymin),tzmin);
|
||||
G4double tmax = std::min(std::min(txmax,tymax),tzmax);
|
||||
|
||||
|
||||
if (tmax <= tmin + halfCarTolerance) return kInfinity; // touch or no hit
|
||||
return (tmin < halfCarTolerance ) ? 0. : tmin;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate exact shortest distance to any boundary from outside
|
||||
// This is the best fast estimation of the shortest distance to trap
|
||||
@@ -914,7 +944,7 @@ G4double G4Trap::DistanceToIn( const G4ThreeVector& p ) const
|
||||
return 0.;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate distance to surface of shape from inside and
|
||||
// find normal at exit point, if required
|
||||
@@ -987,7 +1017,7 @@ G4double G4Trap::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
|
||||
|
||||
// Set normal, if required, and return distance
|
||||
//
|
||||
if (calcNorm)
|
||||
if (calcNorm)
|
||||
{
|
||||
*validNorm = true;
|
||||
if (iside < 0)
|
||||
@@ -998,7 +1028,7 @@ G4double G4Trap::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
|
||||
return tmax;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate exact shortest distance to any boundary from inside
|
||||
// - Returns 0 is ThreeVector outside
|
||||
@@ -1015,7 +1045,7 @@ G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
|
||||
message << " p.x() = " << p.x()/mm << " mm\n";
|
||||
message << " p.y() = " << p.y()/mm << " mm\n";
|
||||
message << " p.z() = " << p.z()/mm << " mm";
|
||||
G4cout.precision(oldprc) ;
|
||||
G4cout.precision(oldprc);
|
||||
G4Exception("G4Trap::DistanceToOut(p)", "GeomSolids1002",
|
||||
JustWarning, message );
|
||||
DumpInfo();
|
||||
@@ -1070,7 +1100,7 @@ G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
|
||||
return 0.;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GetEntityType
|
||||
|
||||
@@ -1099,7 +1129,7 @@ std::ostream& G4Trap::StreamInfo( std::ostream& os ) const
|
||||
+fTthetaSphi*fTthetaSphi));
|
||||
G4double alpha1 = std::atan(fTalpha1);
|
||||
G4double alpha2 = std::atan(fTalpha2);
|
||||
G4String signDegree = "\u00B0";
|
||||
G4String signDegree = "\u00B0";
|
||||
|
||||
G4int oldprc = os.precision(16);
|
||||
os << "-----------------------------------------------------------\n"
|
||||
@@ -1142,38 +1172,29 @@ void G4Trap::GetVertices(G4ThreeVector pt[8]) const
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generate random point on the surface
|
||||
|
||||
G4ThreeVector G4Trap::GetPointOnSurface() const
|
||||
{
|
||||
G4ThreeVector pt[8];
|
||||
G4int iface [6][4] =
|
||||
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
|
||||
G4double sface[6];
|
||||
// Set indeces
|
||||
constexpr G4int iface [6][4] =
|
||||
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
|
||||
|
||||
// Set vertices
|
||||
G4ThreeVector pt[8];
|
||||
GetVertices(pt);
|
||||
G4double stotal = 0;
|
||||
for (G4int i=0; i<6; ++i)
|
||||
{
|
||||
G4double ss = G4GeomTools::QuadAreaNormal(pt[iface[i][0]],
|
||||
pt[iface[i][1]],
|
||||
pt[iface[i][2]],
|
||||
pt[iface[i][3]]).mag();
|
||||
stotal += ss;
|
||||
sface[i] = stotal;
|
||||
}
|
||||
|
||||
// Select face
|
||||
//
|
||||
G4double select = stotal*G4UniformRand();
|
||||
G4double select = fAreas[5]*G4QuickRand();
|
||||
G4int k = 5;
|
||||
if (select <= sface[4]) k = 4;
|
||||
if (select <= sface[3]) k = 3;
|
||||
if (select <= sface[2]) k = 2;
|
||||
if (select <= sface[1]) k = 1;
|
||||
if (select <= sface[0]) k = 0;
|
||||
k -= (select <= fAreas[4]);
|
||||
k -= (select <= fAreas[3]);
|
||||
k -= (select <= fAreas[2]);
|
||||
k -= (select <= fAreas[1]);
|
||||
k -= (select <= fAreas[0]);
|
||||
|
||||
// Select sub-triangle
|
||||
//
|
||||
@@ -1181,14 +1202,13 @@ G4ThreeVector G4Trap::GetPointOnSurface() const
|
||||
G4int i1 = iface[k][1];
|
||||
G4int i2 = iface[k][2];
|
||||
G4int i3 = iface[k][3];
|
||||
G4double s1 = G4GeomTools::TriangleAreaNormal(pt[i0],pt[i1],pt[i3]).mag();
|
||||
G4double s2 = G4GeomTools::TriangleAreaNormal(pt[i2],pt[i1],pt[i3]).mag();
|
||||
if ((s1+s2)*G4UniformRand() > s1) i0 = i2;
|
||||
if (select > fAreas[k] - s2) i0 = i2;
|
||||
|
||||
// Generate point
|
||||
//
|
||||
G4double u = G4UniformRand();
|
||||
G4double v = G4UniformRand();
|
||||
G4double u = G4QuickRand();
|
||||
G4double v = G4QuickRand();
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
return (1.-u-v)*pt[i0] + u*pt[i1] + v*pt[i3];
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
// Implementation for G4Trd class
|
||||
//
|
||||
// 12.01.95 P.Kent: First version
|
||||
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
|
||||
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
|
||||
// 25.05.17 E.Tcherniaev: complete revision, speed-up
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "G4VoxelLimits.hh"
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
@@ -89,7 +89,8 @@ G4Trd::~G4Trd()
|
||||
G4Trd::G4Trd(const G4Trd& rhs)
|
||||
: G4CSGSolid(rhs), halfCarTolerance(rhs.halfCarTolerance),
|
||||
fDx1(rhs.fDx1), fDx2(rhs.fDx2),
|
||||
fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz)
|
||||
fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz),
|
||||
fHx(rhs.fHx), fHy(rhs.fHy)
|
||||
{
|
||||
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
|
||||
}
|
||||
@@ -114,6 +115,7 @@ G4Trd& G4Trd::operator = (const G4Trd& rhs)
|
||||
fDx1 = rhs.fDx1; fDx2 = rhs.fDx2;
|
||||
fDy1 = rhs.fDy1; fDy2 = rhs.fDy2;
|
||||
fDz = rhs.fDz;
|
||||
fHx = rhs.fHx; fHy = rhs.fHy;
|
||||
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
|
||||
|
||||
return *this;
|
||||
@@ -171,14 +173,14 @@ void G4Trd::MakePlanes()
|
||||
G4double dx = fDx1 - fDx2;
|
||||
G4double dy = fDy1 - fDy2;
|
||||
G4double dz = 2*fDz;
|
||||
G4double magx = std::sqrt(dx*dx + dz*dz);
|
||||
G4double magy = std::sqrt(dy*dy + dz*dz);
|
||||
fHx = std::sqrt(dy*dy + dz*dz);
|
||||
fHy = std::sqrt(dx*dx + dz*dz);
|
||||
|
||||
// Set -Y & +Y planes
|
||||
// Set X planes at -Y & +Y
|
||||
//
|
||||
fPlanes[0].a = 0.;
|
||||
fPlanes[0].b = -dz/magy;
|
||||
fPlanes[0].c = dy/magy;
|
||||
fPlanes[0].b = -dz/fHx;
|
||||
fPlanes[0].c = dy/fHx;
|
||||
fPlanes[0].d = fPlanes[0].b*fDy1 + fPlanes[0].c*fDz;
|
||||
|
||||
fPlanes[1].a = fPlanes[0].a;
|
||||
@@ -186,11 +188,11 @@ void G4Trd::MakePlanes()
|
||||
fPlanes[1].c = fPlanes[0].c;
|
||||
fPlanes[1].d = fPlanes[0].d;
|
||||
|
||||
// Set -X & +X planes
|
||||
// Set Y planes at -X & +X
|
||||
//
|
||||
fPlanes[2].a = -dz/magx;
|
||||
fPlanes[2].a = -dz/fHy;
|
||||
fPlanes[2].b = 0.;
|
||||
fPlanes[2].c = dx/magx;
|
||||
fPlanes[2].c = dx/fHy;
|
||||
fPlanes[2].d = fPlanes[2].a*fDx1 + fPlanes[2].c*fDz;
|
||||
|
||||
fPlanes[3].a = -fPlanes[2].a;
|
||||
@@ -222,9 +224,7 @@ G4double G4Trd::GetSurfaceArea()
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
fSurfaceArea =
|
||||
4*(fDx1*fDy1+fDx2*fDy2) +
|
||||
2*(fDy1+fDy2)*std::hypot(fDx1-fDx2,2*fDz) +
|
||||
2*(fDx1+fDx2)*std::hypot(fDy1-fDy2,2*fDz);
|
||||
4*(fDx1*fDy1 + fDx2*fDy2) + 2*(fDx1+fDx2)*fHx + 2*(fDy1+fDy2)*fHy;
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
@@ -328,7 +328,7 @@ G4bool G4Trd::CalculateExtent( const EAxis pAxis,
|
||||
// Return whether point inside/outside/on surface, using tolerance
|
||||
|
||||
EInside G4Trd::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
{
|
||||
G4double dx = fPlanes[3].a*std::abs(p.x())+fPlanes[3].c*p.z()+fPlanes[3].d;
|
||||
G4double dy = fPlanes[1].b*std::abs(p.y())+fPlanes[1].c*p.z()+fPlanes[1].d;
|
||||
G4double dxy = std::max(dx,dy);
|
||||
@@ -336,8 +336,8 @@ EInside G4Trd::Inside( const G4ThreeVector& p ) const
|
||||
G4double dz = std::abs(p.z())-fDz;
|
||||
G4double dist = std::max(dz,dxy);
|
||||
|
||||
if (dist > halfCarTolerance) return kOutside;
|
||||
return (dist > -halfCarTolerance) ? kSurface : kInside;
|
||||
return (dist > halfCarTolerance) ? kOutside :
|
||||
((dist > -halfCarTolerance) ? kSurface : kInside);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -457,7 +457,7 @@ G4double G4Trd::DistanceToIn(const G4ThreeVector& p,
|
||||
if ((std::abs(p.z()) - fDz) >= -halfCarTolerance && p.z()*v.z() >= 0)
|
||||
return kInfinity;
|
||||
G4double invz = (-v.z() == 0) ? DBL_MAX : -1./v.z();
|
||||
G4double dz = (invz < 0) ? fDz : -fDz;
|
||||
G4double dz = (invz < 0) ? fDz : -fDz;
|
||||
G4double tzmin = (p.z() + dz)*invz;
|
||||
G4double tzmax = (p.z() - dz)*invz;
|
||||
|
||||
@@ -626,7 +626,7 @@ G4double G4Trd::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
|
||||
|
||||
// Set normal, if required, and return distance
|
||||
//
|
||||
if (calcNorm)
|
||||
if (calcNorm)
|
||||
{
|
||||
*validNorm = true;
|
||||
if (iside < 0)
|
||||
@@ -654,7 +654,7 @@ G4double G4Trd::DistanceToOut( const G4ThreeVector& p ) const
|
||||
message << " p.x() = " << p.x()/mm << " mm\n";
|
||||
message << " p.y() = " << p.y()/mm << " mm\n";
|
||||
message << " p.z() = " << p.z()/mm << " mm";
|
||||
G4cout.precision(oldprc) ;
|
||||
G4cout.precision(oldprc);
|
||||
G4Exception("G4Trd::DistanceToOut(p)", "GeomSolids1002",
|
||||
JustWarning, message );
|
||||
DumpInfo();
|
||||
@@ -666,7 +666,7 @@ G4double G4Trd::DistanceToOut( const G4ThreeVector& p ) const
|
||||
|
||||
G4double dz = std::abs(p.z())-fDz;
|
||||
G4double dist = std::max(dz,dxy);
|
||||
|
||||
|
||||
return (dist < 0) ? -dist : 0.;
|
||||
}
|
||||
|
||||
@@ -717,56 +717,79 @@ std::ostream& G4Trd::StreamInfo( std::ostream& os ) const
|
||||
|
||||
G4ThreeVector G4Trd::GetPointOnSurface() const
|
||||
{
|
||||
// Set vertices
|
||||
//
|
||||
G4ThreeVector pt[8];
|
||||
pt[0].set(-fDx1,-fDy1,-fDz);
|
||||
pt[1].set( fDx1,-fDy1,-fDz);
|
||||
pt[2].set(-fDx1, fDy1,-fDz);
|
||||
pt[3].set( fDx1, fDy1,-fDz);
|
||||
pt[4].set(-fDx2,-fDy2, fDz);
|
||||
pt[5].set( fDx2,-fDy2, fDz);
|
||||
pt[6].set(-fDx2, fDy2, fDz);
|
||||
pt[7].set( fDx2, fDy2, fDz);
|
||||
|
||||
// Set faces (-Z, -Y, +Y, -X, +X, +Z)
|
||||
//
|
||||
G4int iface [6][4] =
|
||||
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
|
||||
|
||||
// Set areas
|
||||
//
|
||||
G4double sxz = (fDy1 + fDy2)*std::hypot(fDx1 - fDx2, 2*fDz);
|
||||
G4double syz = (fDx1 + fDx2)*std::hypot(fDy1 - fDy2, 2*fDz);
|
||||
G4double sface[6] = { 4*fDx1*fDy1, syz, syz, sxz, sxz, 4*fDx2*fDy2 };
|
||||
for (G4int i=1; i<6; ++i) { sface[i] += sface[i-1]; }
|
||||
//
|
||||
G4double sxz = (fDx1 + fDx2)*fHx;
|
||||
G4double syz = (fDy1 + fDy2)*fHy;
|
||||
G4double ssurf[6] = { 4.*fDx1*fDy1, sxz, sxz, syz, syz, 4.*fDx2*fDy2 };
|
||||
ssurf[1] += ssurf[0];
|
||||
ssurf[2] += ssurf[1];
|
||||
ssurf[3] += ssurf[2];
|
||||
ssurf[4] += ssurf[3];
|
||||
ssurf[5] += ssurf[4];
|
||||
|
||||
// Select face
|
||||
//
|
||||
G4double select = sface[5]*G4UniformRand();
|
||||
G4double select = ssurf[5]*G4QuickRand();
|
||||
G4int k = 5;
|
||||
if (select <= sface[4]) k = 4;
|
||||
if (select <= sface[3]) k = 3;
|
||||
if (select <= sface[2]) k = 2;
|
||||
if (select <= sface[1]) k = 1;
|
||||
if (select <= sface[0]) k = 0;
|
||||
k -= (select <= ssurf[4]);
|
||||
k -= (select <= ssurf[3]);
|
||||
k -= (select <= ssurf[2]);
|
||||
k -= (select <= ssurf[1]);
|
||||
k -= (select <= ssurf[0]);
|
||||
|
||||
// Select sub-triangle
|
||||
// Generate point on selected surface
|
||||
//
|
||||
G4int i0 = iface[k][0];
|
||||
G4int i1 = iface[k][1];
|
||||
G4int i2 = iface[k][2];
|
||||
G4int i3 = iface[k][3];
|
||||
G4double s1 = G4GeomTools::TriangleAreaNormal(pt[i0],pt[i1],pt[i3]).mag();
|
||||
G4double s2 = G4GeomTools::TriangleAreaNormal(pt[i2],pt[i1],pt[i3]).mag();
|
||||
if ((s1+s2)*G4UniformRand() > s1) i0 = i2;
|
||||
|
||||
// Generate point
|
||||
//
|
||||
G4double u = G4UniformRand();
|
||||
G4double v = G4UniformRand();
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
return (1.-u-v)*pt[i0] + u*pt[i1] + v*pt[i3];
|
||||
G4double u = G4QuickRand();
|
||||
G4double v = G4QuickRand();
|
||||
switch(k)
|
||||
{
|
||||
case 0: // base at -Z
|
||||
{
|
||||
return G4ThreeVector((2.*u - 1.)*fDx1, (2.*v - 1.)*fDy1, -fDz);
|
||||
}
|
||||
case 1: // X face at -Y
|
||||
{
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
G4ThreeVector p0(-fDx1,-fDy1,-fDz);
|
||||
G4ThreeVector p1( fDx2,-fDy2, fDz);
|
||||
return (select <= ssurf[0] + fDx1*fHx) ?
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx1,-fDy1,-fDz) :
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx2,-fDy2, fDz);
|
||||
}
|
||||
case 2: // X face at +Y
|
||||
{
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
G4ThreeVector p0( fDx1, fDy1,-fDz);
|
||||
G4ThreeVector p1(-fDx2, fDy2, fDz);
|
||||
return (select <= ssurf[1] + fDx1*fHx) ?
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx1, fDy1,-fDz) :
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx2, fDy2, fDz);
|
||||
}
|
||||
case 3: // Y face at -X
|
||||
{
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
G4ThreeVector p0(-fDx1, fDy1,-fDz);
|
||||
G4ThreeVector p1(-fDx2,-fDy2, fDz);
|
||||
return (select <= ssurf[2] + fDy1*fHy) ?
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx1,-fDy1,-fDz) :
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx2, fDy2, fDz);
|
||||
}
|
||||
case 4: // Y face at +X
|
||||
{
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
G4ThreeVector p0( fDx1,-fDy1,-fDz);
|
||||
G4ThreeVector p1( fDx2, fDy2, fDz);
|
||||
return (select <= ssurf[3] + fDy1*fHy) ?
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx1, fDy1,-fDz) :
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx2,-fDy2, fDz);
|
||||
}
|
||||
case 5: // base at +Z
|
||||
{
|
||||
return G4ThreeVector((2.*u - 1.)*fDx2, (2.*v - 1.)*fDy2, fDz);
|
||||
}
|
||||
}
|
||||
return G4ThreeVector(0., 0., 0.);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -43,12 +43,10 @@
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
|
||||
#include "meshdefs.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4VGraphicsScene.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
|
||||
using namespace CLHEP;
|
||||
|
||||
@@ -103,7 +101,7 @@ G4Tubs::G4Tubs( __void__& a )
|
||||
fRMin(0.), fRMax(0.), fDz(0.), fSPhi(0.), fDPhi(0.),
|
||||
sinCPhi(0.), cosCPhi(0.), cosHDPhi(0.), cosHDPhiOT(0.), cosHDPhiIT(0.),
|
||||
sinSPhi(0.), cosSPhi(0.), sinEPhi(0.), cosEPhi(0.),
|
||||
fPhiFullTube(false), fInvRmax(0.), fInvRmin(0.),
|
||||
fPhiFullTube(false), fInvRmax(0.), fInvRmin(0.),
|
||||
halfCarTolerance(0.), halfRadTolerance(0.),
|
||||
halfAngTolerance(0.)
|
||||
{
|
||||
@@ -141,7 +139,7 @@ G4Tubs::G4Tubs(const G4Tubs& rhs)
|
||||
//
|
||||
// Assignment operator
|
||||
|
||||
G4Tubs& G4Tubs::operator = (const G4Tubs& rhs)
|
||||
G4Tubs& G4Tubs::operator = (const G4Tubs& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -232,7 +230,7 @@ void G4Tubs::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
|
||||
G4bool G4Tubs::CalculateExtent( const EAxis pAxis,
|
||||
const G4VoxelLimits& pVoxelLimit,
|
||||
const G4AffineTransform& pTransform,
|
||||
G4double& pMin,
|
||||
G4double& pMin,
|
||||
G4double& pMax ) const
|
||||
{
|
||||
G4ThreeVector bmin, bmax;
|
||||
@@ -352,7 +350,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
else { tolRMin = 0 ; }
|
||||
|
||||
tolRMax = fRMax - halfRadTolerance ;
|
||||
|
||||
|
||||
if ((r2 >= tolRMin*tolRMin) && (r2 <= tolRMax*tolRMax))
|
||||
{
|
||||
if ( fPhiFullTube )
|
||||
@@ -378,7 +376,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
if ( (std::fabs(pPhi) < halfAngTolerance)
|
||||
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
|
||||
{
|
||||
{
|
||||
pPhi += twopi ; // 0 <= pPhi < 2pi
|
||||
}
|
||||
if ( (pPhi >= fSPhi + halfAngTolerance)
|
||||
@@ -406,7 +404,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
in = kInside ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Try generous boundaries
|
||||
@@ -431,7 +429,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
if ( (std::fabs(pPhi) < halfAngTolerance)
|
||||
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
|
||||
{
|
||||
{
|
||||
pPhi += twopi ; // 0 <= pPhi < 2pi
|
||||
}
|
||||
if ( (pPhi >= fSPhi - halfAngTolerance)
|
||||
@@ -476,7 +474,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
if ( (std::fabs(pPhi) < halfAngTolerance)
|
||||
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
|
||||
{
|
||||
{
|
||||
pPhi += twopi ; // 0 <= pPhi < 2pi
|
||||
}
|
||||
if ( (pPhi >= fSPhi - halfAngTolerance)
|
||||
@@ -493,7 +491,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
in = kSurface ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,22 +521,22 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
distRMax = std::fabs(rho - fRMax);
|
||||
distZ = std::fabs(std::fabs(p.z()) - fDz);
|
||||
|
||||
if (!fPhiFullTube) // Protected against (0,0,z)
|
||||
if (!fPhiFullTube) // Protected against (0,0,z)
|
||||
{
|
||||
if ( rho > halfCarTolerance )
|
||||
{
|
||||
pPhi = std::atan2(p.y(),p.x());
|
||||
|
||||
|
||||
if (pPhi < fSPhi-halfCarTolerance) { pPhi += twopi; }
|
||||
else if (pPhi > fSPhi+fDPhi+halfCarTolerance) { pPhi -= twopi; }
|
||||
|
||||
distSPhi = std::fabs( pPhi - fSPhi );
|
||||
distEPhi = std::fabs( pPhi - fSPhi - fDPhi );
|
||||
distSPhi = std::fabs( pPhi - fSPhi );
|
||||
distEPhi = std::fabs( pPhi - fSPhi - fDPhi );
|
||||
}
|
||||
else if ( !fRMin )
|
||||
{
|
||||
distSPhi = 0.;
|
||||
distEPhi = 0.;
|
||||
distSPhi = 0.;
|
||||
distEPhi = 0.;
|
||||
}
|
||||
nPs = G4ThreeVector( sinSPhi, -cosSPhi, 0 );
|
||||
nPe = G4ThreeVector( -sinEPhi, cosEPhi, 0 );
|
||||
@@ -555,20 +553,20 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
++noSurfaces;
|
||||
sumnorm -= nR;
|
||||
}
|
||||
if( fDPhi < twopi )
|
||||
if( fDPhi < twopi )
|
||||
{
|
||||
if (distSPhi <= halfAngTolerance)
|
||||
if (distSPhi <= halfAngTolerance)
|
||||
{
|
||||
++noSurfaces;
|
||||
sumnorm += nPs;
|
||||
}
|
||||
if (distEPhi <= halfAngTolerance)
|
||||
if (distEPhi <= halfAngTolerance)
|
||||
{
|
||||
++noSurfaces;
|
||||
sumnorm += nPe;
|
||||
}
|
||||
}
|
||||
if (distZ <= halfCarTolerance)
|
||||
if (distZ <= halfCarTolerance)
|
||||
{
|
||||
++noSurfaces;
|
||||
if ( p.z() >= 0.) { sumnorm += nZ; }
|
||||
@@ -583,7 +581,7 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
G4cout<< "G4Tubs::SN ( "<<p.x()<<", "<<p.y()<<", "<<p.z()<<" ); "
|
||||
<< G4endl << G4endl;
|
||||
G4cout.precision(oldprc) ;
|
||||
#endif
|
||||
#endif
|
||||
norm = ApproxSurfaceNormal(p);
|
||||
}
|
||||
else if ( noSurfaces == 1 ) { norm = sumnorm; }
|
||||
@@ -635,8 +633,8 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
distMin = distRMax ;
|
||||
side = kNRMax ;
|
||||
}
|
||||
}
|
||||
if (!fPhiFullTube && rho ) // Protected against (0,0,z)
|
||||
}
|
||||
if (!fPhiFullTube && rho ) // Protected against (0,0,z)
|
||||
{
|
||||
phi = std::atan2(p.y(),p.x()) ;
|
||||
|
||||
@@ -651,7 +649,7 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
distSPhi = std::fabs(phi - fSPhi)*rho ;
|
||||
}
|
||||
distEPhi = std::fabs(phi - fSPhi - fDPhi)*rho ;
|
||||
|
||||
|
||||
if (distSPhi < distEPhi) // Find new minimum
|
||||
{
|
||||
if ( distSPhi < distMin )
|
||||
@@ -666,21 +664,21 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
side = kNEPhi ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch ( side )
|
||||
{
|
||||
case kNRMin : // Inner radius
|
||||
{
|
||||
{
|
||||
norm = G4ThreeVector(-p.x()/rho, -p.y()/rho, 0) ;
|
||||
break ;
|
||||
}
|
||||
case kNRMax : // Outer radius
|
||||
{
|
||||
{
|
||||
norm = G4ThreeVector(p.x()/rho, p.y()/rho, 0) ;
|
||||
break ;
|
||||
}
|
||||
case kNZ : // + or - dz
|
||||
{
|
||||
{
|
||||
if ( p.z() > 0 ) { norm = G4ThreeVector(0,0,1) ; }
|
||||
else { norm = G4ThreeVector(0,0,-1); }
|
||||
break ;
|
||||
@@ -702,8 +700,8 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
"GeomSolids1002", JustWarning,
|
||||
"Undefined side for valid surface normal to solid.");
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return norm;
|
||||
}
|
||||
|
||||
@@ -713,7 +711,7 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
// Calculate distance to shape from outside, along normalised vector
|
||||
// - return kInfinity if no intersection, or intersection distance <= tolerance
|
||||
//
|
||||
// - Compute the intersection with the z planes
|
||||
// - Compute the intersection with the z planes
|
||||
// - if at valid r, phi, return
|
||||
//
|
||||
// -> If point is outer outer radius, compute intersection with rmax
|
||||
@@ -740,8 +738,8 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
// Intersection point variables
|
||||
//
|
||||
G4double Dist, sd, xi, yi, zi, rho2, inum, iden, cosPsi, Comp ;
|
||||
G4double t1, t2, t3, b, c, d ; // Quadratic solver variables
|
||||
|
||||
G4double t1, t2, t3, b, c, d ; // Quadratic solver variables
|
||||
|
||||
// Calculate tolerant rmin and rmax
|
||||
|
||||
if (fRMin > kRadTolerance)
|
||||
@@ -837,7 +835,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
{ // 64 bits systems. Split long distances and recompute
|
||||
G4double fTerm = sd-std::fmod(sd,dRmax);
|
||||
sd = fTerm + DistanceToIn(p+fTerm*v,v);
|
||||
}
|
||||
}
|
||||
// Check z intersection
|
||||
//
|
||||
zi = p.z() + sd*v.z() ;
|
||||
@@ -860,7 +858,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
} // end if (sd>=0)
|
||||
} // end if (d>=0)
|
||||
} // end if (r>=fRMax)
|
||||
else
|
||||
else
|
||||
{
|
||||
// Inside outer radius :
|
||||
// check not inside, and heading through tubs (-> 0 to in)
|
||||
@@ -878,11 +876,11 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
{
|
||||
// In the old version, the small negative tangent for the point
|
||||
// on surface was not taken in account, and returning 0.0 ...
|
||||
// New version: check the tangent for the point on surface and
|
||||
// New version: check the tangent for the point on surface and
|
||||
// if no intersection, return kInfinity, if intersection instead
|
||||
// return sd.
|
||||
//
|
||||
c = t3-fRMax*fRMax;
|
||||
c = t3-fRMax*fRMax;
|
||||
if ( c<=0.0 )
|
||||
{
|
||||
return 0.0;
|
||||
@@ -894,26 +892,26 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
if ( d>=0.0 )
|
||||
{
|
||||
snxt = c/(-b+std::sqrt(d)); // using safe solution
|
||||
// for quadratic equation
|
||||
// for quadratic equation
|
||||
if ( snxt < halfCarTolerance ) { snxt=0; }
|
||||
return snxt ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return kInfinity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
// In the old version, the small negative tangent for the point
|
||||
// on surface was not taken in account, and returning 0.0 ...
|
||||
// New version: check the tangent for the point on surface and
|
||||
// New version: check the tangent for the point on surface and
|
||||
// if no intersection, return kInfinity, if intersection instead
|
||||
// return sd.
|
||||
//
|
||||
c = t3 - fRMax*fRMax;
|
||||
c = t3 - fRMax*fRMax;
|
||||
if ( c<=0.0 )
|
||||
{
|
||||
return 0.0;
|
||||
@@ -925,10 +923,10 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
if ( d>=0.0 )
|
||||
{
|
||||
snxt= c/(-b+std::sqrt(d)); // using safe solution
|
||||
// for quadratic equation
|
||||
// for quadratic equation
|
||||
if ( snxt < halfCarTolerance ) { snxt=0; }
|
||||
return snxt ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return kInfinity;
|
||||
@@ -936,7 +934,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
}
|
||||
} // end if (!fPhiFullTube)
|
||||
} // end if (t3>tolIRMin2)
|
||||
} // end if (Inside Outer Radius)
|
||||
} // end if (Inside Outer Radius)
|
||||
if ( fRMin ) // Try inner cylinder intersection
|
||||
{
|
||||
c = (t3 - fRMin*fRMin)/t1 ;
|
||||
@@ -956,7 +954,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
{ // 64 bits systems. Split long distances and recompute
|
||||
G4double fTerm = sd-std::fmod(sd,dRmax);
|
||||
sd = fTerm + DistanceToIn(p+fTerm*v,v);
|
||||
}
|
||||
}
|
||||
zi = p.z() + sd*v.z() ;
|
||||
if (std::fabs(zi) <= tolODz)
|
||||
{
|
||||
@@ -964,7 +962,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
//
|
||||
if ( fPhiFullTube )
|
||||
{
|
||||
return sd ;
|
||||
return sd ;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -999,7 +997,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
// First phi surface (Starting phi)
|
||||
//
|
||||
Comp = v.x()*sinSPhi - v.y()*cosSPhi ;
|
||||
|
||||
|
||||
if ( Comp < 0 ) // Component in outwards normal dirn
|
||||
{
|
||||
Dist = (p.y()*cosSPhi - p.x()*sinSPhi) ;
|
||||
@@ -1033,13 +1031,13 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Second phi surface (Ending phi)
|
||||
|
||||
Comp = -(v.x()*sinEPhi - v.y()*cosEPhi) ;
|
||||
|
||||
|
||||
if (Comp < 0 ) // Component in outwards normal dirn
|
||||
{
|
||||
Dist = -(p.y()*cosEPhi - p.x()*sinEPhi) ;
|
||||
@@ -1074,17 +1072,17 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
}
|
||||
}
|
||||
} // Comp < 0
|
||||
} // !fPhiFullTube
|
||||
} // !fPhiFullTube
|
||||
if ( snxt<halfCarTolerance ) { snxt=0; }
|
||||
return snxt ;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate distance to shape from outside, along normalised vector
|
||||
// - return kInfinity if no intersection, or intersection distance <= tolerance
|
||||
//
|
||||
// - Compute the intersection with the z planes
|
||||
// - Compute the intersection with the z planes
|
||||
// - if at valid r, phi, return
|
||||
//
|
||||
// -> If point is outer outer radius, compute intersection with rmax
|
||||
@@ -1124,7 +1122,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p ) const
|
||||
// Psi=angle from central phi to point
|
||||
//
|
||||
cosPsi = (p.x()*cosCPhi + p.y()*sinCPhi)/rho ;
|
||||
|
||||
|
||||
if ( cosPsi < cosHDPhi )
|
||||
{
|
||||
// Point lies outside phi range
|
||||
@@ -1158,11 +1156,11 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
ESide side=kNull , sider=kNull, sidephi=kNull ;
|
||||
G4double snxt, srd=kInfinity, sphi=kInfinity, pdist ;
|
||||
G4double deltaR, t1, t2, t3, b, c, d2, roMin2 ;
|
||||
|
||||
|
||||
// Vars for phi intersection:
|
||||
|
||||
G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, vphi, roi2 ;
|
||||
|
||||
|
||||
// Z plane intersection
|
||||
|
||||
if (v.z() > 0 )
|
||||
@@ -1229,7 +1227,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if ( t1 > 0 ) // Check not parallel
|
||||
{
|
||||
// Calculate srd, r exit distance
|
||||
|
||||
|
||||
if ( (t2 >= 0.0) && (roi2 > fRMax*(fRMax + kRadTolerance)) )
|
||||
{
|
||||
// Delta r not negative => leaving via rmax
|
||||
@@ -1253,7 +1251,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
// On tolerant boundary & heading outwards (or perpendicular to)
|
||||
// outer radial surface -> leaving immediately
|
||||
|
||||
if ( calcNorm )
|
||||
if ( calcNorm )
|
||||
{
|
||||
G4double invRho = FastInverseRxy( p, fInvRmax, kNormTolerance );
|
||||
*n = G4ThreeVector(p.x()*invRho,p.y()*invRho,0) ;
|
||||
@@ -1261,10 +1259,10 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
}
|
||||
return snxt = 0 ; // Leaving by rmax immediately
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( t2 < 0. ) // i.e. t2 < 0; Possible rmin intersection
|
||||
{
|
||||
roMin2 = t3 - t2*t2/t1 ; // min ro2 of the plane of movement
|
||||
roMin2 = t3 - t2*t2/t1 ; // min ro2 of the plane of movement
|
||||
|
||||
if ( fRMin && (roMin2 < fRMin*(fRMin - kRadTolerance)) )
|
||||
{
|
||||
@@ -1280,7 +1278,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
|
||||
if (deltaR > kRadTolerance*fRMin)
|
||||
{
|
||||
srd = c/(-b+std::sqrt(d2));
|
||||
srd = c/(-b+std::sqrt(d2));
|
||||
sider = kRMin ;
|
||||
}
|
||||
else
|
||||
@@ -1307,7 +1305,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if (calcNorm)
|
||||
{
|
||||
G4double invRho = FastInverseRxy( p, fInvRmax, kNormTolerance );
|
||||
*n = G4ThreeVector(p.x()*invRho,p.y()*invRho,0) ;
|
||||
*n = G4ThreeVector(p.x()*invRho,p.y()*invRho,0) ;
|
||||
*validNorm = true ;
|
||||
}
|
||||
return snxt = 0.0;
|
||||
@@ -1339,16 +1337,16 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Phi Intersection
|
||||
|
||||
if ( !fPhiFullTube )
|
||||
{
|
||||
// add angle calculation with correction
|
||||
// add angle calculation with correction
|
||||
// of the difference in domain of atan2 and Sphi
|
||||
//
|
||||
vphi = std::atan2(v.y(),v.x()) ;
|
||||
|
||||
|
||||
if ( vphi < fSPhi - halfAngTolerance ) { vphi += twopi; }
|
||||
else if ( vphi > fSPhi + fDPhi + halfAngTolerance ) { vphi -= twopi; }
|
||||
|
||||
@@ -1364,25 +1362,25 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
|
||||
compS = -sinSPhi*v.x() + cosSPhi*v.y() ;
|
||||
compE = sinEPhi*v.x() - cosEPhi*v.y() ;
|
||||
|
||||
|
||||
sidephi = kNull;
|
||||
|
||||
|
||||
if( ( (fDPhi <= pi) && ( (pDistS <= halfCarTolerance)
|
||||
&& (pDistE <= halfCarTolerance) ) )
|
||||
|| ( (fDPhi > pi) && !((pDistS > halfCarTolerance)
|
||||
&& (pDistE > halfCarTolerance) ) ) )
|
||||
{
|
||||
// Inside both phi *full* planes
|
||||
|
||||
|
||||
if ( compS < 0 )
|
||||
{
|
||||
sphi = pDistS/compS ;
|
||||
|
||||
|
||||
if (sphi >= -halfCarTolerance)
|
||||
{
|
||||
xi = p.x() + sphi*v.x() ;
|
||||
yi = p.y() + sphi*v.y() ;
|
||||
|
||||
|
||||
// Check intersecting with correct half-plane
|
||||
// (if not -> no intersect)
|
||||
//
|
||||
@@ -1405,8 +1403,8 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if ( pDistS > -halfCarTolerance )
|
||||
{
|
||||
sphi = 0.0 ; // Leave by sphi immediately
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1421,14 +1419,14 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if ( compE < 0 )
|
||||
{
|
||||
sphi2 = pDistE/compE ;
|
||||
|
||||
|
||||
// Only check further if < starting phi intersection
|
||||
//
|
||||
if ( (sphi2 > -halfCarTolerance) && (sphi2 < sphi) )
|
||||
{
|
||||
xi = p.x() + sphi2*v.x() ;
|
||||
yi = p.y() + sphi2*v.y() ;
|
||||
|
||||
|
||||
if((std::fabs(xi)<=kCarTolerance)&&(std::fabs(yi)<=kCarTolerance))
|
||||
{
|
||||
// Leaving via ending phi
|
||||
@@ -1440,8 +1438,8 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if ( pDistE <= -halfCarTolerance ) { sphi = sphi2 ; }
|
||||
else { sphi = 0.0 ; }
|
||||
}
|
||||
}
|
||||
else // Check intersecting with correct half-plane
|
||||
}
|
||||
else // Check intersecting with correct half-plane
|
||||
|
||||
if ( (yi*cosCPhi-xi*sinCPhi) >= 0)
|
||||
{
|
||||
@@ -1463,7 +1461,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
{
|
||||
// On z axis + travel not || to z axis -> if phi of vector direction
|
||||
// within phi of shape, Step limited by rmax, else Step =0
|
||||
|
||||
|
||||
if ( (fSPhi - halfAngTolerance <= vphi)
|
||||
&& (vphi <= fSPhi + fDPhi + halfAngTolerance ) )
|
||||
{
|
||||
@@ -1471,7 +1469,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
}
|
||||
else
|
||||
{
|
||||
sidephi = kSPhi ; // arbitrary
|
||||
sidephi = kSPhi ; // arbitrary
|
||||
sphi = 0.0 ;
|
||||
}
|
||||
}
|
||||
@@ -1596,7 +1594,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p ) const
|
||||
{
|
||||
safeR1 = rho - fRMin ;
|
||||
safeR2 = fRMax - rho ;
|
||||
|
||||
|
||||
if ( safeR1 < safeR2 ) { safe = safeR1 ; }
|
||||
else { safe = safeR2 ; }
|
||||
}
|
||||
@@ -1624,7 +1622,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p ) const
|
||||
}
|
||||
if ( safe < 0 ) { safe = 0 ; }
|
||||
|
||||
return safe ;
|
||||
return safe ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1674,80 +1672,91 @@ std::ostream& G4Tubs::StreamInfo( std::ostream& os ) const
|
||||
|
||||
G4ThreeVector G4Tubs::GetPointOnSurface() const
|
||||
{
|
||||
G4double xRand, yRand, zRand, phi, cosphi, sinphi, chose,
|
||||
aOne, aTwo, aThr, aFou;
|
||||
G4double rRand;
|
||||
G4double Rmax = fRMax;
|
||||
G4double Rmin = fRMin;
|
||||
G4double hz = 2.*fDz; // height
|
||||
G4double lext = fDPhi*Rmax; // length of external circular arc
|
||||
G4double lint = fDPhi*Rmin; // length of internal circular arc
|
||||
|
||||
aOne = 2.*fDz*fDPhi*fRMax;
|
||||
aTwo = 2.*fDz*fDPhi*fRMin;
|
||||
aThr = 0.5*fDPhi*(fRMax*fRMax-fRMin*fRMin);
|
||||
aFou = 2.*fDz*(fRMax-fRMin);
|
||||
// Set array of surface areas
|
||||
//
|
||||
G4double RRmax = Rmax * Rmax;
|
||||
G4double RRmin = Rmin * Rmin;
|
||||
G4double sbase = 0.5*fDPhi*(RRmax - RRmin);
|
||||
G4double scut = (fDPhi == twopi) ? 0. : hz*(Rmax - Rmin);
|
||||
G4double ssurf[6] = { scut, scut, sbase, sbase, hz*lext, hz*lint };
|
||||
ssurf[1] += ssurf[0];
|
||||
ssurf[2] += ssurf[1];
|
||||
ssurf[3] += ssurf[2];
|
||||
ssurf[4] += ssurf[3];
|
||||
ssurf[5] += ssurf[4];
|
||||
|
||||
phi = G4RandFlat::shoot(fSPhi, fSPhi+fDPhi);
|
||||
cosphi = std::cos(phi);
|
||||
sinphi = std::sin(phi);
|
||||
// Select surface
|
||||
//
|
||||
G4double select = ssurf[5]*G4QuickRand();
|
||||
G4int k = 5;
|
||||
k -= (select <= ssurf[4]);
|
||||
k -= (select <= ssurf[3]);
|
||||
k -= (select <= ssurf[2]);
|
||||
k -= (select <= ssurf[1]);
|
||||
k -= (select <= ssurf[0]);
|
||||
|
||||
rRand = GetRadiusInRing(fRMin,fRMax);
|
||||
|
||||
if( (fSPhi == 0) && (fDPhi == twopi) ) { aFou = 0; }
|
||||
|
||||
chose = G4RandFlat::shoot(0.,aOne+aTwo+2.*aThr+2.*aFou);
|
||||
|
||||
if( (chose >=0) && (chose < aOne) )
|
||||
// Generate point on selected surface
|
||||
//
|
||||
switch(k)
|
||||
{
|
||||
xRand = fRMax*cosphi;
|
||||
yRand = fRMax*sinphi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else if( (chose >= aOne) && (chose < aOne + aTwo) )
|
||||
{
|
||||
xRand = fRMin*cosphi;
|
||||
yRand = fRMin*sinphi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else if( (chose >= aOne + aTwo) && (chose < aOne + aTwo + aThr) )
|
||||
{
|
||||
xRand = rRand*cosphi;
|
||||
yRand = rRand*sinphi;
|
||||
zRand = fDz;
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else if( (chose >= aOne + aTwo + aThr) && (chose < aOne + aTwo + 2.*aThr) )
|
||||
{
|
||||
xRand = rRand*cosphi;
|
||||
yRand = rRand*sinphi;
|
||||
zRand = -1.*fDz;
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else if( (chose >= aOne + aTwo + 2.*aThr)
|
||||
&& (chose < aOne + aTwo + 2.*aThr + aFou) )
|
||||
{
|
||||
xRand = rRand*cosSPhi;
|
||||
yRand = rRand*sinSPhi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else
|
||||
{
|
||||
xRand = rRand*cosEPhi;
|
||||
yRand = rRand*sinEPhi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
case 0: // start phi cut
|
||||
{
|
||||
G4double r = Rmin + (Rmax - Rmin)*G4QuickRand();
|
||||
return G4ThreeVector(r*cosSPhi, r*sinSPhi, hz*G4QuickRand() - fDz);
|
||||
}
|
||||
case 1: // end phi cut
|
||||
{
|
||||
G4double r = Rmin + (Rmax - Rmin)*G4QuickRand();
|
||||
return G4ThreeVector(r*cosEPhi, r*sinEPhi, hz*G4QuickRand() - fDz);
|
||||
}
|
||||
case 2: // base at -dz
|
||||
{
|
||||
G4double r = std::sqrt(RRmin + (RRmax - RRmin)*G4QuickRand());
|
||||
G4double phi = fSPhi + fDPhi*G4QuickRand();
|
||||
return G4ThreeVector(r*std::cos(phi), r*std::sin(phi), -fDz);
|
||||
}
|
||||
case 3: // base at +dz
|
||||
{
|
||||
G4double r = std::sqrt(RRmin + (RRmax - RRmin)*G4QuickRand());
|
||||
G4double phi = fSPhi + fDPhi*G4QuickRand();
|
||||
return G4ThreeVector(r*std::cos(phi), r*std::sin(phi), fDz);
|
||||
}
|
||||
case 4: // external lateral surface
|
||||
{
|
||||
G4double phi = fSPhi + fDPhi*G4QuickRand();
|
||||
G4double z = hz*G4QuickRand() - fDz;
|
||||
G4double x = Rmax*std::cos(phi);
|
||||
G4double y = Rmax*std::sin(phi);
|
||||
return G4ThreeVector(x,y,z);
|
||||
}
|
||||
case 5: // internal lateral surface
|
||||
{
|
||||
G4double phi = fSPhi + fDPhi*G4QuickRand();
|
||||
G4double z = hz*G4QuickRand() - fDz;
|
||||
G4double x = Rmin*std::cos(phi);
|
||||
G4double y = Rmin*std::sin(phi);
|
||||
return G4ThreeVector(x,y,z);
|
||||
}
|
||||
}
|
||||
return G4ThreeVector(0., 0., 0.);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Methods for visualisation
|
||||
|
||||
void G4Tubs::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
|
||||
void G4Tubs::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
|
||||
{
|
||||
scene.AddSolid (*this) ;
|
||||
}
|
||||
|
||||
G4Polyhedron* G4Tubs::CreatePolyhedron () const
|
||||
G4Polyhedron* G4Tubs::CreatePolyhedron () const
|
||||
{
|
||||
return new G4PolyhedronTubs (fRMin, fRMax, fDz, fSPhi, fDPhi) ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user