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

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

import all except CVS

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:  $
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.