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
G4FConicalSurface.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// G4FConicalSurface.cc
33//
34// ----------------------------------------------------------------------
35
36#include "G4FConicalSurface.hh"
38#include "G4Sort.hh"
39#include "G4CircularCurve.hh"
40
41
43{
44 length = 1.0;
45 small_radius = 0.0;
46 large_radius = 1.0;
48}
49
51{
52}
53
55 const G4Vector3D& a,
56 G4double l,
57 G4double srad,
58 G4double lr
59 )
60{
61 // Make a G4FConicalSurface with origin o, axis a, length l, small radius
62 // srad, and large radius lr. The angle is calculated below and the SetAngle
63 // function of G4ConicalSurface is used to set it properly from the default
64 // value used above in the initialization.
65
66 // Create the position with origin o, axis a, and a direction
67
68 G4Vector3D dir(1,1,1);
69 Position.Init(dir, a, o);
70 origin = o;
71
72 // Require length to be nonnegative
73 if (l >=0)
74 length = l;
75 else
76 {
77 std::ostringstream message;
78 message << "Negative length." << G4endl
79 << "Default length of 0.0 is used.";
80 G4Exception("G4FConicalSurface::G4FConicalSurface()",
81 "GeomSolids1001", JustWarning, message);
82
83 length = 0.0;
84 }
85
86 // Require small radius to be non-negative (i.e., allow zero)
87 if ( srad >= 0.0 )
88 small_radius = srad;
89 else
90 {
91 std::ostringstream message;
92 message << "Negative small radius." << G4endl
93 << "Default value of 0.0 is used.";
94 G4Exception("G4FConicalSurface::G4FConicalSurface()",
95 "GeomSolids1001", JustWarning, message);
96
97 small_radius = 0.0;
98 }
99
100 // Require large radius to exceed small radius
101 if ( lr > small_radius )
102 large_radius = lr;
103 else
104 {
105 std::ostringstream message;
106 message << "Large radius must exceed small radius" << G4endl
107 << "Default value of small radius +1 is used.";
108 G4Exception("G4FConicalSurface::G4FConicalSurface()",
109 "GeomSolids1001", JustWarning, message);
110
112 }
113
114 // Calculate the angle of the G4ConicalSurface from the length and radii
116}
117
118
119const char* G4FConicalSurface::Name() const
120{
121 return "G4FConicalSurface";
122}
123
124// Modified by L. Broglia (01/12/98)
126{
129 G4Point3D Tmp;
130
131 G4Point3D Origin = Position.GetLocation();
132 G4Point3D EndOrigin = G4Point3D( Origin + (length * Position.GetAxis()) );
133
134 G4double radius = large_radius;
135 G4Point3D Radius(radius, radius, 0);
136
137 // Default BBox
139 G4Point3D BoxMin(Origin-Tolerance);
140 G4Point3D BoxMax(Origin+Tolerance);
141
142 bbox = new G4BoundingBox3D();
143 bbox->Init(BoxMin, BoxMax);
144
145 Tmp = (Origin - Radius);
146 bbox->Extend(Tmp);
147
148 Tmp = Origin + Radius;
149 bbox->Extend(Tmp);
150
151 Tmp = EndOrigin - Radius;
152 bbox->Extend(Tmp);
153
154 Tmp = EndOrigin + Radius;
155 bbox->Extend(Tmp);
156}
157
158
159void G4FConicalSurface::PrintOn( std::ostream& os ) const
160{
161 // printing function using C++ std::ostream class
162 os << "G4FConicalSurface with origin: " << origin << "\t"
163 << "and axis: " << Position.GetAxis() << "\n"
164 << "\t small radius: " << small_radius
165 << "\t large radius: " << large_radius
166 << "\t and length: " << length << "\n";
167}
168
169
171{
172 return ( origin == c.origin &&
173 Position.GetAxis() == c.Position.GetAxis() &&
176 length == c.length &&
177 tan_angle == c.tan_angle );
178}
179
180
182{
183 // return 1 if point x is within the boundaries of the G4FConicalSurface
184 // return 0 otherwise (assume it is on the G4ConicalSurface)
185 G4Vector3D q = G4Vector3D( x - origin );
186
187 G4double qmag = q.mag();
188 G4double ss = std::sin( std::atan2(large_radius-small_radius, length) );
189 G4double ls = small_radius / ss;
190 G4double ll = large_radius / ss;
191
192 if ( ( qmag >= ls ) && ( qmag <= ll ) )
193 return 1;
194 else
195 return 0;
196}
197
198
200{
201 // Returns the small radius of a G4FConicalSurface unless it is zero, in
202 // which case returns the large radius.
203 // Used for Scale-invariant tests of surface thickness.
204 if ( small_radius == 0.0 )
205 return large_radius;
206 else
207 return small_radius;
208}
209
210
212{
213 // Returns the Area of a G4FConicalSurface
215
216 return ( pi * ( small_radius + large_radius ) *
217 std::sqrt( length * length + rdif * rdif ) );
218}
219
220
222{
223 // Resize a G4FConicalSurface to a new length l, and new radii srad and lr.
224 // Must Reset angle of the G4ConicalSurface as well based on these new
225 // values.
226 // Require length to be non-negative
227
228 // if ( l > 0.0 )
229 if ( l >= 0.0 )
230 length = l;
231 else
232 {
233 std::ostringstream message;
234 message << "Negative length." << G4endl
235 << "Original value of " << length << " is retained.";
236 G4Exception("G4FConicalSurface::resize()",
237 "GeomSolids1001", JustWarning, message);
238 }
239
240 // Require small radius to be non-negative (i.e., allow zero)
241 if ( srad >= 0.0 )
242 small_radius = srad;
243 else
244 {
245 std::ostringstream message;
246 message << "Negative small radius." << G4endl
247 << "Original value of " << small_radius << " is retained.";
248 G4Exception("G4FConicalSurface::resize()",
249 "GeomSolids1001", JustWarning, message);
250 }
251
252 // Require large radius to exceed small radius
253 if ( lr > small_radius )
254 large_radius = lr;
255 else
256 {
257 G4double r = small_radius + 1.0;
258 lr = ( large_radius <= small_radius ) ? r : large_radius;
259 large_radius = lr;
260
261 std::ostringstream message;
262 message << "Large radius must exceed small radius." << G4endl
263 << "Default value of " << large_radius << " is used.";
264 G4Exception("G4FConicalSurface::resize()",
265 "GeomSolids1001", JustWarning, message);
266 }
267
268 // Calculate the angle of the G4ConicalSurface from the length and radii
270
271}
272
273
275{
276 // This function count the number of intersections of a
277 // bounded conical surface by a ray.
278 // At first, calculates the intersections with the semi-infinite
279 // conical surfsace. After, count the intersections within the
280 // finite conical surface boundaries, and set "distance" to the
281 // closest distance from the start point to the nearest intersection
282 // If the point is on the surface it returns or the intersection with
283 // the opposite surface or kInfinity
284 // If no intersection is founded, set distance = kInfinity and
285 // return 0
286
287 distance = kInfinity;
289
290 // origin and direction of the ray
291 G4Point3D x = ry.GetStart();
292 G4Vector3D dhat = ry.GetDir();
293
294 // cone angle and axis
295 G4double ta = tan_angle;
296 G4Vector3D ahat = Position.GetAxis();
297
298 // array of solutions in distance along the ray
299 G4double sol[2];
300 sol[0]=-1.0;
301 sol[1]=-1.0;
302
303 // calculate the two intersections (quadratic equation)
304 G4Vector3D gamma = G4Vector3D( x - Position.GetLocation() );
305
306 G4double t = 1 + ta * ta;
307 G4double ga = gamma * ahat;
308 G4double da = dhat * ahat;
309
310 G4double A = t * da * da - dhat * dhat;
311 G4double B = 2 * ( -gamma * dhat + t * ga * da - large_radius * ta * da);
312 G4double C = ( -gamma * gamma + t * ga * ga
313 - 2 * large_radius * ta * ga
315
316 G4double radical = B * B - 4.0 * A * C;
317
318 if ( radical < 0.0 )
319 // no intersection
320 return 0;
321 else
322 {
323 G4double root = std::sqrt( radical );
324 sol[0] = ( - B + root ) / ( 2. * A );
325 sol[1] = ( - B - root ) / ( 2. * A );
326 }
327
328 // validity of the solutions
329 // the hit point must be into the bounding box of the conical surface
330 G4Point3D p0 = G4Point3D( x + sol[0]*dhat );
331 G4Point3D p1 = G4Point3D( x + sol[1]*dhat );
332
333 if( !GetBBox()->Inside(p0) )
334 sol[0] = kInfinity;
335
336 if( !GetBBox()->Inside(p1) )
337 sol[1] = kInfinity;
338
339 // now loop over each positive solution, keeping the first one (smallest
340 // distance along the ray) which is within the boundary of the sub-shape
341 G4int nbinter = 0;
342 distance = kInfinity;
343
344 for ( G4int i = 0; i < 2; i++ )
345 {
346 if(sol[i] < kInfinity) {
347 if ( (sol[i] > kCarTolerance*0.5) ) {
348 nbinter++;
349 if ( distance > (sol[i]*sol[i]) ) {
350 distance = sol[i]*sol[i];
351 }
352 }
353 }
354 }
355
356 return nbinter;
357}
358
359
361{
362// Shortest distance from the point x to the G4FConicalSurface.
363// The distance will be always positive
364// This function works only with Cone axis equal (0,0,1) or (0,0,-1), it project
365// the surface and the point on the x,z plane and compute the distance in analytical
366// way
367
368 G4double hownear ;
369
371 G4Vector3D downcorner = G4Vector3D ( large_radius, 0 , origin.z());
372 G4Vector3D xd;
373
374 xd = G4Vector3D ( std::sqrt ( x.x()*x.x() + x.y()*x.y() ) , 0 , x.z() );
375
376 G4double r = (upcorner.z() - downcorner.z()) / (upcorner.x() - downcorner.x());
377 G4double q = (downcorner.z()*upcorner.x() - upcorner.z()*downcorner.x()) /
378 (upcorner.x() - downcorner.x());
379
380 G4double Zinter = (xd.z()*r*r + xd.x()*r +q)/(1+r*r) ;
381
382 if ( ((Zinter >= downcorner.z()) && (Zinter <=upcorner.z())) ||
383 ((Zinter >= upcorner.z()) && (Zinter <=downcorner.z())) ) {
384 hownear = std::fabs(r*xd.x()-xd.z()+q)/std::sqrt(1+r*r);
385 return hownear;
386 } else {
387 hownear = std::min ( (xd-upcorner).mag() , (xd-downcorner).mag() );
388 return hownear;
389 }
390}
391
392
394{
395 // return the Normal unit vector to the G4ConicalSurface at a point p
396 // on (or nearly on) the G4ConicalSurface
397 G4Vector3D ss = G4Vector3D( p - origin );
398 G4double da = ss * Position.GetAxis();
399 G4double r = std::sqrt( ss*ss - da*da);
400 G4double z = tan_angle * r;
401
402 if (Position.GetAxis().z() < 0)
403 z = -z;
404
405 G4Vector3D n(p.x(), p.y(), z);
406 n = n.unit();
407
408 if( !sameSense )
409 n = -n;
410
411 return n;
412}
413
415{
416 // Return 0 if point x is outside G4ConicalSurface, 1 if Inside.
417 if ( HowNear( x ) >= -0.5*kCarTolerance )
418 return 1;
419 else
420 return 0;
421}
422
@ 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 const char * Name() const
virtual G4Vector3D SurfaceNormal(const G4Point3D &p) const
virtual G4double HowNear(const G4Vector3D &x) const
virtual G4double Area() const
virtual void resize(G4double l, G4double sr, G4double lr)
G4int Inside(const G4Vector3D &x) const
virtual void PrintOn(std::ostream &os=G4cout) const
G4int Intersect(const G4Ray &ry)
virtual G4double Scale() const
virtual G4int WithinBoundary(const G4Vector3D &x) const
virtual ~G4FConicalSurface()
G4Axis2Placement3D Position
G4int operator==(const G4FConicalSurface &c) 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