#include <G4ConicalSurface.hh>
Inheritance diagram for G4ConicalSurface:
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) |
Definition at line 51 of file G4ConicalSurface.hh.
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] |
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] |
G4Vector3D G4ConicalSurface::GetAxis | ( | ) | const [inline] |
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 }
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] |
G4int G4ConicalSurface::operator== | ( | const G4ConicalSurface & | c | ) | [inline] |
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] |
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 }