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