Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4FCylindricalSurface.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id$
28//
29// ----------------------------------------------------------------------
30// GEANT 4 class source file
31//
32// G4FCylindricalSurface.cc
33//
34// ----------------------------------------------------------------------
35
38#include "G4Sort.hh"
39
40
42 : radius(0.), length(1.)
43{
44}
45
46
48{
49}
50
51
53 const G4Vector3D& a,
54 G4double r,
55 G4double l
56 )
57{
58 // make a G4FCylindricalSurface with origin o, axis a,
59 // radius r, and length l
60 G4Vector3D dir(1,1,1);
61 Position.Init(dir, a, o);
62
63 origin = o;
64 radius = r;
65
66 // Require length to be positive or zero
67 if ( l >= 0.0 )
68 length = l;
69 else
70 {
71 std::ostringstream message;
72 message << "Negative length." << G4endl
73 << "Default length of 0.0 is used.";
74 G4Exception("G4FCylindricalSurface::G4FCylindricalSurface()",
75 "GeomSolids1001", JustWarning, message);
76
77 length = 0.0;
78 }
79
80 // Require radius to be non-negative (i.e., allow zero)
81 if ( r >= 0.0 )
82 radius = r;
83 else
84 {
85 std::ostringstream message;
86 message << "Negative radius." << G4endl
87 << "Default value of 0.0 is used.";
88 G4Exception("G4FCylindricalSurface::G4FCylindricalSurface()",
89 "GeomSolids1001", JustWarning, message);
90
91 radius = 0.0;
92 }
93}
94
95
97{
98 return "G4FCylindricalSurface";
99}
100
101
102void G4FCylindricalSurface::PrintOn( std::ostream& os ) const
103{
104 os << "G4FCylindricalSurface with origin: " << origin << "\t"
105 << "and axis: " << Position.GetAxis() << "\n"
106 << "\t radius: " << radius << "\t and length: "
107 << length << "\n";
108}
109
110
112{
113 return ( 2.0 * pi * radius * length );
114}
115
116
117// Added 18.7-95
118// Modified by L. Broglia (01/12/98)
120{
121 // Finds the bounds of the surface iow
122 // calculates the bounds for a bounding box
123 // to the surface. The bounding box is used
124 // for a preliminary check of intersection.
127
128 G4Point3D Tmp;
129 G4Point3D Origin = Position.GetLocation();
130 G4Point3D EndOrigin = G4Point3D( Origin + (length*Position.GetAxis()) );
131 G4Point3D Radius(radius, radius, 0);
132
133 // Default BBox
135 G4Point3D BoxMin(Origin-Tolerance);
136 G4Point3D BoxMax(Origin+Tolerance);
137
138 bbox = new G4BoundingBox3D();
139 bbox->Init(BoxMin, BoxMax);
140
141
142 Tmp = (Origin - Radius);
143 bbox->Extend(Tmp);
144
145 Tmp = Origin + Radius;
146 bbox->Extend(Tmp);
147
148 Tmp = EndOrigin - Radius;
149 bbox->Extend(Tmp);
150
151 Tmp = EndOrigin + Radius;
152 bbox->Extend(Tmp);
153}
154
155
157{
158 // This function count the number of intersections of a
159 // bounded cylindrical surface by a ray.
160 // At first, calculates the intersections with the infinite
161 // cylindrical surfsace. After, count the intersections within the
162 // finite cylindrical surface boundaries, and set "distance" to the
163 // closest distance from the start point to the nearest intersection
164 // If the point is on the surface it returns or the intersection with
165 // the opposite surface or kInfinity
166
167 // If no intersection is founded, set distance = kInfinity and
168 // return 0
169
170 distance = kInfinity;
172
173 // origin and direction of the ray
174 G4Point3D x = ry.GetStart();
175 G4Vector3D dhat = ry.GetDir();
176
177 // cylinder axis
178 G4Vector3D ahat = Position.GetAxis();
179
180 // array of solutions in distance along the ray
181 G4double sol[2];
182 sol[0]=-1.0;
183 sol[1]=-1.0;
184
185 // calculate the two intersections (quadratic equation)
186 G4Vector3D gamma = G4Vector3D( x - Position.GetLocation() );
187
188 G4double ga = gamma * ahat;
189 G4double da = dhat * ahat;
190
191 G4double A = da * da - dhat * dhat;
192 G4double B = 2 * ( -gamma * dhat + ga * da );
193 G4double C = -gamma * gamma + ga * ga + radius * radius ;
194
195 G4double radical = B * B - 4.0 * A * C;
196
197 if ( radical < 0.0 )
198 // no intersection
199 return 0;
200 else
201 {
202 G4double root = std::sqrt( radical );
203 sol[0] = ( - B + root ) / ( 2. * A );
204 sol[1] = ( - B - root ) / ( 2. * A );
205 }
206
207 // validity of the solutions
208 // the hit point must be into the bounding box of the cylindrical surface
209 G4Point3D p0 = G4Point3D( x + sol[0]*dhat );
210 G4Point3D p1 = G4Point3D( x + sol[1]*dhat );
211
212 if( !GetBBox()->Inside(p0) )
213 sol[0] = kInfinity;
214
215 if( !GetBBox()->Inside(p1) )
216 sol[1] = kInfinity;
217
218 // now loop over each positive solution, keeping the first one (smallest
219 // distance along the Ray) which is within the boundary of the sub-shape
220 G4int nbinter = 0;
221 distance = kInfinity;
222
223 for ( G4int i = 0; i < 2; i++ )
224 {
225 if(sol[i] < kInfinity) {
226 if ( sol[i] >= kCarTolerance*0.5 ) {
227 nbinter ++;
228 // real intersection
229 // set the distance if it is the smallest
230 if( distance > sol[i]*sol[i]) {
231 distance = sol[i]*sol[i];
232 }
233 }
234 }
235 }
236
237 return nbinter;
238}
239
240
242{
243 // Shortest distance from the point x to the G4FCylindricalSurface.
244 // The distance will be always positive
245
246 G4double hownear;
247
248 G4Vector3D upcorner = G4Vector3D ( radius, 0 , origin.z()+length);
249 G4Vector3D downcorner = G4Vector3D ( radius, 0 , origin.z());
250 G4Vector3D xd;
251
252 xd = G4Vector3D ( std::sqrt ( x.x()*x.x() + x.y()*x.y() ) , 0 , x.z() );
253
254
255 G4double Zinter = (xd.z()) ;
256
257 if ( ((Zinter >= downcorner.z()) && (Zinter <=upcorner.z())) ) {
258 hownear = std::fabs( radius - xd.x() );
259 } else {
260 hownear = std::min ( (xd-upcorner).mag() , (xd-downcorner).mag() );
261 }
262
263 return hownear;
264}
265
267{
268 // return 1 if point x is within the boundaries of the G4FCylindricalSurface
269 // return 0 otherwise (assume it is on the cylinder)
270 if ( std::fabs( ( x - Position.GetLocation()) * Position.GetAxis() )
271 <= 0.5 * length )
272 return 1;
273 else
274 return 0;
275}
276
277
279{
280 // Returns the radius of a G4FCylindricalSurface unless it is zero,
281 // in which case returns the length.
282 // Used for Scale-invariant tests of surface thickness.
283 if ( radius == 0.0 )
284 return length;
285 else
286 return radius;
287}
288
289
291{
292 // return the Normal unit vector to the G4CylindricalSurface at a point
293 // p on (or nearly on) the G4CylindricalSurface
294
295 G4Vector3D n = G4Vector3D( ( p - Position.GetLocation() ) -
296 ( ( p - Position.GetLocation()) *
298 G4double nmag = n.mag();
299
300 if ( nmag != 0.0 )
301 n = n * (1/nmag);
302
303 if( !sameSense )
304 n = -n;
305
306 return n;
307}
308
310{
311 // Return 0 if point x is outside G4CylindricalSurface, 1 if Inside.
312 // Outside means that the distance to the G4CylindricalSurface would
313 // be negative.
314 // Use the HowNear function to calculate this distance.
315 if ( HowNear( x ) >= -0.5*kCarTolerance )
316 return 1;
317 else
318 return 0;
319}
320
321
323{
324 // Resize a G4FCylindricalSurface to a new radius r and new length l
325 // Require radius to be non-negative
326 if ( r >= 0.0 )
327 radius = r;
328 else
329 {
330 std::ostringstream message;
331 message << "Negative radius." << G4endl
332 << "Original value of " << radius << " is retained.";
333 G4Exception("G4FCylindricalSurface::resize()",
334 "GeomSolids1001", JustWarning, message);
335 }
336
337 // Require length to be positive
338 if ( l > 0.0 )
339 length = l;
340 else
341 {
342 std::ostringstream message;
343 message << "Negative or zero length." << G4endl
344 << "Original value of " << length << " is retained.";
345 G4Exception("G4FCylindricalSurface::resize()",
346 "GeomSolids1001", JustWarning, message);
347 }
348}
@ JustWarning
HepGeom::Point3D< G4double > G4Point3D
Definition: G4Point3D.hh:35
const G4Point3D PINFINITY(kInfinity, kInfinity, kInfinity)
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
HepGeom::Vector3D< G4double > G4Vector3D
Definition: G4Vector3D.hh:35
#define G4endl
Definition: G4ios.hh:52
void Init(const G4Vector3D &refDirection0, const G4Vector3D &axis0, const G4Point3D &location0)
G4Point3D GetLocation() const
G4Vector3D GetAxis() const
void Init(const G4Point3D &)
void Extend(const G4Point3D &)
virtual G4double Area() const
virtual void PrintOn(std::ostream &os=G4cout) const
virtual G4double Scale() const
G4int Intersect(const G4Ray &)
virtual const char * NameOf() const
virtual void resize(G4double r, G4double l)
virtual G4Vector3D SurfaceNormal(const G4Point3D &p) const
virtual G4int WithinBoundary(const G4Vector3D &x) const
virtual G4double HowNear(const G4Vector3D &x) const
virtual G4int Inside(const G4Vector3D &x) const
Definition: G4Ray.hh:49
const G4Vector3D & GetDir() const
const G4Point3D & GetStart() const
G4int sameSense
Definition: G4Surface.hh:207
G4Vector3D origin
Definition: G4Surface.hh:197
G4BoundingBox3D * GetBBox()
G4double distance
Definition: G4Surface.hh:203
G4BoundingBox3D * bbox
Definition: G4Surface.hh:185
G4Point3D closest_hit
Definition: G4Surface.hh:186
G4double kCarTolerance
Definition: G4Surface.hh:192
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41