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
G4BoundingBox3D.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// G4BoundingBox3D.cc
33//
34// ----------------------------------------------------------------------
35
36#include "G4BoundingBox3D.hh"
37#include "geomdefs.hh"
39
41 space( G4Point3D(-kInfinity, -kInfinity, -kInfinity),
42 G4Point3D(+kInfinity, +kInfinity, +kInfinity) );
43
44/////////////////////////////////////////////////////////////////////////////
45
47{
48 distance = 0;
49 test_result = 0;
51}
52
54{
55 Init(p1, p2);
56}
57
59{
60 Init(p);
61}
62
64{
65}
66
68 : box_min(right.box_min), box_max(right.box_max),
69 distance(right.distance), test_result(right.test_result),
70 MiddlePoint(right.MiddlePoint), GeantBox(right.GeantBox),
71 kCarTolerance(right.kCarTolerance)
72{
73}
74
76{
77 if (&right == this) return *this;
78 box_min = right.box_min;
79 box_max = right.box_max;
80 distance = right.distance;
81 test_result = right.test_result;
82 MiddlePoint = right.MiddlePoint;
83 GeantBox = right.GeantBox;
84 kCarTolerance = right.kCarTolerance;
85
86 return *this;
87}
88
89void G4BoundingBox3D::Init(const G4Point3D& p1, const G4Point3D& p2)
90{
91 // L. Broglia
92 // Maybe temporary
93 // Create a BBox bigger than the reality
94
96
97 box_min.setX( std::min(p1.x(), p2.x()) - kCarTolerance );
98 box_min.setY( std::min(p1.y(), p2.y()) - kCarTolerance );
99 box_min.setZ( std::min(p1.z(), p2.z()) - kCarTolerance );
100 box_max.setX( std::max(p1.x(), p2.x()) + kCarTolerance );
101 box_max.setY( std::max(p1.y(), p2.y()) + kCarTolerance );
102 box_max.setZ( std::max(p1.z(), p2.z()) + kCarTolerance );
103
104 // Calc half spaces
105 GeantBox = (box_max - box_min)*0.5;
106 MiddlePoint = (box_min + box_max)*0.5;
107
108 test_result = 0;
109 distance = 0;
110}
111
112
114{
115 box_min= box_max= MiddlePoint= p;
116 GeantBox= G4Point3D(0, 0, 0);
117 test_result = 0;
118 distance= 0;
120}
121
122
123/////////////////////////////////////////////////////////////////////////////
124
126{
127
128 // L. Broglia
129 // Maybe temporary
130 // Create a BBox bigger than the reality
131
132 if (p.x() < box_min.x())
133 box_min.setX( p.x() - kCarTolerance );
134 else if (p.x() > box_max.x())
135 box_max.setX( p.x() + kCarTolerance );
136
137 if (p.y() < box_min.y())
138 box_min.setY( p.y() - kCarTolerance );
139 else if (p.y() > box_max.y())
140 box_max.setY( p.y() + kCarTolerance );
141
142 if (p.z() < box_min.z())
143 box_min.setZ( p.z() - kCarTolerance );
144 else if (p.z() > box_max.z())
145 box_max.setZ( p.z() + kCarTolerance );
146
147 // L. Broglia
148 // Now re-calculate GeantBox and MiddlePoint
149 GeantBox = (box_max - box_min)*0.5;
150 MiddlePoint = (box_min + box_max)*0.5;
151
152}
153
154////////////////////////////////////////////////////////////////////////////
155
156
158{
159 const G4Point3D& tmp_ray_start = rayref.GetStart();
160 const G4Vector3D& tmp_ray_dir = rayref.GetDir();
161
162 G4Point3D ray_start = tmp_ray_start ;
163 G4Vector3D ray_dir = tmp_ray_dir ;
164
165 G4double rayx,rayy,rayz;
166 rayx = ray_start.x();
167 rayy = ray_start.y();
168 rayz = ray_start.z();
169
170 // Test if ray starting point is in the bbox or not
171 if((rayx < box_min.x()) || (rayx > box_max.x()) ||
172 (rayy < box_min.y()) || (rayy > box_max.y()) ||
173 (rayz < box_min.z()) || (rayz > box_max.z()) )
174 {
175 // Outside, check for intersection with bbox
176
177 // Adapt ray_starting point to box
178
179 const G4Point3D ray_start2 = G4Point3D( ray_start - MiddlePoint );
180 distance = DistanceToIn(ray_start2, ray_dir);
181
182 if(!distance)
183 test_result = 0; // Miss
184 else
185 test_result = 1; // Starting point outside box & hits box
186 }
187 else
188 {
189 // Inside
190 // G4cout << "\nRay starting point Inside bbox.";
191 test_result = 1;
192 distance = 0;
193 }
194
195 return test_result;
196}
197
198///////////////////////////////////////////////////////////////////////////////
199
200
201// Does an intersection exist?
202//
203// ALGORITHM:
204//
205// Check that if point lies outside x/y/z extent of box, travel is towards
206// the box (ie. there is a possiblity of an intersection)
207
208
209G4int G4BoundingBox3D::BoxIntersect(const G4Point3D& ,
210 const G4Point3D& p ,
211 const G4Vector3D& v ) const
212{
213 G4double safx, safy, safz;
214 G4double fdx, fdy, fdz;
215
216 fdx = GeantBox.x();
217 fdy = GeantBox.y();
218 fdz = GeantBox.z();
219
220 safx=std::fabs(p.x())-fdx; // minimum distance to x surface of shape
221 safy=std::fabs(p.y())-fdy;
222 safz=std::fabs(p.z())-fdz;
223
224 // Will we Intersect?
225 // If safx/y/z is >=0 the point is outside/on the box's x/y/z extent.
226 // If both p.X()/y/z and v.X()/y/z repectively are both positive/negative,
227 // travel is in a G4ThreeVec away from the shape.
228
229 if ( ( (p.x()*v.x()>=0.0 ) && safx>0.0 ) ||
230 ( (p.y()*v.y()>=0.0 ) && safy>0.0 ) ||
231 ( (p.z()*v.z()>=0.0 ) && safz>0.0 ) )
232 return 0; // No intersection
233 else
234 return 1; // Possible intersection
235}
236
237///////////////////////////////////////////////////////////////////////////////
238
239
240// Distance to in
241// Calculate distance to box from outside - return kBig if no intersection
242//
243// ALGORITHM:
244//
245// Check that if point lies outside x/y/z extent of box, travel is towards
246// the box (ie. there is a possiblity of an intersection)
247//
248// Calculate pairs of minimum and maximum distances for x/y/z travel for
249// intersection with the box's x/y/z extent.
250// If there is a valid intersection, it is given by the maximum min distance
251// (ie. distance to satisfy x/y/z intersections) *if* <= minimum max distance
252// (ie. distance after which 1+ of x/y/z intersections not satisfied)
253//
254// NOTE:
255//
256// `Inside' safe - meaningful answers given if point is Inside the exact
257// shape.
258
259//G4double G4BoundingBox::distance_to_in(const G4Point3d& gbox, const G4Point3d& p, const G4ThreeVec& v) const
260G4double G4BoundingBox3D::DistanceToIn(const G4Point3D& p,
261 const G4Vector3D& v) const
262{
263 G4double safx, safy, safz, snxt = 0; // snxt = default return value
264 G4double smin, sminx, sminy, sminz;
265 G4double smax, smaxx, smaxy, smaxz;
266 G4double stmp;
267 G4double kBig = 10e20;
268 G4double fdx,fdy,fdz;
269
270 fdx = GeantBox.x();
271 fdy = GeantBox.y();
272 fdz = GeantBox.z();
273
274 safx = std::fabs(p.x())-fdx; // minimum distance to x surface of shape
275 safy = std::fabs(p.y())-fdy;
276 safz = std::fabs(p.z())-fdz;
277
278 // Will we Intersect?
279 // If safx/y/z is >=0 the point is outside/on the box's x/y/z extent.
280 // If both p.X()/y/z and v.X()/y/z repectively are both positive/negative,
281 // travel is in a G4ThreeVec away from the shape.
282
283 if ( ( ( p.x()*v.x()>=0.0 ) && safx>0.0) ||
284 ( ( p.y()*v.y()>=0.0 ) && safy>0.0) ||
285 ( ( p.z()*v.z()>=0.0 ) && safz>0.0) )
286 return snxt;
287
288 // Compute min / max distance for x/y/z travel:
289 if (safx<0.0)
290 {
291 // Inside x extent => Calc distance until trajectory leaves extent
292 sminx=0.0;
293 if (v.x())
294 smaxx = fdx/std::fabs(v.x()) - p.x()/v.x();
295 else
296 smaxx = kBig;
297 }
298 else
299 {
300 // Outside extent or on boundary
301 if (v.x()==0)
302 return snxt; // Travel parallel
303 else
304 {
305 stmp = std::fabs(v.x());
306 sminx = safx/stmp;
307 smaxx = (fdx+std::fabs(p.x()))/stmp;
308 }
309 }
310
311 if (safy<0.0)
312 {
313 // Inside y extent => Calc distance until trajectory leaves extent
314 sminy=0.0;
315 if (v.y())
316 smaxy = fdy/std::fabs(v.y()) - p.y()/v.y();
317 else
318 smaxy = kBig;
319 }
320 else
321 {
322 // Outside extent or on boundary
323 if (v.y()==0)
324 return snxt; // Travel parallel
325 else
326 {
327 stmp = std::fabs(v.y());
328 sminy = safy/stmp;
329 smaxy = (fdy+std::fabs(p.y()))/stmp;
330 }
331 }
332
333 if (safz<0.0)
334 {
335 // Inside z extent => Calc distance until trajectory leaves extent
336 sminz=0.0;
337 if (v.z())
338 smaxz = fdz/std::fabs(v.z()) - p.z()/v.z();
339 else
340 smaxz = kBig;
341 }
342 else
343 {
344 // Outside extent or on boundary
345 if (v.z()==0)
346 return snxt; // Travel parallel
347 else
348 {
349 stmp = std::fabs(v.z());
350 sminz = safz/stmp;
351 smaxz = (fdz+std::fabs(p.z()))/stmp;
352 }
353 }
354
355 // Find minimum allowed Dist given min/max pairs
356 if (sminx>sminy)
357 smin = sminx; // MAX(sminx,sminy,sminz)
358 else
359 smin = sminy;
360
361 if (sminz>smin)
362 smin=sminz;
363
364 if (smaxx<smaxy)
365 smax = smaxx; // MIN(smaxx,smaxy,smaxz)
366 else
367 smax = smaxy;
368
369 if (smaxz<smax)
370 smax = smaxz;
371
372 // If smin <= kCarTolerance then only clipping `tolerant' Area
373 // -> no intersection
374
375 if ((smin>0.) && (smin<=smax)) { snxt=smin; }
376
377 return snxt;
378}
379
380
381///////////////////////////////////////////////////////////////////////////////
382
384{
385 if( ( Pt.x() >= box_min.x() && Pt.x() <= box_max.x() ) &&
386 ( Pt.y() >= box_min.y() && Pt.y() <= box_max.y() ) &&
387 ( Pt.z() >= box_min.z() && Pt.z() <= box_max.z() ) )
388 return 1;
389 else
390 return 0;
391}
HepGeom::Point3D< G4double > G4Point3D
Definition: G4Point3D.hh:35
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
G4BoundingBox3D & operator=(const G4BoundingBox3D &right)
void Init(const G4Point3D &)
void Extend(const G4Point3D &)
G4int Test(const G4Ray &)
static const G4BoundingBox3D space
G4int Inside(const G4Point3D &) const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
Definition: G4Ray.hh:49
const G4Vector3D & GetDir() const
const G4Point3D & GetStart() const