Import Geant4 5.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-08 16:57:27 +02:00
parent 330b82b769
commit 37fff30d2e
5733 changed files with 263867 additions and 74574 deletions
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4ClippablePolygon.cc,v 1.6 2001/07/11 10:00:15 gunter Exp $
// GEANT4 tag $Name: geant4-04-01 $
// $Id: G4ClippablePolygon.cc,v 1.8 2002/10/30 13:52:22 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------------
@@ -31,7 +31,7 @@
//
// G4ClippablePolygon.cc
//
// Includes code from G4VSolid (P. Kent, V. Grichine, J. Allison)
// Includes code from G4VSolid (P.Kent, V.Grichine, J.Allison)
//
// --------------------------------------------------------------------
@@ -43,6 +43,7 @@
// Constructor
//
G4ClippablePolygon::G4ClippablePolygon()
: normal(0.,0.,0.)
{
}
@@ -58,7 +59,7 @@ G4ClippablePolygon::~G4ClippablePolygon()
//
void G4ClippablePolygon::AddVertexInOrder( const G4ThreeVector vertex )
{
vertices.push_back( vertex );
vertices.push_back( vertex );
}
@@ -67,7 +68,7 @@ void G4ClippablePolygon::AddVertexInOrder( const G4ThreeVector vertex )
//
void G4ClippablePolygon::ClearAllVertices()
{
vertices.clear();
vertices.clear();
}
@@ -77,13 +78,13 @@ void G4ClippablePolygon::ClearAllVertices()
//
G4bool G4ClippablePolygon::Clip( const G4VoxelLimits &voxelLimit )
{
if (voxelLimit.IsLimited()) {
ClipAlongOneAxis( voxelLimit, kXAxis );
ClipAlongOneAxis( voxelLimit, kYAxis );
ClipAlongOneAxis( voxelLimit, kZAxis );
}
return (vertices.size() > 0);
if (voxelLimit.IsLimited()) {
ClipAlongOneAxis( voxelLimit, kXAxis );
ClipAlongOneAxis( voxelLimit, kYAxis );
ClipAlongOneAxis( voxelLimit, kZAxis );
}
return (vertices.size() > 0);
}
@@ -92,15 +93,16 @@ G4bool G4ClippablePolygon::Clip( const G4VoxelLimits &voxelLimit )
//
// Clip, while ignoring the indicated axis
//
G4bool G4ClippablePolygon::PartialClip( const G4VoxelLimits &voxelLimit, const EAxis IgnoreMe )
G4bool G4ClippablePolygon::PartialClip( const G4VoxelLimits &voxelLimit,
const EAxis IgnoreMe )
{
if (voxelLimit.IsLimited()) {
if (IgnoreMe != kXAxis) ClipAlongOneAxis( voxelLimit, kXAxis );
if (IgnoreMe != kYAxis) ClipAlongOneAxis( voxelLimit, kYAxis );
if (IgnoreMe != kZAxis) ClipAlongOneAxis( voxelLimit, kZAxis );
}
return (vertices.size() > 0);
if (voxelLimit.IsLimited()) {
if (IgnoreMe != kXAxis) ClipAlongOneAxis( voxelLimit, kXAxis );
if (IgnoreMe != kYAxis) ClipAlongOneAxis( voxelLimit, kYAxis );
if (IgnoreMe != kZAxis) ClipAlongOneAxis( voxelLimit, kZAxis );
}
return (vertices.size() > 0);
}
@@ -108,36 +110,38 @@ G4bool G4ClippablePolygon::PartialClip( const G4VoxelLimits &voxelLimit, const E
// GetExtent
//
G4bool G4ClippablePolygon::GetExtent( const EAxis axis,
G4double &min, G4double &max ) const
G4double &min,
G4double &max ) const
{
//
// Okay, how many entries do we have?
//
G4int noLeft = vertices.size();
//
// Return false if nothing is left
//
if (noLeft == 0) return false;
//
// Initialize min and max to our first vertex
//
min = max = vertices[0].operator()( axis );
//
// Compare to the rest
//
G4int i;
for( i=1; i<noLeft; i++ ) {
G4double component = vertices[i].operator()( axis );
if (component < min )
min = component;
else if (component > max )
max = component;
}
return true;
//
// Okay, how many entries do we have?
//
G4int noLeft = vertices.size();
//
// Return false if nothing is left
//
if (noLeft == 0) return false;
//
// Initialize min and max to our first vertex
//
min = max = vertices[0].operator()( axis );
//
// Compare to the rest
//
G4int i;
for( i=1; i<noLeft; i++ )
{
G4double component = vertices[i].operator()( axis );
if (component < min )
min = component;
else if (component > max )
max = component;
}
return true;
}
@@ -149,22 +153,25 @@ G4bool G4ClippablePolygon::GetExtent( const EAxis axis,
//
const G4ThreeVector *G4ClippablePolygon::GetMinPoint( const EAxis axis ) const
{
G4int noLeft = vertices.size();
if (noLeft==0) G4Exception( "G4ClippablePolygon::GetMinPoint -- empty polygon" );
const G4ThreeVector *answer = &(vertices[0]);
G4double min = answer->operator()(axis);
G4int noLeft = vertices.size();
if (noLeft==0)
G4Exception("G4ClippablePolygon::GetMinPoint() - empty polygon");
const G4ThreeVector *answer = &(vertices[0]);
G4double min = answer->operator()(axis);
G4int i;
for( i=1; i<noLeft; i++ ) {
G4double component = vertices[i].operator()( axis );
if (component < min) {
answer = &(vertices[i]);
min = component;
}
}
return answer;
G4int i;
for( i=1; i<noLeft; i++ )
{
G4double component = vertices[i].operator()( axis );
if (component < min)
{
answer = &(vertices[i]);
min = component;
}
}
return answer;
}
@@ -176,24 +183,27 @@ const G4ThreeVector *G4ClippablePolygon::GetMinPoint( const EAxis axis ) const
//
const G4ThreeVector *G4ClippablePolygon::GetMaxPoint( const EAxis axis ) const
{
G4int noLeft = vertices.size();
if (noLeft==0) G4Exception( "G4ClippablePolygon::GetMaxPoint -- empty polygon" );
const G4ThreeVector *answer = &(vertices[0]);
G4double max = answer->operator()(axis);
G4int noLeft = vertices.size();
if (noLeft==0)
G4Exception("G4ClippablePolygon::GetMaxPoint() - empty polygon");
const G4ThreeVector *answer = &(vertices[0]);
G4double max = answer->operator()(axis);
G4int i;
for( i=1; i<noLeft; i++ ) {
G4double component = vertices[i].operator()( axis );
if (component > max) {
answer = &(vertices[i]);
max = component;
}
}
return answer;
G4int i;
for( i=1; i<noLeft; i++ )
{
G4double component = vertices[i].operator()( axis );
if (component > max)
{
answer = &(vertices[i]);
max = component;
}
}
return answer;
}
//
// InFrontOf
@@ -211,58 +221,63 @@ const G4ThreeVector *G4ClippablePolygon::GetMaxPoint( const EAxis axis ) const
// polygon1.InFrontOf(polygon2)
// polygon2.BehindOf(polygon1)
//
G4bool G4ClippablePolygon::InFrontOf( const G4ClippablePolygon &other, EAxis axis ) const
G4bool G4ClippablePolygon::InFrontOf( const G4ClippablePolygon &other,
EAxis axis ) const
{
//
// If things are empty, do something semi-sensible
//
G4int noLeft = vertices.size();
if (noLeft==0) return false;
if (other.Empty()) return true;
//
// If things are empty, do something semi-sensible
//
G4int noLeft = vertices.size();
if (noLeft==0) return false;
if (other.Empty()) return true;
//
// Get minimum of other polygon
//
const G4ThreeVector *minPointOther = other.GetMinPoint( axis );
const G4double minOther = minPointOther->operator()(axis);
//
// Get minimum of this polygon
//
const G4ThreeVector *minPoint = GetMinPoint( axis );
const G4double min = minPoint->operator()(axis);
//
// Easy decision
//
if (min < minOther-kCarTolerance) return true; // Clear winner
if (minOther < min-kCarTolerance) return false; // Clear loser
//
// We have a tie (this will not be all that rare since our
// polygons are connected)
//
// Check to see if there is a vertex in the other polygon
// that is behind this one (or vice versa)
//
G4bool answer;
G4ThreeVector normalOther = other.GetNormal();
if (fabs(normalOther(axis)) > fabs(normal(axis))) {
G4double minP, maxP;
GetPlanerExtent( *minPointOther, normalOther, minP, maxP );
answer = (normalOther(axis) > 0) ? (minP < -kCarTolerance) : (maxP > +kCarTolerance);
}
else {
G4double minP, maxP;
other.GetPlanerExtent( *minPoint, normal, minP, maxP );
answer = (normal(axis) > 0) ? (maxP > +kCarTolerance) : (minP < -kCarTolerance);
}
return answer;
//
// Get minimum of other polygon
//
const G4ThreeVector *minPointOther = other.GetMinPoint( axis );
const G4double minOther = minPointOther->operator()(axis);
//
// Get minimum of this polygon
//
const G4ThreeVector *minPoint = GetMinPoint( axis );
const G4double min = minPoint->operator()(axis);
//
// Easy decision
//
if (min < minOther-kCarTolerance) return true; // Clear winner
if (minOther < min-kCarTolerance) return false; // Clear loser
//
// We have a tie (this will not be all that rare since our
// polygons are connected)
//
// Check to see if there is a vertex in the other polygon
// that is behind this one (or vice versa)
//
G4bool answer;
G4ThreeVector normalOther = other.GetNormal();
if (fabs(normalOther(axis)) > fabs(normal(axis)))
{
G4double minP, maxP;
GetPlanerExtent( *minPointOther, normalOther, minP, maxP );
answer = (normalOther(axis) > 0) ? (minP < -kCarTolerance)
: (maxP > +kCarTolerance);
}
else
{
G4double minP, maxP;
other.GetPlanerExtent( *minPoint, normal, minP, maxP );
answer = (normal(axis) > 0) ? (maxP > +kCarTolerance)
: (minP < -kCarTolerance);
}
return answer;
}
//
@@ -271,58 +286,63 @@ G4bool G4ClippablePolygon::InFrontOf( const G4ClippablePolygon &other, EAxis axi
// Decide if this polygon is behind another.
// See notes in method "InFrontOf"
//
G4bool G4ClippablePolygon::BehindOf( const G4ClippablePolygon &other, EAxis axis ) const
G4bool G4ClippablePolygon::BehindOf( const G4ClippablePolygon &other,
EAxis axis ) const
{
//
// If things are empty, do something semi-sensible
//
G4int noLeft = vertices.size();
if (noLeft==0) return false;
if (other.Empty()) return true;
//
// If things are empty, do something semi-sensible
//
G4int noLeft = vertices.size();
if (noLeft==0) return false;
if (other.Empty()) return true;
//
// Get minimum of other polygon
//
const G4ThreeVector *maxPointOther = other.GetMaxPoint( axis );
const G4double maxOther = maxPointOther->operator()(axis);
//
// Get minimum of this polygon
//
const G4ThreeVector *maxPoint = GetMaxPoint( axis );
const G4double max = maxPoint->operator()(axis);
//
// Easy decision
//
if (max > maxOther+kCarTolerance) return true; // Clear winner
if (maxOther > max+kCarTolerance) return false; // Clear loser
//
// We have a tie (this will not be all that rare since our
// polygons are connected)
//
// Check to see if there is a vertex in the other polygon
// that is in front of this one (or vice versa)
//
G4bool answer;
G4ThreeVector normalOther = other.GetNormal();
if (fabs(normalOther(axis)) > fabs(normal(axis))) {
G4double minP, maxP;
GetPlanerExtent( *maxPointOther, normalOther, minP, maxP );
answer = (normalOther(axis) > 0) ? (maxP > +kCarTolerance) : (minP < -kCarTolerance);
}
else {
G4double minP, maxP;
other.GetPlanerExtent( *maxPoint, normal, minP, maxP );
answer = (normal(axis) > 0) ? (minP < -kCarTolerance) : (maxP > +kCarTolerance);
}
return answer;
//
// Get minimum of other polygon
//
const G4ThreeVector *maxPointOther = other.GetMaxPoint( axis );
const G4double maxOther = maxPointOther->operator()(axis);
//
// Get minimum of this polygon
//
const G4ThreeVector *maxPoint = GetMaxPoint( axis );
const G4double max = maxPoint->operator()(axis);
//
// Easy decision
//
if (max > maxOther+kCarTolerance) return true; // Clear winner
if (maxOther > max+kCarTolerance) return false; // Clear loser
//
// We have a tie (this will not be all that rare since our
// polygons are connected)
//
// Check to see if there is a vertex in the other polygon
// that is in front of this one (or vice versa)
//
G4bool answer;
G4ThreeVector normalOther = other.GetNormal();
if (fabs(normalOther(axis)) > fabs(normal(axis)))
{
G4double minP, maxP;
GetPlanerExtent( *maxPointOther, normalOther, minP, maxP );
answer = (normalOther(axis) > 0) ? (maxP > +kCarTolerance)
: (minP < -kCarTolerance);
}
else
{
G4double minP, maxP;
other.GetPlanerExtent( *maxPoint, normal, minP, maxP );
answer = (normal(axis) > 0) ? (minP < -kCarTolerance)
: (maxP > +kCarTolerance);
}
return answer;
}
@@ -332,140 +352,140 @@ G4bool G4ClippablePolygon::BehindOf( const G4ClippablePolygon &other, EAxis axis
// Get min/max distance in or out of a plane
//
G4bool G4ClippablePolygon::GetPlanerExtent( const G4ThreeVector &pointOnPlane,
const G4ThreeVector &planeNormal,
G4double &min, G4double &max ) const
const G4ThreeVector &planeNormal,
G4double &min,
G4double &max ) const
{
//
// Okay, how many entries do we have?
//
G4int noLeft = vertices.size();
//
// Return false if nothing is left
//
if (noLeft == 0) return false;
//
// Initialize min and max to our first vertex
//
min = max = planeNormal.dot(vertices[0]-pointOnPlane);
//
// Compare to the rest
//
G4int i;
for( i=1; i<noLeft; i++ ) {
G4double component = planeNormal.dot(vertices[i] - pointOnPlane);
if (component < min )
min = component;
else if (component > max )
max = component;
}
return true;
//
// Okay, how many entries do we have?
//
G4int noLeft = vertices.size();
//
// Return false if nothing is left
//
if (noLeft == 0) return false;
//
// Initialize min and max to our first vertex
//
min = max = planeNormal.dot(vertices[0]-pointOnPlane);
//
// Compare to the rest
//
G4int i;
for( i=1; i<noLeft; i++ )
{
G4double component = planeNormal.dot(vertices[i] - pointOnPlane);
if (component < min )
min = component;
else if (component > max )
max = component;
}
return true;
}
//
// Clip along just one axis, as specified in voxelLimit
//
void G4ClippablePolygon::ClipAlongOneAxis( const G4VoxelLimits &voxelLimit, const EAxis axis )
void G4ClippablePolygon::ClipAlongOneAxis( const G4VoxelLimits &voxelLimit,
const EAxis axis )
{
if (!voxelLimit.IsLimited(axis)) return;
G4ThreeVectorList tempPolygon;
if (!voxelLimit.IsLimited(axis)) return;
G4ThreeVectorList tempPolygon;
//
// Build a "simple" voxelLimit that includes only the min extent
// and apply this to our vertices, producing result in tempPolygon
//
G4VoxelLimits simpleLimit1;
simpleLimit1.AddLimit( axis, voxelLimit.GetMinExtent(axis), kInfinity );
ClipToSimpleLimits( vertices, tempPolygon, simpleLimit1 );
//
// Build a "simple" voxelLimit that includes only the min extent
// and apply this to our vertices, producing result in tempPolygon
//
G4VoxelLimits simpleLimit1;
simpleLimit1.AddLimit( axis, voxelLimit.GetMinExtent(axis), kInfinity );
ClipToSimpleLimits( vertices, tempPolygon, simpleLimit1 );
//
// If nothing is left from the above clip, we might as well return now
// (but with an empty vertices)
//
if (tempPolygon.size() == 0) {
vertices.clear();
return;
}
//
// If nothing is left from the above clip, we might as well return now
// (but with an empty vertices)
//
if (tempPolygon.size() == 0)
{
vertices.clear();
return;
}
//
// Now do the same, but using a "simple" limit that includes only the max extent.
// Apply this to out tempPolygon, producing result in vertices.
//
G4VoxelLimits simpleLimit2;
simpleLimit2.AddLimit( axis, -kInfinity, voxelLimit.GetMaxExtent(axis) );
ClipToSimpleLimits( tempPolygon, vertices, simpleLimit2 );
//
// Now do the same, but using a "simple" limit that includes only the max
// extent. Apply this to out tempPolygon, producing result in vertices.
//
G4VoxelLimits simpleLimit2;
simpleLimit2.AddLimit( axis, -kInfinity, voxelLimit.GetMaxExtent(axis) );
ClipToSimpleLimits( tempPolygon, vertices, simpleLimit2 );
//
// If nothing is left, return now
//
if (vertices.size() == 0) return;
//
// If nothing is left, return now
//
if (vertices.size() == 0) return;
}
//
// pVoxelLimits must be only limited along one axis, and either the maximum
// along the axis must be +kInfinity, or the minimum -kInfinity
//
void G4ClippablePolygon::ClipToSimpleLimits( G4ThreeVectorList& pPolygon,
G4ThreeVectorList& outputPolygon,
const G4VoxelLimits& pVoxelLimit )
G4ThreeVectorList& outputPolygon,
const G4VoxelLimits& pVoxelLimit )
{
G4int i;
G4int noVertices=pPolygon.size();
G4ThreeVector vEnd,vStart;
G4int i;
G4int noVertices=pPolygon.size();
G4ThreeVector vEnd,vStart;
outputPolygon.clear();
outputPolygon.clear();
for (i=0;i<noVertices;i++)
{
vStart=pPolygon[i];
if (i==noVertices-1)
{
vEnd=pPolygon[0];
}
else
{
vEnd=pPolygon[i+1];
}
if (pVoxelLimit.Inside(vStart))
{
if (pVoxelLimit.Inside(vEnd))
{
// vStart and vEnd inside -> output end point
outputPolygon.push_back(vEnd);
}
else
{
// vStart inside, vEnd outside -> output crossing point
pVoxelLimit.ClipToLimits(vStart,vEnd);
outputPolygon.push_back(vEnd);
}
}
else
{
if (pVoxelLimit.Inside(vEnd))
{
// vStart outside, vEnd inside -> output inside section
pVoxelLimit.ClipToLimits(vStart,vEnd);
outputPolygon.push_back(vStart);
outputPolygon.push_back(vEnd);
}
else
// Both point outside -> no output
{
}
}
}
for (i=0;i<noVertices;i++)
{
vStart=pPolygon[i];
if (i==noVertices-1)
{
vEnd=pPolygon[0];
}
else
{
vEnd=pPolygon[i+1];
}
if (pVoxelLimit.Inside(vStart))
{
if (pVoxelLimit.Inside(vEnd))
{
// vStart and vEnd inside -> output end point
//
outputPolygon.push_back(vEnd);
}
else
{
// vStart inside, vEnd outside -> output crossing point
//
pVoxelLimit.ClipToLimits(vStart,vEnd);
outputPolygon.push_back(vEnd);
}
}
else
{
if (pVoxelLimit.Inside(vEnd))
{
// vStart outside, vEnd inside -> output inside section
//
pVoxelLimit.ClipToLimits(vStart,vEnd);
outputPolygon.push_back(vStart);
outputPolygon.push_back(vEnd);
}
else // Both point outside -> no output
{
}
}
}
}
File diff suppressed because it is too large Load Diff
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4EnclosingCylinder.cc,v 1.3 2001/07/11 10:00:16 gunter Exp $
// GEANT4 tag $Name: geant4-04-01 $
// $Id: G4EnclosingCylinder.cc,v 1.5 2002/10/30 13:52:23 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------------
@@ -42,51 +42,52 @@
// Constructor
//
G4EnclosingCylinder::G4EnclosingCylinder( const G4ReduciblePolygon *rz,
G4bool thePhiIsOpen,
G4double theStartPhi,
G4double theTotalPhi )
G4bool thePhiIsOpen,
G4double theStartPhi,
G4double theTotalPhi )
: startPhi(theStartPhi), totalPhi(theTotalPhi),
rx1(0.), ry1(0.), dx1(0.), dy1(0.),
rx2(0.), ry2(0.), dx2(0.), dy2(0.),
concave(theTotalPhi > M_PI)
{
//
// Obtain largest r and smallest and largest z
//
radius = rz->Amax();
zHi = rz->Bmax();
zLo = rz->Bmin();
//
// Save phi info
//
phiIsOpen = thePhiIsOpen;
if ( phiIsOpen )
{
startPhi = theStartPhi;
totalPhi = theTotalPhi;
rx1 = cos(startPhi);
ry1 = sin(startPhi);
dx1 = +ry1*10*kCarTolerance;
dy1 = -rx1*10*kCarTolerance;
rx2 = cos(startPhi+totalPhi);
ry2 = sin(startPhi+totalPhi);
dx2 = -ry2*10*kCarTolerance;
dy2 = +rx2*10*kCarTolerance;
concave = totalPhi > M_PI;
}
//
// Add safety
//
radius += 10*kCarTolerance;
zLo -= 10*kCarTolerance;
zHi += 10*kCarTolerance;
//
// Obtain largest r and smallest and largest z
//
radius = rz->Amax();
zHi = rz->Bmax();
zLo = rz->Bmin();
//
// Save phi info
//
phiIsOpen = thePhiIsOpen;
if ( phiIsOpen )
{
rx1 = cos(startPhi);
ry1 = sin(startPhi);
dx1 = +ry1*10*kCarTolerance;
dy1 = -rx1*10*kCarTolerance;
rx2 = cos(startPhi+totalPhi);
ry2 = sin(startPhi+totalPhi);
dx2 = -ry2*10*kCarTolerance;
dy2 = +rx2*10*kCarTolerance;
}
//
// Add safety
//
radius += 10*kCarTolerance;
zLo -= 10*kCarTolerance;
zHi += 10*kCarTolerance;
}
//
// Destructor
//
G4EnclosingCylinder::~G4EnclosingCylinder() {;}
G4EnclosingCylinder::~G4EnclosingCylinder()
{
}
//
@@ -98,25 +99,28 @@ G4EnclosingCylinder::~G4EnclosingCylinder() {;}
//
G4bool G4EnclosingCylinder::MustBeOutside( const G4ThreeVector &p ) const
{
if (p.perp() > radius) return true;
if (p.z() < zLo) return true;
if (p.z() > zHi) return true;
if (p.perp() > radius) return true;
if (p.z() < zLo) return true;
if (p.z() > zHi) return true;
if (phiIsOpen) {
if (concave) {
if ( ((p.x()-dx1)*ry1 - (p.y()-dy1)*rx1) < 0) return false;
if ( ((p.x()-dx2)*ry2 - (p.y()-dy2)*rx2) > 0) return false;
}
else {
if ( ((p.x()-dx1)*ry1 - (p.y()-dy1)*rx1) > 0) return true;
if ( ((p.x()-dx2)*ry2 - (p.y()-dy2)*rx2) < 0) return true;
}
}
return false;
if (phiIsOpen)
{
if (concave)
{
if ( ((p.x()-dx1)*ry1 - (p.y()-dy1)*rx1) < 0) return false;
if ( ((p.x()-dx2)*ry2 - (p.y()-dy2)*rx2) > 0) return false;
}
else
{
if ( ((p.x()-dx1)*ry1 - (p.y()-dy1)*rx1) > 0) return true;
if ( ((p.x()-dx2)*ry2 - (p.y()-dy2)*rx2) < 0) return true;
}
}
return false;
}
//
// Misses
//
@@ -124,17 +128,19 @@ G4bool G4EnclosingCylinder::MustBeOutside( const G4ThreeVector &p ) const
//
// If one is not sure, return false
//
G4bool G4EnclosingCylinder::ShouldMiss( const G4ThreeVector &p, const G4ThreeVector &v ) const
G4bool G4EnclosingCylinder::ShouldMiss( const G4ThreeVector &p,
const G4ThreeVector &v ) const
{
if (!MustBeOutside(p)) return false;
G4double cross = p.x()*v.y() - p.y()*v.x();
if (cross > radius) return true;
if (p.perp() > radius) {
G4double dot = p.x()*v.x() + p.y()*v.y();
if (dot > 0) return true;
}
if (!MustBeOutside(p)) return false;
G4double cross = p.x()*v.y() - p.y()*v.x();
if (cross > radius) return true;
if (p.perp() > radius)
{
G4double dot = p.x()*v.x() + p.y()*v.y();
if (dot > 0) return true;
}
return false;
}
return false;
}
File diff suppressed because it is too large Load Diff
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4IntersectingCone.cc,v 1.4 2001/07/11 10:00:16 gunter Exp $
// GEANT4 tag $Name: geant4-04-01 $
// $Id: G4IntersectingCone.cc,v 1.5 2002/10/28 11:47:52 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------------
@@ -40,45 +40,53 @@
//
// Constructor
//
G4IntersectingCone::G4IntersectingCone( const G4double r[2], const G4double z[2] )
{
//
// What type of cone are we?
//
type1 = (fabs(z[1]-z[0]) > fabs(r[1]-r[0]));
if (type1) {
B = (r[1]-r[0])/(z[1]-z[0]); // tube like
A = 0.5*( r[1]+r[0] - B*(z[1]+z[0]) );
}
else {
B = (z[1]-z[0])/(r[1]-r[0]); // disk like
A = 0.5*( z[1]+z[0] - B*(r[1]+r[0]) );
}
G4IntersectingCone::G4IntersectingCone( const G4double r[2],
const G4double z[2] )
{
//
// What type of cone are we?
//
type1 = (fabs(z[1]-z[0]) > fabs(r[1]-r[0]));
if (type1)
{
B = (r[1]-r[0])/(z[1]-z[0]); // tube like
A = 0.5*( r[1]+r[0] - B*(z[1]+z[0]) );
}
else
{
B = (z[1]-z[0])/(r[1]-r[0]); // disk like
A = 0.5*( z[1]+z[0] - B*(r[1]+r[0]) );
}
//
// Calculate extent
//
if (r[0] < r[1]) {
rLo = r[0]; rHi = r[1];
}
else {
rLo = r[1]; rHi = r[0];
}
if (z[0] < z[1]) {
zLo = z[0]; zHi = z[1];
}
else {
zLo = z[1]; zHi = z[0];
}
//
// Calculate extent
//
if (r[0] < r[1])
{
rLo = r[0]; rHi = r[1];
}
else
{
rLo = r[1]; rHi = r[0];
}
if (z[0] < z[1])
{
zLo = z[0]; zHi = z[1];
}
else
{
zLo = z[1]; zHi = z[0];
}
}
//
// Destructor
//
G4IntersectingCone::~G4IntersectingCone()
{;}
{
}
//
@@ -87,20 +95,23 @@ G4IntersectingCone::~G4IntersectingCone()
// Check r or z extent, as appropriate, to see if the point is possibly
// on the cone.
//
G4bool G4IntersectingCone::HitOn( const G4double r, const G4double z )
G4bool G4IntersectingCone::HitOn( const G4double r,
const G4double z )
{
//
// Be careful! The inequalities cannot be "<=" and ">=" here without
// punching a tiny hole in our shape!
//
if (type1) {
if (z < zLo || z > zHi) return false;
}
else {
if (r < rLo || r > rHi) return false;
}
//
// Be careful! The inequalities cannot be "<=" and ">=" here without
// punching a tiny hole in our shape!
//
if (type1)
{
if (z < zLo || z > zHi) return false;
}
else
{
if (r < rLo || r > rHi) return false;
}
return true;
return true;
}
@@ -110,15 +121,18 @@ G4bool G4IntersectingCone::HitOn( const G4double r, const G4double z )
// Calculate the intersection of a line with our conical surface, ignoring
// any phi division
//
G4int G4IntersectingCone::LineHitsCone( const G4ThreeVector &p, const G4ThreeVector &v,
G4double *s1, G4double *s2 )
G4int G4IntersectingCone::LineHitsCone( const G4ThreeVector &p,
const G4ThreeVector &v,
G4double *s1, G4double *s2 )
{
if (type1) {
return LineHitsCone1( p, v, s1, s2 );
}
else {
return LineHitsCone2( p, v, s1, s2 );
}
if (type1)
{
return LineHitsCone1( p, v, s1, s2 );
}
else
{
return LineHitsCone2( p, v, s1, s2 );
}
}
@@ -138,15 +152,15 @@ G4int G4IntersectingCone::LineHitsCone( const G4ThreeVector &p, const G4ThreeVec
//
// Solution is quadratic:
//
// a*s**2 + b*s + c = 0
// a*s**2 + b*s + c = 0
//
// where:
//
// a = x0**2 + y0**2 - (A + B*z0)**2
// a = x0**2 + y0**2 - (A + B*z0)**2
//
// b = 2*( x0*tx + y0*ty - (A*B - B*B*z0)*tz)
// b = 2*( x0*tx + y0*ty - (A*B - B*B*z0)*tz)
//
// c = tx**2 + ty**2 - (B*tz)**2
// c = tx**2 + ty**2 - (B*tz)**2
//
// Notice, that if a < 0, this indicates that the two solutions (assuming
// they exist) are in opposite cones (that is, given z0 = -A/B, one z < z0
@@ -181,76 +195,85 @@ G4int G4IntersectingCone::LineHitsCone( const G4ThreeVector &p, const G4ThreeVec
// where epsilon is small, then:
// Delta = epsilon/2/B
//
G4int G4IntersectingCone::LineHitsCone1( const G4ThreeVector &p, const G4ThreeVector &v,
G4double *s1, G4double *s2 )
G4int G4IntersectingCone::LineHitsCone1( const G4ThreeVector &p,
const G4ThreeVector &v,
G4double *s1, G4double *s2 )
{
G4double x0 = p.x(), y0 = p.y(), z0 = p.z();
G4double tx = v.x(), ty = v.y(), tz = v.z();
G4double x0 = p.x(), y0 = p.y(), z0 = p.z();
G4double tx = v.x(), ty = v.y(), tz = v.z();
G4double a = tx*tx + ty*ty - sqr(B*tz);
G4double b = 2*( x0*tx + y0*ty - (A*B + B*B*z0)*tz);
G4double c = x0*x0 + y0*y0 - sqr(A + B*z0);
G4double radical = b*b - 4*a*c;
if (radical < -1E-6*fabs(b)) return 0; // No solution
if (radical < 1E-6*fabs(b)) {
//
// The radical is roughly zero: check for special, very rare, cases
//
if (fabs(a) > 1/kInfinity) {
if ( fabs(x0*ty - y0*tx) < fabs(1E-6/B)) {
*s1 = -0.5*b/a;
return 1;
}
return 0;
}
}
else {
radical = sqrt(radical);
}
if (a > 1/kInfinity) {
G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) );
sa = q/a;
sb = c/q;
if (sa < sb) { *s1 = sa; *s2 = sb; } else { *s1 = sb; *s2 = sa; }
if (A + B*(z0+(*s1)*tz) < 0) return 0;
return 2;
}
else if (a < -1/kInfinity) {
G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) );
sa = q/a;
sb = c/q;
*s1 = (B*tz > 0)^(sa > sb) ? sb : sa;
return 1;
}
else if (fabs(b) < 1/kInfinity) {
return 0;
}
else {
*s1 = -c/b;
if (A + B*(z0+(*s1)*tz) < 0) return 0;
return 1;
}
G4double a = tx*tx + ty*ty - sqr(B*tz);
G4double b = 2*( x0*tx + y0*ty - (A*B + B*B*z0)*tz);
G4double c = x0*x0 + y0*y0 - sqr(A + B*z0);
G4double radical = b*b - 4*a*c;
if (radical < -1E-6*fabs(b)) return 0; // No solution
if (radical < 1E-6*fabs(b))
{
//
// The radical is roughly zero: check for special, very rare, cases
//
if (fabs(a) > 1/kInfinity)
{
if ( fabs(x0*ty - y0*tx) < fabs(1E-6/B))
{
*s1 = -0.5*b/a;
return 1;
}
return 0;
}
}
else
{
radical = sqrt(radical);
}
if (a > 1/kInfinity)
{
G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) );
sa = q/a;
sb = c/q;
if (sa < sb) { *s1 = sa; *s2 = sb; } else { *s1 = sb; *s2 = sa; }
if (A + B*(z0+(*s1)*tz) < 0) return 0;
return 2;
}
else if (a < -1/kInfinity)
{
G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) );
sa = q/a;
sb = c/q;
*s1 = (B*tz > 0)^(sa > sb) ? sb : sa;
return 1;
}
else if (fabs(b) < 1/kInfinity)
{
return 0;
}
else
{
*s1 = -c/b;
if (A + B*(z0+(*s1)*tz) < 0) return 0;
return 1;
}
}
//
// LineHitsCone2
//
// See comments under LineHitsCone1. In this routine, case2, we have:
//
// Z = A + B*R
// Z = A + B*R
//
// The solution is still quadratic:
//
// a = tz**2 - B*B*(tx**2 + ty**2)
// a = tz**2 - B*B*(tx**2 + ty**2)
//
// b = 2*( (z0-A)*tz - B*B*(x0*tx+y0*ty) )
// b = 2*( (z0-A)*tz - B*B*(x0*tx+y0*ty) )
//
// c = ( (z0-A)**2 - B*B*(x0**2 + y0**2) )
// c = ( (z0-A)**2 - B*B*(x0**2 + y0**2) )
//
// The rest is much the same, except some details.
//
@@ -258,73 +281,82 @@ G4int G4IntersectingCone::LineHitsCone1( const G4ThreeVector &p, const G4ThreeVe
//
// a > 0 ? We only want solution which produces R > 0.
// since R = (z0+s*tz-A)/B, for tz/B > 0, this is the largest s
// for tz/B < 0, this is the smallest s
// for tz/B < 0, this is the smallest s
// thus, same as in case 1 ( since sign(tz/B) = sign(tz*B) )
//
G4int G4IntersectingCone::LineHitsCone2( const G4ThreeVector &p, const G4ThreeVector &v,
G4double *s1, G4double *s2 )
G4int G4IntersectingCone::LineHitsCone2( const G4ThreeVector &p,
const G4ThreeVector &v,
G4double *s1, G4double *s2 )
{
G4double x0 = p.x(), y0 = p.y(), z0 = p.z();
G4double tx = v.x(), ty = v.y(), tz = v.z();
//
// Special case which might not be so rare: B = 0 (precisely)
//
if (B==0) {
if (fabs(tz) < 1/kInfinity) return 0;
*s1 = (A-z0)/tz;
return 1;
}
G4double x0 = p.x(), y0 = p.y(), z0 = p.z();
G4double tx = v.x(), ty = v.y(), tz = v.z();
//
// Special case which might not be so rare: B = 0 (precisely)
//
if (B==0)
{
if (fabs(tz) < 1/kInfinity) return 0;
*s1 = (A-z0)/tz;
return 1;
}
G4double B2 = B*B;
G4double B2 = B*B;
G4double a = tz*tz - B2*(tx*tx + ty*ty);
G4double b = 2*( (z0-A)*tz - B2*(x0*tx + y0*ty) );
G4double c = sqr(z0-A) - B2*( x0*x0 + y0*y0 );
G4double radical = b*b - 4*a*c;
if (radical < -1E-6*fabs(b)) return 0; // No solution
if (radical < 1E-6*fabs(b)) {
//
// The radical is roughly zero: check for special, very rare, cases
//
if (fabs(a) > 1/kInfinity) {
if ( fabs(x0*ty - y0*tx) < fabs(1E-6/B)) {
*s1 = -0.5*b/a;
return 1;
}
return 0;
}
}
else {
radical = sqrt(radical);
}
if (a < -1/kInfinity) {
G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) );
sa = q/a;
sb = c/q;
if (sa < sb) { *s1 = sa; *s2 = sb; } else { *s1 = sb; *s2 = sa; }
if ((z0 + (*s1)*tz - A)/B < 0) return 0;
return 2;
}
else if (a > 1/kInfinity) {
G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) );
sa = q/a;
sb = c/q;
*s1 = (tz*B > 0)^(sa > sb) ? sb : sa;
return 1;
}
else if (fabs(b) < 1/kInfinity) {
return 0;
}
else {
*s1 = -c/b;
if ((z0 + (*s1)*tz - A)/B < 0) return 0;
return 1;
}
G4double a = tz*tz - B2*(tx*tx + ty*ty);
G4double b = 2*( (z0-A)*tz - B2*(x0*tx + y0*ty) );
G4double c = sqr(z0-A) - B2*( x0*x0 + y0*y0 );
G4double radical = b*b - 4*a*c;
if (radical < -1E-6*fabs(b)) return 0; // No solution
if (radical < 1E-6*fabs(b))
{
//
// The radical is roughly zero: check for special, very rare, cases
//
if (fabs(a) > 1/kInfinity)
{
if ( fabs(x0*ty - y0*tx) < fabs(1E-6/B))
{
*s1 = -0.5*b/a;
return 1;
}
return 0;
}
}
else
{
radical = sqrt(radical);
}
if (a < -1/kInfinity)
{
G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) );
sa = q/a;
sb = c/q;
if (sa < sb) { *s1 = sa; *s2 = sb; } else { *s1 = sb; *s2 = sa; }
if ((z0 + (*s1)*tz - A)/B < 0) return 0;
return 2;
}
else if (a > 1/kInfinity)
{
G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) );
sa = q/a;
sb = c/q;
*s1 = (tz*B > 0)^(sa > sb) ? sb : sa;
return 1;
}
else if (fabs(b) < 1/kInfinity)
{
return 0;
}
else
{
*s1 = -c/b;
if ((z0 + (*s1)*tz - A)/B < 0) return 0;
return 1;
}
}
File diff suppressed because it is too large Load Diff
+408 -280
View File
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4Polycone.cc,v 1.5 2001/07/11 10:00:16 gunter Exp $
// GEANT4 tag $Name: geant4-04-01 $
// $Id: G4Polycone.cc,v 1.7 2002/10/28 15:18:40 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------------
@@ -36,6 +36,7 @@
// --------------------------------------------------------------------
#include "G4Polycone.hh"
#include "G4PolyconeSide.hh"
#include "G4PolyPhiFace.hh"
@@ -46,44 +47,48 @@
//
// Constructor (GEANT3 style parameters)
//
//
G4Polycone::G4Polycone( const G4String& name,
G4double phiStart,
G4double phiTotal,
G4int numZPlanes,
G4double phiStart,
G4double phiTotal,
G4int numZPlanes,
const G4double zPlane[],
const G4double rInner[],
const G4double rOuter[] ) : G4VCSGfaceted( name )
const G4double rOuter[] )
: G4VCSGfaceted( name )
{
//
// Some historical ugliness
//
original_parameters = new G4PolyconeHistorical();
original_parameters->Start_angle = phiStart;
original_parameters->Opening_angle = phiTotal;
original_parameters->Num_z_planes = numZPlanes;
original_parameters->Z_values = new G4double[numZPlanes];
original_parameters->Rmin = new G4double[numZPlanes];
original_parameters->Rmax = new G4double[numZPlanes];
G4int i;
for (i=0; i<numZPlanes; i++) {
original_parameters->Z_values[i] = zPlane[i];
original_parameters->Rmin[i] = rInner[i];
original_parameters->Rmax[i] = rOuter[i];
}
//
// Build RZ polygon using special PCON/PGON GEANT3 constructor
//
G4ReduciblePolygon *rz = new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
//
// Do the real work
//
Create( phiStart, phiTotal, rz );
delete rz;
//
// Some historical ugliness
//
original_parameters = new G4PolyconeHistorical();
original_parameters->Start_angle = phiStart;
original_parameters->Opening_angle = phiTotal;
original_parameters->Num_z_planes = numZPlanes;
original_parameters->Z_values = new G4double[numZPlanes];
original_parameters->Rmin = new G4double[numZPlanes];
original_parameters->Rmax = new G4double[numZPlanes];
G4int i;
for (i=0; i<numZPlanes; i++)
{
original_parameters->Z_values[i] = zPlane[i];
original_parameters->Rmin[i] = rInner[i];
original_parameters->Rmax[i] = rOuter[i];
}
//
// Build RZ polygon using special PCON/PGON GEANT3 constructor
//
G4ReduciblePolygon *rz =
new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
//
// Do the real work
//
Create( phiStart, phiTotal, rz );
delete rz;
}
@@ -91,154 +96,197 @@ G4Polycone::G4Polycone( const G4String& name,
// Constructor (generic parameters)
//
G4Polycone::G4Polycone( const G4String& name,
G4double phiStart,
G4double phiTotal,
G4int numRZ,
const G4double r[],
const G4double z[] ) : G4VCSGfaceted( name )
G4double phiStart,
G4double phiTotal,
G4int numRZ,
const G4double r[],
const G4double z[] )
: G4VCSGfaceted( name )
{
original_parameters = 0;
original_parameters = 0;
G4ReduciblePolygon *rz = new G4ReduciblePolygon( r, z, numRZ );
Create( phiStart, phiTotal, rz );
delete rz;
G4ReduciblePolygon *rz = new G4ReduciblePolygon( r, z, numRZ );
Create( phiStart, phiTotal, rz );
delete rz;
}
//
// Create
//
// Generic create routine, called by each constructor after conversion of arguments
// Generic create routine, called by each constructor after
// conversion of arguments
//
void G4Polycone::Create( G4double phiStart,
G4double phiTotal,
G4ReduciblePolygon *rz )
G4double phiTotal,
G4ReduciblePolygon *rz )
{
//
// Perform checks of rz values
//
if (rz->Amin() < 0.0)
G4Exception( "G4Polycone: Illegal input parameters: All R values must be >= 0" );
G4double rzArea = rz->Area();
if (rzArea < -kCarTolerance) rz->ReverseOrder();
//
// Perform checks of rz values
//
if (rz->Amin() < 0.0)
{
G4cout << "ERROR - G4Polycone::Create(): " << GetName() << G4endl
<< " All R values must be >= 0 !"
<< G4endl;
G4cerr << "ERROR - G4Polycone::Create(): " << GetName() << G4endl
<< " All R values must be >= 0 !"
<< G4endl;
G4Exception("G4Polycone::Create() - Illegal input parameters");
}
G4double rzArea = rz->Area();
if (rzArea < -kCarTolerance)
rz->ReverseOrder();
else if (rzArea < -kCarTolerance)
G4Exception( "G4Polycone: Illegal input parameters: R/Z cross section is zero or near zero" );
if ((!rz->RemoveDuplicateVertices( kCarTolerance )) ||
(!rz->RemoveRedundantVertices( kCarTolerance )) )
G4Exception( "G4Polycone: Illegal input parameters: Too few unique R/Z values" );
else if (rzArea < -kCarTolerance)
{
G4cout << "ERROR - G4Polycone::Create(): " << GetName() << G4endl
<< " R/Z cross section is zero or near zero: "
<< rzArea << G4endl;
G4cerr << "ERROR - G4Polycone::Create(): " << GetName() << G4endl
<< " R/Z cross section is zero or near zero: "
<< rzArea << G4endl;
G4Exception("G4Polycone::Create() - Illegal input parameters");
}
if ( (!rz->RemoveDuplicateVertices( kCarTolerance ))
|| (!rz->RemoveRedundantVertices( kCarTolerance )) )
{
G4cout << "ERROR - G4Polycone::Create(): " << GetName() << G4endl
<< " Too few unique R/Z values !"
<< G4endl;
G4cerr << "ERROR - G4Polycone::Create(): " << GetName() << G4endl
<< " Too few unique R/Z values !"
<< G4endl;
G4Exception("G4Polycone::Create() - Illegal input parameters");
}
if (rz->CrossesItself(1/kInfinity))
G4Exception( "G4Polycone: Illegal input parameters: R/Z segments cross" );
if (rz->CrossesItself(1/kInfinity))
{
G4cout << "ERROR - G4Polycone::Create(): " << GetName() << G4endl
<< " R/Z segments cross !"
<< G4endl;
G4cerr << "ERROR - G4Polycone::Create(): " << GetName() << G4endl
<< " R/Z segments cross !"
<< G4endl;
G4Exception("G4Polycone::Create() - Illegal input parameters");
}
numCorner = rz->NumVertices();
numCorner = rz->NumVertices();
//
// Phi opening? Account for some possible roundoff, and interpret
// nonsense value as representing no phi opening
//
if (phiTotal <= 0 || phiTotal > 2.0*M_PI-1E-10) {
phiIsOpen = false;
startPhi = 0;
endPhi = 2*M_PI;
}
else {
phiIsOpen = true;
//
// Convert phi into our convention
//
startPhi = phiStart;
while( startPhi < 0 ) startPhi += 2*M_PI;
endPhi = phiStart+phiTotal;
while( endPhi < startPhi ) endPhi += 2*M_PI;
}
//
// Allocate corner array.
//
corners = new G4PolyconeSideRZ[numCorner];
//
// Phi opening? Account for some possible roundoff, and interpret
// nonsense value as representing no phi opening
//
if (phiTotal <= 0 || phiTotal > 2.0*M_PI-1E-10)
{
phiIsOpen = false;
startPhi = 0;
endPhi = 2*M_PI;
}
else
{
phiIsOpen = true;
//
// Convert phi into our convention
//
startPhi = phiStart;
while( startPhi < 0 ) startPhi += 2*M_PI;
endPhi = phiStart+phiTotal;
while( endPhi < startPhi ) endPhi += 2*M_PI;
}
//
// Allocate corner array.
//
corners = new G4PolyconeSideRZ[numCorner];
//
// Copy corners
//
G4ReduciblePolygonIterator iterRZ(rz);
G4PolyconeSideRZ *next = corners;
iterRZ.Begin();
do {
next->r = iterRZ.GetA();
next->z = iterRZ.GetB();
} while( ++next, iterRZ.Next() );
//
// Allocate face pointer array
//
numFace = phiIsOpen ? numCorner+2 : numCorner;
faces = new G4VCSGface*[numFace];
//
// Construct conical faces
//
// But! Don't construct a face if both points are at zero radius!
//
G4PolyconeSideRZ *corner = corners,
*prev = corners + numCorner-1,
*nextNext;
G4VCSGface **face = faces;
do {
next = corner+1;
if (next >= corners+numCorner) next = corners;
nextNext = next+1;
if (nextNext >= corners+numCorner) nextNext = corners;
if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
//
// We must decide here if we can dare declare one of our faces
// as having a "valid" normal (i.e. allBehind = true). This
// is never possible if the face faces "inward" in r.
//
G4bool allBehind;
if (corner->z > next->z) {
allBehind = false;
}
else {
//
// Otherwise, it is only true if the line passing
// through the two points of the segment do not
// split the r/z cross section
//
allBehind = !rz->BisectedBy( corner->r, corner->z,
next->r, next->z, kCarTolerance );
}
*face++ = new G4PolyconeSide( prev, corner, next, nextNext,
startPhi, endPhi-startPhi, phiIsOpen, allBehind );
} while( prev=corner, corner=next, corner > corners );
if (phiIsOpen) {
//
// Construct phi open edges
//
*face++ = new G4PolyPhiFace( rz, startPhi, 0, endPhi );
*face++ = new G4PolyPhiFace( rz, endPhi, 0, startPhi );
}
//
// We might have dropped a face or two: recalculate numFace
//
numFace = face-faces;
//
// Make enclosingCylinder
//
enclosingCylinder = new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
//
// Copy corners
//
G4ReduciblePolygonIterator iterRZ(rz);
G4PolyconeSideRZ *next = corners;
iterRZ.Begin();
do
{
next->r = iterRZ.GetA();
next->z = iterRZ.GetB();
} while( ++next, iterRZ.Next() );
//
// Allocate face pointer array
//
numFace = phiIsOpen ? numCorner+2 : numCorner;
faces = new G4VCSGface*[numFace];
//
// Construct conical faces
//
// But! Don't construct a face if both points are at zero radius!
//
G4PolyconeSideRZ *corner = corners,
*prev = corners + numCorner-1,
*nextNext;
G4VCSGface **face = faces;
do
{
next = corner+1;
if (next >= corners+numCorner) next = corners;
nextNext = next+1;
if (nextNext >= corners+numCorner) nextNext = corners;
if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
//
// We must decide here if we can dare declare one of our faces
// as having a "valid" normal (i.e. allBehind = true). This
// is never possible if the face faces "inward" in r.
//
G4bool allBehind;
if (corner->z > next->z)
{
allBehind = false;
}
else
{
//
// Otherwise, it is only true if the line passing
// through the two points of the segment do not
// split the r/z cross section
//
allBehind = !rz->BisectedBy( corner->r, corner->z,
next->r, next->z, kCarTolerance );
}
*face++ = new G4PolyconeSide( prev, corner, next, nextNext,
startPhi, endPhi-startPhi, phiIsOpen, allBehind );
} while( prev=corner, corner=next, corner > corners );
if (phiIsOpen)
{
//
// Construct phi open edges
//
*face++ = new G4PolyPhiFace( rz, startPhi, 0, endPhi );
*face++ = new G4PolyPhiFace( rz, endPhi, 0, startPhi );
}
//
// We might have dropped a face or two: recalculate numFace
//
numFace = face-faces;
//
// Make enclosingCylinder
//
enclosingCylinder =
new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
}
@@ -247,21 +295,20 @@ void G4Polycone::Create( G4double phiStart,
//
G4Polycone::~G4Polycone()
{
delete [] corners;
if (original_parameters) delete original_parameters;
if (enclosingCylinder) delete enclosingCylinder;
delete [] corners;
if (original_parameters) delete original_parameters;
if (enclosingCylinder) delete enclosingCylinder;
}
//
// Copy constructor
//
G4Polycone::G4Polycone( const G4Polycone &source ) : G4VCSGfaceted( source )
G4Polycone::G4Polycone( const G4Polycone &source )
: G4VCSGfaceted( source )
{
CopyStuff( source );
CopyStuff( source );
}
@@ -270,18 +317,18 @@ G4Polycone::G4Polycone( const G4Polycone &source ) : G4VCSGfaceted( source )
//
const G4Polycone &G4Polycone::operator=( const G4Polycone &source )
{
if (this == &source) return *this;
G4VCSGfaceted::operator=( source );
delete [] corners;
if (original_parameters) delete original_parameters;
delete enclosingCylinder;
CopyStuff( source );
return *this;
if (this == &source) return *this;
G4VCSGfaceted::operator=( source );
delete [] corners;
if (original_parameters) delete original_parameters;
delete enclosingCylinder;
CopyStuff( source );
return *this;
}
@@ -290,111 +337,184 @@ const G4Polycone &G4Polycone::operator=( const G4Polycone &source )
//
void G4Polycone::CopyStuff( const G4Polycone &source )
{
//
// Simple stuff
//
startPhi = source.startPhi;
endPhi = source.endPhi;
phiIsOpen = source.phiIsOpen;
numCorner = source.numCorner;
//
// Simple stuff
//
startPhi = source.startPhi;
endPhi = source.endPhi;
phiIsOpen = source.phiIsOpen;
numCorner = source.numCorner;
//
// The corner array
//
corners = new G4PolyconeSideRZ[numCorner];
G4PolyconeSideRZ *corn = corners,
*sourceCorn = source.corners;
do {
*corn = *sourceCorn;
} while( ++sourceCorn, ++corn < corners+numCorner );
//
// Original parameters
//
if (source.original_parameters) {
original_parameters = new G4PolyconeHistorical( *source.original_parameters );
}
//
// Enclosing cylinder
//
enclosingCylinder = new G4EnclosingCylinder( *source.enclosingCylinder );
//
// The corner array
//
corners = new G4PolyconeSideRZ[numCorner];
G4PolyconeSideRZ *corn = corners,
*sourceCorn = source.corners;
do
{
*corn = *sourceCorn;
} while( ++sourceCorn, ++corn < corners+numCorner );
//
// Original parameters
//
if (source.original_parameters)
{
original_parameters =
new G4PolyconeHistorical( *source.original_parameters );
}
//
// Enclosing cylinder
//
enclosingCylinder = new G4EnclosingCylinder( *source.enclosingCylinder );
}
//
// Inside
//
// This is an override of G4VCSGfaceted::Inside, created in order to speed things
// up by first checking with G4EnclosingCylinder.
// This is an override of G4VCSGfaceted::Inside, created in order
// to speed things up by first checking with G4EnclosingCylinder.
//
EInside G4Polycone::Inside( const G4ThreeVector &p ) const
{
//
// Quick test
//
if (enclosingCylinder->MustBeOutside(p)) return kOutside;
//
// Quick test
//
if (enclosingCylinder->MustBeOutside(p)) return kOutside;
//
// Long answer
//
return G4VCSGfaceted::Inside(p);
//
// Long answer
//
return G4VCSGfaceted::Inside(p);
}
//
// DistanceToIn
//
// This is an override of G4VCSGfaceted::Inside, created in order to speed things
// up by first checking with G4EnclosingCylinder.
// This is an override of G4VCSGfaceted::Inside, created in order
// to speed things up by first checking with G4EnclosingCylinder.
//
G4double G4Polycone::DistanceToIn( const G4ThreeVector &p, const G4ThreeVector &v ) const
G4double G4Polycone::DistanceToIn( const G4ThreeVector &p,
const G4ThreeVector &v ) const
{
//
// Quick test
//
if (enclosingCylinder->ShouldMiss(p,v)) return kInfinity;
//
// Long answer
//
return G4VCSGfaceted::DistanceToIn( p, v );
//
// Quick test
//
if (enclosingCylinder->ShouldMiss(p,v))
return kInfinity;
//
// Long answer
//
return G4VCSGfaceted::DistanceToIn( p, v );
}
//
// DistanceToIn
//
G4double G4Polycone::DistanceToIn( const G4ThreeVector &p ) const
{
return G4VCSGfaceted::DistanceToIn(p);
}
//
// ComputeDimensions
//
void G4Polycone::ComputeDimensions( G4VPVParameterisation* p,
const G4int n,
const G4VPhysicalVolume* pRep)
void G4Polycone::ComputeDimensions( G4VPVParameterisation* p,
const G4int n,
const G4VPhysicalVolume* pRep)
{
}
//
// GetEntityType
//
G4GeometryType G4Polycone::GetEntityType() const
{
return G4String("G4Polycone");
}
//
// Stream object contents to an output stream
//
G4std::ostream& G4Polycone::StreamInfo( G4std::ostream& os ) const
{
os << "-----------------------------------------------------------\n"
<< " *** Dump for solid - " << GetName() << " ***\n"
<< " ===================================================\n"
<< " Solid type: G4Polycone\n"
<< " Parameters: \n"
<< " starting phi angle : " << startPhi/degree << " degrees \n"
<< " ending phi angle : " << endPhi/degree << " degrees \n";
G4int i=0;
if (original_parameters)
{
G4int numPlanes = original_parameters->Num_z_planes;
os << " number of Z planes: " << numPlanes << "\n"
<< " Z values: \n";
for (i=0; i<numPlanes; i++)
{
os << " Z plane " << i << ": "
<< original_parameters->Z_values[i] << "\n";
}
os << " Tangent distances to inner surface: \n";
for (i=0; i<numPlanes; i++)
{
os << " Z plane " << i << ": "
<< original_parameters->Rmin[i] << "\n";
}
os << " Tangent distances to outer surface: \n";
for (i=0; i<numPlanes; i++)
{
os << " Z plane " << i << ": "
<< original_parameters->Rmax[i] << "\n";
}
}
os << " number of RZ points: " << numCorner << "\n"
<< " RZ values: \n";
for (i=0; i<numCorner; i++)
{
os << " "
<< corners[i].r << ", " << corners[i].z << "\n";
}
os << "-----------------------------------------------------------\n";
return os;
}
//
// CreatePolyhedron
//
G4Polyhedron *G4Polycone::CreatePolyhedron() const
G4Polyhedron* G4Polycone::CreatePolyhedron() const
{
//
// This has to be fixed in visualization. Fake it for the moment.
//
if (original_parameters) {
return new G4PolyhedronPcon( original_parameters->Start_angle,
original_parameters->Opening_angle,
original_parameters->Num_z_planes,
original_parameters->Z_values,
original_parameters->Rmin,
original_parameters->Rmax);
}
else {
G4cerr << "G4Polycone: visualization of this type of G4Polycone is not supported at this time" << G4endl;
return 0;
}
}
//
// This has to be fixed in visualization. Fake it for the moment.
//
if (original_parameters)
{
return new G4PolyhedronPcon( original_parameters->Start_angle,
original_parameters->Opening_angle,
original_parameters->Num_z_planes,
original_parameters->Z_values,
original_parameters->Rmin,
original_parameters->Rmax );
}
else
{
G4cerr << "ERROR - G4Polycone::CreatePolyhedron(): " << GetName() << G4endl
<< " Visualization of this type of G4Polycone" << G4endl
<< " is not supported at this time !" << G4endl;
return 0;
}
}
//
@@ -402,35 +522,43 @@ G4Polyhedron *G4Polycone::CreatePolyhedron() const
//
G4NURBS *G4Polycone::CreateNURBS() const
{
return 0;
return 0;
}
//
// G4Polycone:G4PolyconeHistorical stuff
//
G4Polycone::G4PolyconeHistorical::~G4PolyconeHistorical()
G4Polycone::
G4PolyconeHistorical::G4PolyconeHistorical()
{
delete [] Z_values;
delete [] Rmin;
delete [] Rmax;
}
G4Polycone::G4PolyconeHistorical::G4PolyconeHistorical( const G4PolyconeHistorical &source )
G4Polycone::
G4PolyconeHistorical::~G4PolyconeHistorical()
{
Start_angle = source.Start_angle;
Opening_angle = source.Opening_angle;
Num_z_planes = source.Num_z_planes;
Z_values = new G4double[Num_z_planes];
Rmin = new G4double[Num_z_planes];
Rmax = new G4double[Num_z_planes];
G4int i;
for( i = 0; i < Num_z_planes; i++) {
Z_values[i] = source.Z_values[i];
Rmin[i] = source.Rmin[i];
Rmax[i] = source.Rmax[i];
}
delete [] Z_values;
delete [] Rmin;
delete [] Rmax;
}
G4Polycone::
G4PolyconeHistorical::G4PolyconeHistorical( const G4PolyconeHistorical &source )
{
Start_angle = source.Start_angle;
Opening_angle = source.Opening_angle;
Num_z_planes = source.Num_z_planes;
Z_values = new G4double[Num_z_planes];
Rmin = new G4double[Num_z_planes];
Rmax = new G4double[Num_z_planes];
G4int i;
for( i = 0; i < Num_z_planes; i++)
{
Z_values[i] = source.Z_values[i];
Rmin[i] = source.Rmin[i];
Rmax[i] = source.Rmax[i];
}
}
File diff suppressed because it is too large Load Diff
+438 -300
View File
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4Polyhedra.cc,v 1.3 2001/07/11 10:00:16 gunter Exp $
// GEANT4 tag $Name: geant4-04-01 $
// $Id: G4Polyhedra.cc,v 1.5 2002/10/28 15:18:41 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------------
@@ -53,6 +53,7 @@
// --------------------------------------------------------------------
#include "G4Polyhedra.hh"
#include "G4PolyhedraSide.hh"
#include "G4PolyPhiFace.hh"
@@ -64,58 +65,71 @@
// Constructor (GEANT3 style parameters)
//
// GEANT3 PGON radii are specified in the distance to the norm of each face.
//
//
G4Polyhedra::G4Polyhedra( const G4String& name,
G4double phiStart,
G4double thePhiTotal,
G4int theNumSide,
G4int theNumSide,
G4int numZPlanes,
const G4double zPlane[],
const G4double rInner[],
const G4double rOuter[] ) : G4VCSGfaceted( name )
const G4double rOuter[] )
: G4VCSGfaceted( name )
{
if (theNumSide <= 0) G4Exception( "G4Polyhedra:: must have at least one side" );
if (theNumSide <= 0)
{
G4cout << "ERROR - G4Polyhedra::G4Polyhedra(): " << GetName() << G4endl
<< " No sides specified !"
<< G4endl;
G4cerr << "ERROR - G4Polyhedra::G4Polyhedra(): " << GetName() << G4endl
<< " No sides specified !"
<< G4endl;
G4Exception("G4Polyhedra::G4Polyhedra() - must have at least one side");
}
//
// Calculate conversion factor from G3 radius to G4 radius
//
G4double phiTotal = thePhiTotal;
if (phiTotal <=0 || phiTotal >= 2*M_PI*(1-DBL_EPSILON)) phiTotal = 2*M_PI;
G4double convertRad = cos(0.5*phiTotal/theNumSide);
//
// Calculate conversion factor from G3 radius to G4 radius
//
G4double phiTotal = thePhiTotal;
if ( (phiTotal <=0) || (phiTotal >= 2*M_PI*(1-DBL_EPSILON)) )
phiTotal = 2*M_PI;
G4double convertRad = cos(0.5*phiTotal/theNumSide);
//
// Some historical stuff
//
original_parameters = new G4PolyhedraHistorical;
original_parameters->numSide = theNumSide;
original_parameters->Start_angle = phiStart;
original_parameters->Opening_angle = phiTotal;
original_parameters->Num_z_planes = numZPlanes;
original_parameters->Z_values = new G4double[numZPlanes];
original_parameters->Rmin = new G4double[numZPlanes];
original_parameters->Rmax = new G4double[numZPlanes];
//
// Some historical stuff
//
original_parameters = new G4PolyhedraHistorical;
original_parameters->numSide = theNumSide;
original_parameters->Start_angle = phiStart;
original_parameters->Opening_angle = phiTotal;
original_parameters->Num_z_planes = numZPlanes;
original_parameters->Z_values = new G4double[numZPlanes];
original_parameters->Rmin = new G4double[numZPlanes];
original_parameters->Rmax = new G4double[numZPlanes];
G4int i;
for (i=0; i<numZPlanes; i++) {
original_parameters->Z_values[i] = zPlane[i];
original_parameters->Rmin[i] = rInner[i]/convertRad;
original_parameters->Rmax[i] = rOuter[i]/convertRad;
}
//
// Build RZ polygon using special PCON/PGON GEANT3 constructor
//
G4ReduciblePolygon *rz = new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
rz->ScaleA( 1/convertRad );
//
// Do the real work
//
Create( phiStart, phiTotal, theNumSide, rz );
delete rz;
G4int i;
for (i=0; i<numZPlanes; i++)
{
original_parameters->Z_values[i] = zPlane[i];
original_parameters->Rmin[i] = rInner[i]/convertRad;
original_parameters->Rmax[i] = rOuter[i]/convertRad;
}
//
// Build RZ polygon using special PCON/PGON GEANT3 constructor
//
G4ReduciblePolygon *rz =
new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
rz->ScaleA( 1/convertRad );
//
// Do the real work
//
Create( phiStart, phiTotal, theNumSide, rz );
delete rz;
}
@@ -123,164 +137,207 @@ G4Polyhedra::G4Polyhedra( const G4String& name,
// Constructor (generic parameters)
//
G4Polyhedra::G4Polyhedra( const G4String& name,
G4double phiStart,
G4double phiTotal,
G4int theNumSide,
G4int numRZ,
const G4double r[],
const G4double z[] ) : G4VCSGfaceted( name )
G4double phiStart,
G4double phiTotal,
G4int theNumSide,
G4int numRZ,
const G4double r[],
const G4double z[] )
: G4VCSGfaceted( name )
{
original_parameters = 0;
G4ReduciblePolygon *rz = new G4ReduciblePolygon( r, z, numRZ );
Create( phiStart, phiTotal, theNumSide, rz );
delete rz;
original_parameters = 0;
G4ReduciblePolygon *rz = new G4ReduciblePolygon( r, z, numRZ );
Create( phiStart, phiTotal, theNumSide, rz );
delete rz;
}
//
// Create
//
// Generic create routine, called by each constructor after conversion of arguments
// Generic create routine, called by each constructor
// after conversion of arguments
//
void G4Polyhedra::Create( G4double phiStart,
G4double phiTotal,
G4int theNumSide,
G4ReduciblePolygon *rz )
G4double phiTotal,
G4int theNumSide,
G4ReduciblePolygon *rz )
{
//
// Perform checks of rz values
//
if (rz->Amin() < 0.0)
G4Exception( "G4Polyhedra: Illegal input parameters: All R values must be >= 0" );
G4double rzArea = rz->Area();
if (rzArea < -kCarTolerance) rz->ReverseOrder();
//
// Perform checks of rz values
//
if (rz->Amin() < 0.0)
{
G4cout << "ERROR - G4Polyhedra::Create() " << GetName() << G4endl
<< " All R values must be >= 0 !"
<< G4endl;
G4cerr << "ERROR - G4Polyhedra::Create() " << GetName() << G4endl
<< " All R values must be >= 0 !"
<< G4endl;
G4Exception("G4Polyhedra::Create() - Illegal input parameters");
}
else if (rzArea < -kCarTolerance)
G4Exception( "G4Polyhedra: Illegal input parameters: R/Z cross section is zero or near zero" );
if ((!rz->RemoveDuplicateVertices( kCarTolerance )) ||
(!rz->RemoveRedundantVertices( kCarTolerance )) )
G4Exception( "G4Polyhedra: Illegal input parameters: Too few unique R/Z values" );
G4double rzArea = rz->Area();
if (rzArea < -kCarTolerance)
rz->ReverseOrder();
if (rz->CrossesItself( 1/kInfinity ))
G4Exception( "G4Polyhedra: Illegal input parameters: R/Z segments cross" );
else if (rzArea < -kCarTolerance)
{
G4cout << "ERROR - G4Polyhedra::Create() " << GetName() << G4endl
<< " R/Z cross section is zero or near zero: "
<< rzArea << G4endl;
G4cerr << "ERROR - G4Polyhedra::Create() " << GetName() << G4endl
<< " R/Z cross section is zero or near zero: "
<< rzArea << G4endl;
G4Exception("G4Polyhedra::Create() - Illegal input parameters");
}
if ( (!rz->RemoveDuplicateVertices( kCarTolerance ))
|| (!rz->RemoveRedundantVertices( kCarTolerance )) )
{
G4cout << "ERROR - G4Polyhedra::Create() " << GetName() << G4endl
<< " Too few unique R/Z values !"
<< G4endl;
G4cerr << "ERROR - G4Polyhedra::Create() " << GetName() << G4endl
<< " Too few unique R/Z values !"
<< G4endl;
G4Exception("G4Polyhedra::Create() - Illegal input parameters");
}
numCorner = rz->NumVertices();
if (rz->CrossesItself( 1/kInfinity ))
{
G4cout << "ERROR - G4Polyhedra::Create() " << GetName() << G4endl
<< " R/Z segments cross !"
<< G4endl;
G4cerr << "ERROR - G4Polyhedra::Create() " << GetName() << G4endl
<< " R/Z segments cross !"
<< G4endl;
G4Exception("G4Polyhedra::Create() - Illegal input parameters");
}
numCorner = rz->NumVertices();
startPhi = phiStart;
while( startPhi < 0 ) startPhi += 2*M_PI;
//
// Phi opening? Account for some possible roundoff, and interpret
// nonsense value as representing no phi opening
//
if (phiTotal <= 0 || phiTotal > 2.0*M_PI*(1-DBL_EPSILON)) {
phiIsOpen = false;
endPhi = phiStart+2*M_PI;
}
else {
phiIsOpen = true;
//
// Convert phi into our convention
//
endPhi = phiStart+phiTotal;
while( endPhi < startPhi ) endPhi += 2*M_PI;
}
//
// Save number sides
//
numSide = theNumSide;
//
// Allocate corner array.
//
corners = new G4PolyhedraSideRZ[numCorner];
startPhi = phiStart;
while( startPhi < 0 ) startPhi += 2*M_PI;
//
// Phi opening? Account for some possible roundoff, and interpret
// nonsense value as representing no phi opening
//
if ( (phiTotal <= 0) || (phiTotal > 2.0*M_PI*(1-DBL_EPSILON)) )
{
phiIsOpen = false;
endPhi = phiStart+2*M_PI;
}
else
{
phiIsOpen = true;
//
// Convert phi into our convention
//
endPhi = phiStart+phiTotal;
while( endPhi < startPhi ) endPhi += 2*M_PI;
}
//
// Save number sides
//
numSide = theNumSide;
//
// Allocate corner array.
//
corners = new G4PolyhedraSideRZ[numCorner];
//
// Copy corners
//
G4ReduciblePolygonIterator iterRZ(rz);
G4PolyhedraSideRZ *next = corners;
iterRZ.Begin();
do {
next->r = iterRZ.GetA();
next->z = iterRZ.GetB();
} while( ++next, iterRZ.Next() );
//
// Allocate face pointer array
//
numFace = phiIsOpen ? numCorner+2 : numCorner;
faces = new G4VCSGface*[numFace];
//
// Construct side faces
//
// To do so properly, we need to keep track of four successive RZ
// corners.
//
// But! Don't construct a face if both points are at zero radius!
//
G4PolyhedraSideRZ *corner = corners,
*prev = corners + numCorner-1,
*nextNext;
G4VCSGface **face = faces;
do {
next = corner+1;
if (next >= corners+numCorner) next = corners;
nextNext = next+1;
if (nextNext >= corners+numCorner) nextNext = corners;
if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
//
// Copy corners
//
G4ReduciblePolygonIterator iterRZ(rz);
G4PolyhedraSideRZ *next = corners;
iterRZ.Begin();
do
{
next->r = iterRZ.GetA();
next->z = iterRZ.GetB();
} while( ++next, iterRZ.Next() );
//
// Allocate face pointer array
//
numFace = phiIsOpen ? numCorner+2 : numCorner;
faces = new G4VCSGface*[numFace];
//
// Construct side faces
//
// To do so properly, we need to keep track of four successive RZ
// corners.
//
// But! Don't construct a face if both points are at zero radius!
//
G4PolyhedraSideRZ *corner = corners,
*prev = corners + numCorner-1,
*nextNext;
G4VCSGface **face = faces;
do
{
next = corner+1;
if (next >= corners+numCorner) next = corners;
nextNext = next+1;
if (nextNext >= corners+numCorner) nextNext = corners;
if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
//
// We must decide here if we can dare declare one of our faces
// as having a "valid" normal (i.e. allBehind = true). This
// is never possible if the face faces "inward" in r *unless*
// we have only one side
//
G4bool allBehind;
if ((corner->z > next->z) && (numSide > 1)) {
allBehind = false;
}
else {
//
// Otherwise, it is only true if the line passing
// through the two points of the segment do not
// split the r/z cross section
//
allBehind = !rz->BisectedBy( corner->r, corner->z,
next->r, next->z, kCarTolerance );
}
*face++ = new G4PolyhedraSide( prev, corner, next, nextNext,
numSide, startPhi, endPhi-startPhi, phiIsOpen );
} while( prev=corner, corner=next, corner > corners );
if (phiIsOpen) {
//
// Construct phi open edges
//
*face++ = new G4PolyPhiFace( rz, startPhi, phiTotal/numSide, endPhi );
*face++ = new G4PolyPhiFace( rz, endPhi, phiTotal/numSide, startPhi );
}
//
// We might have dropped a face or two: recalculate numFace
//
numFace = face-faces;
//
// Make enclosingCylinder
//
enclosingCylinder = new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
//
// We must decide here if we can dare declare one of our faces
// as having a "valid" normal (i.e. allBehind = true). This
// is never possible if the face faces "inward" in r *unless*
// we have only one side
//
G4bool allBehind;
if ((corner->z > next->z) && (numSide > 1))
{
allBehind = false;
}
else
{
//
// Otherwise, it is only true if the line passing
// through the two points of the segment do not
// split the r/z cross section
//
allBehind = !rz->BisectedBy( corner->r, corner->z,
next->r, next->z, kCarTolerance );
}
*face++ = new G4PolyhedraSide( prev, corner, next, nextNext,
numSide, startPhi, endPhi-startPhi, phiIsOpen );
} while( prev=corner, corner=next, corner > corners );
if (phiIsOpen)
{
//
// Construct phi open edges
//
*face++ = new G4PolyPhiFace( rz, startPhi, phiTotal/numSide, endPhi );
*face++ = new G4PolyPhiFace( rz, endPhi, phiTotal/numSide, startPhi );
}
//
// We might have dropped a face or two: recalculate numFace
//
numFace = face-faces;
//
// Make enclosingCylinder
//
enclosingCylinder =
new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
}
@@ -289,19 +346,20 @@ void G4Polyhedra::Create( G4double phiStart,
//
G4Polyhedra::~G4Polyhedra()
{
delete [] corners;
if (original_parameters) delete original_parameters;
delete enclosingCylinder;
delete [] corners;
if (original_parameters) delete original_parameters;
delete enclosingCylinder;
}
//
// Copy constructor
//
G4Polyhedra::G4Polyhedra( const G4Polyhedra &source ) : G4VCSGfaceted( source )
G4Polyhedra::G4Polyhedra( const G4Polyhedra &source )
: G4VCSGfaceted( source )
{
CopyStuff( source );
CopyStuff( source );
}
@@ -310,18 +368,18 @@ G4Polyhedra::G4Polyhedra( const G4Polyhedra &source ) : G4VCSGfaceted( source )
//
const G4Polyhedra &G4Polyhedra::operator=( const G4Polyhedra &source )
{
if (this == &source) return *this;
if (this == &source) return *this;
G4VCSGfaceted::operator=( source );
delete [] corners;
if (original_parameters) delete original_parameters;
delete enclosingCylinder;
CopyStuff( source );
return *this;
G4VCSGfaceted::operator=( source );
delete [] corners;
if (original_parameters) delete original_parameters;
delete enclosingCylinder;
CopyStuff( source );
return *this;
}
@@ -330,114 +388,188 @@ const G4Polyhedra &G4Polyhedra::operator=( const G4Polyhedra &source )
//
void G4Polyhedra::CopyStuff( const G4Polyhedra &source )
{
//
// Simple stuff
//
numSide = source.numSide;
startPhi = source.startPhi;
endPhi = source.endPhi;
phiIsOpen = source.phiIsOpen;
numCorner = source.numCorner;
//
// Simple stuff
//
numSide = source.numSide;
startPhi = source.startPhi;
endPhi = source.endPhi;
phiIsOpen = source.phiIsOpen;
numCorner = source.numCorner;
//
// The corner array
//
corners = new G4PolyhedraSideRZ[numCorner];
G4PolyhedraSideRZ *corn = corners,
*sourceCorn = source.corners;
do {
*corn = *sourceCorn;
} while( ++sourceCorn, ++corn < corners+numCorner );
//
// Original parameters
//
if (source.original_parameters) {
original_parameters = new G4PolyhedraHistorical( *source.original_parameters );
}
//
// Enclosing cylinder
//
enclosingCylinder = new G4EnclosingCylinder( *source.enclosingCylinder );
//
// The corner array
//
corners = new G4PolyhedraSideRZ[numCorner];
G4PolyhedraSideRZ *corn = corners,
*sourceCorn = source.corners;
do
{
*corn = *sourceCorn;
} while( ++sourceCorn, ++corn < corners+numCorner );
//
// Original parameters
//
if (source.original_parameters)
{
original_parameters =
new G4PolyhedraHistorical( *source.original_parameters );
}
//
// Enclosing cylinder
//
enclosingCylinder = new G4EnclosingCylinder( *source.enclosingCylinder );
}
//
// Inside
//
// This is an override of G4VCSGfaceted::Inside, created in order to speed things
// up by first checking with G4EnclosingCylinder.
// This is an override of G4VCSGfaceted::Inside, created in order
// to speed things up by first checking with G4EnclosingCylinder.
//
EInside G4Polyhedra::Inside( const G4ThreeVector &p ) const
{
//
// Quick test
//
if (enclosingCylinder->MustBeOutside(p)) return kOutside;
//
// Quick test
//
if (enclosingCylinder->MustBeOutside(p)) return kOutside;
//
// Long answer
//
return G4VCSGfaceted::Inside(p);
//
// Long answer
//
return G4VCSGfaceted::Inside(p);
}
//
// DistanceToIn
//
// This is an override of G4VCSGfaceted::Inside, created in order to speed things
// up by first checking with G4EnclosingCylinder.
// This is an override of G4VCSGfaceted::Inside, created in order
// to speed things up by first checking with G4EnclosingCylinder.
//
G4double G4Polyhedra::DistanceToIn( const G4ThreeVector &p, const G4ThreeVector &v ) const
G4double G4Polyhedra::DistanceToIn( const G4ThreeVector &p,
const G4ThreeVector &v ) const
{
//
// Quick test
//
if (enclosingCylinder->ShouldMiss(p,v)) return kInfinity;
//
// Long answer
//
return G4VCSGfaceted::DistanceToIn( p, v );
//
// Quick test
//
if (enclosingCylinder->ShouldMiss(p,v))
return kInfinity;
//
// Long answer
//
return G4VCSGfaceted::DistanceToIn( p, v );
}
//
// DistanceToIn
//
G4double G4Polyhedra::DistanceToIn( const G4ThreeVector &p ) const
{
return G4VCSGfaceted::DistanceToIn(p);
}
//
// ComputeDimensions
//
void G4Polyhedra::ComputeDimensions( G4VPVParameterisation* p,
const G4int n,
const G4VPhysicalVolume* pRep)
void G4Polyhedra::ComputeDimensions( G4VPVParameterisation* p,
const G4int n,
const G4VPhysicalVolume* pRep)
{
}
//
// GetEntityType
//
G4GeometryType G4Polyhedra::GetEntityType() const
{
return G4String("G4Polyhedra");
}
//
// Stream object contents to an output stream
//
G4std::ostream& G4Polyhedra::StreamInfo( G4std::ostream& os ) const
{
os << "-----------------------------------------------------------\n"
<< " *** Dump for solid - " << GetName() << " ***\n"
<< " ===================================================\n"
<< " Solid type: G4Polyhedra\n"
<< " Parameters: \n"
<< " starting phi angle : " << startPhi/degree << " degrees \n"
<< " ending phi angle : " << endPhi/degree << " degrees \n";
G4int i=0;
if (original_parameters)
{
G4int numPlanes = original_parameters->Num_z_planes;
os << " number of Z planes: " << numPlanes << "\n"
<< " Z values: \n";
for (i=0; i<numPlanes; i++)
{
os << " Z plane " << i << ": "
<< original_parameters->Z_values[i] << "\n";
}
os << " Tangent distances to inner surface: \n";
for (i=0; i<numPlanes; i++)
{
os << " Z plane " << i << ": "
<< original_parameters->Rmin[i] << "\n";
}
os << " Tangent distances to outer surface: \n";
for (i=0; i<numPlanes; i++)
{
os << " Z plane " << i << ": "
<< original_parameters->Rmax[i] << "\n";
}
}
os << " number of RZ points: " << numCorner << "\n"
<< " RZ values: \n";
for (i=0; i<numCorner; i++)
{
os << " "
<< corners[i].r << ", " << corners[i].z << "\n";
}
os << "-----------------------------------------------------------\n";
return os;
}
//
// CreatePolyhedron
//
G4Polyhedron *G4Polyhedra::CreatePolyhedron() const
G4Polyhedron* G4Polyhedra::CreatePolyhedron() const
{
//
// This has to be fixed in visualization. Fake it for the moment.
//
if (original_parameters) {
return new G4PolyhedronPgon( original_parameters->Start_angle,
original_parameters->Opening_angle,
original_parameters->numSide,
original_parameters->Num_z_planes,
original_parameters->Z_values,
original_parameters->Rmin,
original_parameters->Rmax);
}
else {
G4cerr << "G4Polyhedra: visualization of this type of G4Polyhedra is not supported at this time" << G4endl;
return 0;
}
}
//
// This has to be fixed in visualization. Fake it for the moment.
//
if (original_parameters)
{
return new G4PolyhedronPgon( original_parameters->Start_angle,
original_parameters->Opening_angle,
original_parameters->numSide,
original_parameters->Num_z_planes,
original_parameters->Z_values,
original_parameters->Rmin,
original_parameters->Rmax);
}
else
{
G4cerr << "ERROR - G4Polyhedra::CreatePolyhedron() " << GetName() << G4endl
<< " Visualization of this type of G4Polycone" << G4endl
<< " is not supported at this time !" << G4endl;
return 0;
}
}
//
@@ -445,38 +577,44 @@ G4Polyhedron *G4Polyhedra::CreatePolyhedron() const
//
G4NURBS *G4Polyhedra::CreateNURBS() const
{
return 0;
return 0;
}
//
// G4Polyhedra::G4PolyhedraHistorical stuff
//
G4Polyhedra::G4PolyhedraHistorical::~G4PolyhedraHistorical()
G4Polyhedra::
G4PolyhedraHistorical::G4PolyhedraHistorical()
{
delete [] Z_values;
delete [] Rmin;
delete [] Rmax;
}
G4Polyhedra::G4PolyhedraHistorical::G4PolyhedraHistorical( const G4PolyhedraHistorical &source )
G4Polyhedra::
G4PolyhedraHistorical::~G4PolyhedraHistorical()
{
Start_angle = source.Start_angle;
Opening_angle = source.Opening_angle;
numSide = source.numSide;
Num_z_planes = source.Num_z_planes;
Z_values = new G4double[Num_z_planes];
Rmin = new G4double[Num_z_planes];
Rmax = new G4double[Num_z_planes];
G4int i;
for( i = 0; i < Num_z_planes; i++) {
Z_values[i] = source.Z_values[i];
Rmin[i] = source.Rmin[i];
Rmax[i] = source.Rmax[i];
}
delete [] Z_values;
delete [] Rmin;
delete [] Rmax;
}
G4Polyhedra::
G4PolyhedraHistorical::
G4PolyhedraHistorical( const G4PolyhedraHistorical &source )
{
Start_angle = source.Start_angle;
Opening_angle = source.Opening_angle;
numSide = source.numSide;
Num_z_planes = source.Num_z_planes;
Z_values = new G4double[Num_z_planes];
Rmin = new G4double[Num_z_planes];
Rmax = new G4double[Num_z_planes];
G4int i;
for( i = 0; i < Num_z_planes; i++)
{
Z_values[i] = source.Z_values[i];
Rmin[i] = source.Rmin[i];
Rmax[i] = source.Rmax[i];
}
}
File diff suppressed because it is too large Load Diff
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4ReduciblePolygon.cc,v 1.4 2001/07/11 10:00:16 gunter Exp $
// GEANT4 tag $Name: geant4-04-01 $
// $Id: G4ReduciblePolygon.cc,v 1.6 2002/10/30 13:52:23 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------------
@@ -44,44 +44,51 @@
//
// Constructor: with simple arrays
//
G4ReduciblePolygon::G4ReduciblePolygon( const G4double a[], const G4double b[],
G4ReduciblePolygon::G4ReduciblePolygon( const G4double a[],
const G4double b[],
G4int n )
: aMin(0.), aMax(0.), bMin(0.), bMax(0.),
vertexHead(0)
{
//
// Do all of the real work in Create
//
Create( a, b, n );
//
// Do all of the real work in Create
//
Create( a, b, n );
}
//
// Constructor: special PGON/PCON case
//
G4ReduciblePolygon::G4ReduciblePolygon( const G4double rmin[], const G4double rmax[],
const G4double z[], G4int n )
G4ReduciblePolygon::G4ReduciblePolygon( const G4double rmin[],
const G4double rmax[],
const G4double z[], G4int n )
: aMin(0.), aMax(0.), bMin(0.), bMax(0.),
vertexHead(0)
{
//
// Translate
//
G4double *a = new G4double[n*2];
G4double *b = new G4double[n*2];
G4double *rOut = a + n,
*zOut = b + n,
*rIn = rOut-1,
*zIn = zOut-1;
G4int i;
for( i=0; i < n; i++, rOut++, zOut++, rIn--, zIn-- ) {
*rOut = rmax[i];
*rIn = rmin[i];
*zOut = *zIn = z[i];
}
Create( a, b, n*2 );
delete [] a;
delete [] b;
//
// Translate
//
G4double *a = new G4double[n*2];
G4double *b = new G4double[n*2];
G4double *rOut = a + n,
*zOut = b + n,
*rIn = rOut-1,
*zIn = zOut-1;
G4int i;
for( i=0; i < n; i++, rOut++, zOut++, rIn--, zIn-- )
{
*rOut = rmax[i];
*rIn = rmin[i];
*zOut = *zIn = z[i];
}
Create( a, b, n*2 );
delete [] a;
delete [] b;
}
@@ -91,30 +98,35 @@ G4ReduciblePolygon::G4ReduciblePolygon( const G4double rmin[], const G4double rm
// To be called by constructors, fill in the list and statistics for a new
// polygon
//
void G4ReduciblePolygon::Create( const G4double a[], const G4double b[], G4int n )
void G4ReduciblePolygon::Create( const G4double a[],
const G4double b[], G4int n )
{
if (n<3) G4Exception( "G4ReduciblePolygon: less than 3 vertices specified" );
const G4double *anext = a, *bnext = b;
ABVertex *prev = 0;
do {
ABVertex *newVertex = new ABVertex;
newVertex->a = *anext;
newVertex->b = *bnext;
newVertex->next = 0;
if (prev==0) {
vertexHead = newVertex;
}
else {
prev->next = newVertex;
}
prev = newVertex;
} while( ++anext, ++bnext < b+n );
if (n<3)
G4Exception("G4ReduciblePolygon::Create() - less than 3 vertices specified");
const G4double *anext = a, *bnext = b;
ABVertex *prev = 0;
do
{
ABVertex *newVertex = new ABVertex;
newVertex->a = *anext;
newVertex->b = *bnext;
newVertex->next = 0;
if (prev==0)
{
vertexHead = newVertex;
}
else
{
prev->next = newVertex;
}
prev = newVertex;
} while( ++anext, ++bnext < b+n );
numVertices = n;
CalculateMaxMin();
numVertices = n;
CalculateMaxMin();
}
@@ -123,12 +135,13 @@ void G4ReduciblePolygon::Create( const G4double a[], const G4double b[], G4int n
//
G4ReduciblePolygon::~G4ReduciblePolygon()
{
ABVertex *curr = vertexHead;
while( curr ) {
ABVertex *toDelete = curr;
curr = curr->next;
delete toDelete;
}
ABVertex *curr = vertexHead;
while( curr )
{
ABVertex *toDelete = curr;
curr = curr->next;
delete toDelete;
}
}
@@ -141,13 +154,14 @@ G4ReduciblePolygon::~G4ReduciblePolygon()
//
void G4ReduciblePolygon::CopyVertices( G4double a[], G4double b[] ) const
{
G4double *anext = a, *bnext = b;
ABVertex *curr = vertexHead;
while( curr ) {
*anext++ = curr->a;
*bnext++ = curr->b;
curr = curr->next;
}
G4double *anext = a, *bnext = b;
ABVertex *curr = vertexHead;
while( curr )
{
*anext++ = curr->a;
*bnext++ = curr->b;
curr = curr->next;
}
}
@@ -158,12 +172,13 @@ void G4ReduciblePolygon::CopyVertices( G4double a[], G4double b[] ) const
//
void G4ReduciblePolygon::ScaleA( G4double scale )
{
ABVertex *curr = vertexHead;
while( curr ) {
curr->a *= scale;
curr = curr->next;
}
}
ABVertex *curr = vertexHead;
while( curr )
{
curr->a *= scale;
curr = curr->next;
}
}
//
@@ -173,12 +188,13 @@ void G4ReduciblePolygon::ScaleA( G4double scale )
//
void G4ReduciblePolygon::ScaleB( G4double scale )
{
ABVertex *curr = vertexHead;
while( curr ) {
curr->b *= scale;
curr = curr->next;
}
}
ABVertex *curr = vertexHead;
while( curr )
{
curr->b *= scale;
curr = curr->next;
}
}
//
@@ -189,46 +205,50 @@ void G4ReduciblePolygon::ScaleB( G4double scale )
//
G4bool G4ReduciblePolygon::RemoveDuplicateVertices( G4double tolerance )
{
ABVertex *curr = vertexHead,
*prev = 0,
*next = curr->next; // A little dangerous
while( curr ) {
next = curr->next;
if (next == 0) next = vertexHead;
if (fabs(curr->a-next->a) < tolerance &&
fabs(curr->b-next->b) < tolerance ) {
//
// Duplicate found: do we have > 3 vertices?
//
if (numVertices <= 3) {
CalculateMaxMin();
return false;
}
//
// Delete
//
ABVertex *toDelete = curr;
curr = curr->next;
delete toDelete;
numVertices--;
if (prev) prev->next = curr; else vertexHead = curr;
}
else {
prev = curr;
curr = curr->next;
}
}
//
// In principle, this is not needed, but why not just play it safe?
//
CalculateMaxMin();
return true;
ABVertex *curr = vertexHead,
*prev = 0,
*next = curr->next; // A little dangerous
while( curr )
{
next = curr->next;
if (next == 0) next = vertexHead;
if (fabs(curr->a-next->a) < tolerance &&
fabs(curr->b-next->b) < tolerance )
{
//
// Duplicate found: do we have > 3 vertices?
//
if (numVertices <= 3)
{
CalculateMaxMin();
return false;
}
//
// Delete
//
ABVertex *toDelete = curr;
curr = curr->next;
delete toDelete;
numVertices--;
if (prev) prev->next = curr; else vertexHead = curr;
}
else
{
prev = curr;
curr = curr->next;
}
}
//
// In principle, this is not needed, but why not just play it safe?
//
CalculateMaxMin();
return true;
}
@@ -240,88 +260,92 @@ G4bool G4ReduciblePolygon::RemoveDuplicateVertices( G4double tolerance )
//
G4bool G4ReduciblePolygon::RemoveRedundantVertices( G4double tolerance )
{
//
// Under these circumstances, we can quit now!
//
if (numVertices <= 2) return false;
G4double tolerance2 = tolerance*tolerance;
//
// Under these circumstances, we can quit now!
//
if (numVertices <= 2) return false;
G4double tolerance2 = tolerance*tolerance;
//
// Loop over all vertices
//
ABVertex *curr = vertexHead,
*next = curr->next; // A little dangerous
while( curr ) {
next = curr->next;
if (next == 0) next = vertexHead;
G4double da = next->a - curr->a,
db = next->b - curr->b;
//
// Loop over all subsequent vertices, up to curr
//
for(;;) {
//
// Get vertex after next
//
ABVertex *test = next->next;
if (test == 0) test = vertexHead;
//
// If we are back to the original vertex, stop
//
if (test==curr) break;
//
// Test for parallel line segments
//
G4double dat = test->a - curr->a,
dbt = test->b - curr->b;
if (fabs(dat*db-dbt*da)>tolerance2) break;
//
// Redundant vertex found: do we have > 3 vertices?
//
if (numVertices <= 3) {
CalculateMaxMin();
return false;
}
//
// Loop over all vertices
//
ABVertex *curr = vertexHead,
*next = curr->next; // A little dangerous
while( curr )
{
next = curr->next;
if (next == 0) next = vertexHead;
G4double da = next->a - curr->a,
db = next->b - curr->b;
//
// Loop over all subsequent vertices, up to curr
//
for(;;)
{
//
// Get vertex after next
//
ABVertex *test = next->next;
if (test == 0) test = vertexHead;
//
// If we are back to the original vertex, stop
//
if (test==curr) break;
//
// Test for parallel line segments
//
G4double dat = test->a - curr->a,
dbt = test->b - curr->b;
if (fabs(dat*db-dbt*da)>tolerance2) break;
//
// Redundant vertex found: do we have > 3 vertices?
//
if (numVertices <= 3)
{
CalculateMaxMin();
return false;
}
//
// Delete vertex pointed to by next. Carefully!
//
if (curr->next) { // next is not head
if (next->next)
curr->next = test; // next is not tail
else
curr->next = 0; // New tail
}
else
vertexHead = test; // New head
delete next;
numVertices--;
//
// Replace next by the vertex we just tested,
// and keep on going...
//
next = test;
da = dat; db = dbt;
}
curr = curr->next;
}
//
// In principle, this is not needed, but why not just play it safe?
//
CalculateMaxMin();
return true;
//
// Delete vertex pointed to by next. Carefully!
//
if (curr->next)
{ // next is not head
if (next->next)
curr->next = test; // next is not tail
else
curr->next = 0; // New tail
}
else
vertexHead = test; // New head
delete next;
numVertices--;
//
// Replace next by the vertex we just tested,
// and keep on going...
//
next = test;
da = dat; db = dbt;
}
curr = curr->next;
}
//
// In principle, this is not needed, but why not just play it safe?
//
CalculateMaxMin();
return true;
}
@@ -332,48 +356,49 @@ G4bool G4ReduciblePolygon::RemoveRedundantVertices( G4double tolerance )
//
void G4ReduciblePolygon::ReverseOrder()
{
//
// Loop over all vertices
//
ABVertex *prev = vertexHead;
if (prev==0) return; // No vertices
ABVertex *curr = prev->next;
if (curr==0) return; // Just one vertex
//
// Our new tail
//
vertexHead->next = 0;
for(;;) {
//
// Save pointer to next vertex (in original order)
//
ABVertex *save = curr->next;
//
// Replace it with a pointer to the previous one
// (in original order)
//
curr->next = prev;
//
// Last vertex?
//
if (save == 0) break;
//
// Next vertex
//
prev = curr;
curr = save;
}
//
// Our new head
//
vertexHead = curr;
//
// Loop over all vertices
//
ABVertex *prev = vertexHead;
if (prev==0) return; // No vertices
ABVertex *curr = prev->next;
if (curr==0) return; // Just one vertex
//
// Our new tail
//
vertexHead->next = 0;
for(;;)
{
//
// Save pointer to next vertex (in original order)
//
ABVertex *save = curr->next;
//
// Replace it with a pointer to the previous one
// (in original order)
//
curr->next = prev;
//
// Last vertex?
//
if (save == 0) break;
//
// Next vertex
//
prev = curr;
curr = save;
}
//
// Our new head
//
vertexHead = curr;
}
@@ -386,53 +411,49 @@ void G4ReduciblePolygon::ReverseOrder()
//
G4bool G4ReduciblePolygon::CrossesItself( G4double tolerance )
{
G4double tolerance2 = tolerance*tolerance;
G4double one = 1.0-tolerance,
zero = tolerance;
//
// Top loop over line segments. By the time we finish
// with the second to last segment, we're done.
//
ABVertex *curr1 = vertexHead, *next1=0;
while (curr1->next) {
next1 = curr1->next;
G4double da1 = next1->a-curr1->a,
db1 = next1->b-curr1->b;
//
// Inner loop over subsequent line segments
//
ABVertex *curr2 = next1->next;
while( curr2 ) {
ABVertex *next2 = curr2->next;
if (next2==0) next2 = vertexHead;
G4double da2 = next2->a-curr2->a,
db2 = next2->b-curr2->b;
G4double a12 = curr2->a-curr1->a,
b12 = curr2->b-curr1->b;
//
// Calculate intersection of the two lines
//
G4double deter = da1*db2 - db1*da2;
if (fabs(deter) > tolerance2) {
G4double s1, s2;
s1 = (a12*db2-b12*da2)/deter;
if (s1 >= zero && s1 < one) {
s2 = -(da1*b12-db1*a12)/deter;
if (s2 >= zero && s2 < one) return true;
}
}
curr2 = curr2->next;
}
curr1 = next1;
}
return false;
G4double tolerance2 = tolerance*tolerance;
G4double one = 1.0-tolerance,
zero = tolerance;
//
// Top loop over line segments. By the time we finish
// with the second to last segment, we're done.
//
ABVertex *curr1 = vertexHead, *next1=0;
while (curr1->next) {
next1 = curr1->next;
G4double da1 = next1->a-curr1->a,
db1 = next1->b-curr1->b;
//
// Inner loop over subsequent line segments
//
ABVertex *curr2 = next1->next;
while( curr2 ) {
ABVertex *next2 = curr2->next;
if (next2==0) next2 = vertexHead;
G4double da2 = next2->a-curr2->a,
db2 = next2->b-curr2->b;
G4double a12 = curr2->a-curr1->a,
b12 = curr2->b-curr1->b;
//
// Calculate intersection of the two lines
//
G4double deter = da1*db2 - db1*da2;
if (fabs(deter) > tolerance2) {
G4double s1, s2;
s1 = (a12*db2-b12*da2)/deter;
if (s1 >= zero && s1 < one) {
s2 = -(da1*b12-db1*a12)/deter;
if (s2 >= zero && s2 < one) return true;
}
}
curr2 = curr2->next;
}
curr1 = next1;
}
return false;
}
@@ -443,33 +464,37 @@ G4bool G4ReduciblePolygon::CrossesItself( G4double tolerance )
// Decide if a line through two points crosses the polygon, within tolerance
//
G4bool G4ReduciblePolygon::BisectedBy( G4double a1, G4double b1,
G4double a2, G4double b2, G4double tolerance )
G4double a2, G4double b2,
G4double tolerance )
{
G4int nNeg = 0, nPos = 0;
G4double a12 = a2-a1, b12 = b2-b1;
G4double len12 = sqrt( a12*a12 + b12*b12 );
a12 /= len12; b12 /= len12;
ABVertex *curr = vertexHead;
do {
G4double av = curr->a - a1,
bv = curr->b - b1;
G4double cross = av*b12 - bv*a12;
if (cross < -tolerance) {
if (nPos) return true;
nNeg++;
}
else if (cross > tolerance) {
if (nNeg) return true;
nPos++;
}
curr = curr->next;
} while( curr );
return false;
G4int nNeg = 0, nPos = 0;
G4double a12 = a2-a1, b12 = b2-b1;
G4double len12 = sqrt( a12*a12 + b12*b12 );
a12 /= len12; b12 /= len12;
ABVertex *curr = vertexHead;
do
{
G4double av = curr->a - a1,
bv = curr->b - b1;
G4double cross = av*b12 - bv*a12;
if (cross < -tolerance)
{
if (nPos) return true;
nNeg++;
}
else if (cross > tolerance)
{
if (nNeg) return true;
nPos++;
}
curr = curr->next;
} while( curr );
return false;
}
@@ -477,26 +502,27 @@ G4bool G4ReduciblePolygon::BisectedBy( G4double a1, G4double b1,
//
// Area
//
// Calculated signed polygon area, where polygons specified in a clockwise manner
// (where x==a, y==b) have negative area
// Calculated signed polygon area, where polygons specified in a
// clockwise manner (where x==a, y==b) have negative area
//
// References: [O' Rourke (C)] pp. 18-27; [Gems II] pp. 5-6:
// "The Area of a Simple Polygon", Jon Rokne.
//
G4double G4ReduciblePolygon::Area()
{
G4double answer = 0;
ABVertex *curr = vertexHead, *next;
do {
next = curr->next;
if (next==0) next = vertexHead;
answer += curr->a*next->b - curr->b*next->a;
curr = curr->next;
} while( curr );
return 0.5*answer;
G4double answer = 0;
ABVertex *curr = vertexHead, *next;
do
{
next = curr->next;
if (next==0) next = vertexHead;
answer += curr->a*next->b - curr->b*next->a;
curr = curr->next;
} while( curr );
return 0.5*answer;
}
@@ -505,11 +531,12 @@ G4double G4ReduciblePolygon::Area()
//
void G4ReduciblePolygon::Print()
{
ABVertex *curr = vertexHead;
do {
G4cerr << curr->a << " " << curr->b << G4endl;
curr = curr->next;
} while( curr );
ABVertex *curr = vertexHead;
do
{
G4cerr << curr->a << " " << curr->b << G4endl;
curr = curr->next;
} while( curr );
}
@@ -521,21 +548,22 @@ void G4ReduciblePolygon::Print()
//
void G4ReduciblePolygon::CalculateMaxMin()
{
ABVertex *curr = vertexHead;
aMin = aMax = curr->a;
bMin = bMax = curr->b;
curr = curr->next;
while( curr ) {
if (curr->a < aMin)
aMin = curr->a;
else if (curr->a > aMax)
aMax = curr->a;
ABVertex *curr = vertexHead;
aMin = aMax = curr->a;
bMin = bMax = curr->b;
curr = curr->next;
while( curr )
{
if (curr->a < aMin)
aMin = curr->a;
else if (curr->a > aMax)
aMax = curr->a;
if (curr->b < bMin)
bMin = curr->b;
else if (curr->b > bMax)
bMax = curr->b;
curr = curr->next;
}
if (curr->b < bMin)
bMin = curr->b;
else if (curr->b > bMax)
bMax = curr->b;
curr = curr->next;
}
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4SolidExtentList.cc,v 1.2 2001/07/11 10:00:17 gunter Exp $
// GEANT4 tag $Name: geant4-04-01 $
// $Id: G4SolidExtentList.cc,v 1.3 2002/10/28 11:47:53 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------------
@@ -38,42 +38,47 @@
#include "G4SolidExtentList.hh"
#include "G4VoxelLimits.hh"
//
// Constructor (default)
//
G4SolidExtentList::G4SolidExtentList()
{
axis = kZAxis;
limited = false;
minLimit = -DBL_MAX;
maxLimit = +DBL_MAX;
axis = kZAxis;
limited = false;
minLimit = -DBL_MAX;
maxLimit = +DBL_MAX;
}
//
// Constructor (limited case)
//
G4SolidExtentList::G4SolidExtentList( const EAxis targetAxis, const G4VoxelLimits &voxelLimits )
G4SolidExtentList::G4SolidExtentList( const EAxis targetAxis,
const G4VoxelLimits &voxelLimits )
{
axis = targetAxis;
limited = voxelLimits.IsLimited( axis );
if (limited) {
minLimit = voxelLimits.GetMinExtent( axis );
maxLimit = voxelLimits.GetMaxExtent( axis );
}
else {
minLimit = -DBL_MAX;
maxLimit = +DBL_MAX;
}
axis = targetAxis;
limited = voxelLimits.IsLimited( axis );
if (limited)
{
minLimit = voxelLimits.GetMinExtent( axis );
maxLimit = voxelLimits.GetMaxExtent( axis );
}
else
{
minLimit = -DBL_MAX;
maxLimit = +DBL_MAX;
}
}
//
// Destructor
//
G4SolidExtentList::~G4SolidExtentList() {;}
G4SolidExtentList::~G4SolidExtentList()
{
}
//
@@ -82,32 +87,35 @@ G4SolidExtentList::~G4SolidExtentList() {;}
//
void G4SolidExtentList::AddSurface( const G4ClippablePolygon &surface )
{
//
// Keep track of four surfaces
//
G4double min, max;
surface.GetExtent( axis, min, max );
if (min > maxLimit) {
//
// Nearest surface beyond maximum limit
//
if (surface.InFrontOf(minAbove,axis)) minAbove = surface;
}
else if (max < minLimit) {
//
// Nearest surface below minimum limit
//
if (surface.BehindOf(maxBelow,axis)) maxBelow = surface;
}
else {
//
// Max and min surfaces inside
//
if (surface.BehindOf(maxSurface,axis)) maxSurface = surface;
if (surface.InFrontOf(minSurface,axis)) minSurface = surface;
}
//
// Keep track of four surfaces
//
G4double min, max;
surface.GetExtent( axis, min, max );
if (min > maxLimit)
{
//
// Nearest surface beyond maximum limit
//
if (surface.InFrontOf(minAbove,axis)) minAbove = surface;
}
else if (max < minLimit)
{
//
// Nearest surface below minimum limit
//
if (surface.BehindOf(maxBelow,axis)) maxBelow = surface;
}
else
{
//
// Max and min surfaces inside
//
if (surface.BehindOf(maxSurface,axis)) maxSurface = surface;
if (surface.InFrontOf(minSurface,axis)) minSurface = surface;
}
}
@@ -119,61 +127,63 @@ void G4SolidExtentList::AddSurface( const G4ClippablePolygon &surface )
//
G4bool G4SolidExtentList::GetExtent( G4double &min, G4double &max ) const
{
//
// Did we have any surfaces within the limits?
//
if (minSurface.Empty()) {
//
// Nothing! Do we have anything above?
//
if (minAbove.Empty()) return false;
//
// Yup. Is it facing inwards?
//
if (minAbove.GetNormal().operator()(axis) < 0) return false;
//
// No. We must be entirely within the solid
//
max = maxLimit + kCarTolerance;
min = minLimit - kCarTolerance;
return true;
}
//
// Check max surface
//
if (maxSurface.GetNormal().operator()(axis) < 0) {
//
// Inward facing: max limit must be embedded within solid
//
max = maxLimit + kCarTolerance;
}
else {
G4double sMin, sMax;
maxSurface.GetExtent( axis, sMin, sMax );
max = ( (sMax > maxLimit) ? maxLimit : sMax ) + kCarTolerance;
}
//
// Check min surface
//
if (minSurface.GetNormal().operator()(axis) > 0) {
//
// Inward facing: max limit must be embedded within solid
//
min = minLimit - kCarTolerance;
}
else {
G4double sMin, sMax;
minSurface.GetExtent( axis, sMin, sMax );
min = ( (sMin < minLimit) ? minLimit : sMin ) - kCarTolerance;
}
return true;
//
// Did we have any surfaces within the limits?
//
if (minSurface.Empty())
{
//
// Nothing! Do we have anything above?
//
if (minAbove.Empty()) return false;
//
// Yup. Is it facing inwards?
//
if (minAbove.GetNormal().operator()(axis) < 0) return false;
//
// No. We must be entirely within the solid
//
max = maxLimit + kCarTolerance;
min = minLimit - kCarTolerance;
return true;
}
//
// Check max surface
//
if (maxSurface.GetNormal().operator()(axis) < 0)
{
//
// Inward facing: max limit must be embedded within solid
//
max = maxLimit + kCarTolerance;
}
else
{
G4double sMin, sMax;
maxSurface.GetExtent( axis, sMin, sMax );
max = ( (sMax > maxLimit) ? maxLimit : sMax ) + kCarTolerance;
}
//
// Check min surface
//
if (minSurface.GetNormal().operator()(axis) > 0)
{
//
// Inward facing: max limit must be embedded within solid
//
min = minLimit - kCarTolerance;
}
else
{
G4double sMin, sMax;
minSurface.GetExtent( axis, sMin, sMax );
min = ( (sMin < minLimit) ? minLimit : sMin ) - kCarTolerance;
}
return true;
}
@@ -26,8 +26,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VCSGfaceted.cc,v 1.7 2001/07/11 10:00:17 gunter Exp $
// GEANT4 tag $Name: geant4-04-01 $
// $Id: G4VCSGfaceted.cc,v 1.9 2002/10/30 13:52:24 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------------
@@ -54,21 +54,32 @@
#include "G4NURBSbox.hh"
#include "G4VisExtent.hh"
//
// Constructor
//
G4VCSGfaceted::G4VCSGfaceted( G4String name )
: G4VSolid(name),
numFace(0), faces(0)
{
}
//
// Destructor
//
G4VCSGfaceted::~G4VCSGfaceted()
{
DeleteStuff();
DeleteStuff();
}
//
// Copy constructor
//
G4VCSGfaceted::G4VCSGfaceted( const G4VCSGfaceted &source ) : G4VSolid( source )
G4VCSGfaceted::G4VCSGfaceted( const G4VCSGfaceted &source )
: G4VSolid( source )
{
CopyStuff( source );
CopyStuff( source );
}
@@ -77,12 +88,12 @@ G4VCSGfaceted::G4VCSGfaceted( const G4VCSGfaceted &source ) : G4VSolid( source )
//
const G4VCSGfaceted &G4VCSGfaceted::operator=( const G4VCSGfaceted &source )
{
if (&source == this) return *this;
DeleteStuff();
CopyStuff( source );
return *this;
if (&source == this) return *this;
DeleteStuff();
CopyStuff( source );
return *this;
}
@@ -93,16 +104,16 @@ const G4VCSGfaceted &G4VCSGfaceted::operator=( const G4VCSGfaceted &source )
//
void G4VCSGfaceted::CopyStuff( const G4VCSGfaceted &source )
{
numFace = source.numFace;
if (numFace == 0) return; // odd, but permissable?
faces = new G4VCSGface*[numFace];
G4VCSGface **face = faces,
**sourceFace = source.faces;
do {
*face = (*sourceFace)->Clone();
} while( ++sourceFace, ++face < faces+numFace );
numFace = source.numFace;
if (numFace == 0) return; // odd, but permissable?
faces = new G4VCSGface*[numFace];
G4VCSGface **face = faces,
**sourceFace = source.faces;
do {
*face = (*sourceFace)->Clone();
} while( ++sourceFace, ++face < faces+numFace );
}
@@ -113,14 +124,15 @@ void G4VCSGfaceted::CopyStuff( const G4VCSGfaceted &source )
//
void G4VCSGfaceted::DeleteStuff()
{
if (numFace) {
G4VCSGface **face = faces;
do {
delete *face;
} while( ++face < faces + numFace );
if (numFace)
{
G4VCSGface **face = faces;
do {
delete *face;
} while( ++face < faces + numFace );
delete [] faces;
}
delete [] faces;
}
}
@@ -128,24 +140,25 @@ void G4VCSGfaceted::DeleteStuff()
// CalculateExtent
//
G4bool G4VCSGfaceted::CalculateExtent( const EAxis axis,
const G4VoxelLimits &voxelLimit,
const G4AffineTransform &transform,
G4double &min, G4double &max ) const
const G4VoxelLimits &voxelLimit,
const G4AffineTransform &transform,
G4double &min,
G4double &max ) const
{
G4SolidExtentList extentList( axis, voxelLimit );
G4SolidExtentList extentList( axis, voxelLimit );
//
// Loop over all faces, checking min/max extent as we go.
//
G4VCSGface **face = faces;
do {
(*face)->CalculateExtent( axis, voxelLimit, transform, extentList );
} while( ++face < faces + numFace );
//
// Return min/max value
//
return extentList.GetExtent( min, max );
//
// Loop over all faces, checking min/max extent as we go.
//
G4VCSGface **face = faces;
do {
(*face)->CalculateExtent( axis, voxelLimit, transform, extentList );
} while( ++face < faces + numFace );
//
// Return min/max value
//
return extentList.GetExtent( min, max );
}
@@ -159,78 +172,84 @@ G4bool G4VCSGfaceted::CalculateExtent( const EAxis axis,
//
EInside G4VCSGfaceted::Inside( const G4ThreeVector &p ) const
{
EInside answer=kOutside;
G4VCSGface **face = faces;
G4double best = kInfinity;
do {
G4double distance;
EInside result = (*face)->Inside( p, kCarTolerance/2, &distance );
if (result == kSurface) return kSurface;
if (distance < best) {
best = distance;
answer = result;
}
} while( ++face < faces + numFace );
EInside answer=kOutside;
G4VCSGface **face = faces;
G4double best = kInfinity;
do {
G4double distance;
EInside result = (*face)->Inside( p, kCarTolerance/2, &distance );
if (result == kSurface) return kSurface;
if (distance < best)
{
best = distance;
answer = result;
}
} while( ++face < faces + numFace );
return answer;
return answer;
}
//
// SurfaceNormal
//
G4ThreeVector G4VCSGfaceted::SurfaceNormal( const G4ThreeVector& p) const
G4ThreeVector G4VCSGfaceted::SurfaceNormal( const G4ThreeVector& p ) const
{
G4ThreeVector answer;
G4VCSGface **face = faces;
G4double best = kInfinity;
do {
G4double distance;
G4ThreeVector normal = (*face)->Normal( p, &distance );
if (distance < best) {
best = distance;
answer = normal;
}
} while( ++face < faces + numFace );
G4ThreeVector answer;
G4VCSGface **face = faces;
G4double best = kInfinity;
do {
G4double distance;
G4ThreeVector normal = (*face)->Normal( p, &distance );
if (distance < best)
{
best = distance;
answer = normal;
}
} while( ++face < faces + numFace );
return answer;
return answer;
}
//
// DistanceToIn(p,v)
//
G4double G4VCSGfaceted::DistanceToIn( const G4ThreeVector &p, const G4ThreeVector &v ) const
G4double G4VCSGfaceted::DistanceToIn( const G4ThreeVector &p,
const G4ThreeVector &v ) const
{
G4double distance = kInfinity;
G4double distFromSurface = kInfinity;
G4VCSGface *bestFace=0;
G4VCSGface **face = faces;
do {
G4double faceDistance,
faceDistFromSurface;
G4ThreeVector faceNormal;
G4bool faceAllBehind;
if ((*face)->Intersect( p, v, false, kCarTolerance/2,
faceDistance, faceDistFromSurface,
faceNormal, faceAllBehind ) ) {
//
// Intersecting face
//
if (faceDistance < distance) {
distance = faceDistance;
distFromSurface = faceDistFromSurface;
bestFace = *face;
if (distFromSurface <= 0) return 0;
}
}
} while( ++face < faces + numFace );
if (distance < kInfinity && distFromSurface<kCarTolerance/2) {
if (bestFace->Distance(p,false) < kCarTolerance/2) distance = 0;
}
G4double distance = kInfinity;
G4double distFromSurface = kInfinity;
G4VCSGface *bestFace=0;
G4VCSGface **face = faces;
do {
G4double faceDistance,
faceDistFromSurface;
G4ThreeVector faceNormal;
G4bool faceAllBehind;
if ((*face)->Intersect( p, v, false, kCarTolerance/2,
faceDistance, faceDistFromSurface,
faceNormal, faceAllBehind ) )
{
//
// Intersecting face
//
if (faceDistance < distance)
{
distance = faceDistance;
distFromSurface = faceDistFromSurface;
bestFace = *face;
if (distFromSurface <= 0) return 0;
}
}
} while( ++face < faces + numFace );
if (distance < kInfinity && distFromSurface<kCarTolerance/2)
{
if (bestFace->Distance(p,false) < kCarTolerance/2) distance = 0;
}
return distance;
return distance;
}
@@ -239,63 +258,71 @@ G4double G4VCSGfaceted::DistanceToIn( const G4ThreeVector &p, const G4ThreeVecto
//
G4double G4VCSGfaceted::DistanceToIn( const G4ThreeVector &p ) const
{
return DistanceTo( p, false );
return DistanceTo( p, false );
}
//
// DistanceToOut(p,v)
//
G4double G4VCSGfaceted::DistanceToOut( const G4ThreeVector &p, const G4ThreeVector &v,
const G4bool calcNorm,
G4bool *validNorm, G4ThreeVector *n ) const
G4double G4VCSGfaceted::DistanceToOut( const G4ThreeVector &p,
const G4ThreeVector &v,
const G4bool calcNorm,
G4bool *validNorm,
G4ThreeVector *n ) const
{
G4bool allBehind = true;
G4double distance = kInfinity;
G4double distFromSurface = kInfinity;
G4ThreeVector normal;
G4VCSGface *bestFace=0;
G4VCSGface **face = faces;
do {
G4double faceDistance,
faceDistFromSurface;
G4ThreeVector faceNormal;
G4bool faceAllBehind;
if ((*face)->Intersect( p, v, true, kCarTolerance/2,
faceDistance, faceDistFromSurface,
faceNormal, faceAllBehind ) ) {
//
// Intersecting face
//
if ( (distance < kInfinity) || (!faceAllBehind) ) allBehind = false;
if (faceDistance < distance) {
distance = faceDistance;
distFromSurface = faceDistFromSurface;
normal = faceNormal;
bestFace = *face;
if (distFromSurface <= 0) break;
}
}
} while( ++face < faces + numFace );
if (distance < kInfinity) {
if (distFromSurface <= 0)
distance = 0;
else if (distFromSurface<kCarTolerance/2) {
if (bestFace->Distance(p,true) < kCarTolerance/2) distance = 0;
}
G4bool allBehind = true;
G4double distance = kInfinity;
G4double distFromSurface = kInfinity;
G4ThreeVector normal;
G4VCSGface *bestFace=0;
G4VCSGface **face = faces;
do {
G4double faceDistance,
faceDistFromSurface;
G4ThreeVector faceNormal;
G4bool faceAllBehind;
if ((*face)->Intersect( p, v, true, kCarTolerance/2,
faceDistance, faceDistFromSurface,
faceNormal, faceAllBehind ) )
{
//
// Intersecting face
//
if ( (distance < kInfinity) || (!faceAllBehind) ) allBehind = false;
if (faceDistance < distance)
{
distance = faceDistance;
distFromSurface = faceDistFromSurface;
normal = faceNormal;
bestFace = *face;
if (distFromSurface <= 0) break;
}
}
} while( ++face < faces + numFace );
if (distance < kInfinity)
{
if (distFromSurface <= 0)
distance = 0;
else if (distFromSurface<kCarTolerance/2)
{
if (bestFace->Distance(p,true) < kCarTolerance/2) distance = 0;
}
if (calcNorm) {
*validNorm = allBehind;
*n = normal;
}
}
else {
if (calcNorm) *validNorm = false;
}
if (calcNorm)
{
*validNorm = allBehind;
*n = normal;
}
}
else
{
if (calcNorm) *validNorm = false;
}
return distance;
return distance;
}
@@ -304,7 +331,7 @@ G4double G4VCSGfaceted::DistanceToOut( const G4ThreeVector &p, const G4ThreeVect
//
G4double G4VCSGfaceted::DistanceToOut( const G4ThreeVector &p ) const
{
return DistanceTo( p, true );
return DistanceTo( p, true );
}
@@ -313,16 +340,17 @@ G4double G4VCSGfaceted::DistanceToOut( const G4ThreeVector &p ) const
//
// Protected routine called by DistanceToIn and DistanceToOut
//
G4double G4VCSGfaceted::DistanceTo( const G4ThreeVector &p, const G4bool outgoing ) const
G4double G4VCSGfaceted::DistanceTo( const G4ThreeVector &p,
const G4bool outgoing ) const
{
G4VCSGface **face = faces;
G4double best = kInfinity;
do {
G4double distance = (*face)->Distance( p, outgoing );
if (distance < best) best = distance;
} while( ++face < faces + numFace );
G4VCSGface **face = faces;
G4double best = kInfinity;
do {
G4double distance = (*face)->Distance( p, outgoing );
if (distance < best) best = distance;
} while( ++face < faces + numFace );
return (best < 0.5*kCarTolerance) ? 0 : best;
return (best < 0.5*kCarTolerance) ? 0 : best;
}
@@ -342,26 +370,54 @@ void G4VCSGfaceted::DescribeYourselfTo( G4VGraphicsScene& scene ) const
//
G4VisExtent G4VCSGfaceted::GetExtent() const
{
static const G4ThreeVector xMax(1,0,0), xMin(-1,0,0),
yMax(0,1,0), yMin(0,-1,0),
zMax(0,0,1), zMin(0,0,-1);
static const G4ThreeVector *axes[6] = { &xMin, &xMax, &yMin, &yMax, &zMin, &zMax };
G4double answers[6] = {-kInfinity, -kInfinity, -kInfinity, -kInfinity, -kInfinity, -kInfinity};
G4VCSGface **face = faces;
do {
const G4ThreeVector **axis = axes+5 ;
G4double *answer = answers+5;
do {
G4double testFace = (*face)->Extent( **axis );
if (testFace > *answer) *answer = testFace;
}
while( --axis, --answer >= answers );
} while( ++face < faces + numFace );
static const G4ThreeVector xMax(1,0,0), xMin(-1,0,0),
yMax(0,1,0), yMin(0,-1,0),
zMax(0,0,1), zMin(0,0,-1);
static const G4ThreeVector *axes[6] =
{ &xMin, &xMax, &yMin, &yMax, &zMin, &zMax };
return G4VisExtent( -answers[0], answers[1],
-answers[2], answers[3],
-answers[4], answers[5] );
G4double answers[6] =
{-kInfinity, -kInfinity, -kInfinity, -kInfinity, -kInfinity, -kInfinity};
G4VCSGface **face = faces;
do {
const G4ThreeVector **axis = axes+5 ;
G4double *answer = answers+5;
do {
G4double testFace = (*face)->Extent( **axis );
if (testFace > *answer) *answer = testFace;
}
while( --axis, --answer >= answers );
} while( ++face < faces + numFace );
return G4VisExtent( -answers[0], answers[1],
-answers[2], answers[3],
-answers[4], answers[5] );
}
//
// GetEntityType
//
G4GeometryType G4VCSGfaceted::GetEntityType() const
{
return G4String("G4CSGfaceted");
}
//
// Stream object contents to an output stream
//
G4std::ostream& G4VCSGfaceted::StreamInfo( G4std::ostream& os ) const
{
os << "-----------------------------------------------------------\n"
<< " *** Dump for solid - " << GetName() << " ***\n"
<< " ===================================================\n"
<< " Solid type: G4VCSGfaceted\n"
<< " Parameters: \n"
<< " number of faces: " << numFace << "\n"
<< "-----------------------------------------------------------\n";
return os;
}