Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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"
38 #include "G4GeometryTolerance.hh"
39 
41  space( G4Point3D(-kInfinity, -kInfinity, -kInfinity),
42  G4Point3D(+kInfinity, +kInfinity, +kInfinity) );
43 
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 
89 void 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 
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 
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 
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 
209 G4int 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 
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
260 G4double 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 
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 }