#include <G4CylindricalSurface.hh>
Inheritance diagram for G4CylindricalSurface:
Public Member Functions | |
G4CylindricalSurface () | |
G4CylindricalSurface (const G4Vector3D &o, const G4Vector3D &a, G4double r) | |
virtual | ~G4CylindricalSurface () |
G4int | operator== (const G4CylindricalSurface &c) const |
G4String | GetEntityType () const |
virtual const char * | NameOf () const |
virtual void | PrintOn (std::ostream &os=G4cout) const |
virtual G4double | HowNear (const G4Vector3D &x) const |
virtual G4Vector3D | Normal (const G4Vector3D &p) const |
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 |
G4int | Intersect (const G4Ray &ry) |
G4Vector3D | GetAxis () const |
G4double | GetRadius () const |
void | SetRadius (G4double r) |
Protected Attributes | |
G4Vector3D | axis |
G4double | radius |
Definition at line 48 of file G4CylindricalSurface.hh.
G4CylindricalSurface::G4CylindricalSurface | ( | ) |
Definition at line 40 of file G4CylindricalSurface.cc.
00040 : G4Surface() 00041 { 00042 // default constructor 00043 // default axis is ( 1.0, 0.0, 0.0 ), default radius is 1.0 00044 00045 axis = G4Vector3D( 1.0, 0.0, 0.0 ); 00046 radius = 1.0; 00047 }
G4CylindricalSurface::G4CylindricalSurface | ( | const G4Vector3D & | o, | |
const G4Vector3D & | a, | |||
G4double | r | |||
) |
Definition at line 50 of file G4CylindricalSurface.cc.
References axis, G4endl, G4Exception(), JustWarning, G4Surface::origin, and radius.
00053 : G4Surface() 00054 { 00055 // Normal constructor 00056 // require axis to be a unit vector 00057 00058 G4double amag = a.mag(); 00059 if ( amag != 0.0 ) 00060 { 00061 axis = a * (1/ amag); // this makes the axis a unit vector 00062 } 00063 else 00064 { 00065 std::ostringstream message; 00066 message << "Axis has zero length." << G4endl 00067 << "Default axis ( 1.0, 0.0, 0.0 ) is used."; 00068 G4Exception("G4CylindricalSurface::G4CylindricalSurface()", 00069 "GeomSolids1001", JustWarning, message); 00070 00071 axis = G4Vector3D( 1.0, 0.0, 0.0 ); 00072 } 00073 00074 // Require radius to be non-negative 00075 // 00076 if ( r >= 0.0 ) 00077 { 00078 radius = r; 00079 } 00080 else 00081 { 00082 std::ostringstream message; 00083 message << "Negative radius." << G4endl 00084 << "Default radius of 1.0 is used."; 00085 G4Exception("G4CylindricalSurface::G4CylindricalSurface()", 00086 "GeomSolids1001", JustWarning, message); 00087 00088 radius = 1.0; 00089 } 00090 00091 origin =o; 00092 }
G4CylindricalSurface::~G4CylindricalSurface | ( | ) | [virtual] |
G4Vector3D G4CylindricalSurface::GetAxis | ( | ) | const [inline] |
Definition at line 52 of file G4CylindricalSurface.icc.
References axis.
Referenced by Intersect().
00053 { 00054 return axis; 00055 }
G4String G4CylindricalSurface::GetEntityType | ( | ) | const [inline, virtual] |
Reimplemented from G4Surface.
Definition at line 46 of file G4CylindricalSurface.icc.
00047 { 00048 return G4String("Cylindrical_Surface"); 00049 }
G4double G4CylindricalSurface::GetRadius | ( | ) | const [inline] |
Definition at line 58 of file G4CylindricalSurface.icc.
References radius.
Referenced by Intersect().
00059 { 00060 return radius; 00061 }
G4double G4CylindricalSurface::HowNear | ( | const G4Vector3D & | x | ) | const [virtual] |
Reimplemented from G4Surface.
Definition at line 241 of file G4CylindricalSurface.cc.
References axis, G4Surface::origin, and radius.
Referenced by Inside(), and WithinBoundary().
00242 { 00243 // Distance from the point x to the infinite G4CylindricalSurface. 00244 // The distance will be positive if the point is Inside the 00245 // G4CylindricalSurface, negative if the point is outside. 00246 // Note that this may not be correct for a bounded cylindrical object 00247 // subclassed to G4CylindricalSurface. 00248 00249 G4Vector3D d = x - origin; 00250 G4double dA = d * axis; 00251 G4double rds = std::sqrt( d.mag2() - dA*dA ); 00252 G4double hownear = std::fabs( radius - rds ); 00253 00254 return hownear; 00255 }
G4int G4CylindricalSurface::Inside | ( | const G4Vector3D & | x | ) | const [virtual] |
Definition at line 868 of file G4CylindricalSurface.cc.
References HowNear(), and G4Surface::kCarTolerance.
Referenced by Intersect().
00869 { 00870 // Return 0 if point x is outside G4CylindricalSurface, 1 if Inside. 00871 // Outside means that the distance to the G4CylindricalSurface would 00872 // be negative. Use the HowNear function to calculate this distance. 00873 00874 if ( HowNear( x ) >= -0.5*kCarTolerance ) 00875 { return 1; } 00876 else 00877 { return 0; } 00878 }
Reimplemented from G4Surface.
Definition at line 128 of file G4CylindricalSurface.cc.
References G4Surface::closest_hit, G4Surface::distance, GetAxis(), G4Ray::GetDir(), G4Surface::GetOrigin(), G4Ray::GetPoint(), GetRadius(), G4Ray::GetStart(), Inside(), G4Surface::kCarTolerance, Normal(), sort_double(), and WithinBoundary().
00129 { 00130 // Distance along a Ray (straight line with G4ThreeVec) to leave or enter 00131 // a G4CylindricalSurface. The input variable which_way should be set 00132 // to +1 to indicate leaving a G4CylindricalSurface, -1 to indicate 00133 // entering a G4CylindricalSurface. 00134 // p is the point of intersection of the Ray with the G4CylindricalSurface. 00135 // If the G4Vector3D of the Ray is opposite to that of the Normal to 00136 // the G4CylindricalSurface at the intersection point, it will not leave 00137 // the G4CylindricalSurface. 00138 // Similarly, if the G4Vector3D of the Ray is along that of the Normal 00139 // to the G4CylindricalSurface at the intersection point, it will not enter 00140 // the G4CylindricalSurface. 00141 // This method is called by all finite shapes sub-classed to 00142 // G4CylindricalSurface. 00143 // Use the virtual function table to check if the intersection point 00144 // is within the boundary of the finite shape. 00145 // A negative result means no intersection. 00146 // If no valid intersection point is found, set the distance 00147 // and intersection point to large numbers. 00148 00149 G4int which_way=1; 00150 00151 if(!Inside(ry.GetStart())) { which_way = -1; } 00152 00153 distance = kInfinity; 00154 G4Vector3D lv ( kInfinity, kInfinity, kInfinity ); 00155 00156 closest_hit = lv; 00157 00158 // Origin and G4Vector3D unit vector of Ray. 00159 // 00160 G4Vector3D x = ry.GetStart(); 00161 G4Vector3D dhat = ry.GetDir(); 00162 00163 // Axis unit vector of the G4CylindricalSurface. 00164 // 00165 G4Vector3D ahat = GetAxis(); 00166 G4int isoln = 0, 00167 maxsoln = 2; 00168 00169 // Array of solutions in distance along the Ray. 00170 // 00171 G4double sol[2]; 00172 sol[0] = -1.0; 00173 sol[1] = -1.0 ; 00174 00175 // Calculate the two solutions (quadratic equation) 00176 // 00177 G4Vector3D d = x - GetOrigin(); 00178 G4double radiu = GetRadius(); 00179 00180 G4double dsq = d * d; 00181 G4double da = d * ahat; 00182 G4double dasq = da * da; 00183 G4double rsq = radiu * radiu; 00184 G4double qsq = dsq - dasq; 00185 G4double dira = dhat * ahat; 00186 G4double a = 1.0 - dira * dira; 00187 00188 if ( a <= 0.0 ) { return 0; } 00189 00190 G4double b = 2. * ( d * dhat - da * dira ); 00191 G4double c = rsq - qsq; 00192 G4double radical = b * b + 4. * a * c; 00193 00194 if ( radical < 0.0 ) { return 0; } 00195 00196 G4double root = std::sqrt( radical ); 00197 sol[0] = ( - b + root ) / ( 2. * a ); 00198 sol[1] = ( - b - root ) / ( 2. * a ); 00199 00200 // Order the possible solutions by increasing distance along the Ray 00201 // 00202 sort_double( sol, isoln, maxsoln-1 ); 00203 00204 // Now loop over each positive solution, keeping the first one (smallest 00205 // distance along the Ray) which is within the boundary of the sub-shape 00206 // and which also has the correct G4Vector3D with respect to the Normal to 00207 // the G4CylindricalSurface at the intersection point 00208 // 00209 for ( isoln = 0; isoln < maxsoln; isoln++ ) 00210 { 00211 if ( sol[isoln] >= kCarTolerance*0.5 ) 00212 { 00213 if ( sol[isoln] >= kInfinity ) // quit if too large 00214 { return 0; } 00215 00216 distance = sol[isoln]; 00217 closest_hit = ry.GetPoint( distance ); 00218 G4double tmp = dhat * (Normal( closest_hit )); 00219 00220 if ((tmp * which_way) >= 0.0 ) 00221 { 00222 if ( WithinBoundary( closest_hit ) == 1 ) 00223 { 00224 distance = distance*distance; 00225 } 00226 } 00227 return 1; 00228 } 00229 } 00230 00231 // Get here only if there was no solution within the boundary, Reset 00232 // distance and intersection point to large numbers 00233 // 00234 distance = kInfinity; 00235 closest_hit = lv; 00236 00237 return 0; 00238 }
const char * G4CylindricalSurface::NameOf | ( | ) | const [virtual] |
G4Vector3D G4CylindricalSurface::Normal | ( | const G4Vector3D & | p | ) | const [virtual] |
Reimplemented from G4Surface.
Definition at line 840 of file G4CylindricalSurface.cc.
References axis, CLHEP::detail::n, and G4Surface::origin.
Referenced by Intersect().
00841 { 00842 // return the Normal unit vector to the G4CylindricalSurface 00843 // at a point p on (or nearly on) the G4CylindricalSurface 00844 00845 G4Vector3D n = ( p - origin ) - ( ( p - origin ) * axis ) * axis; 00846 G4double nmag = n.mag(); 00847 00848 if ( nmag != 0.0 ) { n = n * (1/nmag); } 00849 00850 return n; 00851 }
G4int G4CylindricalSurface::operator== | ( | const G4CylindricalSurface & | c | ) | const [inline] |
void G4CylindricalSurface::PrintOn | ( | std::ostream & | os = G4cout |
) | const [virtual] |
Definition at line 122 of file G4CylindricalSurface.cc.
References axis, G4Surface::origin, and radius.
00123 { 00124 os << "G4CylindricalSurface surface with origin: " << origin << "\t" 00125 << "radius: " << radius << "\tand axis " << axis << "\n"; 00126 }
G4double G4CylindricalSurface::Scale | ( | ) | const [virtual] |
Definition at line 893 of file G4CylindricalSurface.cc.
References radius.
Referenced by WithinBoundary().
00894 { 00895 // Returns the radius of a G4CylindricalSurface unless it is zero, in which 00896 // case returns the arbitrary number 1.0. 00897 // This is ok since derived finite-sized classes will overwrite this. 00898 // Used for Scale-invariant tests of surface thickness. 00899 00900 if ( radius == 0.0 ) 00901 { return 1.0; } 00902 else 00903 { return radius; } 00904 }
void G4CylindricalSurface::SetRadius | ( | G4double | r | ) |
Definition at line 942 of file G4CylindricalSurface.cc.
References G4endl, G4Exception(), JustWarning, and radius.
00943 { 00944 // Reset the radius of the G4CylindricalSurface 00945 // Require radius to be non-negative 00946 00947 if ( r >= 0.0 ) { radius = r; } 00948 else // Use old value (do not change radius) if out of the range, 00949 { // but print warning message 00950 std::ostringstream message; 00951 message << "Negative radius." << G4endl 00952 << "Default radius of " << radius << " is used."; 00953 G4Exception("G4CylindricalSurface::SetRadius()", 00954 "GeomSolids1001", JustWarning, message); 00955 } 00956 }
G4Vector3D G4CylindricalSurface::SurfaceNormal | ( | const G4Point3D & | p | ) | const [virtual] |
Implements G4Surface.
Definition at line 854 of file G4CylindricalSurface.cc.
References axis, CLHEP::detail::n, and G4Surface::origin.
00855 { 00856 // return the Normal unit vector to the G4CylindricalSurface at a point 00857 // p on (or nearly on) the G4CylindricalSurface 00858 00859 G4Vector3D n = ( p - origin ) - ( ( p - origin ) * axis ) * axis; 00860 G4double nmag = n.mag(); 00861 00862 if ( nmag != 0.0 ) { n = n * (1/nmag); } 00863 00864 return n; 00865 }
G4int G4CylindricalSurface::WithinBoundary | ( | const G4Vector3D & | x | ) | const [virtual] |
Definition at line 881 of file G4CylindricalSurface.cc.
References HowNear(), Scale(), and SURFACE_PRECISION.
Referenced by Intersect().
00882 { 00883 // return 1 if point x is on the G4CylindricalSurface, otherwise return zero 00884 // base this on the surface precision factor 00885 00886 if ( std::fabs( HowNear( x ) / Scale() ) <= SURFACE_PRECISION ) 00887 { return 1; } 00888 else 00889 { return 0; } 00890 }
G4Vector3D G4CylindricalSurface::axis [protected] |
Definition at line 177 of file G4CylindricalSurface.hh.
Referenced by G4CylindricalSurface(), GetAxis(), HowNear(), Normal(), operator==(), PrintOn(), and SurfaceNormal().
G4double G4CylindricalSurface::radius [protected] |
Definition at line 180 of file G4CylindricalSurface.hh.
Referenced by G4CylindricalSurface(), GetRadius(), HowNear(), operator==(), PrintOn(), Scale(), and SetRadius().