Import Geant4 0.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-08 15:09:25 +02:00
parent b97f8d0df7
commit aaa409b6ee
2922 changed files with 55107 additions and 81674 deletions
+462 -309
View File
@@ -1,4 +1,15 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BREPSolid.cc,v 1.8 1999/06/10 09:49:30 sgiani Exp $
// GEANT4 tag $Name: geant4-00-01 $
#include "G4BREPSolid.hh"
#include "G4VoxelLimits.hh"
#include "G4AffineTransform.hh"
#include "G4VGraphicsScene.hh"
#include "G4Polyhedron.hh"
@@ -10,7 +21,7 @@
#include "G4SphericalSurface.hh"
G4Ray G4BREPSolid::Track;
G4double G4BREPSolid::ShortestDistance=1000000;
G4double G4BREPSolid::ShortestDistance= kInfinity;
int G4BREPSolid::NumberOfSolids=0;
InstMgr G4BREPSolid::InstanceList;
@@ -68,7 +79,7 @@ void G4BREPSolid::Initialize()
{
// Calc bounding box for solids and surfaces
// Convert concave planes to convex
ShortestDistance=1000000;
ShortestDistance= kInfinity;
IsBox();
CheckSurfaceNormals();
@@ -489,330 +500,401 @@ G4bool G4BREPSolid::IsConvex()
}
G4bool G4BREPSolid::CalculateExtent(const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pMin,
G4double& pMax ) const
G4bool G4BREPSolid::CalculateExtent(const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pMin, G4double& pMax) const
{
G4Point3D Min = bbox->GetBoxMin();
G4Point3D Max = bbox->GetBoxMax();
G4ThreeVector VMin(Min.x(),Min.y(),Min.z());
G4ThreeVector VMax(Max.x(),Max.y(),Max.z());
switch (pAxis)
{
case kXAxis:
pMin=Min.x();
pMax=Max.x();
break;
case kYAxis:
pMin=Min.y();
pMax=Max.y();
break;
if (!pTransform.IsRotated())
{
// Special case handling for unrotated boxes
// Compute x/y/z mins and maxs respecting limits, with early returns
// if outside limits. Then switch() on pAxis
G4double xoffset,xMin,xMax;
G4double yoffset,yMin,yMax;
G4double zoffset,zMin,zMax;
case kZAxis:
pMin=Min.z();
pMax=Max.z();
break;
}
pMin-=kCarTolerance;
pMax+=kCarTolerance;
return true;
xoffset=pTransform.NetTranslation().x();
xMin=xoffset+Min.x();
xMax=xoffset+Max.x();
if (pVoxelLimit.IsXLimited())
{
if (xMin>pVoxelLimit.GetMaxXExtent()
||xMax<pVoxelLimit.GetMinXExtent())
{
return false;
}
else
{
if (xMin<pVoxelLimit.GetMinXExtent())
{
xMin=pVoxelLimit.GetMinXExtent();
}
if (xMax>pVoxelLimit.GetMaxXExtent())
{
xMax=pVoxelLimit.GetMaxXExtent();
}
}
}
/*
if (!pTransform.IsRotated())
{
// if(pVoxelLimit.Inside(VMin))
// if(pVoxelLimit.Inside(VMax))
{
switch (pAxis)
{
case kXAxis:
pMin=VMin.x();
pMax=VMax.x();
break;
case kYAxis:
pMin=VMin.y();
pMax=VMax.y();
break;
case kZAxis:
pMin=VMin.z();
pMax=VMax.z();
break;
}
// pMin-=kCarTolerance;
// pMax+=kCarTolerance;
return true;
}
// else
{
// return false;
}
}
// else
{
// return false;
}
yoffset=pTransform.NetTranslation().y();
yMin=yoffset+Min.y();
yMax=yoffset+Max.y();
if (pVoxelLimit.IsYLimited())
{
if (yMin>pVoxelLimit.GetMaxYExtent()
||yMax<pVoxelLimit.GetMinYExtent())
{
return false;
}
else
{
if (yMin<pVoxelLimit.GetMinYExtent())
{
yMin=pVoxelLimit.GetMinYExtent();
}
if (yMax>pVoxelLimit.GetMaxYExtent())
{
yMax=pVoxelLimit.GetMaxYExtent();
}
}
}
return false;*/
zoffset=pTransform.NetTranslation().z();
zMin=zoffset+Min.z();
zMax=zoffset+Max.z();
if (pVoxelLimit.IsZLimited())
{
if (zMin>pVoxelLimit.GetMaxZExtent()
||zMax<pVoxelLimit.GetMinZExtent())
{
return false;
}
else
{
if (zMin<pVoxelLimit.GetMinZExtent())
{
zMin=pVoxelLimit.GetMinZExtent();
}
if (zMax>pVoxelLimit.GetMaxZExtent())
{
zMax=pVoxelLimit.GetMaxZExtent();
}
}
}
switch (pAxis)
{
case kXAxis:
pMin=xMin;
pMax=xMax;
break;
case kYAxis:
pMin=yMin;
pMax=yMax;
break;
case kZAxis:
pMin=zMin;
pMax=zMax;
break;
}
pMin-=kCarTolerance;
pMax+=kCarTolerance;
return true;
}
else
{
// General rotated case - create and clip mesh to boundaries
G4bool existsAfterClip=false;
G4ThreeVectorList *vertices;
pMin=+kInfinity;
pMax=-kInfinity;
// Calculate rotated vertex coordinates
vertices=CreateRotatedVertices(pTransform);
ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax);
ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
if (pMin!=kInfinity||pMax!=-kInfinity)
{
existsAfterClip=true;
// Add 2*tolerance to avoid precision troubles
pMin-=kCarTolerance;
pMax+=kCarTolerance;
}
else
{
// Check for case where completely enveloping clipping volume
// If point inside then we are confident that the solid completely
// envelopes the clipping volume. Hence set min/max extents according
// to clipping volume extents along the specified axis.
G4ThreeVector clipCentre(
(pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
(pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
(pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
if (Inside(pTransform.Inverse().TransformPoint(clipCentre))!=kOutside)
{
existsAfterClip=true;
pMin=pVoxelLimit.GetMinExtent(pAxis);
pMax=pVoxelLimit.GetMaxExtent(pAxis);
}
}
delete vertices;
return existsAfterClip;
}
}
G4ThreeVectorList*
G4BREPSolid::CreateRotatedVertices(const G4AffineTransform& pTransform) const
{
G4Point3D Min = bbox->GetBoxMin();
G4Point3D Max = bbox->GetBoxMax();
G4ThreeVectorList *vertices;
vertices=new G4ThreeVectorList(8);
if (vertices)
{
G4ThreeVector vertex0(Min.x(),Min.y(),Min.z());
G4ThreeVector vertex1(Max.x(),Min.y(),Min.z());
G4ThreeVector vertex2(Max.x(),Max.y(),Min.z());
G4ThreeVector vertex3(Min.x(),Max.y(),Min.z());
G4ThreeVector vertex4(Min.x(),Min.y(),Max.z());
G4ThreeVector vertex5(Max.x(),Min.y(),Max.z());
G4ThreeVector vertex6(Max.x(),Max.y(),Max.z());
G4ThreeVector vertex7(Min.x(),Max.y(),Max.z());
vertices->insert(pTransform.TransformPoint(vertex0));
vertices->insert(pTransform.TransformPoint(vertex1));
vertices->insert(pTransform.TransformPoint(vertex2));
vertices->insert(pTransform.TransformPoint(vertex3));
vertices->insert(pTransform.TransformPoint(vertex4));
vertices->insert(pTransform.TransformPoint(vertex5));
vertices->insert(pTransform.TransformPoint(vertex6));
vertices->insert(pTransform.TransformPoint(vertex7));
}
else
{
G4Exception("G4BREPSolid::CreateRotatedVertices Out of memory - Cannot alloc vertices");
}
return vertices;
}
EInside G4BREPSolid::Inside(register const G4ThreeVector& Pt)const
{
// This function find if the point Pt is inside,
// outside or on the surface of the solid
G4cout<<"\n Solid Id="<<GetId();
// Tolerance has also to be considered i.e. the cases
// where the Point is very close to the box. -1 is
// returned when the Point is within the boundary.
Reset();
G4double halfTolerance = kCarTolerance*0.5;
// Get the bounding box extents
const G4Point3D min = bbox->GetBoxMin();
const G4Point3D max = bbox->GetBoxMax();
G4Vector3D v(1, 0, 0.01);
G4Vector3D Pttmp(Pt);
G4Vector3D Vtmp(v);
G4Ray r(Pttmp, Vtmp);
// First check if the point is Inside the bbox
// of the solid.
if((Pt.x() < min.x() || Pt.x() > max.x())||
(Pt.y() < min.y() || Pt.y() > max.y())||
(Pt.z() < min.z() || Pt.z() > max.z()))
// Check if point is inside the PCone bounding box
if( !GetBBox()->Inside(Pttmp) )
return kOutside;
// If the point is Inside the bbox, it is possibly Inside
// the solid
// Create the ray.
G4Vector3D v(0,0,1);
Track.Init( Pt, v);
// Check the bboxes of the surfaces first to get the favorable
// surfaces to process.
TestSurfaceBBoxes( Track );
// At this point it might be useful to have a routine that checks
// if the point is outside all the face bboxes, Inside any of them
// or Inside all of them. The last case would mean Inside the solid for
// sure. Also should be considered if various types of solids should be
// handled separately i.e. convex polyhedras versus b-spline solids.
int Hits = 0;
// Continue by shooting an arbitrary ray (G4Vector3D = v) starting from Point
// Repeat this until no more hits are found. The amount of hits gives the
// answer (par : outside; odd : inside)
// Tolerance is a problem as there might be cases where we don't
// get the actual intersection on the surface and the Step is not long
// enough to jump over the real boundary.
G4double Tolerance = 0.0001;
G4double Dist=Tolerance+1;
const G4Vector3D& RayDir = Track.GetDir();
while(Intersect( Track ))
if(FinalEvaluation( Track ))
{
// Step over the tolerance and shoot again in the same
// direction using the Hit point as a starting point
// for the new ray
Hits++;
// Tolerance Step
if(Hits==1)
Dist=ShortestDistance;
const G4Point3D& NewStart = intersection_point+(Tolerance*RayDir);
// Set ray starting point
Track.SetStart(NewStart);
Reset();
// To make the routine more robust a check could be made that
// Hits doesn't grow too much say > 10. If this happens
// v could be changed to be something else. This may avoid
// situations where the direction chosen for the test
// is not plausible since at that direction there are many
// faces very close to each other or a face is highly complex or
// the direction is in the direction of the face.
//if(Hits > 10)
// {
// r.SetStart(Point);Hits = 0;
// r.set_G4Vector3D(G4Vector3D(1,0,0));
// while(first_intersect( r ))
// {
// Hits++;
// intersection_point.X() += Tolerance;
// r.SetStart(intersection_point);
// }
// }
}
// else
// break;
// Set the surfaces to active again
G4Surface* Srf;
Reset();
for(G4int a=0;a<nb_of_surfaces;a++)
{
Srf = SurfaceVec[a];
Srf->Reset();
}
// Test if the bounding box of each surface is intersected
// by the ray. If not, the surface become deactive.
TestSurfaceBBoxes(r);
G4int hits=0, samehit=0;
// G4cout << "\n Inside::Hits = " << Hits << "\n";
if(Dist < (0.5*kCarTolerance))
return kSurface;
// Take the mod of hits with 2
if(Hits&1)
// Inside
for(G4int a=0; a < nb_of_surfaces; a++)
{
if(SurfaceVec[a]->Active())
{
// count the number of intersections.
// if this number is odd, the start of the ray is
// inside the volume bounded by the surfaces, so
// increment the number of intersection by 1 if the
// point is not on the surface and if this intersection
// was not founded before
if( (SurfaceVec[a]->Intersect(r)) & 1 )
{
// test if the point is on the surface
if(SurfaceVec[a]->Distance() < kCarTolerance)
return kSurface;
// test if this intersection was founded before
for(G4int i=0; i<a; i++)
if(SurfaceVec[a]->Distance() == SurfaceVec[i]->Distance())
{
samehit++;
break;
}
// count the number of surfaces intersected by the ray
if(!samehit)
hits++;
}
}
}
// if the number of surfaces intersected is odd,
// the point is inside the solid
if(hits&1)
return kInside;
else
// Outside
return kOutside;
}
G4ThreeVector G4BREPSolid::SurfaceNormal(const G4ThreeVector& GetStart)const
G4ThreeVector G4BREPSolid::SurfaceNormal(const G4ThreeVector& Pt)const
{
return GetStart;;
// This function calculates the normal of the surface
// at a point on the surface
// Note : the sense of the normal depends on the sense of the surface
G4Vector3D n(0,0,0);
G4int iplane;
G4Vector3D norm;
G4Ray r( Pt, G4Vector3D(1, 0, 0) );
// Find on which surface the point is
for(iplane = 0; iplane < nb_of_surfaces; iplane++)
{
if(SurfaceVec[iplane]->HowNear(Pt) < kCarTolerance)
// the point is on this surface
break;
}
// calcul of the normal at this point
norm = SurfaceVec[iplane]->SurfaceNormal(Pt);
n = G4ThreeVector ( norm.x(), norm.y(), norm.z() );
n = n.unit();
return n;
}
G4double G4BREPSolid::DistanceToIn(const G4ThreeVector& Pt)const
{
// This function calculates the approximative distance
// of a point from a surface. For exemple, the DistanceToIn
// from a point to a G4FPlane is the closest distance
// Calculates the shortest distance ("safety") from a point
// outside the solid to any boundary of this solid.
// Return 0 if the point is already inside.
G4cout<<"\n Solid Id="<<GetId();
Reset();
G4double halfTolerance = kCarTolerance*0.5;
G4Surface* srf;
G4double PointDistance = INFINITY;
G4double TmpDistance = 0;
for(G4int a=0; a<nb_of_surfaces;a++)
{
srf = SurfaceVec[a];
TmpDistance = fabs(srf->ClosestDistanceToPoint(Pt));
if( (TmpDistance < PointDistance) && (TmpDistance > halfTolerance) )
PointDistance = TmpDistance;
else if(TmpDistance < halfTolerance)
PointDistance = 0; // the point is on the surface,
// but maybe not into the boundary
G4double *dists = new G4double[nb_of_surfaces];
G4double halfTolerance = kCarTolerance*0.5;
G4int a;
// Set the surfaces to active again
Reset();
if(PointDistance < ShortestDistance)
ShortestDistance = PointDistance;
}
// calcul of the shortest distance of the point to each surfaces
// Be carreful : it's a signed value
for(a=0; a< nb_of_surfaces; a++)
dists[a] = SurfaceVec[a]->HowNear(Pt);
G4double Dist = kInfinity;
return ShortestDistance;
// if dists[] is positive, the point is outside
// so take the shortest of the shortest positive distances
// dists[] can be equal to 0 : point on a surface
// ( Problem with the G4FPlane : there is no inside and no outside...
// So, to test if the point is inside to return 0, utilize the Inside
// function. But I don`t know if it is really needed because dToIn is
// called only if the point is outside )
for(a = 0; a < nb_of_surfaces; a++)
if( fabs(Dist) > fabs(dists[a]) )
//if( dists[a] >= 0)
Dist = dists[a];
delete[] dists;
if(Dist == kInfinity)
// the point is inside the solid or on a surface
return 0;
else
//return Dist;
return fabs(Dist);
}
G4double G4BREPSolid::DistanceToIn(register const G4ThreeVector& Pt,
register const G4ThreeVector& V )const
{
G4cout<<"\n Solid Id="<<GetId();
// Calculates the distance from a point outside the solid
// to the solid`s boundary along a specified direction vector.
//
// Note : Intersections with boundaries less than the
// tolerance must be ignored if the direction
// is away from the boundary
#ifdef G4VERBOSE
if(V.mag2() == 0.0)
G4Exception("Error in G4BREPSolid::DistanceToIn(Pt, Vec) : Vec = 0");
#endif
Reset();
G4double halfTolerance = kCarTolerance*0.5;
Track.Init(G4Point3D(Pt),V);
if(!bbox->Test(Track))
return kInfinity;
/*
if(AxisBox)
{
ShortestDistance = bbox->GetDistance();
if(ShortestDistance > halfTolerance)
return ShortestDistance;
// L. Broglia
// Do not see this surface
//else
// ShortestDistance = kInfinity;
//return 0; // the point is on the surface
}
*/
TestSurfaceBBoxes(Track);
if(Intersect( Track ))
if(FinalEvaluation(Track,1))
return sqrt(ShortestDistance);
return kInfinity;
/*
G4Vector3D Pttmp(Pt);
G4Vector3D Vtmp(V);
// G4double kInfinity = 10e20;
G4Ray r(Pttmp, Vtmp);
if(!bbox->Test3dBBox(r))
return kInfinity;
if(AxisBox)
{
ShortestDistance = bbox->GetDistance();
if(ShortestDistance > halfTolerance)
return ShortestDistance;
else
ShortestDistance = kInfinity;
}
// if(number_of_Surfaces>75)
// RemoveHiddenFaces(r, 1);
TestSurfaceBBoxes(r);
if(Intersect( r ))
if(FinalEvaluation(r,1))
return sqrt(ShortestDistance);
return kInfinity;
*/
}
G4double G4BREPSolid::DistanceToOut(const G4ThreeVector& Pt)const
{
G4cout<<"\n Solid Id="<<GetId();
G4int a;
// Set the surfaces to active again
Reset();
G4double halfTolerance = kCarTolerance*0.5;
G4Surface* srf;
G4double PointDistance = INFINITY;
G4double TmpDistance = 0;
G4double halfTolerance = kCarTolerance*0.5;
G4Vector3D Pttmp(Pt);
G4Vector3D Vtmp(V);
G4Ray r(Pttmp, Vtmp);
// Test if the bounding box of each surface is intersected
// by the ray. If not, the surface become deactive.
TestSurfaceBBoxes(r);
for(G4int a=0; a<nb_of_surfaces;a++)
ShortestDistance = kInfinity;
for(a=0; a< nb_of_surfaces; a++)
{
srf = SurfaceVec[a];
TmpDistance = fabs(srf->ClosestDistanceToPoint(Pt));
if( (TmpDistance < PointDistance) && (TmpDistance > halfTolerance) )
PointDistance = TmpDistance;
else if(TmpDistance < halfTolerance)
PointDistance = 0 ; // the point is on the surface
if(SurfaceVec[a]->Active())
{
// test if the ray intersect the surface
if( (SurfaceVec[a]->Intersect(r)) )
{
// if more than 1 surface is intersected,
// take the nearest one
if( SurfaceVec[a]->Distance() < ShortestDistance )
if( SurfaceVec[a]->Distance() > halfTolerance )
{
ShortestDistance = SurfaceVec[a]->Distance();
}
else
{
// the point is within the boundary
// ignored it if the direction is away from the boundary
G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp);
if( (Norm * Vtmp) < 0 )
ShortestDistance = SurfaceVec[a]->Distance();
}
}
}
}
if(PointDistance < ShortestDistance)
ShortestDistance = PointDistance;
return ShortestDistance;
// Be carreful !
// SurfaceVec->Distance is in fact the squared distance
if(ShortestDistance != kInfinity)
return sqrt(ShortestDistance);
else
// no intersection, return kInfinity
return kInfinity;
}
@@ -822,28 +904,111 @@ G4double G4BREPSolid::DistanceToOut(register const G4ThreeVector& P,
G4bool *validNorm,
G4ThreeVector *n ) const
{
G4cout<<"\n Solid Id="<<GetId();
if(validNorm)
*validNorm = false;
// Calculates the distance from a point inside the solid
// to the solid`s boundary along a specified direction vector.
// Return 0 if the point is already outside.
//
// Note : If the shortest distance to a boundary is less
// than the tolerance, it is ignored. This allows
// for a point within a tolerant boundary to leave
// immediately
#ifdef G4VERBOSE
if(D.mag2() == 0.0)
G4Exception("Error in G4BREPSolid::DistanceToOut(Pt, Vec) : Vec = 0");
#endif
// Set the surfaces to active again
Reset();
const G4double halfTolerance = kCarTolerance*0.5;
G4Vector3D Ptv = P;
G4int a;
// I don`t understand this line
if(validNorm)
*validNorm=false;
G4Vector3D Pttmp(Ptv);
G4Vector3D Vtmp(D);
G4Ray r(Pttmp, Vtmp);
// Test if the bounding box of each surface is intersected
// by the ray. If not, the surface become deactive.
TestSurfaceBBoxes(r);
ShortestDistance = kInfinity;
for(a=0; a< nb_of_surfaces; a++)
{
if(SurfaceVec[a]->Active())
{
// test if the ray intersect the surface
if( (SurfaceVec[a]->Intersect(r)) )
{
// if more than 1 surface is intersected,
// take the nearest one
if( SurfaceVec[a]->Distance() < ShortestDistance )
if( SurfaceVec[a]->Distance() > halfTolerance )
{
ShortestDistance = SurfaceVec[a]->Distance();
}
else
{
// the point is within the boundary: ignored it
}
}
}
}
// Be carreful !
// SurfaceVec->Distance is in fact the squared distance
if(ShortestDistance != kInfinity)
return sqrt(ShortestDistance);
else
// if no intersection is founded, the point is outside
// so return 0
return 0.0;
}
G4double G4BREPSolid::DistanceToOut(const G4ThreeVector& Pt)const
{
// Calculates the shortest distance ("safety") from a point
// inside the solid to any boundary of this solid.
// Return 0 if the point is already outside.
G4double *dists = new G4double[nb_of_surfaces];
G4double halfTolerance = kCarTolerance*0.5;
G4int a;
// Set the surfaces to active again
Reset();
Track.Init(G4Point3D(P),D);
TestSurfaceBBoxes(Track);
if(Intersect(Track))
if(FinalEvaluation(Track))
if(ShortestDistance > kCarTolerance/2) // if d=0, do not see the surface
return sqrt(ShortestDistance);
// calcul of the shortest distance of the point to each surfaces
// Be carreful : it's a signed value
for(a=0; a< nb_of_surfaces; a++)
dists[a] = SurfaceVec[a]->HowNear(Pt);
G4double Dist = kInfinity;
return kInfinity; // This should never happen
// if dists[] is negative, the point is inside
// so take the shortest of the shortest negative distances
// dists[] can be equal to 0 : point on a surface
// ( Problem with the G4FPlane : there is no inside and no outside...
// So, to test if the point is outside to return 0, utilize the Inside
// function. But I don`t know if it is really needed because dToOut is
// called only if the point is inside )
for(a = 0; a < nb_of_surfaces; a++)
if( fabs(Dist) > fabs(dists[a]) )
//if( dists[a] <= 0)
Dist = dists[a];
delete[] dists;
if(Dist == kInfinity)
// the point is ouside the solid or on a surface
return 0;
else
// return Dist;
return fabs(Dist);
}
@@ -937,6 +1102,7 @@ void G4BREPSolid::CalcBBoxes()
// Find max and min of face bboxes to make
// solids bbox.
// replace by Extend
// max < box_max;
if(max.x() < box_max.x()) max.setX(box_max.x());
if(max.y() < box_max.y()) max.setY(box_max.y());
@@ -1086,20 +1252,7 @@ int G4BREPSolid::Intersect(register const G4Ray& rayref) const
{
register G4Surface* tmp;
// L. Broglia
// What is the utility of this test ?
// If only 1 surface is intersected, it return 0
// instead the intersection exist
/*
if((a+1)<nb_of_surfaces)
tmp = SurfaceVec[a+1];
else
tmp = 0;
if((tmp) && ( tmp->Active()))
{
*/
// Get the evaluated point on the surface
G4Point3D& closest_point = srf->closest_hit;
@@ -1234,7 +1387,7 @@ int G4BREPSolid::FinalEvaluation(register const G4Ray& rayref,
if(( Dir * Norm ) >= 0)
{
Dist = INFINITY;
Dist = kInfinity;
srf->Deactivate();
}
@@ -1243,7 +1396,7 @@ int G4BREPSolid::FinalEvaluation(register const G4Ray& rayref,
}
else
{
Dist = INFINITY;
Dist = kInfinity;
srf->Deactivate();
}
}
@@ -1263,7 +1416,7 @@ int G4BREPSolid::FinalEvaluation(register const G4Ray& rayref,
if(TestDistance > Dist)
{
// Hit behind ray starting point, no intersection.
Dist = INFINITY;
Dist = kInfinity;
srf->Deactivate();
}
else
@@ -1286,7 +1439,7 @@ int G4BREPSolid::FinalEvaluation(register const G4Ray& rayref,
//if(( Dir * Norm ) >= 0)
if(( Dir * Norm ) < 0)
{
Dist = INFINITY;
Dist = kInfinity;
srf->Deactivate();
}
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BREPSolidBox.cc,v 2.3 1998/10/20 16:33:37 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BREPSolidBox.cc,v 1.1 1999/01/07 16:07:38 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4BREPSolidBox.hh"
#include "G4FPlane.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BREPSolidCone.cc,v 2.5 1998/10/29 17:49:33 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BREPSolidCone.cc,v 1.1 1999/01/07 16:07:38 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4BREPSolidCone.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BREPSolidCylinder.cc,v 2.6 1998/11/27 17:41:38 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BREPSolidCylinder.cc,v 1.1 1999/01/07 16:07:38 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4BREPSolidCylinder.hh"
@@ -5,9 +5,17 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BREPSolidPCone.cc,v 2.27 1998/12/11 13:40:43 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BREPSolidPCone.cc,v 1.12 1999/05/24 13:51:56 magni Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
//
// The polyconical solid G4BREPSolidPCone is a shape defined by a set of
// inner and outer conical or cylindrical surface sections and two planes
// perpendicular to the Z axis. Each conical surface is defined by its
// radius at two different planes perpendicular to the Z-axis. Inner and
// outer conical surfaces are defined using common Z planes.
//
#include "G4BREPSolidPCone.hh"
#include "G4FCylindricalSurface.hh"
#include "G4FConicalSurface.hh"
@@ -38,18 +46,6 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
G4ThreeVector PlaneAxis(0, 0, 1);
G4ThreeVector PlaneDir (0, 1, 0);
///////////////////////////////////////////////////
// Temporary
for (G4int x = 0; x <= sections; x++)
{
G4cout<<"Z"<<x<<"="<<z_values[x];
G4cout<<" Rmin"<<x<<"="<<RMIN[x];
G4cout<<" Rmax"<<x<<"="<<RMAX[x]<<endl;
}
G4cout<<"start angle ="<<start_angle<<endl;
G4cout<<"open angle ="<<opening_angle<<endl;
G4cout<<"zstart ="<<z_start<<endl;
///////////////////////////////////////////////////
// Test the validity of the R values
@@ -66,10 +62,13 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
G4Exception("RMAX inside the solid can not be nul");
// RMAX[a] must be greater than RMIN[a]
for(a = 0; a < num_z_planes; a++)
for(a = 1; a < num_z_planes-1; a++)
if (RMIN[a] >= RMAX[a])
G4Exception("RMAX must be greater than RMIN");
G4Exception("RMAX must be greater that RMIN in the middle Z planes.");
if( (RMIN[num_z_planes-1] > RMAX[num_z_planes-1] )
|| (RMIN[0] > RMAX[0]) )
G4Exception("RMAX must be greater or equal to RMIN at the ends.");
///////////////////////////////////////////////////
// Create cylindrical et conical surfaces
@@ -97,10 +96,9 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
}
else
{
G4cerr << "Error in construction of G4BREPSolidPCone: "
<< "Exactly the same z, rmin and rmax given for "
<< "consecutive indices, " << a << " and " << a+1 << endl;
// G4Exception("G4BREPSolidPCone constructor: Error in parameter values");
G4cerr << "Error in construction of G4BREPSolidPCone "
<< "Exactly the same z, rmin and rmax given for "
<< "consecutive indices, " << a << " and " << a+1 << endl;
continue;
}
@@ -138,6 +136,9 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
SurfaceVec[b] = new G4FPlane(PlaneDir, PlaneAxis, LocalOrigin);
SurfaceVec[b]->SetBoundaries(&cv1);
// set sense of the surface
// SurfaceVec[b]->SetSameSense(1);
nb_of_surfaces--;
b++;
@@ -157,6 +158,8 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
SurfaceVec[b] = new G4FConicalSurface(ConeOrigin, Axis, Length,
RMIN[a+1], RMIN[a]);
// set sense of the surface
SurfaceVec[b]->SetSameSense(0);
}
else
{
@@ -166,6 +169,9 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
SurfaceVec[b] = new G4FConicalSurface(ConeOrigin, Axis2,
Length, RMIN[a], RMIN[a+1]);
// set sense of the surface
SurfaceVec[b]->SetSameSense(0);
}
b++;
@@ -185,6 +191,10 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
SurfaceVec[b] = new G4FCylindricalSurface(CylOrigin, Axis,
RMIN[a], Length );
// set sense of the surface
SurfaceVec[b]->SetSameSense(0);
b++;
}
}
@@ -199,6 +209,9 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
SurfaceVec[b] = new G4FConicalSurface(ConeOrigin, Axis,
Length, RMAX[a+1], RMAX[a]);
// set sense of the surface
SurfaceVec[b]->SetSameSense(1);
}
else
{
@@ -208,6 +221,9 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
SurfaceVec[b] = new G4FConicalSurface(ConeOrigin, Axis2,
Length, RMAX[a], RMAX[a+1]);
// set sense of the surface
SurfaceVec[b]->SetSameSense(1);
}
b++;
@@ -230,6 +246,10 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
SurfaceVec[b] = new G4FCylindricalSurface(CylOrigin, Axis,
RMAX[a], Length );
// set sense of the surface
SurfaceVec[b]->SetSameSense(1);
b++;
}
}
@@ -241,53 +261,71 @@ G4BREPSolidPCone::G4BREPSolidPCone(G4String name,
///////////////////////////////////////////////////
// Create two end planes
// Create start G4Plane & boundaries
G4Point3D ArcStart1a = Origin + (RMIN[0]*PlaneDir);
G4Point3D ArcStart1b = Origin + (RMAX[0]*PlaneDir);
G4CurveVector cv;
G4CircularCurve* tmp;
tmp = new G4CircularCurve;
tmp->Init(G4Axis2Placement3D(PlaneDir, PlaneAxis, Origin), RMIN[0]);
tmp->SetBounds(ArcStart1a, ArcStart1a);
tmp->SetSameSense(0);
cv.append(tmp);
tmp = new G4CircularCurve;
tmp->Init(G4Axis2Placement3D(PlaneDir, PlaneAxis, Origin), RMAX[0]);
tmp->SetBounds(ArcStart1b, ArcStart1b);
tmp->SetSameSense(1);
cv.append(tmp);
if(RMIN[0] < RMAX[0]) {
SurfaceVec[nb_of_surfaces-2] = new G4FPlane(PlaneDir, PlaneAxis, Origin);
SurfaceVec[nb_of_surfaces-2]->SetBoundaries(&cv);
// Create start G4Plane & boundaries
G4Point3D ArcStart1a = Origin + (RMIN[0]*PlaneDir);
G4Point3D ArcStart1b = Origin + (RMAX[0]*PlaneDir);
// Create end G4Plane & boundaries
G4Point3D ArcStart2a = LocalOrigin + (RMIN[sections]*PlaneDir);
G4Point3D ArcStart2b = LocalOrigin + (RMAX[sections]*PlaneDir);
tmp = new G4CircularCurve;
tmp->Init(G4Axis2Placement3D(PlaneDir, PlaneAxis, Origin), RMIN[0]);
tmp->SetBounds(ArcStart1a, ArcStart1a);
tmp->SetSameSense(0);
cv.append(tmp);
cv.clear();
tmp = new G4CircularCurve;
tmp->Init(G4Axis2Placement3D(PlaneDir, PlaneAxis, Origin), RMAX[0]);
tmp->SetBounds(ArcStart1b, ArcStart1b);
tmp->SetSameSense(1);
cv.append(tmp);
tmp = new G4CircularCurve;
tmp->Init(G4Axis2Placement3D(PlaneDir, PlaneAxis, LocalOrigin),
RMIN[sections]);
tmp->SetBounds(ArcStart2a, ArcStart2a);
tmp->SetSameSense(0);
cv.append(tmp);
SurfaceVec[nb_of_surfaces-2] = new G4FPlane(PlaneDir, -PlaneAxis, Origin);
SurfaceVec[nb_of_surfaces-2]->SetBoundaries(&cv);
tmp = new G4CircularCurve;
tmp->Init(G4Axis2Placement3D(PlaneDir, PlaneAxis, LocalOrigin),
RMAX[sections]);
tmp->SetBounds(ArcStart2b, ArcStart2b);
tmp->SetSameSense(1);
cv.append(tmp);
// set sense of the surface
SurfaceVec[nb_of_surfaces-2]->SetSameSense(0);
}else{
// RMIN[0] == RMAX[0]
// no surface is needed, it is a line!
nb_of_surfaces--;
}
if(RMIN[sections] < RMAX[sections]) {
// Create end G4Plane & boundaries
G4Point3D ArcStart2a = LocalOrigin + (RMIN[sections]*PlaneDir);
G4Point3D ArcStart2b = LocalOrigin + (RMAX[sections]*PlaneDir);
SurfaceVec[nb_of_surfaces-1]= new G4FPlane(PlaneDir, PlaneAxis, LocalOrigin);
SurfaceVec[nb_of_surfaces-1]->SetBoundaries(&cv);
cv.clear();
tmp = new G4CircularCurve;
tmp->Init(G4Axis2Placement3D(PlaneDir, PlaneAxis, LocalOrigin),
RMIN[sections]);
tmp->SetBounds(ArcStart2a, ArcStart2a);
tmp->SetSameSense(0);
cv.append(tmp);
tmp = new G4CircularCurve;
tmp->Init(G4Axis2Placement3D(PlaneDir, PlaneAxis, LocalOrigin),
RMAX[sections]);
tmp->SetBounds(ArcStart2b, ArcStart2b);
tmp->SetSameSense(1);
cv.append(tmp);
SurfaceVec[nb_of_surfaces-1]= new G4FPlane(PlaneDir, PlaneAxis, LocalOrigin);
SurfaceVec[nb_of_surfaces-1]->SetBoundaries(&cv);
// set sense of the surface
SurfaceVec[nb_of_surfaces-1]->SetSameSense(0);
}else{
// RMIN[0] == RMAX[0]
// no surface is needed, it is a line!
nb_of_surfaces--;
}
active=1;
Initialize();
@@ -355,181 +393,202 @@ void G4BREPSolidPCone::Initialize()
EInside G4BREPSolidPCone::Inside(register const G4ThreeVector& Pt) const
{
// Check if point lies between end planes of PCone
G4double dist1 = SurfaceVec[nb_of_surfaces-1]->ClosestDistanceToPoint(Pt);
G4double dist2 = SurfaceVec[nb_of_surfaces-2]->ClosestDistanceToPoint(Pt);
// This function find if the point Pt is inside,
// outside or on the surface of the solid
if((dist1 < -kCarTolerance && dist2 <-kCarTolerance)||
(dist1 > kCarTolerance && dist2 >kCarTolerance) )
return kOutside;
G4Vector3D v(1,0,0);
G4double Dist;
G4double halfTolerance = kCarTolerance*0.5;
// G4Vector3D v(1, 0, 0.01);
G4Vector3D v(1, 0, 0);
G4Vector3D Pttmp(Pt);
G4Vector3D Vtmp(v);
G4Ray r(Pttmp, Vtmp);
// Check if point is inside the PCone bounding box
if( !GetBBox()->Inside(Pttmp) )
return kOutside;
// Set the surfaces to active again
Reset();
// Test if the bounding box of each surface is intersected
// by the ray. If not, the surface become deactive.
TestSurfaceBBoxes(r);
G4int hits=0;
G4double dist = kInfinity;
G4bool isIntersected = false;
G4int WhichSurface = 0;
// Chech if the point is on the surface, otherwise
// find the nearest intersected suface. If there are not intersections the
// point is outside
for(G4int a=0; a < nb_of_surfaces; a++)
{
if(SurfaceVec[a]->Active())
if(SurfaceVec[a]->Intersect(r))
{
if(SurfaceVec[a]->Distance() < kCarTolerance)
return kSurface;
hits++;
{
if(fabs(SurfaceVec[a]->HowNear(Pt)) < kCarTolerance)
return kSurface;
if ( SurfaceVec[a]->Intersect(r) ) {
isIntersected = true;
if ( fabs(SurfaceVec[a]->Distance()) < dist ) {
dist = SurfaceVec[a]->Distance();
WhichSurface = a;
}
}
}
}
if ( !isIntersected ) return kOutside;
// Set the surfaces to active again
for(G4int b=0; b < nb_of_surfaces; b++)
SurfaceVec[b]->Reset();
// Find the point of intersection on the surface and the normal
// !!!! be carefull the distance is sqrt(dist) !!!!
if(hits&1)
return kInside;
G4ThreeVector IntersectionPoint = Pttmp + sqrt(dist)*Vtmp;
G4ThreeVector Normal = SurfaceVec[WhichSurface]->SurfaceNormal(IntersectionPoint);
if ( Normal*Vtmp > 0 ) return kInside;
return kOutside;
}
G4ThreeVector G4BREPSolidPCone::SurfaceNormal(const G4ThreeVector& Pt) const
{
G4cout<<" SurfaceNormal() of G4BREPSolidPCone modified by L. Broglia";
G4Vector3D Ptv = Pt;
{
// This function calculates the normal of the surface
// at a point on the surface
// Note : the sense of the normal depends on the sense of the surface
G4Vector3D n(0,0,0);
G4double zCoord = Pt.z();
const G4int num_z_planes = original_parameters.Num_z_planes;
G4int iplane;
// Find the appropriate z "slice"
//
for(iplane=0; iplane< num_z_planes; iplane++)
if ( (zCoord < original_parameters.Z_values[iplane+1]) &&
(zCoord >= original_parameters.Z_values[iplane]) )
break;
G4int normflag = 0;
G4Vector3D norm;
G4Ray r( Pt, G4Vector3D(1, 0, 0) );
// We must find which is the correct surface, the inner or the outer one
// (if they exist)
for(iplane = 0; iplane < num_z_planes; iplane++)
// Find on which surface the point is
for(iplane = 0; iplane < nb_of_surfaces; iplane++)
{
// check if the point is on the surface
if(SurfaceVec[iplane]->Intersect(r))
if(SurfaceVec[iplane]->Distance() < kCarTolerance)
// the point is on the surface
break;
if( fabs(SurfaceVec[iplane]->HowNear(Pt)) < kCarTolerance) {
// the point is on this surface
normflag = 1;
break;
}
}
norm = SurfaceVec[iplane]->SurfaceNormal(Pt);
// calcul of the normal at this point
if ( normflag ) {
norm = SurfaceVec[iplane]->SurfaceNormal(Pt);
n = G4ThreeVector ( norm.x(), norm.y(), norm.z());
n = n.unit();
/*
if ( SurfaceVec[innerSurface]->WithinBoundary(Ptv) == 1 )
{
norm = SurfaceVec[ innersurface ]->SurfaceNormal(Pt);
}
else if ( SurfaceVec[outerSurface]->WithinBoundary(Ptv) == 1 )
{
norm = SurfaceVec[ outerSurface]->SurfaceNormal(Pt);
}
// Check if it is on one of the top/bottom planes
//
if ( fabs(zCoord - original_parameters.Z_values[0]) < kCarTolerance )
{
// n = G4ThreeVector (0., 0., sign( original_parameters.Z_values[0]
// -original_parameters.Z_values[1]) );
n = G4ThreeVector (0., 0., original_parameters.Z_values[0]
-original_parameters.Z_values[1] );
n = G4ThreeVector ( norm.x(), norm.y(), norm.z() );
n = n.unit();
}
else if (fabs(zCoord - original_parameters.Z_values[num_z_planes-1]) <
kCarTolerance)
{
n = G4ThreeVector(0., 0., original_parameters.Z_values[num_z_planes]
-original_parameters.Z_values[num_z_planes-1] );
n = n.unit();
}
*/
return n;
return n;
} else {
cout << "Warning ... PCone not able to return normal .. " << endl;
return ( G4ThreeVector(1,0,0));
}
}
G4double G4BREPSolidPCone::DistanceToIn(const G4ThreeVector& Pt) const
{
// Calculates the shortest distance ("safety") from a point
// outside the solid to any boundary of this solid.
// Return 0 if the point is already inside.
G4double *dists = new G4double[nb_of_surfaces];
G4double halfTolerance = kCarTolerance*0.5;
G4int a;
for(a=0; a< nb_of_surfaces;a++)
dists[a] = fabs(SurfaceVec[a]->HowNear(Pt));
// Set the surfaces to active again
Reset();
G4double Dist=kInfinity;
// calcul of the shortest distance of the point to each surfaces
// Be carreful : it's a signed value
for(a=0; a< nb_of_surfaces; a++)
dists[a] = SurfaceVec[a]->HowNear(Pt);
G4double Dist = kInfinity;
for(a=0; a< nb_of_surfaces;a++)
if(Dist>dists[a]) Dist = dists[a];
// if dists[] is positive, the point is outside
// so take the shortest of the shortest positive distances
// dists[] can be equal to 0 : point on a surface
// ( Problem with the G4FPlane : there is no inside and no outside...
// So, to test if the point is inside to return 0, utilize the Inside
// function. But I don`t know if it is really needed because dToIn is
// called only if the point is outside )
for(a = 0; a < nb_of_surfaces; a++)
if( fabs(Dist) > fabs(dists[a]) )
//if( dists[a] >= 0)
Dist = dists[a];
delete[] dists;
// Set the surfaces to active again
for(G4int b=0; b < nb_of_surfaces; b++)
SurfaceVec[b]->Reset();
return Dist;
if(Dist == kInfinity)
// the point is inside the solid or on a surface
return 0;
else
//return Dist;
return fabs(Dist);
}
G4double G4BREPSolidPCone::DistanceToIn(register const G4ThreeVector& Pt,
register const G4ThreeVector& V) const
{
int a;
// Calculates the distance from a point outside the solid
// to the solid`s boundary along a specified direction vector.
//
// Note : Intersections with boundaries less than the
// tolerance must be ignored if the direction
// is away from the boundary
G4int a;
// Set the surfaces to active again
Reset();
G4double halfTolerance = kCarTolerance*0.5;
G4Vector3D Pttmp(Pt);
G4Vector3D Vtmp(V);
// G4double kInfinity = ;
G4Ray r(Pttmp, Vtmp);
// Test if the bounding box of each surface is intersected
// by the ray. If not, the surface become deactive.
TestSurfaceBBoxes(r);
ShortestDistance = kInfinity;
for(a=0; a< nb_of_surfaces;a++)
for(a=0; a< nb_of_surfaces; a++)
{
if(SurfaceVec[a]->Active())
if(SurfaceVec[a]->Intersect( r ))
{
if(ShortestDistance > SurfaceVec[a]->Distance())
if(SurfaceVec[a]->Distance()> halfTolerance)
{
ShortestDistance = SurfaceVec[a]->Distance();
}
else
{
G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp);
if((Norm * Vtmp)<0)
{
// test if the ray intersect the surface
G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp);
if( (Norm * Vtmp) < 0 && fabs(SurfaceVec[a]->HowNear(Pt)) < halfTolerance )
return 0;
if( (SurfaceVec[a]->Intersect(r)) ) {
// if more than 1 surface is intersected,
// take the nearest one
if( SurfaceVec[a]->Distance() < ShortestDistance )
if( SurfaceVec[a]->Distance() > halfTolerance )
{
ShortestDistance = SurfaceVec[a]->Distance();
}
}
}
}
}
// Set the surfaces to active again
for(G4int b=0; b < nb_of_surfaces; b++)
SurfaceVec[b]->Reset();
// Be careful !
// SurfaceVec->Distance is in fact the squared distance
if(ShortestDistance != kInfinity)
return sqrt(ShortestDistance);
return kInfinity;
else
// no intersection, return kInfinity
return kInfinity;
}
@@ -539,76 +598,110 @@ G4double G4BREPSolidPCone::DistanceToOut(register const G4ThreeVector& Pt,
G4bool *validNorm,
G4ThreeVector *n ) const
{
// Calculates the distance from a point inside the solid
// to the solid`s boundary along a specified direction vector.
// Return 0 if the point is already outside.
//
// Note : If the shortest distance to a boundary is less
// than the tolerance, it is ignored. This allows
// for a point within a tolerant boundary to leave
// immediately
// Set the surfaces to active again
Reset();
const G4double halfTolerance = kCarTolerance*0.5;
G4Vector3D Ptv = Pt;
G4double wb = 0.0;
G4int a;
for( a=0; a< nb_of_surfaces-2; a++)
{
wb = fabs( SurfaceVec[a]->HowNear(Ptv) );
// If we are on a surface and exiting it return Zero
if ( (wb < halfTolerance) && (V.dot(SurfaceVec[a]->Normal(Ptv))>0) )
{
return (0.0);
}
}
// I don`t understand this line
if(validNorm)
*validNorm=false;
Reset();
G4Vector3D Pttmp(Pt);
G4Vector3D Vtmp(V);
// G4double kInfinity = 10e20;
G4Ray r(Pttmp, Vtmp);
TestSurfaceBBoxes(r);
ShortestDistance = kInfinity;
for(a=0; a< nb_of_surfaces;a++)
if(SurfaceVec[a]->Active())
if(SurfaceVec[a]->Intersect( r ))
if(ShortestDistance > SurfaceVec[a]->Distance()&&
SurfaceVec[a]->Distance()> halfTolerance)
ShortestDistance = SurfaceVec[a]->Distance();
// Set the surfaces to active again
for(G4int b=0; b < nb_of_surfaces; b++)
SurfaceVec[b]->Reset();
// Test if the bounding box of each surface is intersected
// by the ray. If not, the surface become deactive.
TestSurfaceBBoxes(r);
ShortestDistance = kInfinity;
for(a=0; a< nb_of_surfaces; a++)
{
if(SurfaceVec[a]->Active())
{
G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp);
if( (Norm * Vtmp) > 0 && fabs(SurfaceVec[a]->HowNear(Pt)) < halfTolerance )
return 0;
// test if the ray intersect the surface
if( (SurfaceVec[a]->Intersect(r)) )
{
// if more than 1 surface is intersected,
// take the nearest one
if( SurfaceVec[a]->Distance() < ShortestDistance )
if( SurfaceVec[a]->Distance() > halfTolerance )
{
ShortestDistance = SurfaceVec[a]->Distance();
}
}
}
}
// Be carreful !
// SurfaceVec->Distance is in fact the squared distance
if(ShortestDistance != kInfinity)
return sqrt(ShortestDistance);
return kInfinity;
else
// if no intersection is founded, the point is outside
// so return 0
return 0;
}
G4double G4BREPSolidPCone::DistanceToOut(const G4ThreeVector& Pt) const
{
int a;
// Calculates the shortest distance ("safety") from a point
// inside the solid to any boundary of this solid.
// Return 0 if the point is already outside.
G4double *dists = new G4double[nb_of_surfaces];
G4double halfTolerance = kCarTolerance*0.5;
for(a=0; a< nb_of_surfaces; a++)
dists[a] = fabs(SurfaceVec[a]->HowNear(Pt));
G4double Dist=kInfinity;
for(a=0; a< nb_of_surfaces;a++)
if( Dist>dists[a] ) Dist = dists[a];
G4double halfTolerance = kCarTolerance*0.5;
G4int a;
// Set the surfaces to active again
for(G4int b=0; b < nb_of_surfaces; b++)
SurfaceVec[b]->Reset();
Reset();
// calcul of the shortest distance of the point to each surfaces
// Be carreful : it's a signed value
for(a=0; a< nb_of_surfaces; a++)
dists[a] = SurfaceVec[a]->HowNear(Pt);
G4double Dist = kInfinity;
// if dists[] is negative, the point is inside
// so take the shortest of the shortest negative distances
// dists[] can be equal to 0 : point on a surface
// ( Problem with the G4FPlane : there is no inside and no outside...
// So, to test if the point is outside to return 0, utilize the Inside
// function. But I don`t know if it is really needed because dToOut is
// called only if the point is inside )
// If we are on a surface, the return value Dist must be zero!
delete[] dists;
return Dist;
for(a = 0; a < nb_of_surfaces; a++)
if( fabs(Dist) > fabs(dists[a]) )
//if( dists[a] <= 0)
Dist = dists[a];
delete[] dists;
if(Dist == kInfinity)
// the point is ouside the solid or on a surface
return 0;
else
// return Dist;
return fabs(Dist);
}
@@ -639,3 +732,6 @@ G4Polyhedron* G4BREPSolidPCone::CreatePolyhedron() const
@@ -5,8 +5,26 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BREPSolidPolyhedra.cc,v 2.11 1998/12/11 13:40:46 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BREPSolidPolyhedra.cc,v 1.9 1999/05/28 08:49:12 sgiani Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
// Corrections by S.Giani:
// - Xaxis now corresponds to phi=0
// - partial angle = phiTotal / Nsides
// - end planes exact boundary calculation for phiTotal < 2pi
// (also including case with RMIN=RMAX)
// - Xaxis now properly rotated to compute correct scope of vertixes
// - corrected surface orientation for outer faces parallel to Z
// - completed explicit setting of the orientation for all faces
// - some comparison between doubles avoided by using tolerances.
//
//
// The polygonal solid G4BREPSolidPolyhedra is a shape defined by an inner
// and outer polygonal surface and two planes perpendicular to the Z axis.
// Each polygonal surface is created by linking a series of polygons created
// at different planes perpendicular to the Z-axis. All these polygons all
// have the same number of sides (sides) and are defined at the same Z planes
// for both inner and outer polygonal surfaces.
//
#include "G4BREPSolidPolyhedra.hh"
@@ -26,7 +44,7 @@ G4BREPSolidPolyhedra::G4BREPSolidPolyhedra(G4String name,
{
const int sections= num_z_planes - 1;
if(dphi == 2*pi)
if(dphi >= 2*pi-perMillion)
nb_of_surfaces = 2*(sections * sides) + 2;
else
nb_of_surfaces = 2*(sections * sides) + 4;
@@ -35,28 +53,13 @@ G4BREPSolidPolyhedra::G4BREPSolidPolyhedra(G4String name,
SurfaceVec = new G4Surface*[nb_of_surfaces];
G4Vector3D Axis(0,0,1);
G4Vector3D YAxis(0,1,0);
G4Vector3D XAxis(1,0,0);
G4Vector3D TmpAxis;
G4Point3D Origin(0,0,z_start);
G4Point3D LocalOrigin(0,0,z_start);
G4double Length;
int Count =0;
G4double PartAngle = (dphi - phi1)/sides;
///////////////////////////////////////////////////
// Temporary
for (G4int x = 0; x <= sections; x++)
{
cout<<"Z"<<x<<"="<<z_values[x];
cout<<" Rmin"<<x<<"="<<RMIN[x];
cout<<" Rmax"<<x<<"="<<RMAX[x]<<endl;
}
cout<<"phi1 ="<<phi1<<endl;
cout<<"dphi ="<<dphi<<endl;
cout<<"sides ="<<sides<<endl;
cout<<"zstart ="<<z_start<<endl;
G4Point3D Origin(0,0,z_start);
G4Point3D LocalOrigin(0,0,z_start);
G4double Length;
G4int Count = 0 ;
G4double PartAngle = (dphi)/sides;
///////////////////////////////////////////////////
@@ -64,9 +67,13 @@ G4BREPSolidPolyhedra::G4BREPSolidPolyhedra(G4String name,
for(G4int a=0;a<sections;a++)
{
TmpAxis= YAxis;
TmpAxis= XAxis;
TmpAxis.rotateZ(phi1);
Length = z_values[a+1] - z_values[a];
// L. Broglia
// Be careful in the construction of the planes
// See G4FPlane
// Create sides
for(int b=0;b<sides;b++)
@@ -74,25 +81,34 @@ G4BREPSolidPolyhedra::G4BREPSolidPolyhedra(G4String name,
G4Point3DVector PointList(4);
// Create inner side
// Calc points for the planar surface boundary
// The order of the point give the sense
PointList[0] = LocalOrigin + (RMIN[a] * TmpAxis);
PointList[1] = LocalOrigin + (Length*Axis) + (RMIN[a+1] * TmpAxis);
PointList[3] = LocalOrigin + (Length*Axis) + (RMIN[a+1] * TmpAxis);
TmpAxis.rotateZ(PartAngle);
PointList[2] = LocalOrigin + (Length*Axis) + (RMIN[a+1] * TmpAxis);
PointList[3] = LocalOrigin + (RMIN[a] * TmpAxis);
SurfaceVec[Count] = new G4FPlane( &PointList);
PointList[1] = LocalOrigin + (RMIN[a] * TmpAxis);
// Add to surface list and reverse sense
SurfaceVec[Count] = new G4FPlane( &PointList, 0, 0);
Count++;
// Rotate axis back for the other surface point calculation
TmpAxis.rotateZ(-PartAngle);
// Calc points for the planar surface boundary
// Create outer side
// Calc points for the planar surface boundary
// The order of the point give the sense
G4Point3DVector PointList2(4);
PointList2[0] = LocalOrigin + (RMAX[a] * TmpAxis);
PointList2[1] = LocalOrigin + (Length*Axis) + (RMAX[a+1] * TmpAxis);
PointList2[3] = LocalOrigin + (Length*Axis) + (RMAX[a+1] * TmpAxis);
TmpAxis.rotateZ(PartAngle);
PointList2[2] = LocalOrigin + (Length*Axis) + (RMAX[a+1] * TmpAxis);
PointList2[3] = LocalOrigin + (RMAX[a] * TmpAxis);
PointList2[1] = LocalOrigin + (RMAX[a] * TmpAxis);
// Add to surface list and set sense
SurfaceVec[Count] = new G4FPlane(&PointList2);
Count++;
}
@@ -101,14 +117,14 @@ G4BREPSolidPolyhedra::G4BREPSolidPolyhedra(G4String name,
// Create end planes
if(dphi == 2*pi)
if(dphi >= 2*pi-perMillion)
{
// Create only end planes
G4Point3DVector EndPointList(sides);
G4Point3DVector InnerPointList(sides);
G4Point3DVector EndPointList2(sides);
G4Point3DVector InnerPointList2(sides);
TmpAxis = YAxis;
TmpAxis = XAxis;
TmpAxis.rotateZ(phi1);
TmpAxis.rotateZ(dphi);
@@ -122,59 +138,44 @@ G4BREPSolidPolyhedra::G4BREPSolidPolyhedra(G4String name,
TmpAxis.rotateZ(-PartAngle);
}
// Add to surface list and set sense
SurfaceVec[nb_of_surfaces-2] =
new G4FPlane(&EndPointList, &InnerPointList);
// Add to surface list and reverse sense
SurfaceVec[nb_of_surfaces-1] =
new G4FPlane(&EndPointList2, &InnerPointList2);
new G4FPlane(&EndPointList2, &InnerPointList2, 0);
}
else
{
TmpAxis = YAxis;
// If phi section, create a single boundary (case with RMIN=0 included)
TmpAxis = XAxis;
TmpAxis.rotateZ(phi1);
TmpAxis.rotateZ(dphi);
// Create end planes & two planes for the "missing" part
G4Point3DVector EndPointList(sides+2);
G4Point3DVector InnerPointList(sides+2);
G4Point3DVector EndPointList2(sides+2);
G4Point3DVector InnerPointList2(sides+2);
TmpAxis = YAxis;
// Create end planes
G4Point3DVector EndPointList ((sides+1)*2);
G4Point3DVector EndPointList2((sides+1)*2);
for(int c=0;c<sides+1;c++)
{
// outer polyline for origin end
EndPointList[c] = Origin + (RMAX[0] * TmpAxis);
InnerPointList[c] = Origin + (RMIN[0] * TmpAxis);
// outer polylines for origin end and opposite side
EndPointList[c] = Origin + (RMAX[0] * TmpAxis);
EndPointList[(sides+1)*2-1-c] = Origin + (RMIN[0] * TmpAxis);
EndPointList2[c] = LocalOrigin + (RMAX[sections] * TmpAxis);
InnerPointList2[c] = LocalOrigin + (RMIN[sections] * TmpAxis);
EndPointList2[(sides+1)*2-1-c] = LocalOrigin + (RMIN[sections] * TmpAxis);
TmpAxis.rotateZ(-PartAngle);
}
// Create the extra points on the axis
TmpAxis = YAxis;
TmpAxis.rotateZ(phi1);
EndPointList[sides+1] = Origin;
InnerPointList[sides+1] = Origin;
EndPointList2[sides+1] = LocalOrigin;
InnerPointList2[sides+1] = LocalOrigin;
int points = sides+2;
SurfaceVec[nb_of_surfaces-4] =
new G4FPlane(&EndPointList, &InnerPointList);
SurfaceVec[nb_of_surfaces-3] =
new G4FPlane(&EndPointList2, &InnerPointList2);
// Create the planars for the "gap"
TmpAxis = YAxis;
G4ThreeVector TmpAxis2 = YAxis;
// Create the lateral planars
TmpAxis = XAxis;
G4ThreeVector TmpAxis2 = XAxis;
TmpAxis.rotateZ(phi1);
TmpAxis2.rotateZ(phi1);
TmpAxis2.rotateZ(dphi);
LocalOrigin=Origin;
points = sections*2+2;
int points = sections*2+2;
G4Point3DVector GapPointList(points);
G4Point3DVector GapPointList2(points);
Count=0;
@@ -193,8 +194,26 @@ G4BREPSolidPolyhedra::G4BREPSolidPolyhedra(G4String name,
LocalOrigin = LocalOrigin+(Length*Axis);
}
SurfaceVec[nb_of_surfaces-2] = new G4FPlane(&GapPointList);
SurfaceVec[nb_of_surfaces-1] = new G4FPlane(&GapPointList2);
// Add the lateral planars to the surfaces list and set/reverse sense
SurfaceVec[nb_of_surfaces-4] = new G4FPlane(&GapPointList);
SurfaceVec[nb_of_surfaces-3] = new G4FPlane(&GapPointList2, 0, 0);
//Add the end planes to the surfaces list and set/reverse sense
if(RMAX[0]-RMIN[0] >= perMillion){
SurfaceVec[nb_of_surfaces-2] = new G4FPlane(&EndPointList);
}
else{
nb_of_surfaces -= 1;
};
if(RMAX[sections]-RMIN[sections] >= perMillion){
SurfaceVec[nb_of_surfaces-1] = new G4FPlane(&EndPointList2, 0, 0);
}
else{
nb_of_surfaces -= 1;
};
}
@@ -217,6 +236,32 @@ G4BREPSolidPolyhedra::G4BREPSolidPolyhedra(G4String name,
original_parameters.Rmin[is]= RMIN[is]/rFactor;
original_parameters.Rmax[is]= RMAX[is]/rFactor;
}
///////////////////////////////////////////////////
// Print for debugging
#ifdef G4VERBOSE
static G4int print_pgone_parameters = 1;
if(print_pgone_parameters)
{
G4cout << "Parameters of the G4PGone " << name << endl;
G4cout << " starting angle =" << original_parameters.Start_angle << endl;
G4cout << " opening angle =" << original_parameters.Opening_angle << endl;
G4cout << " sides =" << original_parameters.Sides << endl;
G4cout << " nb of z planes=" << original_parameters.Num_z_planes << endl;
for (G4int nb = 0; nb <= sections; nb++)
{
G4cout << " Z[" << nb << "] = " << original_parameters.Z_values[nb];
G4cout << " Rmin[" << nb << "] = " << original_parameters.Rmin[nb];
G4cout << " Rmax[" << nb << "] = " << original_parameters.Rmax[nb]
<< endl;
}
}
#endif
// z_values[0] should be equal to z_start, for consistency
// with what the constructor does.
@@ -261,93 +306,95 @@ void G4BREPSolidPolyhedra::Initialize()
EInside G4BREPSolidPolyhedra::Inside(register const G4ThreeVector& Pt) const
{
G4double *dists = new G4double[nb_of_surfaces];
G4double Dist = kInfinity;
G4double tmpdist=kInfinity;
G4double halfTolerance = kCarTolerance*0.5;
for(int a=0; a< nb_of_surfaces;a++)
{
tmpdist = (SurfaceVec[a]->HowNear(Pt));
if(fabs(Dist) > fabs(tmpdist))
Dist = tmpdist;
}
// This function find if the point Pt is inside,
// outside or on the surface of the solid
if(Dist > halfTolerance)
G4double halfTolerance = kCarTolerance*0.5;
G4Vector3D v(1, 0, 0.01);
G4Vector3D Pttmp(Pt);
G4Vector3D Vtmp(v);
G4Ray r(Pttmp, Vtmp);
// Check if point is inside the Polyhedra bounding box
if( !GetBBox()->Inside(Pttmp) )
return kOutside;
// Set the surfaces to active again
Reset();
if(Dist < -halfTolerance)
return kInside;
// Test if the bounding box of each surface is intersected
// by the ray. If not, the surface become deactive.
TestSurfaceBBoxes(r);
return kSurface;
G4int hits=0, samehit=0;
for(G4int a=0; a < nb_of_surfaces; a++)
{
if(SurfaceVec[a]->Active())
{
// count the number of intersections.
// if this number is odd, the start of the ray is
// inside the volume bounded by the surfaces, so
// increment the number of intersection by 1 if the
// point is not on the surface and if this intersection
// was not founded before
if( (SurfaceVec[a]->Intersect(r)) & 1 )
{
// test if the point is on the surface
if(SurfaceVec[a]->Distance() <= kCarTolerance*kCarTolerance)
return kSurface;
// test if this intersection was founded before
for(G4int i=0; i<a; i++)
if(SurfaceVec[a]->Distance() == SurfaceVec[i]->Distance())
{
samehit++;
break;
}
// count the number of surfaces intersected by the ray
if(!samehit)
hits++;
}
}
}
// if the number of surfaces intersected is odd,
// the point is inside the solid
if(hits&1)
return kInside;
else
return kOutside;
}
G4ThreeVector G4BREPSolidPolyhedra::SurfaceNormal
(const G4ThreeVector& Pt) const
{
G4cout<<" SurfaceNormal() of G4BREPSolidPolyhedra modified by L. Broglia";
// This function calculates the normal of the surface
// at a point on the surface
// Note : the sense of the normal depends on the sense of the surface
/*
//G4Exception(" SurfaceNormal() of G4BREPSolidPolyhedra is not yet implemented." );
#ifdef WILL_IMPLEMENT
G4double zCoord= Pt.z();
G4int a, zSlice, phiSlice;
// Try to find the appropriate z "slice"
for(a=0; a< nb_of_surfaces-2;a++)
if ( (zCoord < original_parameters.Z_values[a+1])
&&(zCoord >= original_parameters.Z_values[a]) )
break;
zSlice= a;
// Try to find the appropriate phi plane
phiSlice = 0;
unsigned int isurface=0;
G4ThreeVec norm = SurfaceVec[isurface]->SurfaceNormal(Pt);
G4ThreeVector normalVector = G4ThreeVector ( norm.GetX(),
norm.GetY(),
norm.GetZ());
#else
G4ThreeVector normalVector = G4ThreeVector ( 0.0, 0.0, 1.0);
#endif
*/
G4Vector3D Ptv = Pt;
G4Vector3D n(0,0,0);
G4double zCoord = Pt.z();
const G4int num_z_planes = original_parameters.Num_z_planes;
G4int iplane;
// Find the appropriate z "slice"
//
for(iplane=0; iplane< num_z_planes; iplane++)
if ( (zCoord < original_parameters.Z_values[iplane+1]) &&
(zCoord >= original_parameters.Z_values[iplane]) )
break;
G4Vector3D norm;
G4Ray r( Pt, G4Vector3D(1, 0, 0) );
// We must find which is the correct surface, the inner or the outer one
// (if they exist)
for(iplane = 0; iplane < num_z_planes; iplane++)
// Find on which surface the point is
for(iplane = 0; iplane < nb_of_surfaces; iplane++)
{
// check if the point is on the surface
if(SurfaceVec[iplane]->Intersect(r))
if(SurfaceVec[iplane]->Distance() < kCarTolerance)
// the point is on the surface
break;
if(SurfaceVec[iplane]->HowNear(Pt) < kCarTolerance)
// the point is on this surface
break;
}
norm = SurfaceVec[iplane]->SurfaceNormal(Pt);
// calcul of the normal at this point
norm = SurfaceVec[iplane]->SurfaceNormal(Pt);
n = G4ThreeVector ( norm.x(), norm.y(), norm.z());
n = G4ThreeVector ( norm.x(), norm.y(), norm.z() );
n = n.unit();
return n;
@@ -356,113 +403,228 @@ G4ThreeVector G4BREPSolidPolyhedra::SurfaceNormal
G4double G4BREPSolidPolyhedra::DistanceToIn(const G4ThreeVector& Pt) const
{
G4double Dist=kInfinity;
G4double tmpdist=kInfinity;
G4double halfTolerance = kCarTolerance*0.5;
// Calculates the shortest distance ("safety") from a point
// outside the solid to any boundary of this solid.
// Return 0 if the point is already inside.
G4double *dists = new G4double[nb_of_surfaces];
G4double halfTolerance = kCarTolerance*0.5;
G4int a;
// Set the surfaces to active again
Reset();
for(int a=0; a< nb_of_surfaces;a++)
{
tmpdist = fabs(SurfaceVec[a]->HowNear(Pt));
if(Dist>tmpdist && tmpdist> halfTolerance) Dist = tmpdist;
}
// calcul of the shortest distance of the point to each surfaces
// Be carreful : it's a signed value
for(a=0; a< nb_of_surfaces; a++)
dists[a] = SurfaceVec[a]->HowNear(Pt);
G4double Dist = kInfinity;
return Dist;
// if dists[] is positive, the point is outside
// so take the shortest of the shortest positive distances
// dists[] can be equal to 0 : point on a surface
// ( Problem with the G4FPlane : there is no inside and no outside...
// So, to test if the point is inside to return 0, utilize the Inside
// function. But I don`t know if it is really needed because dToIn is
// called only if the point is outside )
for(a = 0; a < nb_of_surfaces; a++)
if( fabs(Dist) > fabs(dists[a]) )
//if( dists[a] >= 0)
Dist = dists[a];
delete[] dists;
if(Dist == kInfinity)
// the point is inside the solid or on a surface
return 0;
else
//return Dist;
return fabs(Dist);
}
G4double G4BREPSolidPolyhedra::DistanceToIn(register const G4ThreeVector& Pt,
register const G4ThreeVector& V
) const
register const G4ThreeVector& V) const
{
Reset();
G4Point3D Pttmp(Pt);
G4Vector3D Vtmp(V);
G4double halfTolerance = kCarTolerance*0.5;
// G4double kInfinity = kInfinity;
// Calculates the distance from a point outside the solid
// to the solid`s boundary along a specified direction vector.
//
// Note : Intersections with boundaries less than the
// tolerance must be ignored if the direction
// is away from the boundary
G4int a;
// Set the surfaces to active again
Reset();
G4double halfTolerance = kCarTolerance*0.5;
G4Vector3D Pttmp(Pt);
G4Vector3D Vtmp(V);
G4Ray r(Pttmp, Vtmp);
// Test if the bounding box of each surface is intersected
// by the ray. If not, the surface become deactive.
TestSurfaceBBoxes(r);
QuickSort(SurfaceVec, 0, nb_of_surfaces-1);
ShortestDistance = kInfinity;
for(int a=0; a< nb_of_surfaces;a++)
for(a=0; a< nb_of_surfaces; a++)
{
if(SurfaceVec[a]->Active())
// L. Broglia : old
// if(SurfaceVec[a]->Intersect(r))
if( (G4FPlane*)(SurfaceVec[a])->Evaluate(r) )
if(ShortestDistance > SurfaceVec[a]->Distance())
if(SurfaceVec[a]->Distance() > halfTolerance)
{
// test if the ray intersect the surface
if( (SurfaceVec[a]->Intersect(r)) )
{
// if more than 1 surface is intersected,
// take the nearest one
if( SurfaceVec[a]->Distance() < ShortestDistance )
if( SurfaceVec[a]->Distance() > halfTolerance )
{
ShortestDistance = SurfaceVec[a]->Distance();
}
else
{
G4ThreeVector Norm = SurfaceVec[a]->SurfaceNormal(Pttmp);
if((Norm * Vtmp)<0)
// the point is within the boundary
// ignored it if the direction is away from the boundary
G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp);
if( (Norm * Vtmp) < 0 )
ShortestDistance = SurfaceVec[a]->Distance();
}
}
}
}
// Be carreful !
// SurfaceVec->Distance is in fact the squared distance
if(ShortestDistance != kInfinity)
return sqrt(ShortestDistance);
return kInfinity;
else
// no intersection, return kInfinity
return kInfinity;
}
G4double G4BREPSolidPolyhedra::DistanceToOut(register const G4ThreeVector& Pt,
register const G4ThreeVector& V,
const G4bool calcNorm,
G4bool *validNorm,
G4ThreeVector *n) const
G4double G4BREPSolidPolyhedra::DistanceToOut(register const G4ThreeVector& Pt,
register const G4ThreeVector& V,
const G4bool calcNorm,
G4bool *validNorm,
G4ThreeVector *n ) const
{
// Calculates the distance from a point inside the solid
// to the solid`s boundary along a specified direction vector.
// Return 0 if the point is already outside (even number of
// intersections greater than the tolerance).
//
// Note : If the shortest distance to a boundary is less
// than the tolerance, it is ignored. This allows
// for a point within a tolerant boundary to leave
// immediately
G4int parity = 0;
// Set the surfaces to active again
Reset();
const G4double halfTolerance = kCarTolerance*0.5;
G4Vector3D Ptv = Pt;
G4int a;
// I don`t understand this line
if(validNorm)
*validNorm = false;
*validNorm=false;
Reset();
G4double halfTolerance = kCarTolerance*0.5;
G4Point3D Pttmp(Pt);
G4Vector3D Pttmp(Pt);
G4Vector3D Vtmp(V);
// G4double kInfinity = 10e20;
G4Ray r(Pttmp, Vtmp);
// Test if the bounding box of each surface is intersected
// by the ray. If not, the surface become deactive.
TestSurfaceBBoxes(r);
QuickSort(SurfaceVec, 0, nb_of_surfaces-1);
ShortestDistance = kInfinity;
for(int a=0; a< nb_of_surfaces;a++)
ShortestDistance = kInfinity; // this is actually the square of the distance
for(a=0; a< nb_of_surfaces; a++)
{
if(SurfaceVec[a]->Active())
if(SurfaceVec[a]->Intersect(r))
if(ShortestDistance > SurfaceVec[a]->Distance()&&
SurfaceVec[a]->Distance() > halfTolerance)
ShortestDistance = SurfaceVec[a]->Distance();
{
// test if the ray intersects the surface
if( (SurfaceVec[a]->Intersect(r)) )
{
parity += 1;
// if more than 1 surface is intersected,
// take the nearest one
if( SurfaceVec[a]->Distance() < ShortestDistance )
if( SurfaceVec[a]->Distance() > halfTolerance*halfTolerance )
{
ShortestDistance = SurfaceVec[a]->Distance();
}
else
{
// the point is within the boundary: ignore it
parity -= 1;
}
}
}
}
if(ShortestDistance != kInfinity)
// Be carreful !
// SurfaceVec->Distance is in fact the squared distance
if((ShortestDistance != kInfinity) && (parity&1))
return sqrt(ShortestDistance);
return kInfinity;
else
// if no intersection is found, the point is outside
// so return 0
return 0;
}
G4double G4BREPSolidPolyhedra::DistanceToOut(const G4ThreeVector& Pt) const
{
G4double Dist=kInfinity;
G4double tmpdist=kInfinity;
G4double halfTolerance = kCarTolerance*0.5;
// Calculates the shortest distance ("safety") from a point
// inside the solid to any boundary of this solid.
// Return 0 if the point is already outside.
G4double *dists = new G4double[nb_of_surfaces];
G4double halfTolerance = kCarTolerance*0.5;
G4int a;
// Set the surfaces to active again
Reset();
for(int a=0; a< nb_of_surfaces;a++)
{
tmpdist = fabs(SurfaceVec[a]->HowNear(Pt));
// calcul of the shortest distance of the point to each surfaces
// Be carreful : it's a signed value
for(a=0; a< nb_of_surfaces; a++)
dists[a] = SurfaceVec[a]->HowNear(Pt);
G4double Dist = kInfinity;
if(Dist>tmpdist && tmpdist> halfTolerance)
Dist = tmpdist;
}
// if dists[] is negative, the point is inside
// so take the shortest of the shortest negative distances
// dists[] can be equal to 0 : point on a surface
// ( Problem with the G4FPlane : there is no inside and no outside...
// So, to test if the point is outside to return 0, utilize the Inside
// function. But I don`t know if it is really needed because dToOut is
// called only if the point is inside )
for(a = 0; a < nb_of_surfaces; a++)
if( fabs(Dist) > fabs(dists[a]) )
//if( dists[a] <= 0)
Dist = dists[a];
return Dist;
delete[] dists;
if(Dist == kInfinity)
// the point is ouside the solid or on a surface
return 0;
else
// return Dist;
return fabs(Dist);
}
@@ -479,6 +641,3 @@ G4Polyhedron* G4BREPSolidPolyhedra::CreatePolyhedron() const
original_parameters.Rmin,
original_parameters.Rmax);
}
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BREPSolidSphere.cc,v 2.2 1998/10/20 16:33:39 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BREPSolidSphere.cc,v 1.1 1999/01/07 16:07:39 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4BREPSolidSphere.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BREPSolidTorus.cc,v 2.1 1998/10/20 16:33:39 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BREPSolidTorus.cc,v 1.1 1999/01/07 16:07:39 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4BREPSolidTorus.hh"
#include "G4ToroidalSurface.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BSplineCurve.cc,v 2.8 1998/12/15 15:45:15 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BSplineCurve.cc,v 1.1 1999/01/07 16:07:39 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4BSplineCurve.hh"
#include "G4ControlPoints.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BSplineCurveWithKnots.cc,v 2.1 1998/07/02 17:53:59 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BSplineCurveWithKnots.cc,v 1.1 1999/01/07 16:07:39 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4BSplineCurveWithKnots.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BSplineSurface.cc,v 2.10 1998/11/24 16:41:23 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BSplineSurface.cc,v 1.2 1999/05/20 17:39:21 japost Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "EntityInst.h"
@@ -312,7 +312,7 @@ void G4BSplineSurface::FindIntersections(const G4Ray& rayref)
// Loop through the bezier List
G4BezierSurface* bez_ptr;
distance = INFINITY;
distance = kInfinity;
while(bezier_list.index != (G4Surface*)0)
{
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BezierSurface.cc,v 2.8 1998/11/24 16:41:24 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4BezierSurface.cc,v 1.1 1999/01/07 16:07:40 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
// L. Broglia, 10/10/98
// Error in line 331 and replaced addition of coordinates by
@@ -1,12 +0,0 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4BoundedSurface.cc,v 2.3 1998/10/20 16:33:42 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "G4BoundedSurface.hh"
@@ -311,6 +311,21 @@ G4double G4BoundingBox3D::DistanceToIn(const G4Point3D& p,
}
///////////////////////////////////////////////////////////////////////////////
G4int G4BoundingBox3D::Inside(const G4Point3D& Pt)
{
if( ( Pt.x() >= box_min.x() && Pt.x() <= box_max.x() ) &&
( Pt.y() >= box_min.y() && Pt.y() <= box_max.y() ) &&
( Pt.z() >= box_min.z() && Pt.z() <= box_max.z() ) )
return 1;
else
return 0;
}
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4CircularCurve.cc,v 2.4 1998/10/20 16:33:43 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4CircularCurve.cc,v 1.1 1999/01/07 16:07:41 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4CircularCurve.hh"
@@ -45,7 +45,7 @@ G4Curve* G4CompositeCurve::Project(const G4Transform3D& tr)
return r;
}
/*
void G4CompositeCurve::IntersectRay2D(const G4Ray& ray,
G4CurveRayIntersection& is)
{
@@ -62,7 +62,26 @@ void G4CompositeCurve::IntersectRay2D(const G4Ray& ray,
lastIntersection= is;
}
*/
G4int G4CompositeCurve::IntersectRay2D(const G4Ray& ray)
{
G4int nbinter = 0, temp = 0;
for (G4int i=0; i<segments.entries(); i++)
{
G4Curve& c= *(segments(i));
temp = c.IntersectRay2D(ray);
// test if the point is on the composite curve
if( temp==999 )
return 999;
else
nbinter+= temp;
}
return nbinter;
}
G4bool G4CompositeCurve::Tangent(G4CurvePoint& cp, G4Vector3D& v)
{
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ConicalSurface.cc,v 2.6 1998/11/13 13:58:30 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4ConicalSurface.cc,v 1.1 1999/01/07 16:07:41 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
/* /usr/local/gismo/repo/geometry/G4ConicalSurface.cc,v 1.6 1994/08/03 17:15:01 burnett Exp */
// File: G4ConicalSurface.cc
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ControlPoints.cc,v 2.6 1998/11/04 14:49:55 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4ControlPoints.cc,v 1.1 1999/01/07 16:07:41 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
//
// Modif 8 oct 98 : A.Floquet
+2 -2
View File
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Curve.cc,v 2.3 1998/11/06 15:31:26 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4Curve.cc,v 1.1 1999/01/07 16:07:41 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4Curve.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4CylindricalSurface.cc,v 2.7 1998/12/10 11:02:55 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4CylindricalSurface.cc,v 1.1 1999/01/07 16:07:42 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
/* /usr/local/gismo/repo/geometry/G4CylindricalSurface.cc,v 1.24 1994/08/03 17:15:09 burnett Exp */
// File: G4CylindricalSurface.cc
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Ellipse.cc,v 2.9 1998/12/08 14:04:24 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4Ellipse.cc,v 1.1 1999/01/07 16:07:42 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4Ellipse.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4FConicalSurface.cc,v 2.16 1998/12/10 17:26:41 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4FConicalSurface.cc,v 1.8 1999/05/19 16:57:11 magni Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
/* /usr/local/gismo/repo/geometry/G4FConicalSurface.cc,v 1.2 1993/02/05 00:38:39 alanb Exp */
// File: G4FConicalSurface.cc
@@ -27,6 +27,7 @@
//
// End ---------------------------------------------------------------
#include "G4FConicalSurface.hh"
#include "G4Sort.hh"
#include "G4CircularCurve.hh"
@@ -37,25 +38,20 @@ G4FConicalSurface::G4FConicalSurface(const G4Point3D& o,
G4double l,
G4double sr,
G4double lr
) //: G4ConicalSurface( o, a, 1.0 )
//: G4Surface( o ) doesn`t exist
)
{
// Make a G4FConicalSurface with origin o, axis a, length l, small radius
// sr, and large radius lr. The angle is calculated below and the SetAngle
// function of G4ConicalSurface is used to set it properly from the default
// Make a G4FConicalSurface with origin o, axis a, length l, small radius
// sr, and large radius lr. The angle is calculated below and the SetAngle
// function of G4ConicalSurface is used to set it properly from the default
// value used above in the initialization.
// L. Broglia
// Position.SetSrfPoint(o);
// Position.SetAxis(a);
// Create the position with origin o, axis a, and a direction wich
// is not important
// Create the position with origin o, axis a, and a direction
G4Vector3D dir(1,1,1);
Position.Init(dir, a, o);
origin = o;
// Require length to be nonnegative
// if ( l > 0.0 )
if (l >=0)
length = l;
else
@@ -255,234 +251,152 @@ void G4FConicalSurface::resize( G4double l, G4double sr, G4double lr )
int G4FConicalSurface::Intersect(const G4Ray& ry )
{
// Distance along a Ray (straight line with G4Vector3D) to leave or enter
// a G4FConicalSurface. The input variable which_way should be set to +1 to
// indicate leaving a G4ConicalSurface, -1 to indicate entering a
// G4ConicalSurface.
// p is the point of intersection of the Ray with the G4ConicalSurface.
// If the G4Vector3D of the Ray is opposite to that of the Normal to
// the G4FConicalSurface at the intersection point, it will not leave the
// G4FConicalSurface.
// Similarly, if the G4Vector3D of the Ray is along that of the Normal
// to the G4ConicalSurface at the intersection point, it will not enter the
// G4ConicalSurface.
// This method is called by all finite shapes sub-classed to
// G4ConicalSurface.
// Use the virtual function table to check if the intersection point
// is within the boundary of the finite shape.
// A negative result means no intersection.
// If no valid intersection point is found, set the distance
// and intersection point to large numbers.
int which_way;
if(Inside(ry.GetStart()))
which_way = 1;
else
which_way = -1;
distance = FLT_MAXX;
// This function count the number of intersections of a
// bounded conical surface by a ray.
// At first, calculates the intersections with the semi-infinite
// conical surfsace. After, count the intersections within the
// finite conical surface boundaries, and set "distance" to the
// closest distance from the start point to the nearest intersection
// If the point is on the surface it returns or the intersection with
// the opposite surface or kInfinity
// If no intersection is founded, set distance = kInfinity and
// return 0
G4Vector3D lv ( FLT_MAXX, FLT_MAXX, FLT_MAXX );
closest_hit = lv;
distance = kInfinity;
closest_hit = PINFINITY;
// Origin and G4Vector3D unit vector of Ray.
G4Vector3D x = ry.GetStart();
// origin and direction of the ray
G4Point3D x = ry.GetStart();
G4Vector3D dhat = ry.GetDir();
// Cone angle and axis unit vector.
G4double ta = tan_angle;
// cone angle and axis
G4double ta = tan_angle;
G4Vector3D ahat = Position.GetAxis();
int isoln = 0, maxsoln = 2;
// array of solutions in distance along the Ray
// array of solutions in distance along the ray
G4double s[2];
s[0]=-1.0;
s[1]=-1.0;
// L. Broglia
// calculate the two solutions (quadratic equation)
// calculate the two intersections (quadratic equation)
G4Vector3D gamma = x - Position.GetLocation();
G4double T = 1.0 + ta * ta;
G4double t = 1 + ta * ta;
G4double ga = gamma * ahat;
G4double da = dhat * ahat;
/*
G4double A = 1.0 - T * da * da;
G4double B = 2.0 * ( gamma * dhat - T * ga * da );
G4double C = gamma * gamma - T * ga * ga;
*/
G4double A = - 1.0 + T * da * da;
G4double B = 2 * ( -gamma * dhat + T * ga * da - large_radius * ta * da);
G4double C = ( -gamma * gamma + T * ga * ga
G4double A = t * da * da - dhat * dhat;
G4double B = 2 * ( -gamma * dhat + t * ga * da - large_radius * ta * da);
G4double C = ( -gamma * gamma + t * ga * ga
- 2 * large_radius * ta * ga
+ large_radius * large_radius );
G4double radical = B * B - 4.0 * A * C;
// if quadratic term vanishes, just do the simple solution
if ( fabs( A ) < FLT_EPSILO )
if ( B == 0.0 )
return 1;
else
s[0] = -C / B;
// Normal quadratic case, no intersection if radical is less than zero
if ( radical < 0.0 )
// no intersection
return 0;
else
{
G4double radical = B * B - 4.0 * A * C;
if ( radical < 0.0 )
return 0;
else
{
G4double root = sqrt( radical );
s[0] = ( - B + root ) / ( 2. * A );
s[1] = ( - B - root ) / ( 2. * A );
}
G4double root = sqrt( radical );
s[0] = ( - B + root ) / ( 2. * A );
s[1] = ( - B - root ) / ( 2. * A );
}
// validity of the solutions
// the hit point must be into the bounding box of the conical surface
G4Point3D p0 = x + s[0]*dhat;
G4Point3D p1 = x + s[1]*dhat;
if( !GetBBox()->Inside(p0) )
s[0] = kInfinity;
// order the possible solutions by increasing distance along the Ray
// (G4Sorting routines are in support/G4Sort.h)
G4Sort_double( s, isoln, maxsoln-1 );
if( !GetBBox()->Inside(p1) )
s[1] = kInfinity;
// now loop over each positive solution, keeping the first one (smallest
// distance along the ray) which is within the boundary of the sub-shape
G4int nbinter = 0;
distance = kInfinity;
// now loop over each positive solution, keeping the first one (smallest
// distance along the Ray) which is within the boundary of the sub-shape
// and which also has the correct G4Vector3D with respect to the Normal to
// the G4ConicalSurface at the intersection point
for ( isoln = 0; isoln < maxsoln; isoln++ )
{
if ( s[isoln] >= kCarTolerance*0.5 )
{
if ( s[isoln] >= FLT_MAXX ) // quit if too large
return 0;
distance = s[isoln];
closest_hit = ry.GetPoint( distance );
// Following line necessary to select non-reflective solutions.
if ((( ahat * ( closest_hit - Position.GetLocation() ) > 0.0 ) &&
((( dhat * SurfaceNormal( closest_hit ) * which_way ) >= 0.0 )) &&
( fabs(HowNear( closest_hit )) < 0.1)) )
{
if ( WithinBoundary ( closest_hit ) == 1 )
{
distance = distance*distance;
return 1;
}
for ( G4int i = 0; i < 2; i++ )
{
if(s[i] < kInfinity) {
if ( (s[i] > kCarTolerance*0.5) ) {
nbinter++;
if ( distance > (s[i]*s[i]) ) {
distance = s[i]*s[i];
}
}
distance = distance*distance;
return 1;
}
else
if ( s[isoln] >= -kCarTolerance*0.5 )
{
// the point is on the surface
distance = 0;
return 1;
}
}
// get here only if there was no solution within the boundary, Reset
// distance and intersection point to large numbers
distance = FLT_MAXX;
closest_hit = lv;
return 0;
return nbinter;
}
G4double G4FConicalSurface::HowNear( const G4Vector3D& x ) const
{
// Distance from the point x to the semi-infinite G4FConicalSurface.
// The distance will be positive if the point is Inside the G4ConicalSurface,
// negative if the point is outside.
// Note that this may not be correct for a bounded conical object
// subclassed to G4ConicalSurface.
// Shortest distance from the point x to the G4FConicalSurface.
// The distance will be always positive
// This function works only with Cone axis equal (0,0,1) or (0,0,-1), it project
// the surface and the point on the x,z plane and compute the distance in analytical
// way
G4Vector3D d = x - origin;
G4double dA = d * Position.GetAxis();
G4double rad = sqrt( d.mag2() - dA*dA );
G4double teta = atan2( (large_radius - small_radius) , length );
G4double radiu = fabs( rad - large_radius + dA*tan_angle );
G4double hownear ;
if (dA > length)
hownear =dA - length;
else if (dA < 0)
hownear =dA;
else
hownear = radiu * cos(teta);
G4Vector3D upcorner = G4Vector3D ( small_radius, 0 , origin.z()+Position.GetAxis().z()*length);
G4Vector3D downcorner = G4Vector3D ( large_radius, 0 , origin.z());
G4Vector3D xd;
xd = G4Vector3D ( sqrt ( x.x()*x.x() + x.y()*x.y() ) , 0 , x.z() );
G4double m = (upcorner.z() - downcorner.z()) / (upcorner.x() - downcorner.x());
G4double q = (downcorner.z()*upcorner.x() - upcorner.z()*downcorner.x()) /
(upcorner.x() - downcorner.x());
G4double Zinter = (xd.z()*m*m + xd.x()*m +q)/(1+m*m) ;
if ( ((Zinter >= downcorner.z()) && (Zinter <=upcorner.z())) ||
((Zinter >= upcorner.z()) && (Zinter <=downcorner.z())) ) {
hownear = fabs(m*xd.x()-xd.z()+q)/sqrt(1+m*m);
return hownear;
} else {
hownear = min ( (xd-upcorner).mag() , (xd-downcorner).mag() );
return hownear;
}
return hownear;
}
// Add by L. Broglia
// Verify this function
G4Vector3D G4FConicalSurface::SurfaceNormal( const G4Point3D& p ) const
{
// return the Normal unit vector to the G4ConicalSurface at a point p
// on (or nearly on) the G4ConicalSurface
G4Vector3D s = p - origin;
G4double smag = s.mag2();
G4Vector3D s = p - origin;
G4double da = s * Position.GetAxis();
G4double r = sqrt( s*s - da*da);
G4double z = tan_angle * r;
// if the point happens to be at the origin, calculate a unit vector Normal
// to the axis, with zero z component
if ( smag == 0.0 )
{
G4double ax = Position.GetAxis().x();
G4double ay = Position.GetAxis().y();
G4double ap = sqrt( ax * ax + ay * ay );
if (Position.GetAxis().z() < 0)
z = -z;
if ( ap == 0.0 )
return G4Vector3D( 1.0, 0.0, 0.0 );
else
return G4Vector3D( ay / ap, -ax / ap, 0.0 );
}
G4Vector3D n(p.x(), p.y(), z);
n = n.unit();
if( !sameSense )
n = -n;
// otherwise do the calculation of the Normal to the conical surface
else
{
G4double l = s * Position.GetAxis();
s = s*(1/smag);
G4Vector3D q = origin + l * Position.GetAxis();
G4Vector3D v = p - q;
G4double sl = v.mag2() *
sin( atan2((large_radius - small_radius), length) );
G4Vector3D n = v - sl * s;
G4double nmag = n.mag2();
if ( nmag != 0.0 )
n=n*(1/nmag);
return n;
}
return n;
}
// Add by L. Broglia
int G4FConicalSurface::Inside ( const G4Vector3D& x ) const
{
// Return 0 if point x is outside G4ConicalSurface, 1 if Inside.
// Outside means that the distance to the G4ConicalSurface would be negative.
// Use the HowNear function to calculate this distance.
if ( HowNear( x ) >= -0.5*kCarTolerance )
return 1;
else
return 0;
}
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4FCylindricalSurface.cc,v 2.14 1998/12/10 17:26:42 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4FCylindricalSurface.cc,v 1.8 1999/05/27 10:44:55 japost Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
/* /usr/local/gismo/repo/geometry/FG4Cylinder.cc,v 1.1 1992/10/27 22:02:29 alanb Exp */
// File: FG4Cylinder.cc
@@ -29,6 +29,7 @@
#include "G4Sort.hh"
G4FCylindricalSurface::G4FCylindricalSurface( const G4Point3D& o,
const G4Vector3D& a,
const G4double r,
@@ -39,11 +40,11 @@ G4FCylindricalSurface::G4FCylindricalSurface( const G4Point3D& o,
// radius r, and length l
G4Vector3D dir(1,1,1);
Position.Init(dir, a, o);
origin = o;
origin = o;
radius = r;
// Require length to be positive or zero
// if ( l > 0.0 )
if ( l >= 0.0 )
length = l;
else
@@ -66,7 +67,6 @@ G4FCylindricalSurface::G4FCylindricalSurface( const G4Point3D& o,
radius = 0.0;
}
}
@@ -137,150 +137,114 @@ void G4FCylindricalSurface::CalcBBox()
int G4FCylindricalSurface::Intersect( const G4Ray& ry )
{
// Distance along a Ray (straight line with G4ThreeVec) to leave or enter
// a G4CylindricalSurface. The input variable which_way should be set
// to +1 to indicate leaving a G4CylindricalSurface, -1 to indicate
// entering a G4CylindricalSurface.
// p is the point of intersection of the Ray with the G4CylindricalSurface.
// If the G4Vector3D of the Ray is opposite to that of the Normal to
// the G4CylindricalSurface at the intersection point, it will not leave
// the G4CylindricalSurface.
// Similarly, if the G4Vector3D of the Ray is along that of the Normal
// to the G4CylindricalSurface at the intersection point, it will not enter
// the G4CylindricalSurface.
// This method is called by all finite shapes sub-classed to
// G4CylindricalSurface.
// Use the virtual function table to check if the intersection point
// is within the boundary of the finite shape.
// A negative result means no intersection.
// If no valid intersection point is found, set the distance
// and intersection point to large numbers.
// This function count the number of intersections of a
// bounded cylindrical surface by a ray.
// At first, calculates the intersections with the infinite
// cylindrical surfsace. After, count the intersections within the
// finite cylindrical surface boundaries, and set "distance" to the
// closest distance from the start point to the nearest intersection
// If the point is on the surface it returns or the intersection with
// the opposite surface or kInfinity
// int which_way = -1;
//Originally a parameter.Read explanation above.
int which_way=1;
if(!Inside(ry.GetStart()))
which_way = -1;
distance = FLT_MAXX;
G4Vector3D lv ( FLT_MAXX, FLT_MAXX, FLT_MAXX );
closest_hit = lv;
// If no intersection is founded, set distance = kInfinity and
// return 0
// Origin and G4Vector3D unit vector of Ray.
G4Vector3D x = ry.GetStart();
distance = kInfinity;
closest_hit = PINFINITY;
// origin and direction of the ray
G4Point3D x = ry.GetStart();
G4Vector3D dhat = ry.GetDir();
// Axis unit vector of the G4CylindricalSurface.
G4Vector3D ahat = GetAxis();
int isoln = 0,
maxsoln = 2;
// array of solutions in distance along the Ray
// cylinder axis
G4Vector3D ahat = Position.GetAxis();
// array of solutions in distance along the ray
G4double s[2];
s[0] = -1.0;
s[1] = -1.0 ;
s[0]=-1.0;
s[1]=-1.0;
// calculate the two solutions (quadratic equation)
G4Vector3D d = x - GetOrigin();
G4double radiu = GetRadius();
//quit with no intersection if the radius of the G4CylindricalSurface is zero
// if ( radiu <= 0.0 )
// return 0;
G4double dsq = d * d;
G4double da = d * ahat;
G4double dasq = da * da;
G4double rsq = radiu * radiu;
G4double qsq = dsq - dasq;
G4double dira = dhat * ahat;
G4double a = 1.0 - dira * dira;
// calculate the two intersections (quadratic equation)
G4Vector3D gamma = x - Position.GetLocation();
if ( a <= 0.0 )
return 0;
G4double b = 2. * ( d * dhat - da * dira );
G4double c = rsq - qsq;
G4double radical = b * b + 4. * a * c;
G4double ga = gamma * ahat;
G4double da = dhat * ahat;
G4double A = da * da - dhat * dhat;
G4double B = 2 * ( -gamma * dhat + ga * da );
G4double C = -gamma * gamma + ga * ga + radius * radius ;
G4double radical = B * B - 4.0 * A * C;
if ( radical < 0.0 )
// no intersection
return 0;
G4double root = sqrt( radical );
s[0] = ( - b + root ) / ( 2. * a );
s[1] = ( - b - root ) / ( 2. * a );
// order the possible solutions by increasing distance along the Ray
// (G4Sorting routines are in support/G4Sort.h)
G4Sort_double( s, isoln, maxsoln-1 );
// now loop over each positive solution, keeping the first one (smallest
// distance along the Ray) which is within the boundary of the sub-shape
// and which also has the correct G4Vector3D with respect to the Normal to
// the G4CylindricalSurface at the intersection point
for ( isoln = 0; isoln < maxsoln; isoln++ )
else
{
if ( s[isoln] >= kCarTolerance*0.5 )
{
if ( s[isoln] >= FLT_MAXX ) // quit if too large
return 0;
distance = s[isoln];
closest_hit = ry.GetPoint( distance );
G4double tmp = dhat * (Normal( closest_hit ));
// L. Broglia
// After this test, somtimes we have the distance,
// sometimes we have the squared distance
// For the moment, I delete this test
//if ((tmp * which_way) >= 0.0 )
//if ( WithinBoundary( closest_hit ) == 1 )
distance = distance*distance;
return 1;
}
else
if ( s[isoln] >= -kCarTolerance*0.5 )
{
// the point is on the surface
distance = 0;
return 1;
}
G4double root = sqrt( radical );
s[0] = ( - B + root ) / ( 2. * A );
s[1] = ( - B - root ) / ( 2. * A );
}
// get here only if there was no solution within the boundary, Reset
// distance and intersection point to large numbers
distance = FLT_MAXX;
closest_hit = lv;
return 0;
// validity of the solutions
// the hit point must be into the bounding box of the cylindrical surface
G4Point3D p0 = x + s[0]*dhat;
G4Point3D p1 = x + s[1]*dhat;
if( !GetBBox()->Inside(p0) )
s[0] = kInfinity;
if( !GetBBox()->Inside(p1) )
s[1] = kInfinity;
// now loop over each positive solution, keeping the first one (smallest
// distance along the Ray) which is within the boundary of the sub-shape
G4int nbinter = 0;
distance = kInfinity;
for ( G4int i = 0; i < 2; i++ )
{
if(s[i] < kInfinity) {
if ( s[i] >= kCarTolerance*0.5 ) {
nbinter ++;
// real intersection
// set the distance if it is the smallest
if( distance > s[i]*s[i]) {
distance = s[i]*s[i];
}
}
}
}
return nbinter;
}
G4double G4FCylindricalSurface::HowNear( const G4Vector3D& x ) const
{
// Distance from the point x to the infinite G4CylindricalSurface.
// The distance will be positive if the point is Inside the
// G4FCylindricalSurface, negative if the point is outside.
// Shortest distance from the point x to the G4FCylindricalSurface.
// The distance will be always positive
G4Vector3D d = x - origin;
G4double dA = d * Position.GetAxis();
G4double rad = sqrt( d.mag2() - dA*dA );
G4double hownear;
G4double hownear;
G4Vector3D upcorner = G4Vector3D ( radius, 0 , origin.z()+length);
G4Vector3D downcorner = G4Vector3D ( radius, 0 , origin.z());
G4Vector3D xd;
xd = G4Vector3D ( sqrt ( x.x()*x.x() + x.y()*x.y() ) , 0 , x.z() );
G4double Zinter = (xd.z()) ;
if ( ((Zinter >= downcorner.z()) && (Zinter <=upcorner.z())) ) {
hownear = fabs( radius - xd.x() );
} else {
hownear = min ( (xd-upcorner).mag() , (xd-downcorner).mag() );
}
if(dA > length)
hownear = length - dA;
else if(dA < 0)
hownear = dA;
else
hownear = radius - rad;
return hownear;
}
int G4FCylindricalSurface::WithinBoundary( const G4Vector3D& x ) const
{
// return 1 if point x is within the boundaries of the G4FCylindricalSurface
@@ -315,6 +279,9 @@ G4Vector3D G4FCylindricalSurface::SurfaceNormal( const G4Point3D& p ) const
if ( nmag != 0.0 )
n = n * (1/nmag);
if( !sameSense )
n = -n;
return n;
}
+96 -70
View File
@@ -5,10 +5,16 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4FPlane.cc,v 2.30 1998/12/11 08:29:07 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4FPlane.cc,v 1.6 1999/06/08 11:22:07 sgiani Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
// Corrections by S.Giani:
// - The constructor using iVec now properly stores both the internal and
// external boundaries in the bounds vector.
// - Proper initialization of sameSense in both the constructors.
// - Addition of third argument (sense) in the second constructor to ensure
// consistent setting of the normal in all the client code.
// - Proper use of the tolerance in the Intersect function.
#include "G4FPlane.hh"
#include "G4CompositeCurve.hh"
@@ -25,15 +31,17 @@ G4FPlane::G4FPlane( const G4Vector3D& direction,
G4Point3D Pt2 = Pt0 + axis.cross(direction);
G4Ray::CalcPlane3Pts( Pl, Pt0, Pt1, Pt2 );
active = 1;
sameSense = 1;
CalcNormal();
distance = kInfinity;
Type = 1;
}
G4FPlane::G4FPlane(const G4Point3DVector* pVec, const G4Point3DVector* iVec)
G4FPlane::G4FPlane(const G4Point3DVector* pVec, const G4Point3DVector* iVec, int
sense)
: pplace( (*pVec)[0]-(*pVec)[1], // direction
((*pVec)[pVec->length()-1]-(*pVec)[0])
.cross((*pVec)[0]-(*pVec)[1]), // axis
@@ -46,18 +54,38 @@ G4FPlane::G4FPlane(const G4Point3DVector* pVec, const G4Point3DVector* iVec)
G4CompositeCurve* polygon;
projectedBoundary = new G4SurfaceBoundary;
sameSense = sense;
// Outer boundary
polygon= new G4CompositeCurve(*pVec);
for (G4int i=0; i< polygon->GetSegments().length(); i++)
polygon->GetSegments()[i]->SetSameSense(sameSense);
bounds.insert(polygon);
// Eventual inner boundary
if (iVec)
{
polygon= new G4CompositeCurve(*iVec);
for (G4int i=0; i< polygon->GetSegments().length(); i++)
polygon->GetSegments()[i]->SetSameSense(sameSense);
bounds.insert(polygon);
}
SetBoundaries(&bounds);
// Set sense for boundaries
for (G4int j=0; j< bounds.length(); j++)
bounds[j]->SetSameSense(sameSense);
SetBoundaries(&bounds);
CalcNormal();
IsConvex();
distance = kInfinity;
@@ -147,10 +175,12 @@ int G4FPlane::IsConvex()
int G4FPlane::Intersect(const G4Ray& rayref)
{
Intersected =1;
// This function count the number of intersections of a
// bounded surface by a ray.
// closest_hit = pplace.EvaluateIntersection(rayref);
// L. Broglia : before in G4Placement
// Find the intersection with the infinite plane
Intersected =1;
// s is solution, line is p + tq, n is G4Plane Normal, r is point on G4Plane
// all parameters are pointers to arrays of three elements
@@ -170,9 +200,9 @@ int G4FPlane::Intersect(const G4Ray& rayref)
b = norm.x() * dirx + norm.y() * diry + norm.z() * dirz;
if ( fabs(b) < 0.001 )
if ( fabs(b) < perMillion )
{
// G4cout << "\nLine is parallel to G4Plane.No Hit.";
// G4cout << "\nLine is parallel to G4Plane.No Hit.";
}
else
{
@@ -192,12 +222,21 @@ int G4FPlane::Intersect(const G4Ray& rayref)
solx = startx + t * dirx;
soly = starty + t * diry;
solz = startz + t * dirz;
if(((dirx < 0 && solx < startx)||(dirx >= 0 && solx >= startx))&&
((diry < 0 && soly < starty)||(diry >= 0 && soly >= starty))&&
((dirz < 0 && solz < startz)||(dirz >= 0 && solz >= startz)))
hitpoint= G4Point3D(solx,soly, solz);
// solve tolerance problem
if( (t*dirx >= -kCarTolerance/2) && (t*dirx <= kCarTolerance/2) )
solx = startx;
if( (t*diry >= -kCarTolerance/2) && (t*diry <= kCarTolerance/2) )
soly = starty;
if( (t*dirz >= -kCarTolerance/2) && (t*dirz <= kCarTolerance/2) )
solz = startz;
if( ( (dirx < 0 && solx < startx)||(dirx >= 0 && solx >= startx) ) &&
( (diry < 0 && soly < starty)||(diry >= 0 && soly >= starty) ) &&
( (dirz < 0 && solz < startz)||(dirz >= 0 && solz >= startz) ) )
hitpoint= G4Point3D(solx, soly, solz);
}
// closest_hit is a public Point3D in G4Surface
@@ -205,70 +244,59 @@ int G4FPlane::Intersect(const G4Ray& rayref)
if(closest_hit.x() == kInfinity)
{
// no hit
active=0;
Distance(kInfinity);
return 0;
}
else
{
Distance( RayStart.distance2(closest_hit) );
if(distance < kCarTolerance*0.5)
{
// the point is on the surface
active=1; //active=0;
Distance(0); //Distance(kInfinity);
return 1; //return 0;
}
// calculate the squared distance from the point to the intersection
// and set it in the distance data member (all clients know they have
// to take the sqrt)
Distance( RayStart.distance2(closest_hit) );
G4Point3D hit = closest_hit;
// now, we have to verify that the hit point founded
// is included into the G4FPlane boundaries
// project the hit to the xy plane,
// with the same projection that took the boundary
// into projectedBoundary
G4Point3D projectedHit= pplace.GetToPlacementCoordinates() * hit;
G4Point3D projectedHit= pplace.GetToPlacementCoordinates() * closest_hit;
// test ray from the hit on the xy plane
G4Ray testRay( projectedHit, G4Vector3D(1, 0.01, 0) );
// check if it intersects the boundary
G4Ray testRay(projectedHit, G4Vector3D(1, 0, 0));
G4int nbinter = projectedBoundary->IntersectRay2D(testRay);
G4CurveRayIntersection is;
projectedBoundary->IntersectRay2D(testRay, is);
// if not, we are outside
if ( is.GetDistance() >= kInfinity )
// If this number is par, it`s signify that the projected point
// is outside the projected surface, so the hit point is outside
// the bounded surface
if(nbinter&1)
{
// the intersection point is into the boundaries
// check if the intersection point is on the surface
if(distance <= kCarTolerance*0.5*kCarTolerance*0.5)
{
// the point is on the surface, set the distance to 0
Distance(0);
}
else
{
// the point is outside the surface
}
return 1 ;
}
else
{
// the intersection point is out the boundaries
// it is not a real intersection
active=0;
Distance(kInfinity);
return 0;
}
// if yes, we have to check on which side of the intersected
// curve the hit lies
G4Vector3D tangent;
projectedBoundary->Tangent(is, tangent);
// L. Broglia
// Now replace tangent into the pplace
tangent = pplace.GetFromPlacementCoordinates() * tangent;
// (let's assume that the tangent is defined)
// criterion for outside: (d x t).z() < 0
// d = hit - is & t = tangent
G4Point3D Is = pplace.GetFromPlacementCoordinates() * (is.GetPoint());
G4Vector3D d = hit - Is;
if ( (d.cross(tangent)).z() < 0 )
{
active=0;
Distance(kInfinity);
return 0;
}
// a real intersection point
return 1;
}
}
@@ -278,7 +306,9 @@ G4double G4FPlane::ClosestDistanceToPoint(const G4Point3D& Pt)
// Calculates signed distance of point Pt to G4Plane Pl
// Be careful, the equation of the plane is :
// ax + by + cz = d
return ( Pt.x()*Pl.a + Pt.y()*Pl.b + Pt.z()*Pl.c - Pl.d);
G4double dist = Pt.x()*Pl.a + Pt.y()*Pl.b + Pt.z()*Pl.c - Pl.d;
return dist;
}
@@ -290,15 +320,11 @@ void G4FPlane::InitBounded()
surfaceBoundary.Project( pplace.GetToPlacementCoordinates() );
}
G4double G4FPlane::HowNear( const G4Vector3D& x ) const
G4double G4FPlane::HowNear( const G4Vector3D& Pt ) const
{
const G4Point3D Pt = x;
//G4double d = ClosestDistanceToPoint(Pt);
//return d;
return ( Pt.x()*Pl.a + Pt.y()*Pl.b + Pt.z()*Pl.c - Pl.d);
G4double hownear = Pt.x()*Pl.a + Pt.y()*Pl.b + Pt.z()*Pl.c - Pl.d;
return hownear;
}
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Hyperbola.cc,v 2.8 1998/10/29 17:49:38 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4Hyperbola.cc,v 1.1 1999/01/07 16:07:43 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4Hyperbola.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4KnotVector.cc,v 2.4 1998/10/20 16:33:51 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4KnotVector.cc,v 1.1 1999/01/07 16:07:43 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4KnotVector.hh"
+12 -5
View File
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Line.cc,v 2.6 1998/12/15 10:33:55 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4Line.cc,v 1.3 1999/05/20 09:35:35 sgiani Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4Line.hh"
@@ -17,15 +17,22 @@ G4Curve* G4Line::Project(const G4Transform3D& tr)
{
G4Vector3D newDir= tr*dir;
if (abs(newDir.x())+abs(newDir.y()) < kCarTolerance)
return 0;
if (abs(newDir.x())+abs(newDir.y()) < kCarTolerance){
newDir.setX(kCarTolerance);
newDir.setY(kCarTolerance);
};
G4Point3D newPnt= tr*pnt;
newDir.setZ(0);
newPnt.setZ(0);
G4Line* r= new G4Line();
r->Init(newDir, newPnt);
// L. Broglia : terrible mistake !!!!
//r->Init(newDir, newPnt);
r->Init(newPnt, newDir);
r->SetBounds(GetPStart(), GetPEnd());
return r;
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NISTStepReader.cc,v 2.4 1998/11/04 14:49:56 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4NISTStepReader.cc,v 1.1 1999/01/07 16:07:44 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4NISTStepReader.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4OsloMatrix.cc,v 2.1 1998/10/20 16:33:53 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4OsloMatrix.cc,v 1.1 1999/01/07 16:07:44 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4OsloMatrix.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Parabola.cc,v 2.8 1998/10/29 17:49:38 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4Parabola.cc,v 1.1 1999/01/07 16:07:44 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4Parabola.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4PlacedSolid.cc,v 2.2 1998/10/29 17:49:39 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4PlacedSolid.cc,v 1.1 1999/01/07 16:07:44 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4PlacedSolid.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4PointRat.cc,v 2.2 1998/10/20 16:33:56 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4PointRat.cc,v 1.1 1999/01/07 16:07:45 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
//
// Modif 8 oct 98 : A.Floquet
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ProjectedSurface.cc,v 2.3 1998/10/20 16:33:56 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4ProjectedSurface.cc,v 1.2 1999/05/20 17:39:22 japost Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4ProjectedSurface.hh"
@@ -90,10 +90,10 @@ void G4ProjectedSurface::CalcBBox()
// Loop to search the whole control point mesh
// for the minimum and maximum values for x and y.
G4double box_minx,box_miny,box_maxx,box_maxy;
box_minx = INFINITY;
box_miny = INFINITY;
box_maxx = -INFINITY;
box_maxy = -INFINITY;
box_minx = kInfinity;
box_miny = kInfinity;
box_maxx = -kInfinity;
box_maxy = -kInfinity;
G4double bminx,bminy,bmaxx,bmaxy,tmpx,tmpy;
bminx = box_minx; bminy = box_miny;
+2 -2
View File
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Ray.cc,v 2.5 1998/10/29 17:49:40 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4Ray.cc,v 1.1 1999/01/07 16:07:45 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4Ray.hh"
#include "G4PointRat.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4RectangularTrimmedSurface.cc,v 2.3 1998/10/20 16:33:58 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4RectangularTrimmedSurface.cc,v 1.1 1999/01/07 16:07:45 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "SdaiCONFIG_CONTROL_DESIGN.h"
#include "G4RectangularTrimmedSurface.hh"
+2 -2
View File
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Sort.cc,v 2.1 1998/10/20 16:33:59 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4Sort.cc,v 1.1 1999/01/07 16:07:46 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
// File: G4Sort.cc
// Author: Alan Breakstone
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4SphericalSurface.cc,v 2.8 1998/11/11 11:22:03 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4SphericalSurface.cc,v 1.1 1999/01/07 16:07:46 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
/* $Header: /private/Net/unixhub/u1/ea/liml/gismo/gismo-0.2/geometry/RCS/G4SphericalSurface.cc,v 1.10 1992/08 */
// File: G4SphericalSurface.cc
@@ -125,7 +125,7 @@ G4double G4Surface::ClosestDistanceToPoint(const G4Point3D& Pt)
// Be carreful ! pointdistance is the squared distance
return sqrt(pointDistance);
// G4double PointDistance=INFINITY;
// G4double PointDistance=kInfinity;
// G4double TmpDistance=0;
// PointDistance = OuterBoundary->ClosestDistanceToPoint(Pt);
// TmpDistance =0;
@@ -138,7 +138,7 @@ G4double G4Surface::ClosestDistanceToPoint(const G4Point3D& Pt)
//G4double G4Boundary::ClosestDistanceToPoint(const G4ThreeVec& Pt)
//{
// G4double PointDistance = INFINITY;
// G4double PointDistance = kInfinity;
// G4double TmpDistance = 0;
// for(int a =0; a < NumberOfPoints;a++)
// {
@@ -98,7 +98,7 @@ G4SurfaceBoundary* G4SurfaceBoundary::Project(const G4Transform3D& tr)
return lof;
}
/*
void G4SurfaceBoundary::IntersectRay2D(const G4Ray& ray,
G4CurveRayIntersection& is)
{
@@ -116,6 +116,26 @@ void G4SurfaceBoundary::IntersectRay2D(const G4Ray& ray,
lastIntersection= is;
}
*/
G4int G4SurfaceBoundary::IntersectRay2D(const G4Ray& ray)
{
G4int nbinter = 0, temp = 0;
for (G4int i=0; i < bounds.entries(); i++)
{
G4Curve& c = *bounds.at(i);
temp = c.IntersectRay2D(ray);
// test if the point is on the surface boundary
if( temp==999 )
return 1;
else
nbinter +=temp;
}
return nbinter;
}
G4bool G4SurfaceBoundary::Tangent(G4CurvePoint& cp, G4Vector3D& v)
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4SurfaceList.cc,v 2.2 1998/10/20 16:34:01 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4SurfaceList.cc,v 1.1 1999/01/07 16:07:47 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4SurfaceList.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ThreeMat.cc,v 2.2 1998/10/20 16:34:01 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4ThreeMat.cc,v 1.1 1999/01/07 16:07:47 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
/* G4ThreeMat.cc,v 1.5 1993/08/02 22:21:27 atwood Exp */
// File: G4ThreeMat.cc
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ToroidalSurface.cc,v 2.7 1998/10/29 17:49:41 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4ToroidalSurface.cc,v 1.1 1999/01/07 16:07:48 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
#include "G4ToroidalSurface.hh"