source: trunk/source/geometry/solids/BREPS/src/G4BoundingBox3D.cc@ 1282

Last change on this file since 1282 was 1228, checked in by garnier, 16 years ago

update geant4.9.3 tag

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