G4ConicalSurface Class Reference

#include <G4ConicalSurface.hh>

Inheritance diagram for G4ConicalSurface:

G4Surface G4STEPEntity

Public Member Functions

 G4ConicalSurface ()
 G4ConicalSurface (const G4Point3D &o, const G4Vector3D &a, G4double e)
virtual ~G4ConicalSurface ()
G4int operator== (const G4ConicalSurface &c)
G4String GetEntityType () const
virtual const char * NameOf () const
virtual void PrintOn (std::ostream &os=G4cout) const
virtual G4double HowNear (const G4Vector3D &x) const
void CalcBBox ()
G4int Intersect (const G4Ray &ry)
virtual G4Vector3D SurfaceNormal (const G4Point3D &p) const
virtual G4int Inside (const G4Vector3D &x) const
virtual G4int WithinBoundary (const G4Vector3D &x) const
virtual G4double Scale () const
G4Vector3D GetAxis () const
G4double GetAngle () const
void SetAngle (G4double e)

Detailed Description

Definition at line 51 of file G4ConicalSurface.hh.


Constructor & Destructor Documentation

G4ConicalSurface::G4ConicalSurface (  ) 

Definition at line 42 of file G4ConicalSurface.cc.

00043   : G4Surface(), axis(G4Vector3D(1.,0.,0.)), angle(1.)
00044 {  
00045 }

G4ConicalSurface::G4ConicalSurface ( const G4Point3D o,
const G4Vector3D a,
G4double  e 
)

Definition at line 47 of file G4ConicalSurface.cc.

References G4endl, G4Exception(), JustWarning, and G4INCL::Math::pi.

00050   : G4Surface()
00051 {  
00052   // Normal constructor
00053   // require axis to be a unit vector
00054 
00055   G4double amag = a.mag2();
00056 
00057   if ( amag != 0.0 )
00058   {
00059     axis = a*(1/amag);
00060   }
00061   else
00062   {
00063     std::ostringstream message;
00064     message << "Axis has zero length." << G4endl
00065             << "Default axis ( 1.0, 0.0, 0.0 ) is used.";
00066     G4Exception("G4ConicalSurface::G4ConicalSurface()", "GeomSolids1001",
00067                 JustWarning, message);
00068 
00069     axis = G4Vector3D( 1.0, 0.0, 0.0 );
00070   }
00071 
00072   //  Require angle to range from 0 to PI/2
00073   //
00074   if ( ( e > 0.0 ) && ( e < ( 0.5 * pi ) ) )
00075   {
00076     angle = e;
00077   }
00078   else
00079   {
00080     std::ostringstream message;
00081     message << "Angle out of range." << G4endl
00082             << "Asked for angle out of allowed range of 0 to "
00083             << 0.5*pi << " (PI/2): " << e << G4endl
00084             << "Default angle of 1.0 is used.";    
00085     G4Exception("G4ConicalSurface::G4ConicalSurface()", "GeomSolids1001",
00086                 JustWarning, message);
00087     angle = 1.0;
00088   }
00089 }

G4ConicalSurface::~G4ConicalSurface (  )  [virtual]

Definition at line 92 of file G4ConicalSurface.cc.

00093 {
00094 }


Member Function Documentation

void G4ConicalSurface::CalcBBox (  )  [virtual]

Reimplemented from G4Surface.

Definition at line 119 of file G4ConicalSurface.cc.

References G4SurfaceBoundary::BBox(), G4Surface::bbox, G4BoundingBox3D::GetBoxMax(), G4BoundingBox3D::GetBoxMin(), and G4Surface::surfaceBoundary.

00120 {
00121   bbox= new G4BoundingBox3D(surfaceBoundary.BBox().GetBoxMin(), 
00122                             surfaceBoundary.BBox().GetBoxMax());
00123 }

G4double G4ConicalSurface::GetAngle (  )  const [inline]

Definition at line 56 of file G4ConicalSurface.icc.

Referenced by Intersect().

00057 {
00058   return angle;
00059 }

G4Vector3D G4ConicalSurface::GetAxis (  )  const [inline]

Definition at line 50 of file G4ConicalSurface.icc.

Referenced by Intersect().

00051 {
00052   return axis;
00053 }

G4String G4ConicalSurface::GetEntityType (  )  const [inline, virtual]

Reimplemented from G4Surface.

Definition at line 38 of file G4ConicalSurface.icc.

00039 {
00040   return G4String("Conical_Surface");
00041 }

G4double G4ConicalSurface::HowNear ( const G4Vector3D x  )  const [virtual]

Reimplemented from G4Surface.

Definition at line 134 of file G4ConicalSurface.cc.

References G4Surface::origin.

Referenced by Inside(), Intersect(), and WithinBoundary().

00135 { 
00136   // Distance from the point x to the semi-infinite G4ConicalSurface.
00137   // The distance will be positive if the point is Inside the G4ConicalSurface,
00138   // negative if the point is outside.
00139   // Note that this may not be correct for a bounded conical object
00140   // subclassed to G4ConicalSurface.
00141 
00142   G4Vector3D d    = G4Vector3D( x - origin );
00143   G4double   l    = d * axis;
00144   G4Vector3D q    = G4Vector3D( origin  +  l * axis );
00145   G4Vector3D v    = G4Vector3D( x - q );
00146 
00147   G4double   Dist = ( l*std::tan(angle) - v.mag2() ) * std::cos(angle);
00148 
00149   return Dist;
00150 }

G4int G4ConicalSurface::Inside ( const G4Vector3D x  )  const [virtual]

Definition at line 538 of file G4ConicalSurface.cc.

References HowNear(), and G4Surface::kCarTolerance.

00539 { 
00540   // Return 0 if point x is outside G4ConicalSurface, 1 if Inside.
00541   // Outside means that the distance to the G4ConicalSurface would be negative.
00542   // Use the HowNear function to calculate this distance.
00543 
00544   if ( HowNear( x ) >= -0.5*kCarTolerance )
00545     { return 1; }
00546   else
00547     { return 0; }
00548 }

G4int G4ConicalSurface::Intersect ( const G4Ray ry  )  [virtual]

Reimplemented from G4Surface.

Definition at line 153 of file G4ConicalSurface.cc.

References G4Surface::closest_hit, G4Surface::distance, GetAngle(), GetAxis(), G4Ray::GetDir(), G4Surface::GetOrigin(), G4Ray::GetPoint(), G4Ray::GetStart(), HowNear(), G4Surface::kCarTolerance, sort_double(), and SurfaceNormal().

00154 {
00155   //  Distance along a Ray (straight line with G4Vector3D) to leave or enter
00156   //  a G4ConicalSurface.  The input variable which_way should be set to +1 to
00157   //  indicate leaving a G4ConicalSurface, -1 to indicate entering a 
00158   //  G4ConicalSurface.
00159   //  p is the point of intersection of the Ray with the G4ConicalSurface.
00160   //  If the G4Vector3D of the Ray is opposite to that of the Normal to
00161   //  the G4ConicalSurface at the intersection point, it will not leave the 
00162   //  G4ConicalSurface.
00163   //  Similarly, if the G4Vector3D of the Ray is along that of the Normal 
00164   //  to the G4ConicalSurface at the intersection point, it will not enter the
00165   //  G4ConicalSurface.
00166   //  This method is called by all finite shapes sub-classed to 
00167   //  G4ConicalSurface.
00168   //  Use the virtual function table to check if the intersection point
00169   //  is within the boundary of the finite shape.
00170   //  A negative result means no intersection.
00171   //  If no valid intersection point is found, set the distance
00172   //  and intersection point to large numbers.
00173   
00174   G4int which_way = -1; // Originally a parameter.Read explanation above. 
00175 
00176   distance = kInfinity;
00177 
00178   G4Vector3D lv ( kInfinity, kInfinity, kInfinity );
00179   closest_hit = lv;
00180 
00181   //  Origin and G4Vector3D unit vector of Ray.
00182   //
00183   G4Vector3D x = G4Vector3D( ry.GetStart() );
00184   G4Vector3D dhat = ry.GetDir();
00185   
00186   
00187   //  Cone angle and axis unit vector.
00188   //
00189   G4double   ta      = std::tan( GetAngle() );
00190   G4Vector3D ahat    = GetAxis();
00191   G4int      isoln   = 0, 
00192              maxsoln = 2;
00193 
00194   //  array of solutions in distance along the Ray
00195   //
00196   G4double sol[2];
00197   sol[0] = -1.0; 
00198   sol[1] = -1.0 ;
00199 
00200   //  calculate the two solutions (quadratic equation)
00201   //
00202   G4Vector3D gamma = G4Vector3D( x - GetOrigin() );
00203   G4double   T  = 1.0  +  ta * ta;
00204   G4double   ga = gamma * ahat;
00205   G4double   da = dhat * ahat;
00206   G4double   A  = 1.0 - T * da * da;
00207   G4double   B  = 2.0 * ( gamma * dhat - T * ga * da );
00208   G4double   C  = gamma * gamma - T * ga * ga;
00209 
00210   //  if quadratic term vanishes, just do the simple solution
00211   //
00212   if ( std::fabs( A ) < kCarTolerance ) 
00213   {
00214     if ( B == 0.0 )
00215       { return 1; }
00216     else
00217       { sol[0] = -C / B; }
00218   }
00219 
00220   //  Normal quadratic case, no intersection if radical is less than zero
00221   //
00222   else 
00223   {
00224     G4double radical = B * B  -  4.0 * A * C; 
00225     if ( radical < 0.0 ) 
00226     {
00227       return 1;
00228     }
00229     else 
00230     {
00231       G4double root = std::sqrt( radical );
00232       sol[0] = ( - B + root ) / ( 2. * A );
00233       sol[1] = ( - B - root ) / ( 2. * A );
00234     }
00235   }
00236 
00237   //  order the possible solutions by increasing distance along the Ray
00238   //
00239   sort_double( sol, isoln, maxsoln-1 );
00240 
00241   //  now loop over each positive solution, keeping the first one (smallest
00242   //  distance along the Ray) which is within the boundary of the sub-shape
00243   //  and which also has the correct G4Vector3D with respect to the Normal to
00244   //  the G4ConicalSurface at the intersection point
00245   //
00246   for ( isoln = 0; isoln < maxsoln; isoln++ ) 
00247   {
00248     if ( sol[isoln] >= 0.0 ) 
00249     {
00250       if ( sol[isoln] >= kInfinity )  // quit if too large
00251       {
00252         return 1;
00253       }
00254       
00255       distance = sol[isoln];
00256       closest_hit = ry.GetPoint( distance );
00257 
00258       //  Following line necessary to select non-reflective solutions.
00259       //
00260       if (( ahat * ( closest_hit - GetOrigin() ) > 0.0 ) && 
00261           ((( dhat * SurfaceNormal( closest_hit ) * which_way )) >= 0.0 ) && 
00262           ( std::fabs(HowNear( closest_hit )) < 0.1)                               )
00263       {
00264         return 1;
00265       }
00266     }
00267   }
00268 
00269   //  get here only if there was no solution within the boundary, Reset
00270   //  distance and intersection point to large numbers
00271   //
00272   distance = kInfinity;
00273   closest_hit = lv;
00274 
00275   return 0;
00276 }

const char * G4ConicalSurface::NameOf (  )  const [virtual]

Definition at line 114 of file G4ConicalSurface.cc.

00115 {
00116    return "G4ConicalSurface";
00117 }

G4int G4ConicalSurface::operator== ( const G4ConicalSurface c  )  [inline]

Definition at line 44 of file G4ConicalSurface.icc.

References angle, axis, and G4Surface::origin.

00045 { 
00046   return origin == c.origin  &&  axis == c.axis && angle == c.angle; 
00047 }

void G4ConicalSurface::PrintOn ( std::ostream &  os = G4cout  )  const [virtual]

Definition at line 125 of file G4ConicalSurface.cc.

References G4Surface::origin.

00126 { 
00127   // printing function using C++ std::ostream class
00128 
00129   os << "G4ConicalSurface surface with origin: " << origin << "\t"
00130      << "angle: " << angle << " radians \tand axis " << axis << "\n";
00131 }

G4double G4ConicalSurface::Scale (  )  const [virtual]

Definition at line 562 of file G4ConicalSurface.cc.

Referenced by WithinBoundary().

00563 {
00564   return 1.0;
00565 }

void G4ConicalSurface::SetAngle ( G4double  e  ) 

Definition at line 567 of file G4ConicalSurface.cc.

References G4endl, G4Exception(), JustWarning, and G4INCL::Math::pi.

00568 {
00569   //  Reset the angle of the G4ConicalSurface
00570   //  Require angle to range from 0 to PI/2
00571 
00572   if ( (e > 0.0) && (e <= ( 0.5 * pi )) )
00573   {
00574     angle = e;
00575   }
00576   else   // use old value (do not change angle) if out of the range, 
00577   {      // but print warning message
00578     std::ostringstream message;
00579     message << "Angle out of range." << G4endl
00580             << "Asked for angle out of allowed range of 0 to "
00581             << 0.5*pi << " (PI/2): " << e << G4endl
00582             << "Default angle of " << angle << " is used.";    
00583     G4Exception("G4ConicalSurface::SetAngle()", "GeomSolids1001",
00584                 JustWarning, message);
00585   }
00586 }

G4Vector3D G4ConicalSurface::SurfaceNormal ( const G4Point3D p  )  const [virtual]

Implements G4Surface.

Definition at line 497 of file G4ConicalSurface.cc.

References G4InuclParticleNames::ap, CLHEP::detail::n, and G4Surface::origin.

Referenced by Intersect().

00498 {  
00499   //  return the Normal unit vector to the G4ConicalSurface at a point p 
00500   //  on (or nearly on) the G4ConicalSurface
00501 
00502   G4Vector3D ss   = G4Vector3D( p - origin );
00503   G4double   smag = ss.mag2();
00504   
00505   //  if the point happens to be at the origin, calculate a unit vector Normal
00506   //  to the axis, with zero z component
00507   //
00508   if ( smag == 0.0 )
00509   {
00510     G4double ax = axis.x();
00511     G4double ay = axis.y();
00512     G4double ap = std::sqrt( ax * ax  +  ay * ay );
00513 
00514     if ( ap == 0.0 )
00515       { return G4Vector3D( 1.0, 0.0, 0.0 ); }
00516     else
00517       { return G4Vector3D( ay / ap, -ax / ap, 0.0 ); }
00518   }
00519   else  // otherwise do the calculation of the Normal to the conical surface
00520   {
00521     G4double l = ss * axis;
00522     ss = ss*(1/smag);
00523     G4Vector3D q    = G4Vector3D( origin  +  l * axis );
00524     G4Vector3D v    = G4Vector3D( p - q );
00525     G4double   sl   = v.mag2() * std::sin( angle );
00526     G4Vector3D n    = G4Vector3D( v - sl * ss );
00527     G4double   nmag = n.mag2(); 
00528 
00529     if ( nmag != 0.0 )
00530     {
00531       n=n*(1/nmag);
00532     }
00533     return n;
00534   }
00535 }

G4int G4ConicalSurface::WithinBoundary ( const G4Vector3D x  )  const [virtual]

Definition at line 551 of file G4ConicalSurface.cc.

References HowNear(), Scale(), and SURFACE_PRECISION.

00552 {  
00553   //  return 1 if point x is on the G4ConicalSurface, otherwise return zero
00554   //  base this on the surface precision factor
00555 
00556   if ( std::fabs( HowNear( x ) / Scale() ) <= SURFACE_PRECISION )
00557     { return 1; }
00558   else
00559     { return 0; }
00560 }


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