Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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