Import Geant4 9.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 16:25:56 +02:00
parent 74cad5e589
commit 89a9605df1
4440 changed files with 379508 additions and 189225 deletions
+214 -186
View File
@@ -24,14 +24,14 @@
// ********************************************************************
//
//
// $Id: G4Box.cc,v 1.44 2006/10/19 15:33:37 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4Box.cc,v 1.53 2010/10/19 15:42:09 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
//
// Implementation for G4Box class
//
// 24.06.98 - V. Grichine: insideEdge in DistanceToIn(p,v)
// 24.06.98 - V.Grichine: insideEdge in DistanceToIn(p,v)
// 20.09.98 - V.Grichine: new algorithm of DistanceToIn(p,v)
// 07.05.00 - V.Grichine: d= DistanceToIn(p,v), if d<e/2, d=0
// 09.06.00 - V.Grichine: safety in DistanceToIn(p) against Inside(p)=kOutside
@@ -62,17 +62,11 @@ G4Box::G4Box(const G4String& pName,
G4double pX,
G4double pY,
G4double pZ)
: G4CSGSolid(pName)
: G4CSGSolid(pName), fDx(pX), fDy(pY), fDz(pZ)
{
if ( (pX > 2*kCarTolerance)
&& (pY > 2*kCarTolerance)
&& (pZ > 2*kCarTolerance) )
{
fDx = pX ;
fDy = pY ;
fDz = pZ ;
}
else
if ( (pX < 2*kCarTolerance)
&& (pY < 2*kCarTolerance)
&& (pZ < 2*kCarTolerance) ) // limit to thickness of surfaces
{
G4cerr << "ERROR - G4Box()::G4Box(): " << GetName() << G4endl
<< " Dimensions too small ! - "
@@ -88,7 +82,7 @@ G4Box::G4Box(const G4String& pName,
// for usage restricted to object persistency.
G4Box::G4Box( __void__& a )
: G4CSGSolid(a)
: G4CSGSolid(a), fDx(0.), fDy(0.), fDz(0.)
{
}
@@ -100,12 +94,46 @@ G4Box::~G4Box()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4Box::G4Box(const G4Box& rhs)
: G4CSGSolid(rhs), fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4Box& G4Box::operator = (const G4Box& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4CSGSolid::operator=(rhs);
// Copy data
//
fDx = rhs.fDx;
fDy = rhs.fDy;
fDz = rhs.fDz;
return *this;
}
//////////////////////////////////////////////////////////////////////////////
void G4Box::SetXHalfLength(G4double dx)
{
if(dx > 2*kCarTolerance)
if(dx > 2*kCarTolerance) // limit to thickness of surfaces
{
fDx = dx;
}
else
{
G4cerr << "ERROR - G4Box()::SetXHalfLength(): " << GetName() << G4endl
@@ -121,8 +149,10 @@ void G4Box::SetXHalfLength(G4double dx)
void G4Box::SetYHalfLength(G4double dy)
{
if(dy > 2*kCarTolerance)
if(dy > 2*kCarTolerance) // limit to thickness of surfaces
{
fDy = dy;
}
else
{
G4cerr << "ERROR - G4Box()::SetYHalfLength(): " << GetName() << G4endl
@@ -138,8 +168,10 @@ void G4Box::SetYHalfLength(G4double dy)
void G4Box::SetZHalfLength(G4double dz)
{
if(dz > 2*kCarTolerance)
if(dz > 2*kCarTolerance) // limit to thickness of surfaces
{
fDz = dz;
}
else
{
G4cerr << "ERROR - G4Box()::SetZHalfLength(): " << GetName() << G4endl
@@ -152,8 +184,6 @@ void G4Box::SetZHalfLength(G4double dz)
fSurfaceArea= 0.;
fpPolyhedron = 0;
}
////////////////////////////////////////////////////////////////////////
//
@@ -192,18 +222,12 @@ G4bool G4Box::CalculateExtent(const EAxis pAxis,
if (pVoxelLimit.IsXLimited())
{
if ( xMin > pVoxelLimit.GetMaxXExtent()+kCarTolerance ||
xMax < pVoxelLimit.GetMinXExtent()-kCarTolerance ) return false ;
if ((xMin > pVoxelLimit.GetMaxXExtent()+kCarTolerance) ||
(xMax < pVoxelLimit.GetMinXExtent()-kCarTolerance)) { return false ; }
else
{
if (xMin < pVoxelLimit.GetMinXExtent())
{
xMin = pVoxelLimit.GetMinXExtent() ;
}
if (xMax > pVoxelLimit.GetMaxXExtent())
{
xMax = pVoxelLimit.GetMaxXExtent() ;
}
xMin = std::max(xMin, pVoxelLimit.GetMinXExtent());
xMax = std::min(xMax, pVoxelLimit.GetMaxXExtent());
}
}
yoffset = pTransform.NetTranslation().y() ;
@@ -212,18 +236,12 @@ G4bool G4Box::CalculateExtent(const EAxis pAxis,
if (pVoxelLimit.IsYLimited())
{
if ( yMin > pVoxelLimit.GetMaxYExtent()+kCarTolerance ||
yMax < pVoxelLimit.GetMinYExtent()-kCarTolerance ) return false ;
if ((yMin > pVoxelLimit.GetMaxYExtent()+kCarTolerance) ||
(yMax < pVoxelLimit.GetMinYExtent()-kCarTolerance)) { return false ; }
else
{
if (yMin < pVoxelLimit.GetMinYExtent())
{
yMin = pVoxelLimit.GetMinYExtent() ;
}
if (yMax > pVoxelLimit.GetMaxYExtent())
{
yMax = pVoxelLimit.GetMaxYExtent() ;
}
yMin = std::max(yMin, pVoxelLimit.GetMinYExtent());
yMax = std::min(yMax, pVoxelLimit.GetMaxYExtent());
}
}
zoffset = pTransform.NetTranslation().z() ;
@@ -232,18 +250,12 @@ G4bool G4Box::CalculateExtent(const EAxis pAxis,
if (pVoxelLimit.IsZLimited())
{
if ( zMin > pVoxelLimit.GetMaxZExtent()+kCarTolerance ||
zMax < pVoxelLimit.GetMinZExtent()-kCarTolerance ) return false ;
if ((zMin > pVoxelLimit.GetMaxZExtent()+kCarTolerance) ||
(zMax < pVoxelLimit.GetMinZExtent()-kCarTolerance)) { return false ; }
else
{
if (zMin < pVoxelLimit.GetMinZExtent())
{
zMin = pVoxelLimit.GetMinZExtent() ;
}
if (zMax > pVoxelLimit.GetMaxZExtent())
{
zMax = pVoxelLimit.GetMaxZExtent() ;
}
zMin = std::max(zMin, pVoxelLimit.GetMinZExtent());
zMax = std::min(zMax, pVoxelLimit.GetMaxZExtent());
}
}
switch (pAxis)
@@ -285,14 +297,14 @@ G4bool G4Box::CalculateExtent(const EAxis pAxis,
if (pVoxelLimit.IsLimited(pAxis) == false)
{
if ( pMin != kInfinity || pMax != -kInfinity )
if ( (pMin != kInfinity) || (pMax != -kInfinity) )
{
existsAfterClip = true ;
// Add 2*tolerance to avoid precision troubles
pMin -= kCarTolerance;
pMax += kCarTolerance;
pMin -= kCarTolerance;
pMax += kCarTolerance;
}
}
else
@@ -302,7 +314,7 @@ G4bool G4Box::CalculateExtent(const EAxis pAxis,
( pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
( pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
if ( pMin != kInfinity || pMax != -kInfinity )
if ( (pMin != kInfinity) || (pMax != -kInfinity) )
{
existsAfterClip = true ;
@@ -355,25 +367,27 @@ G4bool G4Box::CalculateExtent(const EAxis pAxis,
EInside G4Box::Inside(const G4ThreeVector& p) const
{
static const G4double delta=0.5*kCarTolerance;
EInside in = kOutside ;
G4ThreeVector q(std::fabs(p.x()), std::fabs(p.y()), std::fabs(p.z()));
if ( std::fabs(p.x()) <= fDx - kCarTolerance*0.5 )
if ( q.x() <= (fDx - delta) )
{
if (std::fabs(p.y()) <= fDy - kCarTolerance*0.5 )
if (q.y() <= (fDy - delta) )
{
if (std::fabs(p.z()) <= fDz - kCarTolerance*0.5 ) in = kInside ;
else if (std::fabs(p.z()) <= fDz + kCarTolerance*0.5 ) in = kSurface ;
if ( q.z() <= (fDz - delta) ) { in = kInside ; }
else if ( q.z() <= (fDz + delta) ) { in = kSurface ; }
}
else if (std::fabs(p.y()) <= fDy + kCarTolerance*0.5 )
else if ( q.y() <= (fDy + delta) )
{
if (std::fabs(p.z()) <= fDz + kCarTolerance*0.5 ) in = kSurface ;
if ( q.z() <= (fDz + delta) ) { in = kSurface ; }
}
}
else if (std::fabs(p.x()) <= fDx + kCarTolerance*0.5 )
else if ( q.x() <= (fDx + delta) )
{
if (std::fabs(p.y()) <= fDy + kCarTolerance*0.5 )
if ( q.y() <= (fDy + delta) )
{
if (std::fabs(p.z()) <= fDz + kCarTolerance*0.5) in = kSurface ;
if ( q.z() <= (fDz + delta) ) { in = kSurface ; }
}
}
return in ;
@@ -388,7 +402,7 @@ EInside G4Box::Inside(const G4ThreeVector& p) const
G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
{
G4double distx, disty, distz ;
G4ThreeVector norm ;
G4ThreeVector norm(0.,0.,0.);
// Calculate distances as if in 1st octant
@@ -399,7 +413,7 @@ G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
// New code for particle on surface including edges and corners with specific
// normals
const G4double delta = 0.5*kCarTolerance;
static const G4double delta = 0.5*kCarTolerance;
const G4ThreeVector nX = G4ThreeVector( 1.0, 0,0 );
const G4ThreeVector nmX = G4ThreeVector(-1.0, 0,0 );
const G4ThreeVector nY = G4ThreeVector( 0, 1.0,0 );
@@ -414,56 +428,53 @@ G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
if (distx <= delta) // on X/mX surface and around
{
noSurfaces ++;
if ( p.x() >= 0.){ // on +X surface
normX= nX ; // G4ThreeVector( 1.0, 0., 0. );
}else{
normX= nmX; // G4ThreeVector(-1.0, 0., 0. );
}
if ( p.x() >= 0. ) { normX= nX ; } // on +X surface : (1,0,0)
else { normX= nmX; } // (-1,0,0)
sumnorm= normX;
}
if (disty <= delta) // on one of the +Y or -Y surfaces
{
noSurfaces ++;
if ( p.y() >= 0.){ // on +Y surface
normY= nY;
}else{
normY = nmY;
}
if ( p.y() >= 0. ) { normY= nY; } // on +Y surface
else { normY= nmY; }
sumnorm += normY;
}
if (distz <= delta) // on one of the +Z or -Z surfaces
{
noSurfaces ++;
if ( p.z() >= 0.){ // on +Z surface
normZ= nZ;
}else{
normZ = nmZ;
}
sumnorm += normZ;
if ( p.z() >= 0. ) { normZ= nZ; } // on +Z surface
else { normZ= nmZ; }
sumnorm += normZ;
}
// sumnorm= normX + normY + normZ;
const G4double invSqrt2 = 1.0 / std::sqrt( 2.0);
const G4double invSqrt3 = 1.0 / std::sqrt( 3.0);
static const G4double invSqrt2 = 1.0 / std::sqrt(2.0);
static const G4double invSqrt3 = 1.0 / std::sqrt(3.0);
norm= G4ThreeVector( 0., 0., 0.);
if( noSurfaces > 0 )
{
if( noSurfaces == 1 ){
if( noSurfaces == 1 )
{
norm= sumnorm;
}else{
}
else
{
// norm = sumnorm . unit();
if( noSurfaces == 2 ) {
if( noSurfaces == 2 )
{
// 2 surfaces -> on edge
norm = invSqrt2 * sumnorm;
} else {
}
else
{
// 3 surfaces (on corner)
norm = invSqrt3 * sumnorm;
}
}
}else{
}
else
{
#ifdef G4CSGDEBUG
G4Exception("G4Box::SurfaceNormal(p)", "Notification", JustWarning,
"Point p is not on surface !?" );
@@ -482,7 +493,7 @@ G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
G4ThreeVector G4Box::ApproxSurfaceNormal( const G4ThreeVector& p ) const
{
G4double distx, disty, distz ;
G4ThreeVector norm ;
G4ThreeVector norm(0.,0.,0.);
// Calculate distances as if in 1st octant
@@ -494,26 +505,26 @@ G4ThreeVector G4Box::ApproxSurfaceNormal( const G4ThreeVector& p ) const
{
if ( distx <= distz ) // Closest to X
{
if ( p.x() < 0 ) norm = G4ThreeVector(-1.0,0,0) ;
else norm = G4ThreeVector( 1.0,0,0) ;
if ( p.x() < 0 ) { norm = G4ThreeVector(-1.0,0,0) ; }
else { norm = G4ThreeVector( 1.0,0,0) ; }
}
else // Closest to Z
{
if ( p.z() < 0 ) norm = G4ThreeVector(0,0,-1.0) ;
else norm = G4ThreeVector(0,0, 1.0) ;
if ( p.z() < 0 ) { norm = G4ThreeVector(0,0,-1.0) ; }
else { norm = G4ThreeVector(0,0, 1.0) ; }
}
}
else
{
if ( disty <= distz ) // Closest to Y
{
if ( p.y() < 0 ) norm = G4ThreeVector(0,-1.0,0) ;
else norm = G4ThreeVector(0, 1.0,0) ;
if ( p.y() < 0 ) { norm = G4ThreeVector(0,-1.0,0) ; }
else { norm = G4ThreeVector(0, 1.0,0) ; }
}
else // Closest to Z
{
if ( p.z() < 0 ) norm = G4ThreeVector(0,0,-1.0) ;
else norm = G4ThreeVector(0,0, 1.0) ;
if ( p.z() < 0 ) { norm = G4ThreeVector(0,0,-1.0) ; }
else { norm = G4ThreeVector(0,0, 1.0) ; }
}
}
return norm;
@@ -540,7 +551,8 @@ G4ThreeVector G4Box::ApproxSurfaceNormal( const G4ThreeVector& p ) const
// `Inside' safe - meaningful answers given if point is inside the exact
// shape.
G4double G4Box::DistanceToIn(const G4ThreeVector& p,const G4ThreeVector& v) const
G4double G4Box::DistanceToIn(const G4ThreeVector& p,
const G4ThreeVector& v) const
{
G4double safx, safy, safz ;
G4double smin=0.0, sminy, sminz ; // , sminx ;
@@ -548,6 +560,8 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,const G4ThreeVector& v) cons
G4double stmp ;
G4double sOut=kInfinity, sOuty=kInfinity, sOutz=kInfinity ;
static const G4double delta = 0.5*kCarTolerance;
safx = std::fabs(p.x()) - fDx ; // minimum distance to x surface of shape
safy = std::fabs(p.y()) - fDy ;
safz = std::fabs(p.z()) - fDz ;
@@ -557,9 +571,9 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,const G4ThreeVector& v) cons
// If both p.x/y/z and v.x/y/z repectively are both positive/negative,
// travel is in a direction away from the shape.
if ( ((p.x()*v.x() >= 0.0) && safx > -kCarTolerance*0.5)
|| ((p.y()*v.y() >= 0.0) && safy > -kCarTolerance*0.5)
|| ((p.z()*v.z() >= 0.0) && safz > -kCarTolerance*0.5) )
if ( ((p.x()*v.x() >= 0.0) && (safx > -delta))
|| ((p.y()*v.y() >= 0.0) && (safy > -delta))
|| ((p.z()*v.z() >= 0.0) && (safz > -delta)) )
{
return kInfinity ; // travel away or parallel within tolerance
}
@@ -567,7 +581,7 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,const G4ThreeVector& v) cons
// Compute min / max distances for x/y/z travel:
// X Planes
if ( v.x())
if ( v.x() ) // != 0
{
stmp = 1.0/std::fabs(v.x()) ;
@@ -578,14 +592,14 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,const G4ThreeVector& v) cons
}
else
{
if (v.x() > 0) sOut = (fDx - p.x())*stmp ;
if (v.x() < 0) sOut = (fDx + p.x())*stmp ;
if (v.x() < 0) { sOut = (fDx + p.x())*stmp ; }
else { sOut = (fDx - p.x())*stmp ; }
}
}
// Y Planes
if ( v.y())
if ( v.y() ) // != 0
{
stmp = 1.0/std::fabs(v.y()) ;
@@ -594,54 +608,54 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,const G4ThreeVector& v) cons
sminy = safy*stmp ;
smaxy = (fDy+std::fabs(p.y()))*stmp ;
if (sminy > smin) smin=sminy ;
if (smaxy < smax) smax=smaxy ;
if (sminy > smin) { smin=sminy ; }
if (smaxy < smax) { smax=smaxy ; }
if (smin >= smax-kCarTolerance*0.5)
if (smin >= (smax-delta))
{
return kInfinity ; // touch XY corner
}
}
else
{
if (v.y() > 0) sOuty = (fDy - p.y())*stmp ;
if (v.y() < 0) sOuty = (fDy + p.y())*stmp ;
if( sOuty < sOut ) sOut = sOuty ;
if (v.y() < 0) { sOuty = (fDy + p.y())*stmp ; }
else { sOuty = (fDy - p.y())*stmp ; }
if( sOuty < sOut ) { sOut = sOuty ; }
}
}
// Z planes
if ( v.z() )
if ( v.z() ) // != 0
{
stmp = 1.0/std::fabs(v.z()) ;
if ( safz >= 0.0)
if ( safz >= 0.0 )
{
sminz = safz*stmp ;
smaxz = (fDz+std::fabs(p.z()))*stmp ;
if (sminz > smin) smin = sminz ;
if (smaxz < smax) smax = smaxz ;
if (sminz > smin) { smin = sminz ; }
if (smaxz < smax) { smax = smaxz ; }
if (smin >= smax-kCarTolerance*0.5)
if (smin >= (smax-delta))
{
return kInfinity ; // touch ZX or ZY corners
}
}
else
{
if (v.z() > 0) sOutz = (fDz - p.z())*stmp ;
if (v.z() < 0) sOutz = (fDz + p.z())*stmp ;
if( sOutz < sOut ) sOut = sOutz ;
if (v.z() < 0) { sOutz = (fDz + p.z())*stmp ; }
else { sOutz = (fDz - p.z())*stmp ; }
if( sOutz < sOut ) { sOut = sOutz ; }
}
}
if ( sOut <= smin + 0.5*kCarTolerance) // travel over edge
if (sOut <= (smin + delta)) // travel over edge
{
return kInfinity ;
}
if (smin < 0.5*kCarTolerance) smin = 0.0 ;
if (smin < delta) { smin = 0.0 ; }
return smin ;
}
@@ -661,16 +675,16 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p) const
safey = std::fabs(p.y()) - fDy ;
safez = std::fabs(p.z()) - fDz ;
if (safex > safe) safe = safex ;
if (safey > safe) safe = safey ;
if (safez > safe) safe = safez ;
if (safex > safe) { safe = safex ; }
if (safey > safe) { safe = safey ; }
if (safez > safe) { safe = safez ; }
return safe ;
}
/////////////////////////////////////////////////////////////////////////
//
// Calcluate distance to surface of box from inside
// Calculate distance to surface of box from inside
// by calculating distances to box's x/y/z planes.
// Smallest distance is exact distance to exiting.
// - Eliminate one side of each pair by considering direction of v
@@ -681,122 +695,125 @@ G4double G4Box::DistanceToOut( const G4ThreeVector& p,const G4ThreeVector& v,
G4bool *validNorm,G4ThreeVector *n) const
{
ESide side = kUndefined ;
G4double pdist,stmp,snxt;
G4double pdist,stmp,snxt=kInfinity;
if (calcNorm) *validNorm = true ; // All normals are valid
static const G4double delta = 0.5*kCarTolerance;
if (v.x() > 0) // X planes
if (calcNorm) { *validNorm = true ; } // All normals are valid
if (v.x() > 0) // X planes
{
pdist = fDx - p.x() ;
if (pdist > kCarTolerance*0.5)
if (pdist > delta)
{
snxt = pdist/v.x() ;
side = kPX ;
}
else
{
if (calcNorm) *n = G4ThreeVector(1,0,0) ;
return snxt = 0 ;
if (calcNorm) { *n = G4ThreeVector(1,0,0) ; }
return snxt = 0 ;
}
}
else if (v.x() < 0)
else if (v.x() < 0)
{
pdist = fDx + p.x() ;
if (pdist > kCarTolerance*0.5)
if (pdist > delta)
{
snxt = -pdist/v.x() ;
side = kMX ;
}
else
{
if (calcNorm) *n = G4ThreeVector(-1,0,0) ;
if (calcNorm) { *n = G4ThreeVector(-1,0,0) ; }
return snxt = 0 ;
}
}
else snxt = kInfinity ;
if ( v.y() > 0 ) // Y planes
if (v.y() > 0) // Y planes
{
pdist=fDy-p.y();
pdist = fDy-p.y();
if (pdist>kCarTolerance*0.5)
if (pdist > delta)
{
stmp=pdist/v.y();
stmp = pdist/v.y();
if (stmp<snxt)
if (stmp < snxt)
{
snxt=stmp;
side=kPY;
snxt = stmp;
side = kPY;
}
}
else
{
if (calcNorm) *n = G4ThreeVector(0,1,0) ;
return snxt = 0 ;
if (calcNorm) { *n = G4ThreeVector(0,1,0) ; }
return snxt = 0 ;
}
}
else if ( v.y() < 0 )
else if (v.y() < 0)
{
pdist = fDy + p.y() ;
if (pdist > kCarTolerance*0.5)
if (pdist > delta)
{
stmp=-pdist/v.y();
stmp = -pdist/v.y();
if (stmp<snxt)
if ( stmp < snxt )
{
snxt=stmp;
side=kMY;
snxt = stmp;
side = kMY;
}
}
else
{
if (calcNorm) *n = G4ThreeVector(0,-1,0) ;
return snxt = 0 ;
if (calcNorm) { *n = G4ThreeVector(0,-1,0) ; }
return snxt = 0 ;
}
}
if (v.z()>0) // Z planes
if (v.z() > 0) // Z planes
{
pdist=fDz-p.z();
pdist = fDz-p.z();
if (pdist > kCarTolerance*0.5)
if ( pdist > delta )
{
stmp=pdist/v.z();
stmp = pdist/v.z();
if (stmp < snxt)
if ( stmp < snxt )
{
snxt=stmp;
side=kPZ;
snxt = stmp;
side = kPZ;
}
}
else
{
if (calcNorm) *n = G4ThreeVector(0,0,1) ;
return snxt = 0 ;
if (calcNorm) { *n = G4ThreeVector(0,0,1) ; }
return snxt = 0 ;
}
}
else if (v.z()<0)
else if (v.z() < 0)
{
pdist = fDz + p.z() ;
pdist = fDz + p.z();
if (pdist > kCarTolerance*0.5)
if ( pdist > delta )
{
stmp=-pdist/v.z();
stmp = -pdist/v.z();
if (stmp < snxt)
if ( stmp < snxt )
{
snxt=stmp;
side=kMZ;
snxt = stmp;
side = kMZ;
}
}
else
{
if (calcNorm) *n = G4ThreeVector(0,0,-1) ;
return snxt = 0 ;
if (calcNorm) { *n = G4ThreeVector(0,0,-1) ; }
return snxt = 0 ;
}
}
if (calcNorm)
{
switch (side)
@@ -833,6 +850,7 @@ G4double G4Box::DistanceToOut( const G4ThreeVector& p,const G4ThreeVector& v,
G4cout << "v.z() = " << v.z() << G4endl << G4endl;
G4cout << "Proposed distance :" << G4endl << G4endl;
G4cout << "snxt = " << snxt/mm << " mm" << G4endl << G4endl;
G4cout.precision(6);
G4Exception("G4Box::DistanceToOut(p,v,..)","Notification",JustWarning,
"Undefined side for valid surface normal to solid.");
break;
@@ -853,13 +871,14 @@ G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4cout.precision(16) ;
G4int oldprc = G4cout.precision(16) ;
G4cout << G4endl ;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl ;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
G4cout.precision(oldprc) ;
G4Exception("G4Box::DistanceToOut(p)", "Notification", JustWarning,
"Point p is outside !?" );
}
@@ -874,14 +893,14 @@ G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
// shortest Dist to any boundary now MIN(safx1,safx2,safy1..)
if (safx2 < safx1) safe = safx2 ;
else safe = safx1 ;
if (safy1 < safe) safe = safy1 ;
if (safy2 < safe) safe = safy2 ;
if (safz1 < safe) safe = safz1 ;
if (safz2 < safe) safe = safz2 ;
if (safx2 < safx1) { safe = safx2; }
else { safe = safx1; }
if (safy1 < safe) { safe = safy1; }
if (safy2 < safe) { safe = safy2; }
if (safz1 < safe) { safe = safz1; }
if (safz2 < safe) { safe = safz2; }
if (safe < 0) safe = 0 ;
if (safe < 0) { safe = 0 ; }
return safe ;
}
@@ -898,10 +917,10 @@ G4ThreeVectorList*
G4Box::CreateRotatedVertices(const G4AffineTransform& pTransform) const
{
G4ThreeVectorList* vertices = new G4ThreeVectorList();
vertices->reserve(8);
if (vertices)
{
vertices->reserve(8);
G4ThreeVector vertex0(-fDx,-fDy,-fDz) ;
G4ThreeVector vertex1(fDx,-fDy,-fDz) ;
G4ThreeVector vertex2(fDx,fDy,-fDz) ;
@@ -978,28 +997,37 @@ G4ThreeVector G4Box::GetPointOnSurface() const
px = -fDx +2*fDx*G4UniformRand();
py = -fDy +2*fDy*G4UniformRand();
if(G4UniformRand() > 0.5) pz = fDz;
else pz = -fDz;
if(G4UniformRand() > 0.5) { pz = fDz; }
else { pz = -fDz; }
}
else if ( ( select - Sxy ) < Sxz )
{
px = -fDx +2*fDx*G4UniformRand();
pz = -fDz +2*fDz*G4UniformRand();
if(G4UniformRand() > 0.5) py = fDy;
else py = -fDy;
if(G4UniformRand() > 0.5) { py = fDy; }
else { py = -fDy; }
}
else
{
py = -fDy +2*fDy*G4UniformRand();
pz = -fDz +2*fDz*G4UniformRand();
if(G4UniformRand() > 0.5) px = fDx;
else px = -fDx;
if(G4UniformRand() > 0.5) { px = fDx; }
else { px = -fDx; }
}
return G4ThreeVector(px,py,pz);
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Box::Clone() const
{
return new G4Box(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Methods for visualisation
+41 -2
View File
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4CSGSolid.cc,v 1.13 2006/10/19 15:33:37 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4CSGSolid.cc,v 1.16 2010/10/19 15:42:09 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// --------------------------------------------------------------------
@@ -53,11 +53,50 @@ G4CSGSolid::G4CSGSolid( __void__& a )
{
}
//////////////////////////////////////////////////////////////////////////
//
// Destructor
//
G4CSGSolid::~G4CSGSolid()
{
delete fpPolyhedron;
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
//
G4CSGSolid::G4CSGSolid(const G4CSGSolid& rhs)
: G4VSolid(rhs), fCubicVolume(rhs.fCubicVolume),
fSurfaceArea(rhs.fSurfaceArea), fpPolyhedron(0)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4VSolid::operator=(rhs);
// Copy data
//
fCubicVolume = rhs.fCubicVolume;
fSurfaceArea = rhs.fSurfaceArea;
fpPolyhedron = 0;
return *this;
}
std::ostream& G4CSGSolid::StreamInfo(std::ostream& os) const
{
os << "-----------------------------------------------------------\n"
+77 -28
View File
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4Cons.cc,v 1.67 2009/11/12 11:53:11 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4Cons.cc,v 1.73 2010/10/19 15:42:09 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
// class G4Cons
@@ -80,18 +80,15 @@ G4Cons::G4Cons( const G4String& pName,
G4double pRmin2, G4double pRmax2,
G4double pDz,
G4double pSPhi, G4double pDPhi)
: G4CSGSolid(pName), fSPhi(0), fDPhi(0)
: G4CSGSolid(pName), fRmin1(pRmin1), fRmin2(pRmin2),
fRmax1(pRmax1), fRmax2(pRmax2), fDz(pDz), fSPhi(0.), fDPhi(0.)
{
kRadTolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance();
kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance();
// Check z-len
//
if ( pDz > 0 )
{
fDz = pDz;
}
else
if ( pDz < 0 )
{
G4cerr << "ERROR - G4Cons()::G4Cons(): " << GetName() << G4endl
<< " Negative Z half-length ! - "
@@ -102,17 +99,7 @@ G4Cons::G4Cons( const G4String& pName,
// Check radii
//
if ( (pRmin1<pRmax1) && (pRmin2<pRmax2) && (pRmin1>=0) && (pRmin2>=0) )
{
fRmin1 = pRmin1 ;
fRmax1 = pRmax1 ;
fRmin2 = pRmin2 ;
fRmax2 = pRmax2 ;
if( (pRmin1 == 0.0) && (pRmin2 > 0.0) ) { fRmin1 = 1e3*kRadTolerance ; }
if( (pRmin2 == 0.0) && (pRmin1 > 0.0) ) { fRmin2 = 1e3*kRadTolerance ; }
}
else
if (((pRmin1>=pRmax1) || (pRmin2>=pRmax2) || (pRmin1<0)) && (pRmin2<0))
{
G4cerr << "ERROR - G4Cons()::G4Cons(): " << GetName() << G4endl
<< " Invalide values for radii ! - "
@@ -121,6 +108,8 @@ G4Cons::G4Cons( const G4String& pName,
G4Exception("G4Cons::G4Cons()", "InvalidSetup",
FatalException, "Invalid radii.") ;
}
if( (pRmin1 == 0.0) && (pRmin2 > 0.0) ) { fRmin1 = 1e3*kRadTolerance ; }
if( (pRmin2 == 0.0) && (pRmin1 > 0.0) ) { fRmin2 = 1e3*kRadTolerance ; }
// Check angles
//
@@ -133,7 +122,11 @@ G4Cons::G4Cons( const G4String& pName,
// for usage restricted to object persistency.
//
G4Cons::G4Cons( __void__& a )
: G4CSGSolid(a)
: G4CSGSolid(a), kRadTolerance(0.), kAngTolerance(0.),
fRmin1(0.), fRmin2(0.), fRmax1(0.), fRmax2(0.), fDz(0.),
fSPhi(0.), fDPhi(0.), sinCPhi(0.), cosCPhi(0.), cosHDPhiOT(0.),
cosHDPhiIT(0.), sinSPhi(0.), cosSPhi(0.), sinEPhi(0.), cosEPhi(0.),
fPhiFullCone(false)
{
}
@@ -145,6 +138,51 @@ G4Cons::~G4Cons()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4Cons::G4Cons(const G4Cons& rhs)
: G4CSGSolid(rhs), kRadTolerance(rhs.kRadTolerance),
kAngTolerance(rhs.kAngTolerance), fRmin1(rhs.fRmin1), fRmin2(rhs.fRmin2),
fRmax1(rhs.fRmax1), fRmax2(rhs.fRmax2), fDz(rhs.fDz), fSPhi(rhs.fSPhi),
fDPhi(rhs.fDPhi), sinCPhi(rhs.sinCPhi), cosCPhi(rhs.cosCPhi),
cosHDPhiOT(rhs.cosHDPhiOT), cosHDPhiIT(rhs.cosHDPhiIT),
sinSPhi(rhs.sinSPhi), cosSPhi(rhs.cosSPhi), sinEPhi(rhs.sinEPhi),
cosEPhi(rhs.cosEPhi), fPhiFullCone(rhs.fPhiFullCone)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4Cons& G4Cons::operator = (const G4Cons& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4CSGSolid::operator=(rhs);
// Copy data
//
kRadTolerance = rhs.kRadTolerance;
kAngTolerance = rhs.kAngTolerance;
fRmin1 = rhs.fRmin1; fRmin2 = rhs.fRmin2;
fRmax1 = rhs.fRmax1; fRmax2 = rhs.fRmax2;
fDz = rhs.fDz; fSPhi = rhs.fSPhi; fDPhi = rhs.fDPhi;
sinCPhi = rhs.sinCPhi; cosCPhi = rhs.cosCPhi;
cosHDPhiOT = rhs.cosHDPhiOT; cosHDPhiIT = rhs.cosHDPhiIT;
sinSPhi = rhs.sinSPhi; cosSPhi = rhs.cosSPhi;
sinEPhi = rhs.sinEPhi; cosEPhi = rhs.cosEPhi;
fPhiFullCone = rhs.fPhiFullCone;
return *this;
}
/////////////////////////////////////////////////////////////////////
//
// Return whether point inside/outside/on surface
@@ -624,7 +662,7 @@ G4ThreeVector G4Cons::ApproxSurfaceNormal( const G4ThreeVector& p ) const
rho *= secRMax ;
norm = G4ThreeVector(p.x()/rho, p.y()/rho, -tanRMax/secRMax) ;
break ;
case kNZ: // +/- dz
case kNZ: // +/- dz
if (p.z() > 0) { norm = G4ThreeVector(0,0,1); }
else { norm = G4ThreeVector(0,0,-1); }
break ;
@@ -634,7 +672,7 @@ G4ThreeVector G4Cons::ApproxSurfaceNormal( const G4ThreeVector& p ) const
case kNEPhi:
norm=G4ThreeVector(-std::sin(fSPhi+fDPhi), std::cos(fSPhi+fDPhi), 0) ;
break ;
default:
default: // Should never reach this case...
DumpInfo();
G4Exception("G4Cons::ApproxSurfaceNormal()", "Notification", JustWarning,
"Undefined side for valid surface normal to solid.") ;
@@ -1828,8 +1866,8 @@ G4double G4Cons::DistanceToOut( const G4ThreeVector& p,
// Check intersecting with correct half-plane
// (if not -> no intersect)
//
if ( (std::abs(xi)<=kCarTolerance)
&& (std::abs(yi)<=kCarTolerance) )
if ( (std::fabs(xi)<=kCarTolerance)
&& (std::fabs(yi)<=kCarTolerance) )
{
sidephi= kSPhi;
if ( ( fSPhi-halfAngTolerance <= vphi )
@@ -1875,8 +1913,8 @@ G4double G4Cons::DistanceToOut( const G4ThreeVector& p,
// Check intersecting with correct half-plane
if ( (std::abs(xi)<=kCarTolerance)
&& (std::abs(yi)<=kCarTolerance) )
if ( (std::fabs(xi)<=kCarTolerance)
&& (std::fabs(yi)<=kCarTolerance) )
{
// Leaving via ending phi
@@ -1997,6 +2035,7 @@ G4double G4Cons::DistanceToOut( const G4ThreeVector& p,
G4cout << "v.z() = " << v.z() << G4endl<< G4endl ;
G4cout << "Proposed distance :" << G4endl<< G4endl ;
G4cout << "snxt = " << snxt/mm << " mm" << G4endl << G4endl ;
G4cout.precision(6) ;
G4Exception("G4Cons::DistanceToOut(p,v,..)","Notification",JustWarning,
"Undefined side for valid surface normal to solid.") ;
break ;
@@ -2020,7 +2059,7 @@ G4double G4Cons::DistanceToOut(const G4ThreeVector& p) const
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4cout.precision(16) ;
G4int oldprc=G4cout.precision(16) ;
G4cout << G4endl ;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl ;
@@ -2034,6 +2073,7 @@ G4double G4Cons::DistanceToOut(const G4ThreeVector& p) const
G4cout << "point phi = " << std::atan2(p.y(),p.x())/degree
<< " degree" << G4endl << G4endl ;
}
G4cout.precision(oldprc) ;
G4Exception("G4Cons::DistanceToOut(p)", "Notification",
JustWarning, "Point p is outside !?" );
}
@@ -2134,10 +2174,10 @@ G4Cons::CreateRotatedVertices(const G4AffineTransform& pTransform) const
sAngle = fSPhi ;
}
vertices = new G4ThreeVectorList();
vertices->reserve(noCrossSections*4) ;
if (vertices)
{
vertices->reserve(noCrossSections*4) ;
for (crossSection = 0 ; crossSection < noCrossSections ; crossSection++)
{
// Compute coordinates of cross section at section crossSection
@@ -2187,6 +2227,15 @@ G4GeometryType G4Cons::GetEntityType() const
return G4String("G4Cons");
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Cons::Clone() const
{
return new G4Cons(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Stream object contents to an output stream
+111 -72
View File
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4Orb.cc,v 1.30 2009/11/30 10:20:38 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4Orb.cc,v 1.35 2010/10/19 15:42:10 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// class G4Orb
//
@@ -74,8 +74,8 @@ const G4double G4Orb::fEpsilon = 2.e-11; // relative tolerance of fRmax
// constructor - check positive radius
//
G4Orb::G4Orb( const G4String& pName,G4double pRmax )
: G4CSGSolid(pName)
G4Orb::G4Orb( const G4String& pName, G4double pRmax )
: G4CSGSolid(pName), fRmax(pRmax)
{
G4double kRadTolerance
@@ -83,11 +83,7 @@ G4Orb::G4Orb( const G4String& pName,G4double pRmax )
// Check radius
//
if (pRmax >= 10*kCarTolerance )
{
fRmax = pRmax;
}
else
if ( pRmax < 10*kCarTolerance )
{
G4Exception("G4Orb::G4Orb()", "InvalidSetup", FatalException,
"Invalid radius > 10*kCarTolerance.");
@@ -102,7 +98,7 @@ G4Orb::G4Orb( const G4String& pName,G4double pRmax )
// for usage restricted to object persistency.
//
G4Orb::G4Orb( __void__& a )
: G4CSGSolid(a)
: G4CSGSolid(a), fRmax(0.), fRmaxTolerance(0.)
{
}
@@ -114,14 +110,45 @@ G4Orb::~G4Orb()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4Orb::G4Orb(const G4Orb& rhs)
: G4CSGSolid(rhs), fRmax(rhs.fRmax), fRmaxTolerance(rhs.fRmaxTolerance)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4Orb& G4Orb::operator = (const G4Orb& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4CSGSolid::operator=(rhs);
// Copy data
//
fRmax = rhs.fRmax;
fRmaxTolerance = rhs.fRmaxTolerance;
return *this;
}
//////////////////////////////////////////////////////////////////////////
//
// Dispatch to parameterisation for replication mechanism dimension
// computation & modification.
void G4Orb::ComputeDimensions( G4VPVParameterisation* p,
const G4int n,
const G4VPhysicalVolume* pRep)
const G4int n,
const G4VPhysicalVolume* pRep )
{
p->ComputeDimensions(*this,n,pRep);
}
@@ -295,7 +322,7 @@ EInside G4Orb::Inside( const G4ThreeVector& p ) const
EInside in;
rad2 = p.x()*p.x()+p.y()*p.y()+p.z()*p.z() ;
rad2 = p.x()*p.x()+p.y()*p.y()+p.z()*p.z();
G4double rad = std::sqrt(rad2);
@@ -303,14 +330,14 @@ EInside G4Orb::Inside( const G4ThreeVector& p ) const
// Check radial surface
// sets `in'
tolRMax = fRmax - fRmaxTolerance*0.5 ;
tolRMax = fRmax - fRmaxTolerance*0.5;
if ( rad <= tolRMax ) { in = kInside ; }
if ( rad <= tolRMax ) { in = kInside; }
else
{
tolRMax = fRmax + fRmaxTolerance*0.5 ;
if ( rad <= tolRMax ) { in = kSurface ; }
else { in = kOutside ; }
tolRMax = fRmax + fRmaxTolerance*0.5;
if ( rad <= tolRMax ) { in = kSurface; }
else { in = kOutside; }
}
return in;
}
@@ -332,12 +359,10 @@ G4ThreeVector G4Orb::SurfaceNormal( const G4ThreeVector& p ) const
case kNRMax:
norm = G4ThreeVector(p.x()/rad,p.y()/rad,p.z()/rad);
break;
default:
default: // Should never reach this case ...
DumpInfo();
#ifdef G4CSGDEBUG
G4Exception("G4Orb::SurfaceNormal()", "Notification", JustWarning,
"Undefined side for valid surface normal to solid.");
#endif
break;
}
@@ -356,22 +381,22 @@ G4ThreeVector G4Orb::SurfaceNormal( const G4ThreeVector& p ) const
G4double G4Orb::DistanceToIn( const G4ThreeVector& p,
const G4ThreeVector& v ) const
{
G4double snxt = kInfinity ; // snxt = default return value
G4double snxt = kInfinity; // snxt = default return value
G4double rad2, pDotV3d, tolORMax2, tolIRMax2 ;
G4double c, d2, s = kInfinity ;
G4double rad, pDotV3d; // , tolORMax2, tolIRMax2;
G4double c, d2, s = kInfinity;
const G4double dRmax = 100.*fRmax;
// General Precalcs
rad2 = p.x()*p.x() + p.y()*p.y() + p.z()*p.z() ;
pDotV3d = p.x()*v.x() + p.y()*v.y() + p.z()*v.z() ;
rad = std::sqrt(p.x()*p.x() + p.y()*p.y() + p.z()*p.z());
pDotV3d = p.x()*v.x() + p.y()*v.y() + p.z()*v.z();
// Radial Precalcs
tolORMax2 = (fRmax+fRmaxTolerance*0.5)*(fRmax+fRmaxTolerance*0.5) ;
tolIRMax2 = (fRmax-fRmaxTolerance*0.5)*(fRmax-fRmaxTolerance*0.5) ;
// tolORMax2 = (fRmax+fRmaxTolerance*0.5)*(fRmax+fRmaxTolerance*0.5);
// tolIRMax2 = (fRmax-fRmaxTolerance*0.5)*(fRmax-fRmaxTolerance*0.5);
// Outer spherical shell intersection
// - Only if outside tolerant fRmax
@@ -387,57 +412,59 @@ G4double G4Orb::DistanceToIn( const G4ThreeVector& p,
//
// => s=-pDotV3d+-std::sqrt(pDotV3d^2-(rad2-R^2))
G4double rad = std::sqrt(rad2);
c = (rad - fRmax)*(rad + fRmax);
if ( c > fRmaxTolerance*fRmax )
if( rad > fRmax-fRmaxTolerance*0.5 ) // not inside in terms of Inside(p)
{
// If outside tolerant boundary of outer G4Orb
// [ should be std::sqrt(rad2) - fRmax > fRmaxTolerance*0.5 ]
d2 = pDotV3d*pDotV3d - c ;
if ( d2 >= 0 )
if ( c > fRmaxTolerance*fRmax )
{
s = -pDotV3d - std::sqrt(d2) ;
if ( s >= 0 )
// If outside tolerant boundary of outer G4Orb in terms of c
// [ should be std::sqrt(rad2) - fRmax > fRmaxTolerance*0.5 ]
d2 = pDotV3d*pDotV3d - c;
if ( d2 >= 0 )
{
if ( s>dRmax ) // Avoid rounding errors due to precision issues seen on
{ // 64 bits systems. Split long distances and recompute
G4double fTerm = s-std::fmod(s,dRmax);
s = fTerm + DistanceToIn(p+fTerm*v,v);
}
return snxt = s;
s = -pDotV3d - std::sqrt(d2);
if ( s >= 0 )
{
if ( s > dRmax ) // Avoid rounding errors due to precision issues seen on
{ // 64 bits systems. Split long distances and recompute
G4double fTerm = s - std::fmod(s,dRmax);
s = fTerm + DistanceToIn(p+fTerm*v,v);
}
return snxt = s;
}
}
}
else // No intersection with G4Orb
{
return snxt = kInfinity;
}
}
else
{
if ( c > -fRmaxTolerance*fRmax ) // on surface
{
d2 = pDotV3d*pDotV3d - c ;
if ( (d2 < fRmaxTolerance*fRmax) || (pDotV3d >= 0) )
else // No intersection with G4Orb
{
return snxt = kInfinity;
}
else
}
else // not outside in terms of c
{
if ( c > -fRmaxTolerance*fRmax ) // on surface
{
return snxt = 0.;
d2 = pDotV3d*pDotV3d - c;
if ( (d2 < fRmaxTolerance*fRmax) || (pDotV3d >= 0) )
{
return snxt = kInfinity;
}
else
{
return snxt = 0.;
}
}
}
}
#ifdef G4CSGDEBUG
else // inside ???
{
else // inside ???
{
G4Exception("G4Orb::DistanceToIn(p,v)", "Notification",
JustWarning, "Point p is inside !?");
}
#endif
}
#endif
return snxt;
}
@@ -519,15 +546,15 @@ G4double G4Orb::DistanceToOut( const G4ThreeVector& p,
{
if(calcNorm)
{
*validNorm = true ;
*n = G4ThreeVector(p.x()/fRmax,p.y()/fRmax,p.z()/fRmax) ;
*validNorm = true;
*n = G4ThreeVector(p.x()/fRmax,p.y()/fRmax,p.z()/fRmax);
}
return snxt = 0;
}
else
{
snxt = -pDotV3d + std::sqrt(d2); // second root since inside Rmax
side = kRMax ;
side = kRMax;
}
}
}
@@ -548,6 +575,7 @@ G4double G4Orb::DistanceToOut( const G4ThreeVector& p,
G4cout << "v.z() = " << v.z() << G4endl << G4endl;
G4cout << "Proposed distance :" << G4endl << G4endl;
G4cout << "snxt = " << snxt/mm << " mm" << G4endl << G4endl;
G4cout.precision(6);
G4Exception("G4Orb::DistanceToOut(p,v,..)", "Notification",
JustWarning, "Logic error: snxt = kInfinity ???");
}
@@ -576,6 +604,7 @@ G4double G4Orb::DistanceToOut( const G4ThreeVector& p,
G4cout << "v.z() = " << v.z() << G4endl << G4endl;
G4cout << "Proposed distance :" << G4endl << G4endl;
G4cout << "snxt = " << snxt/mm << " mm" << G4endl << G4endl;
G4cout.precision(6);
G4Exception("G4Orb::DistanceToOut(p,v,..)","Notification",JustWarning,
"Undefined side for valid surface normal to solid.");
break;
@@ -595,13 +624,14 @@ G4double G4Orb::DistanceToOut( const G4ThreeVector& p ) const
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4cout.precision(16) ;
G4cout << G4endl ;
G4int oldprc = G4cout.precision(16);
G4cout << G4endl;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl ;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
G4cout << "Position:" << G4endl << G4endl;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl;
G4cout.precision(oldprc);
G4Exception("G4Orb::DistanceToOut(p)", "Notification", JustWarning,
"Point p is outside !?" );
}
@@ -621,6 +651,15 @@ G4GeometryType G4Orb::GetEntityType() const
return G4String("G4Orb");
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Orb::Clone() const
{
return new G4Orb(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Stream object contents to an output stream
+69 -35
View File
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4Para.cc,v 1.39 2006/10/19 15:33:37 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4Para.cc,v 1.43 2010/10/19 15:42:10 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// class G4Para
//
@@ -104,11 +104,7 @@ G4Para::G4Para(const G4String& pName,
G4double pAlpha, G4double pTheta, G4double pPhi)
: G4CSGSolid(pName)
{
if (pDx>0&&pDy>0&&pDz>0)
{
SetAllParameters( pDx, pDy, pDz, pAlpha, pTheta, pPhi);
}
else
if ((pDx<=0) || (pDy<=0) || (pDz<=0))
{
G4cerr << "ERROR - G4Para()::G4Para(): " << GetName() << G4endl
<< " Invalid dimensions ! - "
@@ -116,6 +112,7 @@ G4Para::G4Para(const G4String& pName,
G4Exception("G4Para::G4Para()", "InvalidSetup",
FatalException, "Invalid Length Parameters.");
}
SetAllParameters( pDx, pDy, pDz, pAlpha, pTheta, pPhi);
}
////////////////////////////////////////////////////////////////////////
@@ -128,37 +125,29 @@ G4Para::G4Para( const G4String& pName,
const G4ThreeVector pt[8] )
: G4CSGSolid(pName)
{
if ( pt[0].z()<0 && pt[0].z()==pt[1].z() && pt[0].z()==pt[2].z() &&
pt[0].z()==pt[3].z() && pt[4].z()>0 && pt[4].z()==pt[5].z() &&
pt[4].z()==pt[6].z() && pt[4].z()==pt[7].z() &&
(pt[0].z()+pt[4].z())==0 &&
pt[0].y()==pt[1].y() && pt[2].y()==pt[3].y() &&
pt[4].y()==pt[5].y() && pt[6].y()==pt[7].y() &&
( pt[0].y() + pt[2].y() + pt[4].y() + pt[6].y() ) == 0 &&
( pt[0].x() + pt[1].x() + pt[4].x() + pt[5].x() ) == 0)
{
fDz = (pt[7]).z() ;
fDy = ((pt[2]).y()-(pt[1]).y())*0.5 ;
fDx = ((pt[1]).x()-(pt[0]).x())*0.5 ;
fDx = ((pt[3]).x()-(pt[2]).x())*0.5 ;
fTalpha = ((pt[2]).x()+(pt[3]).x()-(pt[1]).x()-(pt[0]).x())*0.25/fDy ;
// fDy = ((pt[6]).y()-(pt[5]).y())*0.5 ;
// fDx = ((pt[5]).x()-(pt[4]).x())*0.5 ;
// fDx = ((pt[7]).x()-(pt[6]).x())*0.5 ;
// fTalpha = ((pt[6]).x()+(pt[7]).x()-(pt[5]).x()-(pt[4]).x())*0.25/fDy ;
fTthetaCphi = ((pt[4]).x()+fDy*fTalpha+fDx)/fDz ;
fTthetaSphi = ((pt[4]).y()+fDy)/fDz ;
}
else
if (!( pt[0].z()<0 && pt[0].z()==pt[1].z() && pt[0].z()==pt[2].z() &&
pt[0].z()==pt[3].z() && pt[4].z()>0 && pt[4].z()==pt[5].z() &&
pt[4].z()==pt[6].z() && pt[4].z()==pt[7].z() &&
(pt[0].z()+pt[4].z())==0 &&
pt[0].y()==pt[1].y() && pt[2].y()==pt[3].y() &&
pt[4].y()==pt[5].y() && pt[6].y()==pt[7].y() &&
( pt[0].y() + pt[2].y() + pt[4].y() + pt[6].y() ) == 0 &&
( pt[0].x() + pt[1].x() + pt[4].x() + pt[5].x() ) == 0) )
{
G4cerr << "ERROR - G4Para()::G4Para(): " << GetName() << G4endl
<< " Invalid dimensions !" << G4endl;
G4Exception("G4Para::G4Para()", "InvalidSetup",
FatalException, "Invalid vertice coordinates.");
}
fDx = ((pt[3]).x()-(pt[2]).x())*0.5;
fDy = ((pt[2]).y()-(pt[1]).y())*0.5;
fDz = (pt[7]).z();
fTalpha = ((pt[2]).x()+(pt[3]).x()-(pt[1]).x()-(pt[0]).x())*0.25/fDy ;
fTthetaCphi = ((pt[4]).x()+fDy*fTalpha+fDx)/fDz ;
fTthetaSphi = ((pt[4]).y()+fDy)/fDz ;
fCubicVolume = 0.;
fSurfaceArea = 0.;
fpPolyhedron = 0;
}
///////////////////////////////////////////////////////////////////////
@@ -167,7 +156,8 @@ G4Para::G4Para( const G4String& pName,
// for usage restricted to object persistency.
//
G4Para::G4Para( __void__& a )
: G4CSGSolid(a)
: G4CSGSolid(a), fDx(0.), fDy(0.), fDz(0.),
fTalpha(0.), fTthetaCphi(0.), fTthetaSphi(0.)
{
}
@@ -178,6 +168,40 @@ G4Para::~G4Para()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4Para::G4Para(const G4Para& rhs)
: G4CSGSolid(rhs), fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz),
fTalpha(rhs.fTalpha), fTthetaCphi(rhs.fTthetaCphi),
fTthetaSphi(rhs.fTthetaSphi)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4Para& G4Para::operator = (const G4Para& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4CSGSolid::operator=(rhs);
// Copy data
//
fDx = rhs.fDx; fDy = rhs.fDy; fDz = rhs.fDz;
fTalpha = rhs.fTalpha; fTthetaCphi = rhs.fTthetaCphi;
fTthetaSphi = rhs.fTthetaSphi;
return *this;
}
//////////////////////////////////////////////////////////////////////////
//
// Dispatch to parameterisation for replication mechanism dimension
@@ -1100,13 +1124,14 @@ G4double G4Para::DistanceToOut( const G4ThreeVector& p ) const
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4cout.precision(16) ;
G4int oldprc = G4cout.precision(16) ;
G4cout << G4endl ;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl ;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
G4cout.precision(oldprc) ;
G4Exception("G4Para::DistanceToOut(p)", "Notification",
JustWarning, "Point p is outside !?" );
}
@@ -1162,9 +1187,9 @@ G4Para::CreateRotatedVertices( const G4AffineTransform& pTransform ) const
{
G4ThreeVectorList *vertices;
vertices=new G4ThreeVectorList();
vertices->reserve(8);
if (vertices)
{
vertices->reserve(8);
G4ThreeVector vertex0(-fDz*fTthetaCphi-fDy*fTalpha-fDx,
-fDz*fTthetaSphi-fDy, -fDz);
G4ThreeVector vertex1(-fDz*fTthetaCphi-fDy*fTalpha+fDx,
@@ -1210,6 +1235,15 @@ G4GeometryType G4Para::GetEntityType() const
return G4String("G4Para");
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Para::Clone() const
{
return new G4Para(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Stream object contents to an output stream
+96 -24
View File
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4Sphere.cc,v 1.84 2009/08/07 15:56:23 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4Sphere.cc,v 1.90 2010/11/23 14:45:56 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// class G4Sphere
//
@@ -82,6 +82,8 @@ enum ESide {kNull,kRMin,kRMax,kSPhi,kEPhi,kSTheta,kETheta};
enum ENorm {kNRMin,kNRMax,kNSPhi,kNEPhi,kNSTheta,kNETheta};
const G4double G4Sphere::fEpsilon = 2.e-11; // relative tolerance of radii
////////////////////////////////////////////////////////////////////////
//
// constructor - check parameters, convert angles so 0<sphi+dpshi<=2_PI
@@ -93,21 +95,13 @@ G4Sphere::G4Sphere( const G4String& pName,
G4double pSTheta, G4double pDTheta )
: G4CSGSolid(pName), fFullPhiSphere(true), fFullThetaSphere(true)
{
fEpsilon = 2.0e-11; // relative radial tolerance constant
kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance();
// Check radii and set radial tolerances
G4double kRadTolerance = G4GeometryTolerance::GetInstance()
->GetRadialTolerance();
if ( (pRmin < pRmax) && (pRmax >= 10*kRadTolerance) && (pRmin >= 0) )
{
fRmin=pRmin; fRmax=pRmax;
fRminTolerance = (pRmin) ? std::max( kRadTolerance, fEpsilon*fRmin ) : 0;
fRmaxTolerance = std::max( kRadTolerance, fEpsilon*fRmax );
}
else
if ( (pRmin >= pRmax) || (pRmax < 10*kRadTolerance) || (pRmin < 0) )
{
G4cerr << "ERROR - G4Sphere()::G4Sphere(): " << GetName() << G4endl
<< " Invalide values for radii ! - "
@@ -115,6 +109,9 @@ G4Sphere::G4Sphere( const G4String& pName,
G4Exception("G4Sphere::G4Sphere()", "InvalidSetup", FatalException,
"Invalid radii");
}
fRmin=pRmin; fRmax=pRmax;
fRminTolerance = (pRmin) ? std::max( kRadTolerance, fEpsilon*fRmin ) : 0;
fRmaxTolerance = std::max( kRadTolerance, fEpsilon*fRmax );
// Check angles
@@ -128,7 +125,13 @@ G4Sphere::G4Sphere( const G4String& pName,
// for usage restricted to object persistency.
//
G4Sphere::G4Sphere( __void__& a )
: G4CSGSolid(a)
: G4CSGSolid(a), fRminTolerance(0.), fRmaxTolerance(0.), kAngTolerance(0.),
fRmin(0.), fRmax(0.), fSPhi(0.), fDPhi(0.), fSTheta(0.),
fDTheta(0.), sinCPhi(0.), cosCPhi(0.), cosHDPhiOT(0.), cosHDPhiIT(0.),
sinSPhi(0.), cosSPhi(0.), sinEPhi(0.), cosEPhi(0.), hDPhi(0.), cPhi(0.),
ePhi(0.), sinSTheta(0.), cosSTheta(0.), sinETheta(0.), cosETheta(0.),
tanSTheta(0.), tanSTheta2(0.), tanETheta(0.), tanETheta2(0.), eTheta(0.),
fFullPhiSphere(false), fFullThetaSphere(false), fFullSphere(true)
{
}
@@ -140,6 +143,63 @@ G4Sphere::~G4Sphere()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4Sphere::G4Sphere(const G4Sphere& rhs)
: G4CSGSolid(rhs), fRminTolerance(rhs.fRminTolerance),
fRmaxTolerance(rhs.fRmaxTolerance), kAngTolerance(rhs.kAngTolerance),
fRmin(rhs.fRmin), fRmax(rhs.fRmax), fSPhi(rhs.fSPhi), fDPhi(rhs.fDPhi),
fSTheta(rhs.fSTheta), fDTheta(rhs.fDTheta),
sinCPhi(rhs.sinCPhi), cosCPhi(rhs.cosCPhi),
cosHDPhiOT(rhs.cosHDPhiOT), cosHDPhiIT(rhs.cosHDPhiIT),
sinSPhi(rhs.sinSPhi), cosSPhi(rhs.cosSPhi),
sinEPhi(rhs.sinEPhi), cosEPhi(rhs.cosEPhi),
hDPhi(rhs.hDPhi), cPhi(rhs.cPhi), ePhi(rhs.ePhi),
sinSTheta(rhs.sinSTheta), cosSTheta(rhs.cosSTheta),
sinETheta(rhs.sinETheta), cosETheta(rhs.cosETheta),
tanSTheta(rhs.tanSTheta), tanSTheta2(rhs.tanSTheta2),
tanETheta(rhs.tanETheta), tanETheta2(rhs.tanETheta2), eTheta(rhs.eTheta),
fFullPhiSphere(rhs.fFullPhiSphere), fFullThetaSphere(rhs.fFullThetaSphere),
fFullSphere(rhs.fFullSphere)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4Sphere& G4Sphere::operator = (const G4Sphere& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4CSGSolid::operator=(rhs);
// Copy data
//
fRminTolerance = rhs.fRminTolerance; fRmaxTolerance = rhs.fRmaxTolerance;
kAngTolerance = rhs.kAngTolerance; fRmin = rhs.fRmin; fRmax = rhs.fRmax;
fSPhi = rhs.fSPhi; fDPhi = rhs.fDPhi; fSTheta = rhs.fSTheta;
fDTheta = rhs.fDTheta; sinCPhi = rhs.sinCPhi; cosCPhi = rhs.cosCPhi;
cosHDPhiOT = rhs.cosHDPhiOT; cosHDPhiIT = rhs.cosHDPhiIT;
sinSPhi = rhs.sinSPhi; cosSPhi = rhs.cosSPhi;
sinEPhi = rhs.sinEPhi; cosEPhi = rhs.cosEPhi;
hDPhi = rhs.hDPhi; cPhi = rhs.cPhi; ePhi = rhs.ePhi;
sinSTheta = rhs.sinSTheta; cosSTheta = rhs.cosSTheta;
sinETheta = rhs.sinETheta; cosETheta = rhs.cosETheta;
tanSTheta = rhs.tanSTheta; tanSTheta2 = rhs.tanSTheta2;
tanETheta = rhs.tanETheta; tanETheta2 = rhs.tanETheta2;
eTheta = rhs.eTheta; fFullPhiSphere = rhs.fFullPhiSphere;
fFullThetaSphere = rhs.fFullThetaSphere; fFullSphere = rhs.fFullSphere;
return *this;
}
//////////////////////////////////////////////////////////////////////////
//
// Dispatch to parameterisation for replication mechanism dimension
@@ -759,7 +819,7 @@ G4ThreeVector G4Sphere::ApproxSurfaceNormal( const G4ThreeVector& p ) const
cosETheta*std::sin(pPhi),
-sinETheta );
break;
default:
default: // Should never reach this case ...
DumpInfo();
G4Exception("G4Sphere::ApproxSurfaceNormal()","Notification",JustWarning,
"Undefined side for valid surface normal to solid.");
@@ -2296,7 +2356,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
// Check intersection with correct half-plane (if not -> no intersect)
//
if( (std::abs(xi)<=kCarTolerance) && (std::abs(yi)<=kCarTolerance) )
if( (std::fabs(xi)<=kCarTolerance) && (std::fabs(yi)<=kCarTolerance) )
{
vphi = std::atan2(v.y(),v.x());
sidephi = kSPhi;
@@ -2328,7 +2388,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
// Check intersection with correct half-plane
//
if ((std::abs(xi)<=kCarTolerance) && (std::abs(yi)<=kCarTolerance))
if ((std::fabs(xi)<=kCarTolerance) && (std::fabs(yi)<=kCarTolerance))
{
// Leaving via ending phi
//
@@ -2396,7 +2456,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
// Check intersection in correct half-plane
// (if not -> not leaving phi extent)
//
if( (std::abs(xi)<=kCarTolerance)&&(std::abs(yi)<=kCarTolerance) )
if( (std::fabs(xi)<=kCarTolerance)&&(std::fabs(yi)<=kCarTolerance) )
{
vphi = std::atan2(v.y(),v.x());
sidephi = kSPhi;
@@ -2434,7 +2494,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
// Check intersection in correct half-plane
// (if not -> remain in extent)
//
if( (std::abs(xi)<=kCarTolerance)&&(std::abs(yi)<=kCarTolerance) )
if( (std::fabs(xi)<=kCarTolerance)&&(std::fabs(yi)<=kCarTolerance) )
{
vphi = std::atan2(v.y(),v.x());
sidephi = kSPhi;
@@ -2478,7 +2538,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
// Check intersection in correct half-plane
// (if not -> not leaving phi extent)
//
if( (std::abs(xi)<=kCarTolerance)&&(std::abs(yi)<=kCarTolerance) )
if( (std::fabs(xi)<=kCarTolerance)&&(std::fabs(yi)<=kCarTolerance) )
{
vphi = std::atan2(v.y(),v.x()) ;
sidephi = kSPhi;
@@ -2516,7 +2576,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
// Check intersection in correct half-plane
// (if not -> remain in extent)
//
if((std::abs(xi)<=kCarTolerance) && (std::abs(yi)<=kCarTolerance))
if((std::fabs(xi)<=kCarTolerance) && (std::fabs(yi)<=kCarTolerance))
{
vphi = std::atan2(v.y(),v.x()) ;
sidephi = kSPhi;
@@ -2670,7 +2730,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
break;
default:
G4cout.precision(16);
G4int old_prc = G4cout.precision(16);
G4cout << G4endl;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl;
@@ -2683,6 +2743,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
G4cout << "v.z() = " << v.z() << G4endl << G4endl;
G4cout << "Proposed distance :" << G4endl << G4endl;
G4cout << "snxt = " << snxt/mm << " mm" << G4endl << G4endl;
G4cout.precision(old_prc);
G4Exception("G4Sphere::DistanceToOut(p,v,..)",
"Notification", JustWarning,
"Undefined side for valid surface normal to solid.");
@@ -2691,7 +2752,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
}
if (snxt == kInfinity)
{
G4cout.precision(24);
G4int old_prc = G4cout.precision(24);
G4cout << G4endl;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl;
@@ -2706,6 +2767,7 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p,
G4cout << "v.z() = " << v.z() << G4endl << G4endl;
G4cout << "Proposed distance :" << G4endl << G4endl;
G4cout << "snxt = " << snxt/mm << " mm" << G4endl << G4endl;
G4cout.precision(old_prc);
G4Exception("G4Sphere::DistanceToOut(p,v,..)",
"Notification", JustWarning,
"Logic error: snxt = kInfinity ???");
@@ -2730,13 +2792,14 @@ G4double G4Sphere::DistanceToOut( const G4ThreeVector& p ) const
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4cout.precision(16) ;
G4cout << G4endl ;
G4int old_prc = G4cout.precision(16);
G4cout << G4endl;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl ;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
G4cout.precision(old_prc) ;
G4Exception("G4Sphere::DistanceToOut(p)",
"Notification", JustWarning, "Point p is outside !?" );
}
@@ -2877,9 +2940,9 @@ G4Sphere::CreateRotatedVertices( const G4AffineTransform& pTransform,
G4double* cosCrossTheta = new G4double[noThetaSections];
G4double* sinCrossTheta = new G4double[noThetaSections];
vertices=new G4ThreeVectorList();
vertices->reserve(noPhiCrossSections*(noThetaSections*2));
if (vertices && cosCrossTheta && sinCrossTheta)
{
vertices->reserve(noPhiCrossSections*(noThetaSections*2));
for (crossSectionPhi=0;
crossSectionPhi<noPhiCrossSections; crossSectionPhi++)
{
@@ -2941,6 +3004,15 @@ G4GeometryType G4Sphere::GetEntityType() const
return G4String("G4Sphere");
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Sphere::Clone() const
{
return new G4Sphere(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Stream object contents to an output stream
+200 -266
View File
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4Torus.cc,v 1.65 2009/11/26 10:31:06 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4Torus.cc,v 1.71 2010/10/19 15:42:10 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
// class G4Torus
@@ -172,7 +172,8 @@ G4Torus::SetAllParameters( G4double pRmin,
// for usage restricted to object persistency.
//
G4Torus::G4Torus( __void__& a )
: G4CSGSolid(a)
: G4CSGSolid(a), fRmin(0.), fRmax(0.), fRtor(0.), fSPhi(0.),
fDPhi(0.), kRadTolerance(0.), kAngTolerance(0.)
{
}
@@ -183,6 +184,40 @@ G4Torus::G4Torus( __void__& a )
G4Torus::~G4Torus()
{}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4Torus::G4Torus(const G4Torus& rhs)
: G4CSGSolid(rhs), fRmin(rhs.fRmin),fRmax(rhs.fRmax),
fRtor(rhs.fRtor),fSPhi(rhs.fSPhi),fDPhi(rhs.fDPhi),
kRadTolerance(rhs.kRadTolerance), kAngTolerance(rhs.kAngTolerance)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4Torus& G4Torus::operator = (const G4Torus& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4CSGSolid::operator=(rhs);
// Copy data
//
fRmin = rhs.fRmin; fRmax = rhs.fRmax;
fRtor = rhs.fRtor; fSPhi = rhs.fSPhi; fDPhi = rhs.fDPhi;
kRadTolerance = rhs.kRadTolerance; kAngTolerance = rhs.kAngTolerance;
return *this;
}
//////////////////////////////////////////////////////////////////////
//
// Dispatch to parameterisation for replication mechanism dimension
@@ -202,14 +237,14 @@ void G4Torus::ComputeDimensions( G4VPVParameterisation* p,
// Calculate the real roots to torus surface.
// Returns negative solutions as well.
std::vector<G4double> G4Torus::TorusRootsJT( const G4ThreeVector& p,
const G4ThreeVector& v,
G4double r ) const
void G4Torus::TorusRootsJT( const G4ThreeVector& p,
const G4ThreeVector& v,
G4double r,
std::vector<G4double>& roots ) const
{
G4int i, num ;
G4double c[5], sr[4], si[4] ;
std::vector<G4double> roots ;
G4double Rtor2 = fRtor*fRtor, r2 = r*r ;
@@ -232,9 +267,7 @@ std::vector<G4double> G4Torus::TorusRootsJT( const G4ThreeVector& p,
if( si[i] == 0. ) { roots.push_back(sr[i]) ; } // store real roots
}
std::sort(roots.begin() , roots.end() ) ; // sorting with <
return roots;
std::sort(roots.begin() , roots.end() ) ; // sorting with <
}
//////////////////////////////////////////////////////////////////////////////
@@ -252,13 +285,15 @@ G4double G4Torus::SolveNumericJT( const G4ThreeVector& p,
G4double bigdist = 10*mm ;
G4double tmin = kInfinity ;
G4double t, scal ;
static const G4double halfCarTolerance = 0.5*kCarTolerance;
static const G4double halfAngTolerance = 0.5*kAngTolerance;
// calculate the distances to the intersections with the Torus
// from a given point p and direction v.
//
std::vector<G4double> roots ;
std::vector<G4double> rootsrefined ;
roots = TorusRootsJT(p,v,r) ;
TorusRootsJT(p,v,r,roots) ;
G4ThreeVector ptmp ;
@@ -268,12 +303,12 @@ G4double G4Torus::SolveNumericJT( const G4ThreeVector& p,
{
t = roots[k] ;
if ( t < -0.5*kCarTolerance ) { continue ; } // skip negative roots
if ( t < -halfCarTolerance ) { continue ; } // skip negative roots
if ( t > bigdist && t<kInfinity ) // problem with big distances
{
ptmp = p + t*v ;
rootsrefined = TorusRootsJT(ptmp,v,r) ;
TorusRootsJT(ptmp,v,r,rootsrefined) ;
if ( rootsrefined.size()==roots.size() )
{
t = t + rootsrefined[k] ;
@@ -286,27 +321,27 @@ G4double G4Torus::SolveNumericJT( const G4ThreeVector& p,
if ( fSPhi >= 0 )
{
if ( theta < - kAngTolerance*0.5 ) { theta += twopi; }
if ( (std::abs(theta) < kAngTolerance*0.5)
&& (std::abs(fSPhi + fDPhi - twopi) < kAngTolerance*0.5) )
if ( theta < - halfAngTolerance ) { theta += twopi; }
if ( (std::fabs(theta) < halfAngTolerance)
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
{
theta += twopi ; // 0 <= theta < 2pi
}
}
if ((fSPhi <= -pi )&&(theta>kAngTolerance*0.5)) { theta = theta-twopi; }
if ((fSPhi <= -pi )&&(theta>halfAngTolerance)) { theta = theta-twopi; }
// We have to verify if this root is inside the region between
// fSPhi and fSPhi + fDPhi
//
if ( (theta - fSPhi >= - kAngTolerance*0.5)
&& (theta - (fSPhi + fDPhi) <= kAngTolerance*0.5) )
if ( (theta - fSPhi >= - halfAngTolerance)
&& (theta - (fSPhi + fDPhi) <= halfAngTolerance) )
{
// check if P is on the surface, and called from DistanceToIn
// DistanceToIn has to return 0.0 if particle is going inside the solid
if ( IsDistanceToIn == true )
{
if (std::fabs(t) < 0.5*kCarTolerance )
if (std::fabs(t) < halfCarTolerance )
{
// compute scalar product at position p : v.n
// ( n taken from SurfaceNormal, not normalized )
@@ -329,7 +364,7 @@ G4double G4Torus::SolveNumericJT( const G4ThreeVector& p,
if ( IsDistanceToIn == false )
{
if (std::fabs(t) < 0.5*kCarTolerance )
if (std::fabs(t) < halfCarTolerance )
{
// compute scalar product at position p : v.n
//
@@ -348,7 +383,7 @@ G4double G4Torus::SolveNumericJT( const G4ThreeVector& p,
// check if distance is larger than 1/2 kCarTolerance
//
if( t > 0.5*kCarTolerance )
if( t > halfCarTolerance )
{
tmin = t ;
return tmin ;
@@ -417,7 +452,7 @@ G4bool G4Torus::CalculateExtent( const EAxis pAxis,
else
{
if (yMin < pVoxelLimit.GetMinYExtent() )
{
{
yMin = pVoxelLimit.GetMinYExtent() ;
}
if (yMax > pVoxelLimit.GetMaxYExtent() )
@@ -469,6 +504,7 @@ G4bool G4Torus::CalculateExtent( const EAxis pAxis,
// Y limits don't cross max/min x => compute max delta x,
// hence new mins/maxs
//
RTorus=fRmax+fRtor;
delta = RTorus*RTorus - yoff1*yoff1;
diff1 = (delta>0.) ? std::sqrt(delta) : 0.;
@@ -587,14 +623,17 @@ EInside G4Torus::Inside( const G4ThreeVector& p ) const
G4double r2, pt2, pPhi, tolRMin, tolRMax ;
EInside in = kOutside ;
static const G4double halfRadTolerance = 0.5*kRadTolerance;
static const G4double halfAngTolerance = 0.5*kAngTolerance;
// General precals
r2 = p.x()*p.x() + p.y()*p.y() ;
pt2 = r2 + p.z()*p.z() + fRtor*fRtor - 2*fRtor*std::sqrt(r2) ;
if (fRmin) tolRMin = fRmin + kRadTolerance*0.5 ;
if (fRmin) tolRMin = fRmin + halfRadTolerance ;
else tolRMin = 0 ;
tolRMax = fRmax - kRadTolerance*0.5;
tolRMax = fRmax - halfRadTolerance;
if (pt2 >= tolRMin*tolRMin && pt2 <= tolRMax*tolRMax )
{
@@ -609,29 +648,29 @@ EInside G4Torus::Inside( const G4ThreeVector& p ) const
pPhi = std::atan2(p.y(),p.x()) ;
if ( pPhi < -kAngTolerance*0.5 ) { pPhi += twopi ; } // 0<=pPhi<2pi
if ( pPhi < -halfAngTolerance ) { pPhi += twopi ; } // 0<=pPhi<2pi
if ( fSPhi >= 0 )
{
if ( (std::abs(pPhi) < kAngTolerance*0.5)
&& (std::abs(fSPhi + fDPhi - twopi) < kAngTolerance*0.5) )
if ( (std::fabs(pPhi) < halfAngTolerance)
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
{
pPhi += twopi ; // 0 <= pPhi < 2pi
}
if ( (pPhi >= fSPhi + kAngTolerance*0.5)
&& (pPhi <= fSPhi + fDPhi - kAngTolerance*0.5) )
if ( (pPhi >= fSPhi + halfAngTolerance)
&& (pPhi <= fSPhi + fDPhi - halfAngTolerance) )
{
in = kInside ;
}
else if ( (pPhi >= fSPhi - kAngTolerance*0.5)
&& (pPhi <= fSPhi + fDPhi + kAngTolerance*0.5) )
else if ( (pPhi >= fSPhi - halfAngTolerance)
&& (pPhi <= fSPhi + fDPhi + halfAngTolerance) )
{
in = kSurface ;
}
}
else // fSPhi < 0
{
if ( (pPhi <= fSPhi + twopi - kAngTolerance*0.5)
&& (pPhi >= fSPhi + fDPhi + kAngTolerance*0.5) ) {;}
if ( (pPhi <= fSPhi + twopi - halfAngTolerance)
&& (pPhi >= fSPhi + fDPhi + halfAngTolerance) ) {;}
else
{
in = kSurface ;
@@ -641,8 +680,8 @@ EInside G4Torus::Inside( const G4ThreeVector& p ) const
}
else // Try generous boundaries
{
tolRMin = fRmin - kRadTolerance*0.5 ;
tolRMax = fRmax + kRadTolerance*0.5 ;
tolRMin = fRmin - halfRadTolerance ;
tolRMax = fRmax + halfRadTolerance ;
if (tolRMin < 0 ) { tolRMin = 0 ; }
@@ -656,24 +695,24 @@ EInside G4Torus::Inside( const G4ThreeVector& p ) const
{
pPhi = std::atan2(p.y(),p.x()) ;
if ( pPhi < -kAngTolerance*0.5 ) { pPhi += twopi ; } // 0<=pPhi<2pi
if ( pPhi < -halfAngTolerance ) { pPhi += twopi ; } // 0<=pPhi<2pi
if ( fSPhi >= 0 )
{
if ( (std::abs(pPhi) < kAngTolerance*0.5)
&& (std::abs(fSPhi + fDPhi - twopi) < kAngTolerance*0.5) )
if ( (std::fabs(pPhi) < halfAngTolerance)
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
{
pPhi += twopi ; // 0 <= pPhi < 2pi
}
if ( (pPhi >= fSPhi - kAngTolerance*0.5)
&& (pPhi <= fSPhi + fDPhi + kAngTolerance*0.5) )
if ( (pPhi >= fSPhi - halfAngTolerance)
&& (pPhi <= fSPhi + fDPhi + halfAngTolerance) )
{
in = kSurface;
}
}
else // fSPhi < 0
{
if ( (pPhi <= fSPhi + twopi - kAngTolerance*0.5)
&& (pPhi >= fSPhi + fDPhi + kAngTolerance*0.5) ) {;}
if ( (pPhi <= fSPhi + twopi - halfAngTolerance)
&& (pPhi >= fSPhi + fDPhi + halfAngTolerance) ) {;}
else
{
in = kSurface ;
@@ -697,7 +736,10 @@ G4ThreeVector G4Torus::SurfaceNormal( const G4ThreeVector& p ) const
G4double rho2, rho, pt2, pt, pPhi;
G4double distRMin = kInfinity;
G4double distSPhi = kInfinity, distEPhi = kInfinity;
G4double delta = 0.5*kCarTolerance, dAngle = 0.5*kAngTolerance;
static const G4double delta = 0.5*kCarTolerance;
static const G4double dAngle = 0.5*kAngTolerance;
G4ThreeVector nR, nPs, nPe;
G4ThreeVector norm, sumnorm(0.,0.,0.);
@@ -845,7 +887,7 @@ G4ThreeVector G4Torus::ApproxSurfaceNormal( const G4ThreeVector& p ) const
case kNEPhi:
norm = G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0) ;
break;
default:
default: // Should never reach this case ...
DumpInfo();
G4Exception("G4Torus::ApproxSurfaceNormal()",
"Notification", JustWarning,
@@ -896,8 +938,11 @@ G4double G4Torus::DistanceToIn( const G4ThreeVector& p,
G4double tolORMin2,tolIRMin2; // `generous' radii squared
G4double tolORMax2,tolIRMax2 ;
G4double Dist,xi,yi,zi,rhoi2,it2; // Intersection point variables
static const G4double halfCarTolerance = 0.5*kCarTolerance;
static const G4double halfRadTolerance = 0.5*kRadTolerance;
static const G4double halfAngTolerance = 0.5*kAngTolerance;
G4double Dist,xi,yi,zi,rhoi2,it2; // Intersection point variables
G4double Comp;
G4double cosSPhi,sinSPhi; // Trig for phi start intersect
@@ -910,8 +955,8 @@ G4double G4Torus::DistanceToIn( const G4ThreeVector& p,
seg = true ;
hDPhi = 0.5*fDPhi ; // half delta phi
cPhi = fSPhi + hDPhi ;
hDPhiOT = hDPhi+0.5*kAngTolerance ; // outers tol' half delta phi
hDPhiIT = hDPhi - 0.5*kAngTolerance ;
hDPhiOT = hDPhi + halfAngTolerance ; // outers tol' half delta phi
hDPhiIT = hDPhi - halfAngTolerance ;
sinCPhi = std::sin(cPhi) ;
cosCPhi = std::cos(cPhi) ;
cosHDPhiOT = std::cos(hDPhiOT) ;
@@ -924,16 +969,16 @@ G4double G4Torus::DistanceToIn( const G4ThreeVector& p,
if (fRmin > kRadTolerance) // Calculate tolerant rmin and rmax
{
tolORMin2 = (fRmin - 0.5*kRadTolerance)*(fRmin - 0.5*kRadTolerance) ;
tolIRMin2 = (fRmin + 0.5*kRadTolerance)*(fRmin + 0.5*kRadTolerance) ;
tolORMin2 = (fRmin - halfRadTolerance)*(fRmin - halfRadTolerance) ;
tolIRMin2 = (fRmin + halfRadTolerance)*(fRmin + halfRadTolerance) ;
}
else
{
tolORMin2 = 0 ;
tolIRMin2 = 0 ;
}
tolORMax2 = (fRmax + 0.5*kRadTolerance)*(fRmax + 0.5*kRadTolerance) ;
tolIRMax2 = (fRmax - kRadTolerance*0.5)*(fRmax - kRadTolerance*0.5) ;
tolORMax2 = (fRmax + halfRadTolerance)*(fRmax + halfRadTolerance) ;
tolIRMax2 = (fRmax - halfRadTolerance)*(fRmax - halfRadTolerance) ;
// Intersection with Rmax (possible return) and Rmin (must also check phi)
@@ -966,7 +1011,7 @@ G4double G4Torus::DistanceToIn( const G4ThreeVector& p,
{
Dist = (p.y()*cosSPhi - p.x()*sinSPhi) ;
if (Dist < kCarTolerance*0.5)
if (Dist < halfCarTolerance)
{
sphi = Dist/Comp ;
if (sphi < snxt)
@@ -998,7 +1043,7 @@ G4double G4Torus::DistanceToIn( const G4ThreeVector& p,
{
Dist = -(p.y()*cosEPhi - p.x()*sinEPhi) ;
if (Dist < kCarTolerance*0.5 )
if (Dist < halfCarTolerance )
{
sphi = Dist/Comp ;
if (sphi < snxt )
@@ -1022,7 +1067,7 @@ G4double G4Torus::DistanceToIn( const G4ThreeVector& p,
}
}
}
if(snxt < 0.5*kCarTolerance) { snxt = 0.0 ; }
if(snxt < halfCarTolerance) { snxt = 0.0 ; }
return snxt ;
}
@@ -1091,6 +1136,10 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p,
ESide side = kNull, sidephi = kNull ;
G4double snxt = kInfinity, sphi, s[4] ;
static const G4double halfCarTolerance = 0.5*kCarTolerance;
static const G4double halfRadTolerance = 0.5*kRadTolerance;
static const G4double halfAngTolerance = 0.5*kAngTolerance;
// Vars for phi intersection
//
G4double sinSPhi, cosSPhi, ePhi, sinEPhi, cosEPhi;
@@ -1117,7 +1166,7 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p,
G4double pDotV = p.x()*v.x() + p.y()*v.y() + p.z()*v.z() ;
G4double tolRMax = fRmax - kRadTolerance*0.5 ;
G4double tolRMax = fRmax - halfRadTolerance ;
G4double vDotNmax = pDotV - fRtor*(v.x()*p.x() + v.y()*p.y())/rho ;
G4double pDotxyNmax = (1 - fRtor/rho) ;
@@ -1145,7 +1194,7 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p,
if ( fRmin )
{
G4double tolRMin = fRmin + kRadTolerance*0.5 ;
G4double tolRMin = fRmin + halfRadTolerance ;
if ( (pt2 < tolRMin*tolRMin) && (vDotNmax < 0) )
{
@@ -1186,7 +1235,7 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p,
}
#endif
if (fDPhi < twopi) // Phi Intersections
{
sinSPhi = std::sin(fSPhi) ;
@@ -1197,6 +1246,14 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p,
cPhi = fSPhi + fDPhi*0.5 ;
sinCPhi = std::sin(cPhi) ;
cosCPhi = std::cos(cPhi) ;
// angle calculation with correction
// of difference in domain of atan2 and Sphi
//
vphi = std::atan2(v.y(),v.x()) ;
if ( vphi < fSPhi - halfAngTolerance ) { vphi += twopi; }
else if ( vphi > ePhi + halfAngTolerance ) { vphi -= twopi; }
if ( p.x() || p.y() ) // Check if on z axis (rho not needed later)
{
@@ -1208,243 +1265,108 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p,
compS = -sinSPhi*v.x() + cosSPhi*v.y() ;
compE = sinEPhi*v.x() - cosEPhi*v.y() ;
sidephi = kNull ;
if ( (pDistS <= 0) && (pDistE <= 0) )
if( ( (fDPhi <= pi) && ( (pDistS <= halfCarTolerance)
&& (pDistE <= halfCarTolerance) ) )
|| ( (fDPhi > pi) && !((pDistS > halfCarTolerance)
&& (pDistE > halfCarTolerance) ) ) )
{
// Inside both phi *full* planes
if (compS<0)
if ( compS < 0 )
{
sphi=pDistS/compS;
xi=p.x()+sphi*v.x();
yi=p.y()+sphi*v.y();
// Check intersecting with correct half-plane
// (if not -> no intersect)
//
if ((yi*cosCPhi-xi*sinCPhi)>=0)
sphi = pDistS/compS ;
if (sphi >= -halfCarTolerance)
{
sphi=kInfinity;
}
else
{
sidephi=kSPhi;
if (pDistS>-kCarTolerance*0.5) { sphi=0; } // Leave by sphi
// immediately
}
}
else
{
sphi=kInfinity;
}
if (compE<0)
{
sphi2=pDistE/compE;
// Only check further if < starting phi intersection
//
if (sphi2<sphi)
{
xi=p.x()+sphi2*v.x();
yi=p.y()+sphi2*v.y();
xi = p.x() + sphi*v.x() ;
yi = p.y() + sphi*v.y() ;
// Check intersecting with correct half-plane
//
if ((yi*cosCPhi-xi*sinCPhi)>=0)
// (if not -> no intersect)
//
if ( (std::fabs(xi)<=kCarTolerance)
&& (std::fabs(yi)<=kCarTolerance) )
{
// Leaving via ending phi
//
sidephi=kEPhi;
if (pDistE<=-kCarTolerance*0.5)
sidephi = kSPhi;
if ( ((fSPhi-halfAngTolerance)<=vphi)
&& ((ePhi+halfAngTolerance)>=vphi) )
{
sphi=sphi2;
}
else
{
sphi=0;
sphi = kInfinity;
}
}
}
}
}
else if ( (pDistS>=0) && (pDistE>=0) )
{
// Outside both *full* phi planes
if (pDistS <= pDistE)
{
sidephi = kSPhi ;
}
else
{
sidephi = kEPhi ;
}
if (fDPhi>pi)
{
if ( (compS<0) && (compE<0) ) { sphi=0; }
else { sphi=kInfinity; }
}
else
{
// if towards both >=0 then once inside (after error)
// will remain inside
//
if ( (compS>=0) && (compE>=0) )
{
sphi=kInfinity;
}
else
{
sphi=0;
}
}
}
else if ( (pDistS>0) && (pDistE<0) )
{
// Outside full starting plane, inside full ending plane
if (fDPhi>pi)
{
if (compE<0)
{
sphi=pDistE/compE;
xi=p.x()+sphi*v.x();
yi=p.y()+sphi*v.y();
// Check intersection in correct half-plane
// (if not -> not leaving phi extent)
//
if ((yi*cosCPhi-xi*sinCPhi)<=0)
else if ( yi*cosCPhi-xi*sinCPhi >=0 )
{
sphi=kInfinity;
sphi = kInfinity ;
}
else
{
// Leaving via Ending phi
//
sidephi = kEPhi ;
if (pDistE>-kCarTolerance*0.5) { sphi=0; }
}
sidephi = kSPhi ;
}
}
else
{
sphi=kInfinity;
sphi = kInfinity ;
}
}
else
{
if (compS>=0)
{
if (compE<0)
{
sphi=pDistE/compE;
xi=p.x()+sphi*v.x();
yi=p.y()+sphi*v.y();
sphi = kInfinity ;
}
// Check intersection in correct half-plane
// (if not -> remain in extent)
if ( compE < 0 )
{
sphi2 = pDistE/compE ;
// Only check further if < starting phi intersection
//
if ( (sphi2 > -kCarTolerance) && (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
//
if ((yi*cosCPhi-xi*sinCPhi)<=0)
if( !( (fSPhi-halfAngTolerance <= vphi)
&& (ePhi+halfAngTolerance >= vphi) ) )
{
sphi=kInfinity;
sidephi = kEPhi ;
sphi = sphi2;
}
else
}
else // Check intersecting with correct half-plane
{
if ( (yi*cosCPhi-xi*sinCPhi) >= 0)
{
// otherwise leaving via Ending phi
// Leaving via ending phi
//
sidephi=kEPhi;
sidephi = kEPhi ;
sphi = sphi2;
}
}
else { sphi=kInfinity; }
}
else
{
// leaving immediately by starting phi
//
sidephi=kSPhi;
sphi=0;
}
}
}
else
{
// Must be pDistS<0&&pDistE>0
// Inside full starting plane, outside full ending plane
if (fDPhi>pi)
{
if (compS<0)
{
sphi=pDistS/compS;
xi=p.x()+sphi*v.x();
yi=p.y()+sphi*v.y();
// Check intersection in correct half-plane
// (if not -> not leaving phi extent)
//
if ((yi*cosCPhi-xi*sinCPhi)>=0)
{
sphi=kInfinity;
}
else
{
// Leaving via Starting phi
//
sidephi = kSPhi ;
if (pDistS>-kCarTolerance*0.5) { sphi=0; }
}
}
else
{
sphi=kInfinity;
}
}
else
{
if (compE>=0)
{
if (compS<0)
{
sphi=pDistS/compS;
xi=p.x()+sphi*v.x();
yi=p.y()+sphi*v.y();
// Check intersection in correct half-plane
// (if not -> remain in extent)
//
if ((yi*cosCPhi-xi*sinCPhi)>=0)
{
sphi=kInfinity;
}
else
{
// otherwise leaving via Starting phi
//
sidephi=kSPhi;
}
}
else { sphi=kInfinity; }
}
else
{
// leaving immediately by ending
//
sidephi=kEPhi;
sphi=0;
}
}
sphi = kInfinity ;
}
}
}
else
{
// On z axis + travel not || to z axis -> if phi of vector direction
// within phi of shape, Step limited by rmax, else Step =0
vphi=std::atan2(v.y(),v.x());
if ( (fSPhi<vphi) && (vphi<fSPhi+fDPhi) )
vphi = std::atan2(v.y(),v.x());
if ( ( fSPhi-halfAngTolerance <= vphi ) &&
( vphi <= ( ePhi+halfAngTolerance ) ) )
{
sphi=kInfinity;
sphi = kInfinity;
}
else
{
@@ -1461,8 +1383,8 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p,
side=sidephi;
}
}
G4double rhoi2,rhoi,it2,it,iDotxyNmax ;
G4double rhoi2,rhoi,it2,it,iDotxyNmax ;
// Note: by numerical computation we know where the ray hits the torus
// So I propose to return the side where the ray hits
@@ -1524,7 +1446,7 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p,
// It seems we go here from time to time ...
G4cout.precision(16);
G4int oldprc = G4cout.precision(16);
G4cout << G4endl;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl;
@@ -1537,12 +1459,14 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p,
G4cout << "v.z() = " << v.z() << G4endl << G4endl;
G4cout << "Proposed distance :" << G4endl << G4endl;
G4cout << "snxt = " << snxt/mm << " mm" << G4endl << G4endl;
G4cout.precision(oldprc);
G4Exception("G4Torus::DistanceToOut(p,v,..)",
"Notification",JustWarning,
"Undefined side for valid surface normal to solid.");
break;
}
}
if ( snxt<halfCarTolerance ) { snxt=0 ; }
return snxt;
}
@@ -1564,13 +1488,14 @@ G4double G4Torus::DistanceToOut( const G4ThreeVector& p ) const
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4cout.precision(16) ;
G4int oldprc = G4cout.precision(16) ;
G4cout << G4endl ;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl ;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
G4cout.precision(oldprc);
G4Exception("G4Torus::DistanceToOut(p)", "Notification",
JustWarning, "Point p is outside !?" );
}
@@ -1651,7 +1576,7 @@ G4Torus::CreateRotatedVertices( const G4AffineTransform& pTransform,
// If complete in phi, set start angle such that mesh will be at fRmax
// on the x axis. Will give better extent calculations when not rotated
if ( (fDPhi == pi*2.0) && (fSPhi == 0) )
if ( (fDPhi == twopi) && (fSPhi == 0) )
{
sAngle = -meshAngle*0.5 ;
}
@@ -1660,10 +1585,10 @@ G4Torus::CreateRotatedVertices( const G4AffineTransform& pTransform,
sAngle = fSPhi ;
}
vertices = new G4ThreeVectorList();
vertices->reserve(noCrossSections*4) ;
if (vertices)
{
vertices->reserve(noCrossSections*4) ;
for (crossSection=0;crossSection<noCrossSections;crossSection++)
{
// Compute coordinates of cross section at section crossSection
@@ -1707,6 +1632,15 @@ G4GeometryType G4Torus::GetEntityType() const
return G4String("G4Torus");
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Torus::Clone() const
{
return new G4Torus(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Stream object contents to an output stream
@@ -1737,18 +1671,18 @@ G4ThreeVector G4Torus::GetPointOnSurface() const
G4double cosu, sinu,cosv, sinv, aOut, aIn, aSide, chose, phi, theta, rRand;
phi = RandFlat::shoot(fSPhi,fSPhi+fDPhi);
theta = RandFlat::shoot(0.,2.*pi);
theta = RandFlat::shoot(0.,twopi);
cosu = std::cos(phi); sinu = std::sin(phi);
cosv = std::cos(theta); sinv = std::sin(theta);
// compute the areas
aOut = (fDPhi)*2.*pi*fRtor*fRmax;
aIn = (fDPhi)*2.*pi*fRtor*fRmin;
aOut = (fDPhi)*twopi*fRtor*fRmax;
aIn = (fDPhi)*twopi*fRtor*fRmin;
aSide = pi*(fRmax*fRmax-fRmin*fRmin);
if(fSPhi == 0 && fDPhi == twopi){ aSide = 0; }
if ((fSPhi == 0) && (fDPhi == twopi)){ aSide = 0; }
chose = RandFlat::shoot(0.,aOut + aIn + 2.*aSide);
if(chose < aOut)
@@ -1795,7 +1729,7 @@ G4NURBS* G4Torus::CreateNURBS () const
G4NURBS* pNURBS;
if (fRmin != 0)
{
if (fDPhi >= 2.0 * pi)
if (fDPhi >= twopi)
{
pNURBS = new G4NURBStube(fRmin, fRmax, fRtor);
}
@@ -1806,7 +1740,7 @@ G4NURBS* G4Torus::CreateNURBS () const
}
else
{
if (fDPhi >= 2.0 * pi)
if (fDPhi >= twopi)
{
pNURBS = new G4NURBScylinder (fRmax, fRtor);
}
+405 -364
View File
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4Trap.cc,v 1.45 2008/04/23 09:49:57 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4Trap.cc,v 1.49 2010/10/19 15:42:10 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// class G4Trap
//
@@ -91,26 +91,8 @@ G4Trap::G4Trap( const G4String& pName,
G4double pAlp2)
: G4CSGSolid(pName)
{
if ( pDz > 0 && pDy1 > 0 && pDx1 > 0 &&
pDx2 > 0 && pDy2 > 0 && pDx3 > 0 && pDx4 > 0 )
{
fDz=pDz;
fTthetaCphi=std::tan(pTheta)*std::cos(pPhi);
fTthetaSphi=std::tan(pTheta)*std::sin(pPhi);
fDy1=pDy1;
fDx1=pDx1;
fDx2=pDx2;
fTalpha1=std::tan(pAlp1);
fDy2=pDy2;
fDx3=pDx3;
fDx4=pDx4;
fTalpha2=std::tan(pAlp2);
MakePlanes();
}
else
if ( pDz <= 0 || pDy1 <= 0 || pDx1 <= 0 ||
pDx2 <= 0 || pDy2 <= 0 || pDx3 <= 0 || pDx4 <= 0 )
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl
<< " Invalid dimensions !" << G4endl
@@ -121,6 +103,22 @@ G4Trap::G4Trap( const G4String& pName,
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Invalid length G4Trap parameters.");
}
fDz=pDz;
fTthetaCphi=std::tan(pTheta)*std::cos(pPhi);
fTthetaSphi=std::tan(pTheta)*std::sin(pPhi);
fDy1=pDy1;
fDx1=pDx1;
fDx2=pDx2;
fTalpha1=std::tan(pAlp1);
fDy2=pDy2;
fDx3=pDx3;
fDx4=pDx4;
fTalpha2=std::tan(pAlp2);
MakePlanes();
}
////////////////////////////////////////////////////////////////////////////
@@ -133,87 +131,85 @@ G4Trap::G4Trap( const G4String& pName,
const G4ThreeVector pt[8] )
: G4CSGSolid(pName)
{
G4bool good;
// Start with check of centering - the center of gravity trap line
// should cross the origin of frame
if ( pt[0].z() < 0
&& pt[0].z() == pt[1].z() && pt[0].z() == pt[2].z()
&& pt[0].z() == pt[3].z()
&& pt[4].z() > 0
&& pt[4].z() == pt[5].z() && pt[4].z() == pt[6].z()
&& pt[4].z() == pt[7].z()
&& std::fabs( pt[0].z() + pt[4].z() ) < kCarTolerance
&& pt[0].y() == pt[1].y() && pt[2].y() == pt[3].y()
&& pt[4].y() == pt[5].y() && pt[6].y() == pt[7].y()
&& std::fabs( pt[0].y() + pt[2].y() + pt[4].y() + pt[6].y() ) < kCarTolerance
&& std::fabs( pt[0].x() + pt[1].x() + pt[4].x() + pt[5].x() +
pt[2].x() + pt[3].x() + pt[6].x() + pt[7].x() ) < kCarTolerance )
{
G4bool good;
// Bottom side with normal approx. -Y
good = MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
if (!good)
{
DumpInfo();
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-Y not planar.");
}
// Top side with normal approx. +Y
good = MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+Y not planar.");
}
// Front side with normal approx. -X
good = MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-X not planar.");
}
// Back side iwth normal approx. +X
good = MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+X not planar.");
}
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;
fTalpha1 = ((pt[2]).x()+(pt[3]).x()-(pt[1]).x()-(pt[0]).x())*0.25/fDy1;
fDy2 = ((pt[6]).y()-(pt[5]).y())*0.5;
fDx3 = ((pt[5]).x()-(pt[4]).x())*0.5;
fDx4 = ((pt[7]).x()-(pt[6]).x())*0.5;
fTalpha2 = ((pt[6]).x()+(pt[7]).x()-(pt[5]).x()-(pt[4]).x())*0.25/fDy2;
fTthetaCphi = ((pt[4]).x()+fDy2*fTalpha2+fDx3)/fDz;
fTthetaSphi = ((pt[4]).y()+fDy2)/fDz;
}
else
if (!( pt[0].z() < 0
&& pt[0].z() == pt[1].z() && pt[0].z() == pt[2].z()
&& pt[0].z() == pt[3].z()
&& pt[4].z() > 0
&& pt[4].z() == pt[5].z() && pt[4].z() == pt[6].z()
&& pt[4].z() == pt[7].z()
&& std::fabs( pt[0].z() + pt[4].z() ) < kCarTolerance
&& pt[0].y() == pt[1].y() && pt[2].y() == pt[3].y()
&& pt[4].y() == pt[5].y() && pt[6].y() == pt[7].y()
&& std::fabs( pt[0].y() + pt[2].y() + pt[4].y() + pt[6].y() ) < kCarTolerance
&& std::fabs( pt[0].x() + pt[1].x() + pt[4].x() + pt[5].x() +
pt[2].x() + pt[3].x() + pt[6].x() + pt[7].x() ) < kCarTolerance ) )
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Invalid vertice coordinates.");
}
// Bottom side with normal approx. -Y
good = MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
if (!good)
{
DumpInfo();
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-Y not planar.");
}
// Top side with normal approx. +Y
good = MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+Y not planar.");
}
// Front side with normal approx. -X
good = MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-X not planar.");
}
// Back side iwth normal approx. +X
good = MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+X not planar.");
}
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;
fTalpha1 = ((pt[2]).x()+(pt[3]).x()-(pt[1]).x()-(pt[0]).x())*0.25/fDy1;
fDy2 = ((pt[6]).y()-(pt[5]).y())*0.5;
fDx3 = ((pt[5]).x()-(pt[4]).x())*0.5;
fDx4 = ((pt[7]).x()-(pt[6]).x())*0.5;
fTalpha2 = ((pt[6]).x()+(pt[7]).x()-(pt[5]).x()-(pt[4]).x())*0.25/fDy2;
fTthetaCphi = ((pt[4]).x()+fDy2*fTalpha2+fDx3)/fDz;
fTthetaSphi = ((pt[4]).y()+fDy2)/fDz;
}
//////////////////////////////////////////////////////////////////////////////
@@ -224,92 +220,89 @@ G4Trap::G4Trap( const G4String& pName,
G4double pZ,
G4double pY,
G4double pX, G4double pLTX )
: G4CSGSolid(pName)
: G4CSGSolid(pName)
{
G4bool good;
if ( pZ>0 && pY>0 && pX>0 && pLTX>0 && pLTX<=pX )
{
fDz = 0.5*pZ ;
fTthetaCphi = 0 ;
fTthetaSphi = 0 ;
fDy1 = 0.5*pY;
fDx1 = 0.5*pX ;
fDx2 = 0.5*pLTX;
fTalpha1 = 0.5*(pLTX - pX)/pY;
fDy2 = fDy1 ;
fDx3 = fDx1;
fDx4 = fDx2 ;
fTalpha2 = fTalpha1 ;
G4ThreeVector pt[8] ;
pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
// Bottom side with normal approx. -Y
//
good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-Y not planar.");
}
// Top side with normal approx. +Y
//
good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+Y not planar.");
}
// Front side with normal approx. -X
//
good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-X not planar.");
}
// Back side iwth normal approx. +X
//
good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+X not planar.");
}
}
else
if ( pZ<=0 || pY<=0 || pX<=0 || pLTX<=0 || pLTX>pX )
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Invalid length G4Trap parameters.");
}
fDz = 0.5*pZ ;
fTthetaCphi = 0 ;
fTthetaSphi = 0 ;
fDy1 = 0.5*pY;
fDx1 = 0.5*pX ;
fDx2 = 0.5*pLTX;
fTalpha1 = 0.5*(pLTX - pX)/pY;
fDy2 = fDy1 ;
fDx3 = fDx1;
fDx4 = fDx2 ;
fTalpha2 = fTalpha1 ;
G4ThreeVector pt[8] ;
pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
// Bottom side with normal approx. -Y
//
good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-Y not planar.");
}
// Top side with normal approx. +Y
//
good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+Y not planar.");
}
// Front side with normal approx. -X
//
good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-X not planar.");
}
// Back side iwth normal approx. +X
//
good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+X not planar.");
}
}
///////////////////////////////////////////////////////////////////////////////
@@ -324,87 +317,85 @@ G4Trap::G4Trap( const G4String& pName,
{
G4bool good;
if ( pDz>0 && pDy1>0 && pDx1>0 && pDx2>0 && pDy2>0 )
{
fDz = pDz;
fTthetaCphi = 0 ;
fTthetaSphi = 0 ;
fDy1 = pDy1 ;
fDx1 = pDx1 ;
fDx2 = pDx1 ;
fTalpha1 = 0 ;
fDy2 = pDy2 ;
fDx3 = pDx2 ;
fDx4 = pDx2 ;
fTalpha2 = 0 ;
G4ThreeVector pt[8] ;
pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
// Bottom side with normal approx. -Y
//
good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-Y not planar.");
}
// Top side with normal approx. +Y
//
good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+Y not planar.");
}
// Front side with normal approx. -X
//
good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-X not planar.");
}
// Back side iwth normal approx. +X
//
good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+X not planar.");
}
}
else
if ( pDz<=0 || pDy1<=0 || pDx1<=0 || pDx2<=0 || pDy2<=0 )
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Invalid length G4Trap parameters.");
}
fDz = pDz;
fTthetaCphi = 0 ;
fTthetaSphi = 0 ;
fDy1 = pDy1 ;
fDx1 = pDx1 ;
fDx2 = pDx1 ;
fTalpha1 = 0 ;
fDy2 = pDy2 ;
fDx3 = pDx2 ;
fDx4 = pDx2 ;
fTalpha2 = 0 ;
G4ThreeVector pt[8] ;
pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
// Bottom side with normal approx. -Y
//
good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-Y not planar.");
}
// Top side with normal approx. +Y
//
good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+Y not planar.");
}
// Front side with normal approx. -X
//
good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-X not planar.");
}
// Back side iwth normal approx. +X
//
good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+X not planar.");
}
}
////////////////////////////////////////////////////////////////////////////
@@ -415,92 +406,90 @@ G4Trap::G4Trap( const G4String& pName,
G4double pDx, G4double pDy,
G4double pDz,
G4double pAlpha,
G4double pTheta, G4double pPhi)
G4double pTheta, G4double pPhi )
: G4CSGSolid(pName)
{
G4bool good;
if ( pDz>0 && pDy>0 && pDx>0 )
{
fDz = pDz ;
fTthetaCphi = std::tan(pTheta)*std::cos(pPhi) ;
fTthetaSphi = std::tan(pTheta)*std::sin(pPhi) ;
fDy1 = pDy ;
fDx1 = pDx ;
fDx2 = pDx ;
fTalpha1 = std::tan(pAlpha) ;
fDy2 = pDy ;
fDx3 = pDx ;
fDx4 = pDx ;
fTalpha2 = fTalpha1 ;
G4ThreeVector pt[8] ;
pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
// Bottom side with normal approx. -Y
//
good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-Y not planar.");
}
// Top side with normal approx. +Y
//
good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+Y not planar.");
}
// Front side with normal approx. -X
//
good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-X not planar.");
}
// Back side iwth normal approx. +X
//
good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+X not planar.");
}
}
else
if ( pDz<=0 || pDy<=0 || pDx<=0 )
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Invalid length G4Trap parameters.");
}
fDz = pDz ;
fTthetaCphi = std::tan(pTheta)*std::cos(pPhi) ;
fTthetaSphi = std::tan(pTheta)*std::sin(pPhi) ;
fDy1 = pDy ;
fDx1 = pDx ;
fDx2 = pDx ;
fTalpha1 = std::tan(pAlpha) ;
fDy2 = pDy ;
fDx3 = pDx ;
fDx4 = pDx ;
fTalpha2 = fTalpha1 ;
G4ThreeVector pt[8] ;
pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,
-fDz*fTthetaSphi+fDy1,-fDz);
pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,
+fDz*fTthetaSphi-fDy2,+fDz);
pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,
+fDz*fTthetaSphi+fDy2,+fDz);
// Bottom side with normal approx. -Y
//
good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-Y not planar.");
}
// Top side with normal approx. +Y
//
good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+Y not planar.");
}
// Front side with normal approx. -X
//
good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~-X not planar.");
}
// Back side iwth normal approx. +X
//
good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
if (!good)
{
G4cerr << "ERROR - G4Trap()::G4Trap(): " << GetName() << G4endl;
G4Exception("G4Trap::G4Trap()", "InvalidSetup", FatalException,
"Face at ~+X not planar.");
}
}
///////////////////////////////////////////////////////////////////////////
@@ -510,20 +499,11 @@ G4Trap::G4Trap( const G4String& pName,
// angles: final check of coplanarity
G4Trap::G4Trap( const G4String& pName )
: G4CSGSolid (pName),
fDz (1.),
fTthetaCphi (0.),
fTthetaSphi (0.),
fDy1 (1.),
fDx1 (1.),
fDx2 (1.),
fTalpha1 (0.),
fDy2 (1.),
fDx3 (1.),
fDx4 (1.),
fTalpha2 (0.)
: G4CSGSolid (pName), fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.),
fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.),
fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.)
{
MakePlanes();
MakePlanes();
}
///////////////////////////////////////////////////////////////////////
@@ -532,8 +512,11 @@ G4Trap::G4Trap( const G4String& pName )
// for usage restricted to object persistency.
//
G4Trap::G4Trap( __void__& a )
: G4CSGSolid(a)
: G4CSGSolid(a), fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.),
fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.),
fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.)
{
MakePlanes();
}
////////////////////////////////////////////////////////////////////////
@@ -544,6 +527,56 @@ G4Trap::~G4Trap()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4Trap::G4Trap(const G4Trap& rhs)
: G4CSGSolid(rhs), fDz(rhs.fDz),
fTthetaCphi(rhs.fTthetaCphi), fTthetaSphi(rhs.fTthetaSphi),
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 (size_t i=0; i<4; ++i)
{
fPlanes[i].a = rhs.fPlanes[i].a;
fPlanes[i].b = rhs.fPlanes[i].b;
fPlanes[i].c = rhs.fPlanes[i].c;
fPlanes[i].d = rhs.fPlanes[i].d;
}
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4Trap& G4Trap::operator = (const G4Trap& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4CSGSolid::operator=(rhs);
// Copy data
//
fDz = rhs.fDz;
fTthetaCphi = rhs.fTthetaCphi; fTthetaSphi = rhs.fTthetaSphi;
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 (size_t i=0; i<4; ++i)
{
fPlanes[i].a = rhs.fPlanes[i].a;
fPlanes[i].b = rhs.fPlanes[i].b;
fPlanes[i].c = rhs.fPlanes[i].c;
fPlanes[i].d = rhs.fPlanes[i].d;
}
return *this;
}
///////////////////////////////////////////////////////////////////////
//
// Set all parameters, as for constructor - check and set half-widths
@@ -561,28 +594,7 @@ void G4Trap::SetAllParameters ( G4double pDz,
G4double pDx4,
G4double pAlp2 )
{
fCubicVolume= 0.;
fSurfaceArea= 0.;
fpPolyhedron = 0;
if ( pDz>0 && pDy1>0 && pDx1>0 && pDx2>0 && pDy2>0 && pDx3>0 && pDx4>0 )
{
fDz=pDz;
fTthetaCphi=std::tan(pTheta)*std::cos(pPhi);
fTthetaSphi=std::tan(pTheta)*std::sin(pPhi);
fDy1=pDy1;
fDx1=pDx1;
fDx2=pDx2;
fTalpha1=std::tan(pAlp1);
fDy2=pDy2;
fDx3=pDx3;
fDx4=pDx4;
fTalpha2=std::tan(pAlp2);
MakePlanes();
}
else
if ( pDz<=0 || pDy1<=0 || pDx1<=0 || pDx2<=0 || pDy2<=0 || pDx3<=0 || pDx4<=0 )
{
G4cerr << "ERROR - G4Trap()::SetAllParameters(): " << GetName() << G4endl
<< " Invalid dimensions !" << G4endl
@@ -593,6 +605,24 @@ void G4Trap::SetAllParameters ( G4double pDz,
G4Exception("G4Trap::SetAllParameters()", "InvalidSetup",
FatalException, "Invalid Length Parameters.");
}
fCubicVolume= 0.;
fSurfaceArea= 0.;
fpPolyhedron = 0;
fDz=pDz;
fTthetaCphi=std::tan(pTheta)*std::cos(pPhi);
fTthetaSphi=std::tan(pTheta)*std::sin(pPhi);
fDy1=pDy1;
fDx1=pDx1;
fDx2=pDx2;
fTalpha1=std::tan(pAlp1);
fDy2=pDy2;
fDx3=pDx3;
fDx4=pDx4;
fTalpha2=std::tan(pAlp2);
MakePlanes();
}
//////////////////////////////////////////////////////////////////////////
@@ -1633,6 +1663,7 @@ G4double G4Trap::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
G4cout << "v.z() = " << v.z() << G4endl << G4endl;
G4cout << "Proposed distance :" << G4endl << G4endl;
G4cout << "snxt = " << snxt/mm << " mm" << G4endl << G4endl;
G4cout.precision(6);
G4Exception("G4Trap::DistanceToOut(p,v,..)","Notification",JustWarning,
"Undefined side for valid surface normal to solid.");
break;
@@ -1654,13 +1685,14 @@ G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4cout.precision(16) ;
G4int oldprc = G4cout.precision(16) ;
G4cout << G4endl ;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl ;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
G4cout.precision(oldprc) ;
G4Exception("G4Trap::DistanceToOut(p)",
"Notification", JustWarning, "Point p is outside !?" );
}
@@ -1695,9 +1727,9 @@ G4Trap::CreateRotatedVertices( const G4AffineTransform& pTransform ) const
{
G4ThreeVectorList *vertices;
vertices=new G4ThreeVectorList();
vertices->reserve(8);
if (vertices)
{
vertices->reserve(8);
G4ThreeVector vertex0(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,
-fDz*fTthetaSphi-fDy1,-fDz);
G4ThreeVector vertex1(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,
@@ -1743,6 +1775,15 @@ G4GeometryType G4Trap::GetEntityType() const
return G4String("G4Trap");
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Trap::Clone() const
{
return new G4Trap(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Stream object contents to an output stream
+48 -5
View File
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4Trd.cc,v 1.34 2006/10/19 15:33:38 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4Trd.cc,v 1.38 2010/10/19 15:42:10 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
// Implementation for G4Trd class
@@ -119,7 +119,7 @@ void G4Trd::CheckAndSetAllParameters ( G4double pdx1, G4double pdx2,
// for usage restricted to object persistency.
//
G4Trd::G4Trd( __void__& a )
: G4CSGSolid(a)
: G4CSGSolid(a), fDx1(0.), fDx2(0.), fDy1(0.), fDy2(0.), fDz(0.)
{
}
@@ -131,6 +131,39 @@ G4Trd::~G4Trd()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4Trd::G4Trd(const G4Trd& rhs)
: G4CSGSolid(rhs), fDx1(rhs.fDx1), fDx2(rhs.fDx2),
fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4Trd& G4Trd::operator = (const G4Trd& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4CSGSolid::operator=(rhs);
// Copy data
//
fDx1 = rhs.fDx1; fDx2 = rhs.fDx2;
fDy1 = rhs.fDy1; fDy2 = rhs.fDy2;
fDz = rhs.fDz;
return *this;
}
////////////////////////////////////////////////////////////////////////////
//
//
@@ -1236,13 +1269,14 @@ G4double G4Trd::DistanceToOut( const G4ThreeVector& p ) const
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4cout.precision(16) ;
G4int oldprc = G4cout.precision(16) ;
G4cout << G4endl ;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl ;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
G4cout.precision(oldprc) ;
G4Exception("G4Trd::DistanceToOut(p)", "Notification", JustWarning,
"Point p is outside !?" );
}
@@ -1287,9 +1321,9 @@ G4Trd::CreateRotatedVertices( const G4AffineTransform& pTransform ) const
{
G4ThreeVectorList *vertices;
vertices=new G4ThreeVectorList();
vertices->reserve(8);
if (vertices)
{
vertices->reserve(8);
G4ThreeVector vertex0(-fDx1,-fDy1,-fDz);
G4ThreeVector vertex1(fDx1,-fDy1,-fDz);
G4ThreeVector vertex2(fDx1,fDy1,-fDz);
@@ -1327,6 +1361,15 @@ G4GeometryType G4Trd::GetEntityType() const
return G4String("G4Trd");
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Trd::Clone() const
{
return new G4Trd(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Stream object contents to an output stream
+82 -30
View File
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4Tubs.cc,v 1.79 2009/06/30 10:10:11 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4Tubs.cc,v 1.84 2010/10/19 15:42:10 gcosmo Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
// class G4Tubs
@@ -89,17 +89,13 @@ G4Tubs::G4Tubs( const G4String &pName,
G4double pRMin, G4double pRMax,
G4double pDz,
G4double pSPhi, G4double pDPhi )
: G4CSGSolid(pName), fSPhi(0), fDPhi(0)
: G4CSGSolid(pName), fRMin(pRMin), fRMax(pRMax), fDz(pDz), fSPhi(0), fDPhi(0)
{
kRadTolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance();
kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance();
if (pDz>0) // Check z-len
{
fDz = pDz ;
}
else
if (pDz<=0) // Check z-len
{
G4cerr << "ERROR - G4Tubs()::G4Tubs()" << G4endl
<< " Negative Z half-length (" << pDz << ") in solid: "
@@ -107,12 +103,7 @@ G4Tubs::G4Tubs( const G4String &pName,
G4Exception("G4Tubs::G4Tubs()", "InvalidSetup", FatalException,
"Invalid Z half-length");
}
if ( (pRMin < pRMax) && (pRMin >= 0) ) // Check radii
{
fRMin = pRMin ;
fRMax = pRMax ;
}
else
if ( (pRMin >= pRMax) || (pRMin < 0) ) // Check radii
{
G4cerr << "ERROR - G4Tubs()::G4Tubs()" << G4endl
<< " Invalid values for radii in solid " << GetName()
@@ -123,7 +114,7 @@ G4Tubs::G4Tubs( const G4String &pName,
}
// Check angles
//
CheckPhiAngles(pSPhi, pDPhi);
}
@@ -133,7 +124,11 @@ G4Tubs::G4Tubs( const G4String &pName,
// for usage restricted to object persistency.
//
G4Tubs::G4Tubs( __void__& a )
: G4CSGSolid(a)
: G4CSGSolid(a), kRadTolerance(0.), kAngTolerance(0.),
fRMin(0.), fRMax(0.), fDz(0.), fSPhi(0.), fDPhi(0.),
sinCPhi(0.), cosCPhi(0.), cosHDPhiOT(0.), cosHDPhiIT(0.),
sinSPhi(0.), cosSPhi(0.), sinEPhi(0.), cosEPhi(0.),
fPhiFullTube(false)
{
}
@@ -145,6 +140,50 @@ G4Tubs::~G4Tubs()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4Tubs::G4Tubs(const G4Tubs& rhs)
: G4CSGSolid(rhs),
kRadTolerance(rhs.kRadTolerance), kAngTolerance(rhs.kAngTolerance),
fRMin(rhs.fRMin), fRMax(rhs.fRMax), fDz(rhs.fDz),
fSPhi(rhs.fSPhi), fDPhi(rhs.fDPhi),
sinCPhi(rhs.sinCPhi), cosCPhi(rhs.sinCPhi),
cosHDPhiOT(rhs.cosHDPhiOT), cosHDPhiIT(rhs.cosHDPhiOT),
sinSPhi(rhs.sinSPhi), cosSPhi(rhs.cosSPhi),
sinEPhi(rhs.sinEPhi), cosEPhi(rhs.cosEPhi), fPhiFullTube(rhs.fPhiFullTube)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4Tubs& G4Tubs::operator = (const G4Tubs& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
G4CSGSolid::operator=(rhs);
// Copy data
//
kRadTolerance = rhs.kRadTolerance; kAngTolerance = rhs.kAngTolerance;
fRMin = rhs.fRMin; fRMax = rhs.fRMax; fDz = rhs.fDz;
fSPhi = rhs.fSPhi; fDPhi = rhs.fDPhi;
sinCPhi = rhs.sinCPhi; cosCPhi = rhs.sinCPhi;
cosHDPhiOT = rhs.cosHDPhiOT; cosHDPhiIT = rhs.cosHDPhiOT;
sinSPhi = rhs.sinSPhi; cosSPhi = rhs.cosSPhi;
sinEPhi = rhs.sinEPhi; cosEPhi = rhs.cosEPhi;
fPhiFullTube = rhs.fPhiFullTube;
return *this;
}
/////////////////////////////////////////////////////////////////////////
//
// Dispatch to parameterisation for replication mechanism dimension
@@ -403,7 +442,8 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
// Try inner tolerant phi boundaries (=>inside)
// if not inside, try outer tolerant phi boundaries
if ((tolRMin==0)&&(p.x()<=halfCarTolerance)&&(p.y()<=halfCarTolerance))
if ( (tolRMin==0) && (std::fabs(p.x())<=halfCarTolerance)
&& (std::fabs(p.y())<=halfCarTolerance) )
{
in=kSurface;
}
@@ -414,8 +454,8 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
if ( fSPhi >= 0 )
{
if ( (std::abs(pPhi) < halfAngTolerance)
&& (std::abs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
if ( (std::fabs(pPhi) < halfAngTolerance)
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
{
pPhi += twopi ; // 0 <= pPhi < 2pi
}
@@ -467,8 +507,8 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
if ( pPhi < -halfAngTolerance) { pPhi += twopi; } // 0<=pPhi<2pi
if ( fSPhi >= 0 )
{
if ( (std::abs(pPhi) < halfAngTolerance)
&& (std::abs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
if ( (std::fabs(pPhi) < halfAngTolerance)
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
{
pPhi += twopi ; // 0 <= pPhi < 2pi
}
@@ -512,8 +552,8 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
if ( pPhi < -halfAngTolerance ) { pPhi += twopi; } // 0<=pPhi<2pi
if ( fSPhi >= 0 )
{
if ( (std::abs(pPhi) < halfAngTolerance)
&& (std::abs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
if ( (std::fabs(pPhi) < halfAngTolerance)
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
{
pPhi += twopi ; // 0 <= pPhi < 2pi
}
@@ -620,9 +660,10 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
#ifdef G4CSGDEBUG
G4Exception("G4Tube::SurfaceNormal(p)", "Notification",
JustWarning, "Point p is not on surface !?" );
G4cout.precision(20);
G4int oldprc = G4cout.precision(20);
G4cout<< "G4Tubs::SN ( "<<p.x()<<", "<<p.y()<<", "<<p.z()<<" ); "
<< G4endl << G4endl;
G4cout.precision(oldprc) ;
#endif
norm = ApproxSurfaceNormal(p);
}
@@ -718,7 +759,7 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
norm = G4ThreeVector(p.x()/rho, p.y()/rho, 0) ;
break ;
}
case kNZ : // + or - dz
case kNZ : // + or - dz
{
if ( p.z() > 0 ) { norm = G4ThreeVector(0,0,1) ; }
else { norm = G4ThreeVector(0,0,-1); }
@@ -734,7 +775,7 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
norm = G4ThreeVector(-std::sin(fSPhi+fDPhi), std::cos(fSPhi+fDPhi), 0) ;
break;
}
default:
default: // Should never reach this case ...
{
DumpInfo();
G4Exception("G4Tubs::ApproxSurfaceNormal()", "Notification", JustWarning,
@@ -1425,7 +1466,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
// Check intersecting with correct half-plane
// (if not -> no intersect)
//
if( (std::abs(xi)<=kCarTolerance)&&(std::abs(yi)<=kCarTolerance) )
if( (std::fabs(xi)<=kCarTolerance)&&(std::fabs(yi)<=kCarTolerance) )
{
sidephi = kSPhi;
if (((fSPhi-halfAngTolerance)<=vphi)
@@ -1468,7 +1509,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
xi = p.x() + sphi2*v.x() ;
yi = p.y() + sphi2*v.y() ;
if ((std::abs(xi)<=kCarTolerance)&&(std::abs(yi)<=kCarTolerance))
if ((std::fabs(xi)<=kCarTolerance)&&(std::fabs(yi)<=kCarTolerance))
{
// Leaving via ending phi
//
@@ -1592,6 +1633,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
G4cout << "v.z() = " << v.z() << G4endl << G4endl ;
G4cout << "Proposed distance :" << G4endl << G4endl ;
G4cout << "snxt = " << snxt/mm << " mm" << G4endl << G4endl ;
G4cout.precision(6) ;
G4Exception("G4Tubs::DistanceToOut(p,v,..)","Notification",JustWarning,
"Undefined side for valid surface normal to solid.");
break ;
@@ -1614,13 +1656,14 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p ) const
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4cout.precision(16) ;
G4int oldprc = G4cout.precision(16) ;
G4cout << G4endl ;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl ;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
G4cout.precision(oldprc) ;
G4Exception("G4Tubs::DistanceToOut(p)", "Notification", JustWarning,
"Point p is outside !?");
}
@@ -1709,10 +1752,10 @@ G4Tubs::CreateRotatedVertices( const G4AffineTransform& pTransform ) const
else { sAngle = fSPhi ; }
vertices = new G4ThreeVectorList();
vertices->reserve(noCrossSections*4);
if ( vertices )
{
vertices->reserve(noCrossSections*4);
for (crossSection = 0 ; crossSection < noCrossSections ; crossSection++ )
{
// Compute coordinates of cross section at section crossSection
@@ -1764,6 +1807,15 @@ G4GeometryType G4Tubs::GetEntityType() const
return G4String("G4Tubs");
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Tubs::Clone() const
{
return new G4Tubs(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Stream object contents to an output stream