G4BREPSolidPolyhedra Class Reference

#include <G4BREPSolidPolyhedra.hh>

Inheritance diagram for G4BREPSolidPolyhedra:

G4BREPSolid G4VSolid

Public Member Functions

 G4BREPSolidPolyhedra (const G4String &name, G4double phi1, G4double dphi, G4int sides, G4int num_z_planes, G4double z_start, G4double z_values[], G4double RMIN[], G4double RMAX[])
 ~G4BREPSolidPolyhedra ()
void Initialize ()
EInside Inside (register const G4ThreeVector &Pt) const
G4ThreeVector SurfaceNormal (const G4ThreeVector &) const
G4double DistanceToIn (const G4ThreeVector &) const
G4double DistanceToIn (register const G4ThreeVector &Pt, register const G4ThreeVector &V) const
G4double DistanceToOut (register const G4ThreeVector &Pt, register const G4ThreeVector &V, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
G4double DistanceToOut (const G4ThreeVector &) const
G4VSolidClone () const
std::ostream & StreamInfo (std::ostream &os) const
G4PolyhedronCreatePolyhedron () const
void Reset () const
 G4BREPSolidPolyhedra (__void__ &)
 G4BREPSolidPolyhedra (const G4BREPSolidPolyhedra &rhs)
G4BREPSolidPolyhedraoperator= (const G4BREPSolidPolyhedra &rhs)

Data Structures

struct  G4BREPPolyhedraParams

Detailed Description

Definition at line 59 of file G4BREPSolidPolyhedra.hh.


Constructor & Destructor Documentation

G4BREPSolidPolyhedra::G4BREPSolidPolyhedra ( const G4String name,
G4double  phi1,
G4double  dphi,
G4int  sides,
G4int  num_z_planes,
G4double  z_start,
G4double  z_values[],
G4double  RMIN[],
G4double  RMAX[] 
)

Definition at line 71 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolid::active, G4endl, G4Exception(), and JustWarning.

Referenced by Clone().

00080   : G4BREPSolid(name)
00081 {    
00082   // Store the original parameters, to be used in visualisation
00083   // Note radii are not scaled because this BREP uses the radius of the
00084   // circumscribed circle and also graphics_reps/G4Polyhedron uses the
00085   // radius of the circumscribed circle.
00086   
00087   // Save contructor parameters
00088   //
00089   constructorParams.start_angle    = start_angle;
00090   constructorParams.opening_angle  = opening_angle;
00091   constructorParams.sides          = sides;
00092   constructorParams.num_z_planes   = num_z_planes;
00093   constructorParams.z_start        = z_start;
00094   constructorParams.z_values       = 0;
00095   constructorParams.RMIN           = 0;
00096   constructorParams.RMAX           = 0;
00097   
00098   if( num_z_planes > 0 )
00099   {               
00100     constructorParams.z_values       = new G4double[num_z_planes];
00101     constructorParams.RMIN           = new G4double[num_z_planes];
00102     constructorParams.RMAX           = new G4double[num_z_planes];
00103     for( G4int idx = 0; idx < num_z_planes; ++idx )
00104     {
00105       constructorParams.z_values[idx] = z_values[idx];
00106       constructorParams.RMIN[idx]     = RMIN[idx];
00107       constructorParams.RMAX[idx]     = RMAX[idx];      
00108     }
00109   }
00110 
00111   // z_values[0]  should be equal to z_start, for consistency 
00112   //   with what the constructor does.
00113   // Otherwise the z_values that are shifted by (z_values[0] - z_start) , 
00114   //   because z_values are only used in the form 
00115   //   length = z_values[d+1] - z_values[d];         // JA Apr 2, 97
00116   
00117   if( z_values[0] != z_start )
00118   {
00119     std::ostringstream message;
00120     message << "Construction Error. z_values[0] must be equal to z_start!"
00121             << G4endl
00122             << "        Wrong solid parameters: "
00123             << " z_values[0]= " << z_values[0] << " is not equal to "
00124             << " z_start= " << z_start << ".";
00125     G4Exception( "G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
00126                  "GeomSolids1002", JustWarning, message );
00127     if( num_z_planes <= 0 )  { constructorParams.z_values = new G4double[1]; }
00128     constructorParams.z_values[0]= z_start; 
00129   }
00130 
00131   active=1;
00132   InitializePolyhedra(); 
00133 }

G4BREPSolidPolyhedra::~G4BREPSolidPolyhedra (  ) 

Definition at line 148 of file G4BREPSolidPolyhedra.cc.

00149 {
00150   if( constructorParams.num_z_planes > 0 )
00151   {
00152     delete [] constructorParams.z_values;
00153     delete [] constructorParams.RMIN;
00154     delete [] constructorParams.RMAX;
00155   }  
00156 }

G4BREPSolidPolyhedra::G4BREPSolidPolyhedra ( __void__ &   ) 

Definition at line 135 of file G4BREPSolidPolyhedra.cc.

00136   : G4BREPSolid(a)
00137 {
00138   constructorParams.start_angle    = 0.;
00139   constructorParams.opening_angle  = 0.;
00140   constructorParams.sides          = 0;
00141   constructorParams.num_z_planes   = 0;
00142   constructorParams.z_start        = 0.;
00143   constructorParams.z_values = 0;
00144   constructorParams.RMIN = 0;
00145   constructorParams.RMAX = 0;
00146 }

G4BREPSolidPolyhedra::G4BREPSolidPolyhedra ( const G4BREPSolidPolyhedra rhs  ) 

Definition at line 158 of file G4BREPSolidPolyhedra.cc.

References constructorParams.

00159   : G4BREPSolid(rhs)
00160 {
00161   constructorParams.start_angle    = rhs.constructorParams.start_angle;
00162   constructorParams.opening_angle  = rhs.constructorParams.opening_angle;
00163   constructorParams.sides          = rhs.constructorParams.sides;
00164   constructorParams.num_z_planes   = rhs.constructorParams.num_z_planes;
00165   constructorParams.z_start        = rhs.constructorParams.z_start;
00166   constructorParams.z_values       = 0;
00167   constructorParams.RMIN           = 0;
00168   constructorParams.RMAX           = 0;
00169   G4int num_z_planes = constructorParams.num_z_planes;
00170   if( num_z_planes > 0 )
00171   {               
00172     constructorParams.z_values       = new G4double[num_z_planes];
00173     constructorParams.RMIN           = new G4double[num_z_planes];
00174     constructorParams.RMAX           = new G4double[num_z_planes];
00175     for( G4int idx = 0; idx < num_z_planes; ++idx )
00176     {
00177       constructorParams.z_values[idx] = rhs.constructorParams.z_values[idx];
00178       constructorParams.RMIN[idx]     = rhs.constructorParams.RMIN[idx];
00179       constructorParams.RMAX[idx]     = rhs.constructorParams.RMAX[idx];      
00180     }
00181   }
00182 
00183   InitializePolyhedra();
00184 }


Member Function Documentation

G4VSolid * G4BREPSolidPolyhedra::Clone (  )  const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 1340 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolidPolyhedra().

01341 {
01342   return new G4BREPSolidPolyhedra(*this);
01343 }

G4Polyhedron * G4BREPSolidPolyhedra::CreatePolyhedron (  )  const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 1517 of file G4BREPSolidPolyhedra.cc.

01518 {
01519   return new G4PolyhedronPgon( constructorParams.start_angle, 
01520                                constructorParams.opening_angle, 
01521                                constructorParams.sides, 
01522                                constructorParams.num_z_planes, 
01523                                constructorParams.z_values,
01524                                constructorParams.RMIN,
01525                                constructorParams.RMAX);
01526 }

G4double G4BREPSolidPolyhedra::DistanceToIn ( register const G4ThreeVector Pt,
register const G4ThreeVector V 
) const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 1106 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolid::Intersect(), G4VSolid::kCarTolerance, G4BREPSolid::nb_of_surfaces, Reset(), G4BREPSolid::ShortestDistance, G4Surface::SurfaceNormal(), G4BREPSolid::SurfaceVec, and G4BREPSolid::TestSurfaceBBoxes().

01108 {
01109   // Calculates the distance from a point outside the solid
01110   // to the solid`s boundary along a specified direction vector.
01111   //
01112   // Note : Intersections with boundaries less than the 
01113   //        tolerance must be ignored if the direction 
01114   //        is away from the boundary
01115   
01116   G4int a;
01117   
01118   // Set the surfaces to active again
01119   //
01120   Reset();
01121   
01122   const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25;    
01123   G4Vector3D Pttmp(Pt);
01124   G4Vector3D Vtmp(V);   
01125   G4Ray r(Pttmp, Vtmp);
01126 
01127   // Test if the bounding box of each surface is intersected
01128   // by the ray. If not, the surface become deactive.
01129   //
01130   TestSurfaceBBoxes(r);
01131   
01132   ShortestDistance = kInfinity;
01133   
01134   for(a=0; a< nb_of_surfaces; a++)
01135   {
01136     if( SurfaceVec[a]->IsActive() )
01137     {
01138       // test if the ray intersect the surface
01139       //
01140       if( SurfaceVec[a]->Intersect(r) )
01141       {
01142         G4double surfDistance = SurfaceVec[a]->GetDistance();
01143         
01144         // if more than 1 surface is intersected,
01145         // take the nearest one
01146         //
01147         if( surfDistance < ShortestDistance )
01148         {
01149           if( surfDistance > sqrHalfTolerance )
01150           {
01151             ShortestDistance = surfDistance;
01152           }
01153           else
01154           {
01155             // the point is within the boundary
01156             // ignore it if the direction is away from the boundary
01157             //    
01158             G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp);
01159 
01160             if( (Norm * Vtmp) < 0 )
01161             {
01162               ShortestDistance = surfDistance;
01163 //              ShortestDistance = surfDistance==0
01164 //                                 ? sqrHalfTolerance
01165 //                                 : surfDistance;
01166             }
01167           }
01168         }
01169       }
01170     }
01171   }
01172 
01173   // Be careful !
01174   // SurfaceVec->Distance is in fact the squared distance
01175   //
01176   if(ShortestDistance != kInfinity)
01177   {
01178     return std::sqrt(ShortestDistance);
01179   }
01180   else  // no intersection
01181   {
01182     return kInfinity;
01183   }
01184 }

G4double G4BREPSolidPolyhedra::DistanceToIn ( const G4ThreeVector  )  const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 1057 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolid::nb_of_surfaces, Reset(), and G4BREPSolid::SurfaceVec.

01058 {
01059   // Calculates the shortest distance ("safety") from a point
01060   // outside the solid to any boundary of this solid.
01061   // Return 0 if the point is already inside.
01062 
01063   G4double *dists = new G4double[nb_of_surfaces];
01064   G4int a;
01065 
01066   // Set the surfaces to active again
01067   //
01068   Reset();
01069    
01070   // compute the shortest distance of the point to each surfaces
01071   // Be careful : it's a signed value
01072   //
01073   for(a=0; a< nb_of_surfaces; a++)  
01074     dists[a] = SurfaceVec[a]->HowNear(Pt);
01075      
01076   G4double Dist = kInfinity;
01077   
01078   // if dists[] is positive, the point is outside
01079   // so take the shortest of the shortest positive distances
01080   // dists[] can be equal to 0 : point on a surface
01081   // ( Problem with the G4FPlane : there is no inside and no outside...
01082   //   So, to test if the point is inside to return 0, utilize the Inside
01083   //   function. But I don`t know if it is really needed because dToIn is 
01084   //   called only if the point is outside )
01085   //
01086   for(a = 0; a < nb_of_surfaces; a++)
01087     if( std::fabs(Dist) > std::fabs(dists[a]) ) 
01088       //if( dists[a] >= 0)
01089       Dist = dists[a];
01090   
01091   delete[] dists;
01092 
01093   if(Dist == kInfinity)
01094   {
01095     // the point is inside the solid or on a surface
01096     //
01097     return 0;
01098   }
01099   else 
01100   {
01101     return std::fabs(Dist);
01102   }
01103 }

G4double G4BREPSolidPolyhedra::DistanceToOut ( const G4ThreeVector  )  const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 1285 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolid::nb_of_surfaces, Reset(), and G4BREPSolid::SurfaceVec.

01286 {
01287   // Calculates the shortest distance ("safety") from a point
01288   // inside the solid to any boundary of this solid.
01289   // Return 0 if the point is already outside.
01290 
01291   G4double *dists = new G4double[nb_of_surfaces];
01292   G4int a;
01293 
01294   // Set the surfaces to active again
01295   //
01296   Reset();
01297   
01298   // calculate the shortest distance of the point to each surfaces
01299   // Be careful : it's a signed value
01300   //
01301   for(a=0; a< nb_of_surfaces; a++)
01302   {
01303     dists[a] = SurfaceVec[a]->HowNear(Pt);
01304   }
01305 
01306   G4double Dist = kInfinity;
01307   
01308   // if dists[] is negative, the point is inside
01309   // so take the shortest of the shortest negative distances
01310   // dists[] can be equal to 0 : point on a surface
01311   // ( Problem with the G4FPlane : there is no inside and no outside...
01312   //   So, to test if the point is outside to return 0, utilize the Inside
01313   //   function. But I don`t know if it is really needed because dToOut is 
01314   //   called only if the point is inside )
01315 
01316   for(a = 0; a < nb_of_surfaces; a++)
01317   {
01318     if( std::fabs(Dist) > std::fabs(dists[a]) )
01319     {
01320       //if( dists[a] <= 0)
01321       Dist = dists[a];
01322     }
01323   }
01324   
01325   delete[] dists;
01326 
01327   if(Dist == kInfinity)
01328   {
01329     // the point is ouside the solid or on a surface
01330     //
01331     return 0;
01332   }
01333   else
01334   {
01335     // return Dist;
01336     return std::fabs(Dist);
01337   }
01338 }

G4double G4BREPSolidPolyhedra::DistanceToOut ( register const G4ThreeVector Pt,
register const G4ThreeVector V,
const G4bool  calcNorm = false,
G4bool validNorm = 0,
G4ThreeVector n = 0 
) const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 1187 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolid::Intersect(), G4VSolid::kCarTolerance, G4BREPSolid::nb_of_surfaces, Reset(), G4BREPSolid::ShortestDistance, G4BREPSolid::SurfaceVec, and G4BREPSolid::TestSurfaceBBoxes().

01192 {
01193   // Calculates the distance from a point inside the solid
01194   // to the solid`s boundary along a specified direction vector.
01195   // Return 0 if the point is already outside (even number of
01196   // intersections greater than the tolerance).
01197   //
01198   // Note : If the shortest distance to a boundary is less 
01199   //        than the tolerance, it is ignored. This allows
01200   //        for a point within a tolerant boundary to leave
01201   //        immediately
01202 
01203   G4int parity = 0;
01204 
01205   // Set the surfaces to active again
01206   //
01207   Reset();
01208 
01209   const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25;    
01210   G4Vector3D Ptv = Pt;
01211   G4int a;
01212 
01213   // I don`t understand this line
01214   //
01215   if(validNorm)
01216     *validNorm=false;
01217 
01218   G4Vector3D Pttmp(Pt);
01219   G4Vector3D Vtmp(V);   
01220   
01221   G4Ray r(Pttmp, Vtmp);
01222 
01223   // Test if the bounding box of each surface is intersected
01224   // by the ray. If not, the surface become deactive.
01225   //
01226   TestSurfaceBBoxes(r);
01227   
01228   ShortestDistance = kInfinity; // this is actually the square of the distance
01229  
01230   for(a=0; a< nb_of_surfaces; a++)
01231   {
01232     G4double surfDistance = SurfaceVec[a]->GetDistance();
01233     
01234     if(SurfaceVec[a]->IsActive())
01235     {
01236       G4int intersects = SurfaceVec[a]->Intersect(r);
01237 
01238       // test if the ray intersects the surface
01239       //
01240       if( intersects != 0 )
01241       {
01242         parity += 1;
01243 
01244         // if more than 1 surface is intersected, take the nearest one
01245         //
01246         if( surfDistance < ShortestDistance )
01247         {
01248           if( surfDistance > sqrHalfTolerance )
01249           {
01250             ShortestDistance = surfDistance;
01251           }
01252           else
01253           {
01254             // the point is within the boundary: ignore it
01255             //
01256             parity -= 1;
01257           }
01258         }
01259       }      
01260     }
01261   }
01262 
01263    G4double distance = 0.;
01264    
01265   // Be careful !
01266   // SurfaceVec->Distance is in fact the squared distance
01267   //
01268    // This condition was changed in order to give not zero answer
01269    // when particle is passing the border of two Touching Surfaces
01270    // and the distance to this surfaces is not zero.
01271    // parity is for the points on the boundary,
01272    // parity is counting only surfDistance<kCarTolerance/2. 
01273    //
01274    //  if((ShortestDistance != kInfinity) && (parity&1))
01275    //  
01276    //
01277    if((ShortestDistance != kInfinity) || (parity&1))
01278   {
01279     distance = std::sqrt(ShortestDistance);
01280   }
01281 
01282   return distance;
01283 }

void G4BREPSolidPolyhedra::Initialize (  )  [virtual]

Reimplemented from G4BREPSolid.

Definition at line 906 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolid::AxisBox, G4BREPSolid::Box, G4BREPSolid::CalcBBoxes(), G4BREPSolid::CheckSurfaceNormals(), G4BREPSolid::IsConvex(), and G4BREPSolid::ShortestDistance.

00907 {
00908   // Calc bounding box for solids and surfaces
00909   // Convert concave planes to convex
00910   //
00911   ShortestDistance=1000000;
00912   CheckSurfaceNormals();
00913   if(!Box || !AxisBox)
00914     IsConvex();
00915   
00916   CalcBBoxes();
00917 }

EInside G4BREPSolidPolyhedra::Inside ( register const G4ThreeVector Pt  )  const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 929 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolid::GetBBox(), G4Surface::GetDistance(), G4VSolid::kCarTolerance, kInside, kOutside, kSurface, G4BREPSolid::nb_of_surfaces, Reset(), G4BREPSolid::SurfaceVec, and G4BREPSolid::TestSurfaceBBoxes().

00930 {
00931   // This function find if the point Pt is inside, 
00932   // outside or on the surface of the solid
00933 
00934   const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25;    
00935 
00936   G4Vector3D v(1, 0, 0.01);
00937   G4Vector3D Pttmp(Pt);
00938   G4Vector3D Vtmp(v);
00939   G4Ray r(Pttmp, Vtmp);
00940   
00941   // Check if point is inside the Polyhedra bounding box
00942   //
00943   if( !GetBBox()->Inside(Pttmp) )
00944   {
00945     return kOutside;
00946   }
00947 
00948   // Set the surfaces to active again
00949   //
00950   Reset();
00951   
00952   // Test if the bounding box of each surface is intersected
00953   // by the ray. If not, the surface is deactivated.
00954   //
00955   TestSurfaceBBoxes(r);
00956   
00957   G4int hits=0, samehit=0;
00958 
00959   for(G4int a=0; a < nb_of_surfaces; a++)
00960   {
00961     G4Surface* surface = SurfaceVec[a];
00962 
00963     if(surface->IsActive())
00964     {
00965       // count the number of intersections.
00966       // if this number is odd, the start of the ray is
00967       // inside the volume bounded by the surfaces, so 
00968       // increment the number of intersection by 1 if the 
00969       // point is not on the surface and if this intersection 
00970       // was not found before
00971       //
00972       if( (surface->Intersect(r)) & 1 )
00973       {
00974         // test if the point is on the surface
00975         //
00976         if(surface->GetDistance() < sqrHalfTolerance)
00977         {
00978           return kSurface;
00979         }
00980         // test if this intersection was found before
00981         //
00982         for(G4int i=0; i<a; i++)
00983         {
00984           if(surface->GetDistance() == SurfaceVec[i]->GetDistance())
00985           {
00986             samehit++;
00987             break;
00988           }
00989         }
00990 
00991         // count the number of surfaces intersected by the ray
00992         //
00993         if(!samehit)
00994         {
00995           hits++;
00996         }
00997       }
00998     }
00999   }
01000    
01001   // if the number of surfaces intersected is odd,
01002   // the point is inside the solid
01003   //
01004   return ( (hits&1) ? kInside : kOutside );
01005 }

G4BREPSolidPolyhedra & G4BREPSolidPolyhedra::operator= ( const G4BREPSolidPolyhedra rhs  ) 

Definition at line 187 of file G4BREPSolidPolyhedra.cc.

References constructorParams, and G4BREPSolid::operator=().

00188 {
00189   // Check assignment to self
00190   //
00191   if (this == &rhs)  { return *this; }
00192 
00193   // Copy base class data
00194   //
00195   G4BREPSolid::operator=(rhs);
00196 
00197   // Copy data
00198   //
00199   constructorParams.start_angle    = rhs.constructorParams.start_angle;
00200   constructorParams.opening_angle  = rhs.constructorParams.opening_angle;
00201   constructorParams.sides          = rhs.constructorParams.sides;
00202   constructorParams.num_z_planes   = rhs.constructorParams.num_z_planes;
00203   constructorParams.z_start        = rhs.constructorParams.z_start;
00204   G4int num_z_planes = constructorParams.num_z_planes;
00205   if( num_z_planes > 0 )
00206   {               
00207     delete [] constructorParams.z_values;
00208     delete [] constructorParams.RMIN;
00209     delete [] constructorParams.RMAX;
00210     constructorParams.z_values       = new G4double[num_z_planes];
00211     constructorParams.RMIN           = new G4double[num_z_planes];
00212     constructorParams.RMAX           = new G4double[num_z_planes];
00213     for( G4int idx = 0; idx < num_z_planes; ++idx )
00214     {
00215       constructorParams.z_values[idx] = rhs.constructorParams.z_values[idx];
00216       constructorParams.RMIN[idx]     = rhs.constructorParams.RMIN[idx];
00217       constructorParams.RMAX[idx]     = rhs.constructorParams.RMAX[idx];      
00218     }
00219   }
00220   
00221   InitializePolyhedra();
00222 
00223   return *this;
00224 }  

void G4BREPSolidPolyhedra::Reset (  )  const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 919 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolid::Active(), G4BREPSolid::nb_of_surfaces, G4BREPSolid::ShortestDistance, G4BREPSolid::StartInside(), and G4BREPSolid::SurfaceVec.

Referenced by DistanceToIn(), DistanceToOut(), and Inside().

00920 {
00921   Active(1);
00922   ((G4BREPSolidPolyhedra*)this)->intersectionDistance=kInfinity;
00923   StartInside(0);
00924   for(register G4int a=0;a<nb_of_surfaces;a++)
00925     SurfaceVec[a]->Reset();
00926   ShortestDistance = kInfinity;
00927 }

std::ostream & G4BREPSolidPolyhedra::StreamInfo ( std::ostream &  os  )  const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 1345 of file G4BREPSolidPolyhedra.cc.

References G4BREPSolid::StreamInfo().

01346 {
01347   // Streams solid contents to output stream.
01348 
01349   G4BREPSolid::StreamInfo( os )
01350   << "\n start_angle:   " << constructorParams.start_angle
01351   << "\n opening_angle: " << constructorParams.opening_angle
01352   << "\n sides:         " << constructorParams.sides
01353   << "\n num_z_planes:  " << constructorParams.num_z_planes
01354   << "\n z_start:       " << constructorParams.z_start
01355   << "\n z_values:      ";
01356   G4int idx;
01357   for( idx = 0; idx < constructorParams.num_z_planes; idx++ )
01358   {
01359     os << constructorParams.z_values[idx] << " ";
01360   }
01361   os << "\n RMIN:          "; 
01362   for( idx = 0; idx < constructorParams.num_z_planes; idx++ )
01363   {
01364     os << constructorParams.RMIN[idx] << " ";
01365   }
01366   os << "\n RMAX:          ";
01367   for( idx = 0; idx < constructorParams.num_z_planes; idx++ )
01368   {
01369     os << constructorParams.RMAX[idx] << " ";
01370   }
01371   os << "\n-----------------------------------------------------------\n";
01372 
01373   return os;
01374 }

G4ThreeVector G4BREPSolidPolyhedra::SurfaceNormal ( const G4ThreeVector  )  const [virtual]

Reimplemented from G4BREPSolid.

Definition at line 1008 of file G4BREPSolidPolyhedra.cc.

References G4FPlane::GetSrfPoint(), G4VSolid::kCarTolerance, G4BREPSolid::nb_of_surfaces, G4FPlane::SurfaceNormal(), and G4BREPSolid::SurfaceVec.

01009 {
01010   // This function calculates the normal of the closest surface
01011   // to the given point
01012   // Note : the sense of the normal depends on the sense of the surface 
01013 
01014   G4int        iplane;
01015   G4bool       normflag = false;
01016   const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25;    
01017 
01018   // Determine if the point is on the surface
01019   //
01020   G4double minDist = kInfinity;
01021   G4int normPlane = 0;
01022   for(iplane = 0; iplane < nb_of_surfaces; iplane++)
01023   {
01024     G4double dist = std::fabs(SurfaceVec[iplane]->HowNear(Pt));
01025     if( minDist > dist )
01026     {
01027       minDist = dist;
01028       normPlane = iplane;
01029     }
01030     if( dist < sqrHalfTolerance)
01031     {
01032       // the point is on this surface, so take this as the
01033       // the surface to consider for computing the normal
01034       //
01035       normflag = true;
01036       break;
01037     }
01038   }
01039 
01040   // Calculate the normal at this point, if the point is on the
01041   // surface, otherwise compute the normal to the closest surface
01042   //
01043   if ( normflag )  // point on surface
01044   {
01045     G4ThreeVector norm = SurfaceVec[iplane]->SurfaceNormal(Pt);
01046     return norm.unit();
01047   }
01048   else             // point not on surface
01049   {
01050     G4FPlane* nPlane = (G4FPlane*)(SurfaceVec[normPlane]);
01051     G4ThreeVector hitPt = nPlane->GetSrfPoint();
01052     G4ThreeVector hitNorm = nPlane->SurfaceNormal(hitPt);
01053     return hitNorm.unit();
01054   }
01055 }


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:51:34 2013 for Geant4 by  doxygen 1.4.7