G4Trd Class Reference

#include <G4Trd.hh>

Inheritance diagram for G4Trd:

G4CSGSolid G4VSolid

Public Types

 kUndefined
 kPX
 kMX
 kPY
 kMY
 kPZ
 kMZ
enum  ESide {
  kUndefined, kPX, kMX, kPY,
  kMY, kPZ, kMZ
}

Public Member Functions

 G4Trd (const G4String &pName, G4double pdx1, G4double pdx2, G4double pdy1, G4double pdy2, G4double pdz)
 ~G4Trd ()
G4double GetXHalfLength1 () const
G4double GetXHalfLength2 () const
G4double GetYHalfLength1 () const
G4double GetYHalfLength2 () const
G4double GetZHalfLength () const
void SetXHalfLength1 (G4double val)
void SetXHalfLength2 (G4double val)
void SetYHalfLength1 (G4double val)
void SetYHalfLength2 (G4double val)
void SetZHalfLength (G4double val)
G4double GetCubicVolume ()
G4double GetSurfaceArea ()
void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
EInside Inside (const G4ThreeVector &p) const
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const
G4double DistanceToIn (const G4ThreeVector &p) const
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
G4double DistanceToOut (const G4ThreeVector &p) const
void CheckAndSetAllParameters (G4double pdx1, G4double pdx2, G4double pdy1, G4double pdy2, G4double pdz)
void SetAllParameters (G4double pdx1, G4double pdx2, G4double pdy1, G4double pdy2, G4double pdz)
G4GeometryType GetEntityType () const
G4ThreeVector GetPointOnSurface () const
G4VSolidClone () const
std::ostream & StreamInfo (std::ostream &os) const
void DescribeYourselfTo (G4VGraphicsScene &scene) const
G4PolyhedronCreatePolyhedron () const
G4NURBSCreateNURBS () const
 G4Trd (__void__ &)
 G4Trd (const G4Trd &rhs)
G4Trdoperator= (const G4Trd &rhs)
G4ThreeVectorListCreateRotatedVertices (const G4AffineTransform &pTransform) const
G4ThreeVector ApproxSurfaceNormal (const G4ThreeVector &p) const

Detailed Description

Definition at line 62 of file G4Trd.hh.


Member Enumeration Documentation

enum G4Trd::ESide

Enumerator:
kUndefined 
kPX 
kMX 
kPY 
kMY 
kPZ 
kMZ 

Definition at line 148 of file G4Trd.hh.


Constructor & Destructor Documentation

G4Trd::G4Trd ( const G4String pName,
G4double  pdx1,
G4double  pdx2,
G4double  pdy1,
G4double  pdy2,
G4double  pdz 
)

Definition at line 60 of file G4Trd.cc.

References CheckAndSetAllParameters().

Referenced by Clone().

00064   : G4CSGSolid(pName)
00065 {
00066   CheckAndSetAllParameters (pdx1, pdx2, pdy1, pdy2, pdz);
00067 }

G4Trd::~G4Trd (  ) 

Definition at line 128 of file G4Trd.cc.

00129 {
00130 }

G4Trd::G4Trd ( __void__ &   ) 

Definition at line 119 of file G4Trd.cc.

00120   : G4CSGSolid(a), fDx1(0.), fDx2(0.), fDy1(0.), fDy2(0.), fDz(0.)
00121 {
00122 }

G4Trd::G4Trd ( const G4Trd rhs  ) 

Definition at line 136 of file G4Trd.cc.

00137   : G4CSGSolid(rhs), fDx1(rhs.fDx1), fDx2(rhs.fDx2),
00138     fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz)
00139 {
00140 }


Member Function Documentation

G4ThreeVector G4Trd::ApproxSurfaceNormal ( const G4ThreeVector p  )  const

Definition at line 503 of file G4Trd.cc.

References fcos().

Referenced by SurfaceNormal().

00504 {
00505   G4ThreeVector norm;
00506   G4double z,tanx,secx,newpx,widx;
00507   G4double tany,secy,newpy,widy;
00508   G4double distx,disty,distz,fcos;
00509 
00510   z=2.0*fDz;
00511 
00512   tanx=(fDx2-fDx1)/z;
00513   secx=std::sqrt(1.0+tanx*tanx);
00514   newpx=std::fabs(p.x())-p.z()*tanx;
00515   widx=fDx2-fDz*tanx;
00516 
00517   tany=(fDy2-fDy1)/z;
00518   secy=std::sqrt(1.0+tany*tany);
00519   newpy=std::fabs(p.y())-p.z()*tany;
00520   widy=fDy2-fDz*tany;
00521 
00522   distx=std::fabs(newpx-widx)/secx;  // perpendicular distance to x side
00523   disty=std::fabs(newpy-widy)/secy;  //                        to y side
00524   distz=std::fabs(std::fabs(p.z())-fDz);  //                        to z side
00525 
00526   // find closest side
00527   //
00528   if (distx<=disty)
00529   { 
00530     if (distx<=distz) 
00531     {
00532       // Closest to X
00533       //
00534       fcos=1.0/secx;
00535       // normal=(+/-std::cos(ang),0,-std::sin(ang))
00536       if (p.x()>=0)
00537         norm=G4ThreeVector(fcos,0,-tanx*fcos);
00538       else
00539         norm=G4ThreeVector(-fcos,0,-tanx*fcos);
00540     }
00541     else
00542     {
00543       // Closest to Z
00544       //
00545       if (p.z()>=0)
00546         norm=G4ThreeVector(0,0,1);
00547       else
00548         norm=G4ThreeVector(0,0,-1);
00549     }
00550   }
00551   else
00552   {  
00553     if (disty<=distz)
00554     {
00555       // Closest to Y
00556       //
00557       fcos=1.0/secy;
00558       if (p.y()>=0)
00559         norm=G4ThreeVector(0,fcos,-tany*fcos);
00560       else
00561         norm=G4ThreeVector(0,-fcos,-tany*fcos);
00562     }
00563     else 
00564     {
00565       // Closest to Z
00566       //
00567       if (p.z()>=0)
00568         norm=G4ThreeVector(0,0,1);
00569       else
00570         norm=G4ThreeVector(0,0,-1);
00571     }
00572   }
00573   return norm;   
00574 }

G4bool G4Trd::CalculateExtent ( const EAxis  pAxis,
const G4VoxelLimits pVoxelLimit,
const G4AffineTransform pTransform,
G4double pMin,
G4double pMax 
) const [virtual]

Implements G4VSolid.

Definition at line 193 of file G4Trd.cc.

References G4VSolid::ClipBetweenSections(), G4VSolid::ClipCrossSection(), CreateRotatedVertices(), G4VoxelLimits::GetMaxExtent(), G4VoxelLimits::GetMaxXExtent(), G4VoxelLimits::GetMaxYExtent(), G4VoxelLimits::GetMaxZExtent(), G4VoxelLimits::GetMinExtent(), G4VoxelLimits::GetMinXExtent(), G4VoxelLimits::GetMinYExtent(), G4VoxelLimits::GetMinZExtent(), Inside(), G4AffineTransform::Inverse(), G4AffineTransform::IsRotated(), G4VoxelLimits::IsXLimited(), G4VoxelLimits::IsYLimited(), G4VoxelLimits::IsZLimited(), G4VSolid::kCarTolerance, kOutside, kXAxis, kYAxis, kZAxis, G4AffineTransform::NetTranslation(), and G4AffineTransform::TransformPoint().

00197 {
00198   if (!pTransform.IsRotated())
00199   {
00200     // Special case handling for unrotated solids
00201     // Compute x/y/z mins and maxs respecting limits, with early returns
00202     // if outside limits. Then switch() on pAxis
00203 
00204     G4double xoffset,xMin,xMax;
00205     G4double yoffset,yMin,yMax;
00206     G4double zoffset,zMin,zMax;
00207 
00208     zoffset=pTransform.NetTranslation().z();
00209     zMin=zoffset-fDz;
00210     zMax=zoffset+fDz;
00211     if (pVoxelLimit.IsZLimited())
00212     {
00213       if ( (zMin>pVoxelLimit.GetMaxZExtent()+kCarTolerance)
00214         || (zMax<pVoxelLimit.GetMinZExtent()-kCarTolerance) )
00215       {
00216         return false;
00217       }
00218         else
00219       {
00220         if (zMin<pVoxelLimit.GetMinZExtent())
00221         {
00222           zMin=pVoxelLimit.GetMinZExtent();
00223         }
00224         if (zMax>pVoxelLimit.GetMaxZExtent())
00225         {
00226           zMax=pVoxelLimit.GetMaxZExtent();
00227         }
00228       }
00229     }
00230     xoffset=pTransform.NetTranslation().x();
00231     if (fDx2 >= fDx1)
00232     { 
00233       xMax =  xoffset+(fDx1+fDx2)/2+(zMax-zoffset)*(fDx2-fDx1)/(2*fDz) ;
00234       xMin = 2*xoffset - xMax ;
00235     }
00236     else
00237     {
00238       xMax =  xoffset+(fDx1+fDx2)/2+(zMin-zoffset)*(fDx2-fDx1)/(2*fDz) ;
00239       xMin =  2*xoffset - xMax ;
00240     }   
00241     if (pVoxelLimit.IsXLimited())
00242     {
00243       if ( (xMin>pVoxelLimit.GetMaxXExtent()+kCarTolerance)
00244         || (xMax<pVoxelLimit.GetMinXExtent()-kCarTolerance) )
00245       {
00246         return false;
00247       }
00248       else
00249       {
00250         if (xMin<pVoxelLimit.GetMinXExtent())
00251         {
00252           xMin=pVoxelLimit.GetMinXExtent();
00253         }
00254         if (xMax>pVoxelLimit.GetMaxXExtent())
00255         {
00256           xMax=pVoxelLimit.GetMaxXExtent();
00257         }
00258       }
00259     }
00260     yoffset= pTransform.NetTranslation().y() ;
00261     if(fDy2 >= fDy1)
00262     {
00263       yMax = yoffset+(fDy2+fDy1)/2+(zMax-zoffset)*(fDy2-fDy1)/(2*fDz) ;
00264       yMin = 2*yoffset - yMax ;
00265     }
00266     else
00267     {
00268       yMax = yoffset+(fDy2+fDy1)/2+(zMin-zoffset)*(fDy2-fDy1)/(2*fDz) ;
00269       yMin = 2*yoffset - yMax ;  
00270     }  
00271     if (pVoxelLimit.IsYLimited())
00272     {
00273       if ( (yMin>pVoxelLimit.GetMaxYExtent()+kCarTolerance)
00274         || (yMax<pVoxelLimit.GetMinYExtent()-kCarTolerance) )
00275       {
00276         return false;
00277       }
00278       else
00279       {
00280         if (yMin<pVoxelLimit.GetMinYExtent())
00281         {
00282           yMin=pVoxelLimit.GetMinYExtent();
00283         }
00284         if (yMax>pVoxelLimit.GetMaxYExtent())
00285         {
00286           yMax=pVoxelLimit.GetMaxYExtent();
00287         }
00288       }
00289     }
00290 
00291     switch (pAxis)
00292     {
00293       case kXAxis:
00294         pMin=xMin;
00295         pMax=xMax;
00296         break;
00297       case kYAxis:
00298         pMin=yMin;
00299         pMax=yMax;
00300         break;
00301       case kZAxis:
00302         pMin=zMin;
00303         pMax=zMax;
00304         break;
00305       default:
00306         break;
00307     }
00308 
00309     // Add 2*Tolerance to avoid precision troubles ?
00310     //
00311     pMin-=kCarTolerance;
00312     pMax+=kCarTolerance;
00313 
00314     return true;
00315   }
00316   else
00317   {
00318     // General rotated case - create and clip mesh to boundaries
00319 
00320     G4bool existsAfterClip=false;
00321     G4ThreeVectorList *vertices;
00322 
00323     pMin=+kInfinity;
00324     pMax=-kInfinity;
00325 
00326     // Calculate rotated vertex coordinates
00327     //
00328     vertices=CreateRotatedVertices(pTransform);
00329     ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
00330     ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax);
00331     ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
00332       
00333     if (pMin!=kInfinity||pMax!=-kInfinity)
00334     {
00335       existsAfterClip=true;
00336 
00337       // Add 2*tolerance to avoid precision troubles
00338       //
00339       pMin-=kCarTolerance;
00340       pMax+=kCarTolerance;
00341         
00342     }
00343     else
00344     {
00345       // Check for case where completely enveloping clipping volume
00346       // If point inside then we are confident that the solid completely
00347       // envelopes the clipping volume. Hence set min/max extents according
00348       // to clipping volume extents along the specified axis.
00349 
00350       G4ThreeVector clipCentre(
00351          (pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
00352          (pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
00353          (pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
00354         
00355       if (Inside(pTransform.Inverse().TransformPoint(clipCentre))!=kOutside)
00356       {
00357         existsAfterClip=true;
00358         pMin=pVoxelLimit.GetMinExtent(pAxis);
00359         pMax=pVoxelLimit.GetMaxExtent(pAxis);
00360       }
00361     }
00362     delete vertices;
00363     return existsAfterClip;
00364   }
00365 }

void G4Trd::CheckAndSetAllParameters ( G4double  pdx1,
G4double  pdx2,
G4double  pdy1,
G4double  pdy2,
G4double  pdz 
)

Definition at line 73 of file G4Trd.cc.

References FatalException, G4CSGSolid::fCubicVolume, G4CSGSolid::fpPolyhedron, G4CSGSolid::fSurfaceArea, G4endl, G4Exception(), G4VSolid::GetName(), and G4VSolid::kCarTolerance.

Referenced by G4Trd(), and SetAllParameters().

00076 {
00077   if ( pdx1>0&&pdx2>0&&pdy1>0&&pdy2>0&&pdz>0 )
00078   {
00079     fDx1=pdx1; fDx2=pdx2;
00080     fDy1=pdy1; fDy2=pdy2;
00081     fDz=pdz;
00082   }
00083   else
00084   {
00085     if ( pdx1>=0 && pdx2>=0 && pdy1>=0 && pdy2>=0 && pdz>=0 )
00086     {
00087       // G4double  Minimum_length= (1+per_thousand) * kCarTolerance/2.;
00088       // FIX-ME : temporary solution for ZERO or very-small parameters
00089       //
00090       G4double  Minimum_length= kCarTolerance/2.;
00091       fDx1=std::max(pdx1,Minimum_length); 
00092       fDx2=std::max(pdx2,Minimum_length); 
00093       fDy1=std::max(pdy1,Minimum_length); 
00094       fDy2=std::max(pdy2,Minimum_length); 
00095       fDz=std::max(pdz,Minimum_length);
00096     }
00097     else
00098     {
00099       std::ostringstream message;
00100       message << "Invalid negative dimensions for Solid: " << GetName()
00101               << G4endl
00102               << "          X - " << pdx1 << ", " << pdx2 << G4endl
00103               << "          Y - " << pdy1 << ", " << pdy2 << G4endl
00104               << "          Z - " << pdz;
00105       G4Exception("G4Trd::CheckAndSetAllParameters()",
00106                   "GeomSolids0002", FatalException, message);
00107     }
00108   }
00109   fCubicVolume= 0.;
00110   fSurfaceArea= 0.;
00111   fpPolyhedron = 0;
00112 }

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

Reimplemented from G4VSolid.

Definition at line 1367 of file G4Trd.cc.

References G4Trd().

01368 {
01369   return new G4Trd(*this);
01370 }

void G4Trd::ComputeDimensions ( G4VPVParameterisation p,
const G4int  n,
const G4VPhysicalVolume pRep 
) [virtual]

Reimplemented from G4VSolid.

Definition at line 181 of file G4Trd.cc.

References G4VPVParameterisation::ComputeDimensions().

00184 {
00185   p->ComputeDimensions(*this,n,pRep);
00186 }

G4NURBS * G4Trd::CreateNURBS (  )  const [virtual]

Reimplemented from G4VSolid.

Definition at line 1476 of file G4Trd.cc.

01477 {
01478   //  return new G4NURBSbox (fDx, fDy, fDz);
01479   return 0;
01480 }

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

Reimplemented from G4VSolid.

Definition at line 1471 of file G4Trd.cc.

01472 {
01473   return new G4PolyhedronTrd2 (fDx1, fDx2, fDy1, fDy2, fDz);
01474 }

G4ThreeVectorList * G4Trd::CreateRotatedVertices ( const G4AffineTransform pTransform  )  const

Definition at line 1319 of file G4Trd.cc.

References G4VSolid::DumpInfo(), FatalException, G4Exception(), and G4AffineTransform::TransformPoint().

Referenced by CalculateExtent().

01320 {
01321   G4ThreeVectorList *vertices;
01322   vertices=new G4ThreeVectorList();
01323   if (vertices)
01324   {
01325     vertices->reserve(8);
01326     G4ThreeVector vertex0(-fDx1,-fDy1,-fDz);
01327     G4ThreeVector vertex1(fDx1,-fDy1,-fDz);
01328     G4ThreeVector vertex2(fDx1,fDy1,-fDz);
01329     G4ThreeVector vertex3(-fDx1,fDy1,-fDz);
01330     G4ThreeVector vertex4(-fDx2,-fDy2,fDz);
01331     G4ThreeVector vertex5(fDx2,-fDy2,fDz);
01332     G4ThreeVector vertex6(fDx2,fDy2,fDz);
01333     G4ThreeVector vertex7(-fDx2,fDy2,fDz);
01334 
01335     vertices->push_back(pTransform.TransformPoint(vertex0));
01336     vertices->push_back(pTransform.TransformPoint(vertex1));
01337     vertices->push_back(pTransform.TransformPoint(vertex2));
01338     vertices->push_back(pTransform.TransformPoint(vertex3));
01339     vertices->push_back(pTransform.TransformPoint(vertex4));
01340     vertices->push_back(pTransform.TransformPoint(vertex5));
01341     vertices->push_back(pTransform.TransformPoint(vertex6));
01342     vertices->push_back(pTransform.TransformPoint(vertex7));
01343   }
01344   else
01345   {
01346     DumpInfo();
01347     G4Exception("G4Trd::CreateRotatedVertices()",
01348                 "GeomSolids0003", FatalException,
01349                 "Error in allocation of vertices. Out of memory !");
01350   }
01351   return vertices;
01352 }

void G4Trd::DescribeYourselfTo ( G4VGraphicsScene scene  )  const [virtual]

Implements G4VSolid.

Definition at line 1466 of file G4Trd.cc.

References G4VGraphicsScene::AddSolid().

01467 {
01468   scene.AddSolid (*this);
01469 }

G4double G4Trd::DistanceToIn ( const G4ThreeVector p  )  const [virtual]

Implements G4VSolid.

Definition at line 822 of file G4Trd.cc.

00823 {
00824   G4double safe=0.0;
00825   G4double tanxz,distx,safx;
00826   G4double tanyz,disty,safy;
00827   G4double zbase;
00828 
00829   safe=std::fabs(p.z())-fDz;
00830   if (safe<0) safe=0;      // Also used to ensure x/y distances
00831                            // POSITIVE 
00832 
00833   zbase=fDz+p.z();
00834 
00835   // Find distance along x direction to closest x plane
00836   //
00837   tanxz=(fDx2-fDx1)*0.5/fDz;
00838   //    widx=fDx1+tanxz*(fDz+p.z()); // x width at p.z
00839   //    distx=std::fabs(p.x())-widx;      // distance to plane
00840   distx=std::fabs(p.x())-(fDx1+tanxz*zbase);
00841   if (distx>safe)
00842   {
00843     safx=distx/std::sqrt(1.0+tanxz*tanxz); // vector Dist=Dist*std::cos(ang)
00844     if (safx>safe) safe=safx;
00845   }
00846 
00847   // Find distance along y direction to slanted wall
00848   tanyz=(fDy2-fDy1)*0.5/fDz;
00849   //    widy=fDy1+tanyz*(fDz+p.z()); // y width at p.z
00850   //    disty=std::fabs(p.y())-widy;      // distance to plane
00851   disty=std::fabs(p.y())-(fDy1+tanyz*zbase);
00852   if (disty>safe)    
00853   {
00854     safy=disty/std::sqrt(1.0+tanyz*tanyz); // distance along vector
00855     if (safy>safe) safe=safy;
00856   }
00857   return safe;
00858 }

G4double G4Trd::DistanceToIn ( const G4ThreeVector p,
const G4ThreeVector v 
) const [virtual]

Implements G4VSolid.

Definition at line 596 of file G4Trd.cc.

References G4VSolid::kCarTolerance.

00598 {  
00599   G4double snxt = kInfinity ;    // snxt = default return value
00600   G4double smin,smax;
00601   G4double s1,s2,tanxz,tanyz,ds1,ds2;
00602   G4double ss1,ss2,sn1=0.,sn2=0.,Dist;
00603 
00604   if ( v.z() )  // Calculate valid z intersect range
00605   {
00606     if ( v.z() > 0 )   // Calculate smax: must be +ve or no intersection.
00607     {
00608       Dist = fDz - p.z() ;  // to plane at +dz
00609 
00610       if (Dist >= 0.5*kCarTolerance)
00611       {
00612         smax = Dist/v.z() ;
00613         smin = -(fDz + p.z())/v.z() ;
00614       }
00615       else  return snxt ;
00616     }
00617     else // v.z <0
00618     {
00619       Dist=fDz+p.z();  // plane at -dz
00620 
00621       if ( Dist >= 0.5*kCarTolerance )
00622       {
00623         smax = -Dist/v.z() ;
00624         smin = (fDz - p.z())/v.z() ;
00625       }
00626       else return snxt ; 
00627     }
00628     if (smin < 0 ) smin = 0 ;
00629   }
00630   else // v.z=0
00631   {
00632     if (std::fabs(p.z()) >= fDz ) return snxt ;     // Outside & no intersect
00633     else
00634     {
00635       smin = 0 ;    // Always inside z range
00636       smax = kInfinity;
00637     }
00638   }
00639 
00640   // Calculate x intersection range
00641   //
00642   // Calc half width at p.z, and components towards planes
00643 
00644   tanxz = (fDx2 - fDx1)*0.5/fDz ;
00645   s1    = 0.5*(fDx1+fDx2) + tanxz*p.z() ;  // x half width at p.z
00646   ds1   = v.x() - tanxz*v.z() ;       // Components of v towards faces at +-x
00647   ds2   = v.x() + tanxz*v.z() ;
00648   ss1   = s1 - p.x() ;         // -delta x to +ve plane
00649                                // -ve when outside
00650   ss2   = -s1 - p.x() ;        // -delta x to -ve plane
00651                                // +ve when outside
00652     
00653   if (ss1 < 0 && ss2 <= 0 )
00654   {
00655     if (ds1 < 0)   // In +ve coord Area
00656     {
00657       sn1 = ss1/ds1 ;
00658 
00659       if ( ds2 < 0 ) sn2 = ss2/ds2 ;           
00660       else           sn2 = kInfinity ;
00661     }
00662     else return snxt ;
00663   }
00664   else if ( ss1 >= 0 && ss2 > 0 )
00665   {
00666     if ( ds2 > 0 )  // In -ve coord Area
00667     {
00668       sn1 = ss2/ds2 ;
00669 
00670       if (ds1 > 0)  sn2 = ss1/ds1 ;      
00671       else          sn2 = kInfinity;      
00672         
00673     }
00674     else   return snxt ;
00675   }
00676   else if (ss1 >= 0 && ss2 <= 0 )
00677   {
00678     // Inside Area - calculate leaving distance
00679     // *Don't* use exact distance to side for tolerance
00680     //                                             = ss1*std::cos(ang xz)
00681     //                                             = ss1/std::sqrt(1.0+tanxz*tanxz)
00682     sn1 = 0 ;
00683 
00684     if ( ds1 > 0 )
00685     {
00686       if (ss1 > 0.5*kCarTolerance) sn2 = ss1/ds1 ; // Leave +ve side extent
00687       else                         return snxt ;   // Leave immediately by +ve 
00688     }
00689     else  sn2 = kInfinity ;
00690       
00691     if ( ds2 < 0 )
00692     {
00693       if ( ss2 < -0.5*kCarTolerance )
00694       {
00695         Dist = ss2/ds2 ;            // Leave -ve side extent
00696         if ( Dist < sn2 ) sn2 = Dist ;
00697       }
00698       else  return snxt ;
00699     }    
00700   }
00701   else if (ss1 < 0 && ss2 > 0 )
00702   {
00703     // Within +/- plane cross-over areas (not on boundaries ss1||ss2==0)
00704 
00705     if ( ds1 >= 0 || ds2 <= 0 )
00706     {   
00707       return snxt ;
00708     }
00709     else  // Will intersect & stay inside
00710     {
00711       sn1  = ss1/ds1 ;
00712       Dist = ss2/ds2 ;
00713       if (Dist > sn1 ) sn1 = Dist ;
00714       sn2 = kInfinity ;
00715     }
00716   }
00717 
00718   // Reduce allowed range of distances as appropriate
00719 
00720   if ( sn1 > smin ) smin = sn1 ;
00721   if ( sn2 < smax ) smax = sn2 ;
00722 
00723   // Check for incompatible ranges (eg z intersects between 50 ->100 and x
00724   // only 10-40 -> no intersection)
00725 
00726   if ( smax < smin ) return snxt ;
00727 
00728   // Calculate valid y intersection range 
00729   // (repeat of x intersection code)
00730 
00731   tanyz = (fDy2-fDy1)*0.5/fDz ;
00732   s2    = 0.5*(fDy1+fDy2) + tanyz*p.z() ;  // y half width at p.z
00733   ds1   = v.y() - tanyz*v.z() ;       // Components of v towards faces at +-y
00734   ds2   = v.y() + tanyz*v.z() ;
00735   ss1   = s2 - p.y() ;         // -delta y to +ve plane
00736   ss2   = -s2 - p.y() ;        // -delta y to -ve plane
00737     
00738   if ( ss1 < 0 && ss2 <= 0 )
00739   {
00740     if (ds1 < 0 ) // In +ve coord Area
00741     {
00742       sn1 = ss1/ds1 ;
00743       if ( ds2 < 0 )  sn2 = ss2/ds2 ;
00744       else            sn2 = kInfinity ;
00745     }
00746     else   return snxt ;
00747   }
00748   else if ( ss1 >= 0 && ss2 > 0 )
00749   {
00750     if ( ds2 > 0 )  // In -ve coord Area
00751     {
00752       sn1 = ss2/ds2 ;
00753       if ( ds1 > 0 )  sn2 = ss1/ds1 ;
00754       else            sn2 = kInfinity ;      
00755     }
00756     else   return snxt ;
00757   }
00758   else if (ss1 >= 0 && ss2 <= 0 )
00759   {
00760     // Inside Area - calculate leaving distance
00761     // *Don't* use exact distance to side for tolerance
00762     //                                          = ss1*std::cos(ang yz)
00763     //                                          = ss1/std::sqrt(1.0+tanyz*tanyz)
00764     sn1 = 0 ;
00765 
00766     if ( ds1 > 0 )
00767     {
00768       if (ss1 > 0.5*kCarTolerance) sn2 = ss1/ds1 ; // Leave +ve side extent
00769       else                         return snxt ;   // Leave immediately by +ve
00770     }
00771     else  sn2 = kInfinity ;
00772       
00773     if ( ds2 < 0 )
00774     {
00775       if ( ss2 < -0.5*kCarTolerance )
00776       {
00777         Dist = ss2/ds2 ; // Leave -ve side extent
00778         if (Dist < sn2) sn2=Dist;
00779       }
00780       else  return snxt ;
00781     }    
00782   }
00783   else if (ss1 < 0 && ss2 > 0 )
00784   {
00785     // Within +/- plane cross-over areas (not on boundaries ss1||ss2==0)
00786 
00787     if (ds1 >= 0 || ds2 <= 0 )  
00788     {
00789       return snxt ;
00790     }
00791     else  // Will intersect & stay inside
00792     {
00793       sn1 = ss1/ds1 ;
00794       Dist = ss2/ds2 ;
00795       if (Dist > sn1 ) sn1 = Dist ;
00796       sn2 = kInfinity ;
00797     }
00798   }
00799   
00800   // Reduce allowed range of distances as appropriate
00801 
00802   if ( sn1 > smin) smin = sn1 ;
00803   if ( sn2 < smax) smax = sn2 ;
00804 
00805   // Check for incompatible ranges (eg x intersects between 50 ->100 and y
00806   // only 10-40 -> no intersection). Set snxt if ok
00807 
00808   if ( smax > smin ) snxt = smin ;
00809   if (snxt < 0.5*kCarTolerance ) snxt = 0.0 ;
00810 
00811   return snxt ;
00812 }

G4double G4Trd::DistanceToOut ( const G4ThreeVector p  )  const [virtual]

Implements G4VSolid.

Definition at line 1261 of file G4Trd.cc.

References G4VSolid::DumpInfo(), G4cout, G4endl, G4Exception(), Inside(), JustWarning, and kOutside.

01262 {
01263   G4double safe=0.0;
01264   G4double tanxz,xdist,saf1;
01265   G4double tanyz,ydist,saf2;
01266   G4double zbase;
01267 
01268 #ifdef G4CSGDEBUG
01269   if( Inside(p) == kOutside )
01270   {
01271      G4int oldprc = G4cout.precision(16) ;
01272      G4cout << G4endl ;
01273      DumpInfo();
01274      G4cout << "Position:"  << G4endl << G4endl ;
01275      G4cout << "p.x() = "   << p.x()/mm << " mm" << G4endl ;
01276      G4cout << "p.y() = "   << p.y()/mm << " mm" << G4endl ;
01277      G4cout << "p.z() = "   << p.z()/mm << " mm" << G4endl << G4endl ;
01278      G4cout.precision(oldprc) ;
01279      G4Exception("G4Trd::DistanceToOut(p)", "GeomSolids1002", JustWarning, 
01280                  "Point p is outside !?" );
01281   }
01282 #endif
01283 
01284   safe=fDz-std::fabs(p.z());  // z perpendicular Dist
01285 
01286   zbase=fDz+p.z();
01287 
01288   // xdist = distance perpendicular to z axis to closest x plane from p
01289   //       = (x half width of shape at p.z) - std::fabs(p.x)
01290   //
01291   tanxz=(fDx2-fDx1)*0.5/fDz;
01292   xdist=fDx1+tanxz*zbase-std::fabs(p.x());
01293   saf1=xdist/std::sqrt(1.0+tanxz*tanxz); // x*std::cos(ang_xz) =
01294                                     // shortest (perpendicular)
01295                                     // distance to plane
01296   tanyz=(fDy2-fDy1)*0.5/fDz;
01297   ydist=fDy1+tanyz*zbase-std::fabs(p.y());
01298   saf2=ydist/std::sqrt(1.0+tanyz*tanyz);
01299 
01300   // Return minimum x/y/z distance
01301   //
01302   if (safe>saf1) safe=saf1;
01303   if (safe>saf2) safe=saf2;
01304 
01305   if (safe<0) safe=0;
01306   return safe;     
01307 }

G4double G4Trd::DistanceToOut ( const G4ThreeVector p,
const G4ThreeVector v,
const G4bool  calcNorm = false,
G4bool validNorm = 0,
G4ThreeVector n = 0 
) const [virtual]

Implements G4VSolid.

Definition at line 869 of file G4Trd.cc.

References G4VSolid::DumpInfo(), G4Exception(), JustWarning, G4VSolid::kCarTolerance, kMX, kMY, kMZ, kPX, kPY, kPZ, and kUndefined.

00874 {
00875   ESide side = kUndefined, snside = kUndefined;
00876   G4double snxt,pdist;
00877   G4double central,ss1,ss2,ds1,ds2,sn=0.,sn2=0.;
00878   G4double tanxz=0.,cosxz=0.,tanyz=0.,cosyz=0.;
00879 
00880   if (calcNorm) *validNorm=true; // All normals are valid
00881 
00882   // Calculate z plane intersection
00883   if (v.z()>0)
00884   {
00885     pdist=fDz-p.z();
00886     if (pdist>kCarTolerance/2)
00887     {
00888       snxt=pdist/v.z();
00889       side=kPZ;
00890     }
00891     else
00892     {
00893       if (calcNorm)
00894       {
00895         *n=G4ThreeVector(0,0,1);
00896       }
00897       return snxt=0;
00898     }
00899   }
00900   else if (v.z()<0) 
00901   {
00902     pdist=fDz+p.z();
00903     if (pdist>kCarTolerance/2)
00904     {
00905       snxt=-pdist/v.z();
00906       side=kMZ;
00907     }
00908     else
00909     {
00910       if (calcNorm)
00911       {
00912         *n=G4ThreeVector(0,0,-1);
00913       }
00914       return snxt=0;
00915     }
00916   }
00917   else
00918   {
00919     snxt=kInfinity;
00920   }
00921 
00922   //
00923   // Calculate x intersection
00924   //
00925   tanxz=(fDx2-fDx1)*0.5/fDz;
00926   central=0.5*(fDx1+fDx2);
00927 
00928   // +ve plane (1)
00929   //
00930   ss1=central+tanxz*p.z()-p.x();  // distance || x axis to plane
00931                                   // (+ve if point inside)
00932   ds1=v.x()-tanxz*v.z();    // component towards plane at +x
00933                             // (-ve if +ve -> -ve direction)
00934   // -ve plane (2)
00935   //
00936   ss2=-tanxz*p.z()-p.x()-central;  //distance || x axis to plane
00937                                    // (-ve if point inside)
00938   ds2=tanxz*v.z()+v.x();    // component towards plane at -x
00939 
00940   if (ss1>0&&ss2<0)
00941   {
00942     // Normal case - entirely inside region
00943     if (ds1<=0&&ds2<0)
00944     {   
00945       if (ss2<-kCarTolerance/2)
00946       {
00947         sn=ss2/ds2;  // Leave by -ve side
00948         snside=kMX;
00949       }
00950       else
00951       {
00952         sn=0; // Leave immediately by -ve side
00953         snside=kMX;
00954       }
00955     }
00956     else if (ds1>0&&ds2>=0)
00957     {
00958       if (ss1>kCarTolerance/2)
00959       {
00960         sn=ss1/ds1;  // Leave by +ve side
00961         snside=kPX;
00962       }
00963       else
00964       {
00965         sn=0; // Leave immediately by +ve side
00966         snside=kPX;
00967       }
00968     }
00969     else if (ds1>0&&ds2<0)
00970     {
00971       if (ss1>kCarTolerance/2)
00972       {
00973         // sn=ss1/ds1;  // Leave by +ve side
00974         if (ss2<-kCarTolerance/2)
00975         {
00976           sn=ss1/ds1;  // Leave by +ve side
00977           sn2=ss2/ds2;
00978           if (sn2<sn)
00979           {
00980             sn=sn2;
00981             snside=kMX;
00982           }
00983           else
00984           {
00985             snside=kPX;
00986           }
00987         }
00988         else
00989         {
00990           sn=0; // Leave immediately by -ve
00991           snside=kMX;
00992         }      
00993       }
00994       else
00995       {
00996         sn=0; // Leave immediately by +ve side
00997         snside=kPX;
00998       }
00999     }
01000     else
01001     {
01002       // Must be || to both
01003       //
01004       sn=kInfinity;    // Don't leave by either side
01005     }
01006   }
01007   else if (ss1<=0&&ss2<0)
01008   {
01009     // Outside, in +ve Area
01010     
01011     if (ds1>0)
01012     {
01013       sn=0;       // Away from shape
01014                   // Left by +ve side
01015       snside=kPX;
01016     }
01017     else
01018     {
01019       if (ds2<0)
01020       {
01021         // Ignore +ve plane and use -ve plane intersect
01022         //
01023         sn=ss2/ds2; // Leave by -ve side
01024         snside=kMX;
01025       }
01026       else
01027       {
01028         // Must be || to both -> exit determined by other axes
01029         //
01030         sn=kInfinity; // Don't leave by either side
01031       }
01032     }
01033   }
01034   else if (ss1>0&&ss2>=0)
01035   {
01036     // Outside, in -ve Area
01037 
01038     if (ds2<0)
01039     {
01040       sn=0;       // away from shape
01041                   // Left by -ve side
01042       snside=kMX;
01043     }
01044     else
01045     {
01046       if (ds1>0)
01047       {
01048         // Ignore +ve plane and use -ve plane intersect
01049         //
01050         sn=ss1/ds1; // Leave by +ve side
01051         snside=kPX;
01052       }
01053       else
01054       {
01055         // Must be || to both -> exit determined by other axes
01056         //
01057         sn=kInfinity; // Don't leave by either side
01058       }
01059     }
01060   }
01061 
01062   // Update minimum exit distance
01063 
01064   if (sn<snxt)
01065   {
01066     snxt=sn;
01067     side=snside;
01068   }
01069   if (snxt>0)
01070   {
01071     // Calculate y intersection
01072 
01073     tanyz=(fDy2-fDy1)*0.5/fDz;
01074     central=0.5*(fDy1+fDy2);
01075 
01076     // +ve plane (1)
01077     //
01078     ss1=central+tanyz*p.z()-p.y(); // distance || y axis to plane
01079                                    // (+ve if point inside)
01080     ds1=v.y()-tanyz*v.z();  // component towards +ve plane
01081                             // (-ve if +ve -> -ve direction)
01082     // -ve plane (2)
01083     //
01084     ss2=-tanyz*p.z()-p.y()-central; // distance || y axis to plane
01085                                     // (-ve if point inside)
01086     ds2=tanyz*v.z()+v.y();  // component towards -ve plane
01087 
01088     if (ss1>0&&ss2<0)
01089     {
01090       // Normal case - entirely inside region
01091 
01092       if (ds1<=0&&ds2<0)
01093       {   
01094         if (ss2<-kCarTolerance/2)
01095         {
01096           sn=ss2/ds2;  // Leave by -ve side
01097           snside=kMY;
01098         }
01099         else
01100         {
01101           sn=0; // Leave immediately by -ve side
01102           snside=kMY;
01103         }
01104       }
01105       else if (ds1>0&&ds2>=0)
01106       {
01107         if (ss1>kCarTolerance/2)
01108         {
01109           sn=ss1/ds1;  // Leave by +ve side
01110           snside=kPY;
01111         }
01112         else
01113         {
01114           sn=0; // Leave immediately by +ve side
01115           snside=kPY;
01116         }
01117       }
01118       else if (ds1>0&&ds2<0)
01119       {
01120         if (ss1>kCarTolerance/2)
01121         {
01122           // sn=ss1/ds1;  // Leave by +ve side
01123           if (ss2<-kCarTolerance/2)
01124           {
01125             sn=ss1/ds1;  // Leave by +ve side
01126             sn2=ss2/ds2;
01127             if (sn2<sn)
01128             {
01129               sn=sn2;
01130               snside=kMY;
01131             }
01132             else
01133             {
01134               snside=kPY;
01135             }
01136           }
01137           else
01138           {
01139             sn=0; // Leave immediately by -ve
01140             snside=kMY;
01141           }
01142         }
01143         else
01144         {
01145           sn=0; // Leave immediately by +ve side
01146           snside=kPY;
01147         }
01148       }
01149       else
01150       {
01151         // Must be || to both
01152         //
01153         sn=kInfinity;    // Don't leave by either side
01154       }
01155     }
01156     else if (ss1<=0&&ss2<0)
01157     {
01158       // Outside, in +ve Area
01159 
01160       if (ds1>0)
01161       {
01162         sn=0;       // Away from shape
01163                     // Left by +ve side
01164         snside=kPY;
01165       }
01166       else
01167       {
01168         if (ds2<0)
01169         {
01170           // Ignore +ve plane and use -ve plane intersect
01171           //
01172           sn=ss2/ds2; // Leave by -ve side
01173           snside=kMY;
01174         }
01175         else
01176         {
01177           // Must be || to both -> exit determined by other axes
01178           //
01179           sn=kInfinity; // Don't leave by either side
01180         }
01181       }
01182     }
01183     else if (ss1>0&&ss2>=0)
01184     {
01185       // Outside, in -ve Area
01186       if (ds2<0)
01187       {
01188         sn=0;       // away from shape
01189                     // Left by -ve side
01190         snside=kMY;
01191       }
01192       else
01193       {
01194         if (ds1>0)
01195         {
01196           // Ignore +ve plane and use -ve plane intersect
01197           //
01198           sn=ss1/ds1; // Leave by +ve side
01199           snside=kPY;
01200         }
01201         else
01202         {
01203           // Must be || to both -> exit determined by other axes
01204           //
01205           sn=kInfinity; // Don't leave by either side
01206         }
01207       }
01208     }
01209 
01210     // Update minimum exit distance
01211 
01212     if (sn<snxt)
01213     {
01214       snxt=sn;
01215       side=snside;
01216     }
01217   }
01218 
01219   if (calcNorm)
01220   {
01221     switch (side)
01222     {
01223       case kPX:
01224         cosxz=1.0/std::sqrt(1.0+tanxz*tanxz);
01225         *n=G4ThreeVector(cosxz,0,-tanxz*cosxz);
01226         break;
01227       case kMX:
01228         cosxz=-1.0/std::sqrt(1.0+tanxz*tanxz);
01229         *n=G4ThreeVector(cosxz,0,tanxz*cosxz);
01230         break;
01231       case kPY:
01232         cosyz=1.0/std::sqrt(1.0+tanyz*tanyz);
01233         *n=G4ThreeVector(0,cosyz,-tanyz*cosyz);
01234         break;
01235       case kMY:
01236         cosyz=-1.0/std::sqrt(1.0+tanyz*tanyz);
01237         *n=G4ThreeVector(0,cosyz,tanyz*cosyz);
01238         break;
01239       case kPZ:
01240         *n=G4ThreeVector(0,0,1);
01241         break;
01242       case kMZ:
01243         *n=G4ThreeVector(0,0,-1);
01244         break;
01245       default:
01246         DumpInfo();
01247         G4Exception("G4Trd::DistanceToOut(p,v,..)",
01248                     "GeomSolids1002", JustWarning, 
01249                     "Undefined side for valid surface normal to solid.");
01250         break;
01251     }
01252   }
01253   return snxt; 
01254 }

G4double G4Trd::GetCubicVolume (  )  [inline, virtual]

Reimplemented from G4VSolid.

Definition at line 113 of file G4Trd.icc.

References G4CSGSolid::fCubicVolume.

00114 {
00115   if(fCubicVolume != 0.) {;}
00116   else
00117   {
00118     fCubicVolume = 2*fDz*( (fDx1+fDx2)*(fDy1+fDy2)
00119                          + (fDx2-fDx1)*(fDy2-fDy1)/3 );
00120   }
00121   return fCubicVolume;
00122 }

G4GeometryType G4Trd::GetEntityType (  )  const [virtual]

Implements G4VSolid.

Definition at line 1358 of file G4Trd.cc.

01359 {
01360   return G4String("G4Trd");
01361 }

G4ThreeVector G4Trd::GetPointOnSurface (  )  const [virtual]

Reimplemented from G4VSolid.

Definition at line 1403 of file G4Trd.cc.

References G4UniformRand.

01404 {
01405   G4double px, py, pz, tgX, tgY, secX, secY, select, sumS, tmp;
01406   G4double Sxy1, Sxy2, Sxy, Sxz, Syz;
01407 
01408   tgX  = 0.5*(fDx2-fDx1)/fDz;
01409   secX = std::sqrt(1+tgX*tgX);
01410   tgY  = 0.5*(fDy2-fDy1)/fDz;
01411   secY = std::sqrt(1+tgY*tgY);
01412 
01413   // calculate 0.25 of side surfaces, sumS is 0.25 of total surface
01414 
01415   Sxy1 = fDx1*fDy1; 
01416   Sxy2 = fDx2*fDy2;
01417   Sxy  = Sxy1 + Sxy2; 
01418   Sxz  = (fDx1 + fDx2)*fDz*secY; 
01419   Syz  = (fDy1 + fDy2)*fDz*secX;
01420   sumS = Sxy + Sxz + Syz;
01421 
01422   select = sumS*G4UniformRand();
01423  
01424   if( select < Sxy )                  // Sxy1 or Sxy2
01425   {
01426     if( select < Sxy1 ) 
01427     {
01428       pz = -fDz;
01429       px = -fDx1 + 2*fDx1*G4UniformRand();
01430       py = -fDy1 + 2*fDy1*G4UniformRand();
01431     }
01432     else      
01433     {
01434       pz =  fDz;
01435       px = -fDx2 + 2*fDx2*G4UniformRand();
01436       py = -fDy2 + 2*fDy2*G4UniformRand();
01437     }
01438   }
01439   else if ( ( select - Sxy ) < Sxz )    // Sxz
01440   {
01441     pz  = -fDz  + 2*fDz*G4UniformRand();
01442     tmp =  fDx1 + (pz + fDz)*tgX;
01443     px  = -tmp  + 2*tmp*G4UniformRand();
01444     tmp =  fDy1 + (pz + fDz)*tgY;
01445 
01446     if(G4UniformRand() > 0.5) { py =  tmp; }
01447     else                      { py = -tmp; }
01448   }
01449   else                                   // Syz
01450   {
01451     pz  = -fDz  + 2*fDz*G4UniformRand();
01452     tmp =  fDy1 + (pz + fDz)*tgY;
01453     py  = -tmp  + 2*tmp*G4UniformRand();
01454     tmp =  fDx1 + (pz + fDz)*tgX;
01455 
01456     if(G4UniformRand() > 0.5) { px =  tmp; }
01457     else                      { px = -tmp; }
01458   } 
01459   return G4ThreeVector(px,py,pz);
01460 }

G4double G4Trd::GetSurfaceArea (  )  [inline, virtual]

Reimplemented from G4VSolid.

Definition at line 125 of file G4Trd.icc.

References G4CSGSolid::fSurfaceArea.

00126 {
00127   if(fSurfaceArea != 0.) {;}
00128   else
00129   { 
00130     fSurfaceArea = 4*(fDx1*fDy1+fDx2*fDy2)
00131                  + 2*((fDy1+fDy2)*std::sqrt(4*fDz*fDz+(fDx2-fDx1)*(fDx2-fDx1))
00132                  + (fDx1+fDx2) *std::sqrt(4*fDz*fDz+(fDy2-fDy1)*(fDy2-fDy1)) );
00133   }
00134   return fSurfaceArea;
00135 }

G4double G4Trd::GetXHalfLength1 (  )  const [inline]

Definition at line 38 of file G4Trd.icc.

Referenced by G4HepRepSceneHandler::AddSolid(), G4HepRepFileSceneHandler::AddSolid(), G4ParameterisationTrdZ::ComputeDimensions(), G4ParameterisationTrdY::ComputeDimensions(), G4ParameterisationTrdX::ComputeDimensions(), G4ParameterisationTrdX::ComputeTransformation(), G4ParameterisationTrdX::G4ParameterisationTrdX(), G4VParameterisationTrd::G4VParameterisationTrd(), G4ParameterisationTrdX::GetMaxParameter(), G4tgbGeometryDumper::GetSolidParams(), G4GDMLWriteParamvol::Trd_dimensionsWrite(), and G4GDMLWriteSolids::TrdWrite().

00039 {
00040   return fDx1;
00041 }

G4double G4Trd::GetXHalfLength2 (  )  const [inline]

Definition at line 44 of file G4Trd.icc.

Referenced by G4HepRepSceneHandler::AddSolid(), G4HepRepFileSceneHandler::AddSolid(), G4ParameterisationTrdZ::ComputeDimensions(), G4ParameterisationTrdY::ComputeDimensions(), G4ParameterisationTrdX::ComputeDimensions(), G4ParameterisationTrdX::ComputeTransformation(), G4ParameterisationTrdX::G4ParameterisationTrdX(), G4VParameterisationTrd::G4VParameterisationTrd(), G4ParameterisationTrdX::GetMaxParameter(), G4tgbGeometryDumper::GetSolidParams(), G4GDMLWriteParamvol::Trd_dimensionsWrite(), and G4GDMLWriteSolids::TrdWrite().

00045 {
00046   return fDx2;
00047 }

G4double G4Trd::GetYHalfLength1 (  )  const [inline]

Definition at line 50 of file G4Trd.icc.

Referenced by G4HepRepSceneHandler::AddSolid(), G4HepRepFileSceneHandler::AddSolid(), G4ParameterisationTrdY::CheckParametersValidity(), G4ParameterisationTrdZ::ComputeDimensions(), G4ParameterisationTrdX::ComputeDimensions(), G4ParameterisationTrdY::ComputeTransformation(), G4ParameterisationTrdY::G4ParameterisationTrdY(), G4VParameterisationTrd::G4VParameterisationTrd(), G4ParameterisationTrdY::GetMaxParameter(), G4tgbGeometryDumper::GetSolidParams(), G4GDMLWriteParamvol::Trd_dimensionsWrite(), and G4GDMLWriteSolids::TrdWrite().

00051 {
00052   return fDy1;
00053 }

G4double G4Trd::GetYHalfLength2 (  )  const [inline]

Definition at line 56 of file G4Trd.icc.

Referenced by G4HepRepSceneHandler::AddSolid(), G4HepRepFileSceneHandler::AddSolid(), G4ParameterisationTrdY::CheckParametersValidity(), G4ParameterisationTrdZ::ComputeDimensions(), G4ParameterisationTrdX::ComputeDimensions(), G4VParameterisationTrd::G4VParameterisationTrd(), G4tgbGeometryDumper::GetSolidParams(), G4GDMLWriteParamvol::Trd_dimensionsWrite(), and G4GDMLWriteSolids::TrdWrite().

00057 {
00058   return fDy2;
00059 }

G4double G4Trd::GetZHalfLength (  )  const [inline]

Definition at line 62 of file G4Trd.icc.

Referenced by G4HepRepSceneHandler::AddSolid(), G4HepRepFileSceneHandler::AddSolid(), G4ParameterisationTrdZ::ComputeDimensions(), G4ParameterisationTrdY::ComputeDimensions(), G4ParameterisationTrdX::ComputeDimensions(), G4ParameterisationTrdZ::ComputeTransformation(), G4ParameterisationTrdZ::G4ParameterisationTrdZ(), G4VParameterisationTrd::G4VParameterisationTrd(), G4ParameterisationTrdZ::GetMaxParameter(), G4tgbGeometryDumper::GetSolidParams(), G4GDMLWriteParamvol::Trd_dimensionsWrite(), and G4GDMLWriteSolids::TrdWrite().

00063 {
00064   return fDz;
00065 }

EInside G4Trd::Inside ( const G4ThreeVector p  )  const [virtual]

Implements G4VSolid.

Definition at line 371 of file G4Trd.cc.

References G4VSolid::kCarTolerance, kInside, kOutside, and kSurface.

Referenced by CalculateExtent(), and DistanceToOut().

00372 {  
00373   EInside in=kOutside;
00374   G4double x,y,zbase1,zbase2;
00375     
00376   if (std::fabs(p.z())<=fDz-kCarTolerance/2)
00377   {
00378     zbase1=p.z()+fDz;  // Dist from -ve z plane
00379     zbase2=fDz-p.z();  // Dist from +ve z plane
00380 
00381     // Check whether inside x tolerance
00382     //
00383     x=0.5*(fDx2*zbase1+fDx1*zbase2)/fDz - kCarTolerance/2;
00384     if (std::fabs(p.x())<=x)
00385     {
00386       y=0.5*((fDy2*zbase1+fDy1*zbase2))/fDz - kCarTolerance/2;
00387       if (std::fabs(p.y())<=y)
00388       {
00389         in=kInside;
00390       }
00391       else if (std::fabs(p.y())<=y+kCarTolerance)
00392       {
00393         in=kSurface;
00394       }
00395     }
00396     else if (std::fabs(p.x())<=x+kCarTolerance)
00397     {
00398       // y = y half width of shape at z of point + tolerant boundary
00399       //
00400       y=0.5*((fDy2*zbase1+fDy1*zbase2))/fDz + kCarTolerance/2;
00401       if (std::fabs(p.y())<=y)
00402       {
00403         in=kSurface;
00404       }
00405     }
00406   }
00407   else if (std::fabs(p.z())<=fDz+kCarTolerance/2)
00408   {
00409     // Only need to check outer tolerant boundaries
00410     //
00411     zbase1=p.z()+fDz;  // Dist from -ve z plane
00412     zbase2=fDz-p.z();   // Dist from +ve z plane
00413 
00414     // x = x half width of shape at z of point plus tolerance
00415     //
00416     x=0.5*(fDx2*zbase1+fDx1*zbase2)/fDz + kCarTolerance/2;
00417     if (std::fabs(p.x())<=x)
00418     {
00419       // y = y half width of shape at z of point
00420       //
00421       y=0.5*((fDy2*zbase1+fDy1*zbase2))/fDz + kCarTolerance/2;
00422       if (std::fabs(p.y())<=y) in=kSurface;
00423     }
00424   }  
00425   return in;
00426 }

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

Definition at line 146 of file G4Trd.cc.

References fDx1, fDx2, fDy1, fDy2, fDz, and G4CSGSolid::operator=().

00147 {
00148    // Check assignment to self
00149    //
00150    if (this == &rhs)  { return *this; }
00151 
00152    // Copy base class data
00153    //
00154    G4CSGSolid::operator=(rhs);
00155 
00156    // Copy data
00157    //
00158    fDx1 = rhs.fDx1; fDx2 = rhs.fDx2;
00159    fDy1 = rhs.fDy1; fDy2 = rhs.fDy2;
00160    fDz = rhs.fDz;
00161 
00162    return *this;
00163 }

void G4Trd::SetAllParameters ( G4double  pdx1,
G4double  pdx2,
G4double  pdy1,
G4double  pdy2,
G4double  pdz 
)

Definition at line 169 of file G4Trd.cc.

References CheckAndSetAllParameters().

Referenced by G4ParameterisationTrdZ::ComputeDimensions(), G4ParameterisationTrdY::ComputeDimensions(), and G4ParameterisationTrdX::ComputeDimensions().

00171 {
00172   CheckAndSetAllParameters (pdx1, pdx2, pdy1, pdy2, pdz);
00173 }

void G4Trd::SetXHalfLength1 ( G4double  val  )  [inline]

Definition at line 68 of file G4Trd.icc.

References G4CSGSolid::fCubicVolume, G4CSGSolid::fpPolyhedron, and G4CSGSolid::fSurfaceArea.

00069 {
00070   fDx1= val;
00071   fCubicVolume= 0.;
00072   fSurfaceArea=0;
00073   fpPolyhedron = 0;
00074 }

void G4Trd::SetXHalfLength2 ( G4double  val  )  [inline]

Definition at line 77 of file G4Trd.icc.

References G4CSGSolid::fCubicVolume, G4CSGSolid::fpPolyhedron, and G4CSGSolid::fSurfaceArea.

00078 {
00079   fDx2= val;
00080   fCubicVolume= 0.;
00081   fSurfaceArea=0;
00082   fpPolyhedron = 0;
00083 }

void G4Trd::SetYHalfLength1 ( G4double  val  )  [inline]

Definition at line 86 of file G4Trd.icc.

References G4CSGSolid::fCubicVolume, G4CSGSolid::fpPolyhedron, and G4CSGSolid::fSurfaceArea.

00087 {
00088   fDy1= val;
00089   fCubicVolume= 0.;
00090   fSurfaceArea=0;
00091   fpPolyhedron = 0;
00092 }

void G4Trd::SetYHalfLength2 ( G4double  val  )  [inline]

Definition at line 95 of file G4Trd.icc.

References G4CSGSolid::fCubicVolume, G4CSGSolid::fpPolyhedron, and G4CSGSolid::fSurfaceArea.

00096 {
00097   fDy2= val;
00098   fCubicVolume= 0.;
00099   fSurfaceArea=0;
00100   fpPolyhedron = 0;
00101 }

void G4Trd::SetZHalfLength ( G4double  val  )  [inline]

Definition at line 104 of file G4Trd.icc.

References G4CSGSolid::fCubicVolume, G4CSGSolid::fpPolyhedron, and G4CSGSolid::fSurfaceArea.

00105 {
00106   fDz= val;
00107   fCubicVolume= 0.;
00108   fSurfaceArea=0;
00109   fpPolyhedron = 0;
00110 }

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

Reimplemented from G4CSGSolid.

Definition at line 1376 of file G4Trd.cc.

References G4VSolid::GetName().

01377 {
01378   G4int oldprc = os.precision(16);
01379   os << "-----------------------------------------------------------\n"
01380      << "    *** Dump for solid - " << GetName() << " ***\n"
01381      << "    ===================================================\n"
01382      << " Solid type: G4Trd\n"
01383      << " Parameters: \n"
01384      << "    half length X, surface -dZ: " << fDx1/mm << " mm \n"
01385      << "    half length X, surface +dZ: " << fDx2/mm << " mm \n"
01386      << "    half length Y, surface -dZ: " << fDy1/mm << " mm \n"
01387      << "    half length Y, surface +dZ: " << fDy2/mm << " mm \n"
01388      << "    half length Z             : " << fDz/mm << " mm \n"
01389      << "-----------------------------------------------------------\n";
01390   os.precision(oldprc);
01391 
01392   return os;
01393 }

G4ThreeVector G4Trd::SurfaceNormal ( const G4ThreeVector p  )  const [virtual]

Implements G4VSolid.

Definition at line 434 of file G4Trd.cc.

References ApproxSurfaceNormal(), fcos(), G4Exception(), JustWarning, and G4VSolid::kCarTolerance.

00435 {
00436   G4ThreeVector norm, sumnorm(0.,0.,0.);
00437   G4int noSurfaces = 0; 
00438   G4double z = 2.0*fDz, tanx, secx, newpx, widx;
00439   G4double tany, secy, newpy, widy;
00440   G4double distx, disty, distz, fcos;
00441   G4double delta = 0.5*kCarTolerance;
00442 
00443   tanx  = (fDx2 - fDx1)/z;
00444   secx  = std::sqrt(1.0+tanx*tanx);
00445   newpx = std::fabs(p.x())-p.z()*tanx;
00446   widx  = fDx2 - fDz*tanx;
00447 
00448   tany  = (fDy2 - fDy1)/z;
00449   secy  = std::sqrt(1.0+tany*tany);
00450   newpy = std::fabs(p.y())-p.z()*tany;
00451   widy  = fDy2 - fDz*tany;
00452 
00453   distx = std::fabs(newpx-widx)/secx;       // perp. distance to x side
00454   disty = std::fabs(newpy-widy)/secy;       //                to y side
00455   distz = std::fabs(std::fabs(p.z())-fDz);  //                to z side
00456 
00457   fcos              = 1.0/secx;
00458   G4ThreeVector nX  = G4ThreeVector( fcos,0,-tanx*fcos);
00459   G4ThreeVector nmX = G4ThreeVector(-fcos,0,-tanx*fcos);
00460 
00461   fcos              = 1.0/secy;
00462   G4ThreeVector nY  = G4ThreeVector(0, fcos,-tany*fcos);
00463   G4ThreeVector nmY = G4ThreeVector(0,-fcos,-tany*fcos);
00464   G4ThreeVector nZ  = G4ThreeVector( 0, 0,  1.0);
00465  
00466   if (distx <= delta)      
00467   {
00468     noSurfaces ++;
00469     if ( p.x() >= 0.) sumnorm += nX;
00470     else              sumnorm += nmX;   
00471   }
00472   if (disty <= delta)
00473   {
00474     noSurfaces ++;
00475     if ( p.y() >= 0.) sumnorm += nY;
00476     else              sumnorm += nmY;   
00477   }
00478   if (distz <= delta)  
00479   {
00480     noSurfaces ++;
00481     if ( p.z() >= 0.) sumnorm += nZ;
00482     else              sumnorm -= nZ; 
00483   }
00484   if ( noSurfaces == 0 )
00485   {
00486 #ifdef G4CSGDEBUG
00487     G4Exception("G4Trd::SurfaceNormal(p)", "GeomSolids1002", JustWarning, 
00488                 "Point p is not on surface !?" );
00489 #endif 
00490      norm = ApproxSurfaceNormal(p);
00491   }
00492   else if ( noSurfaces == 1 ) norm = sumnorm;
00493   else                        norm = sumnorm.unit();
00494   return norm;   
00495 }


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