Import Geant4 5.0.0 source tree
This commit is contained in:
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user