00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "G4BoundingBox3D.hh"
00037 #include "geomdefs.hh"
00038 #include "G4GeometryTolerance.hh"
00039
00040 const G4BoundingBox3D G4BoundingBox3D::
00041 space( G4Point3D(-kInfinity, -kInfinity, -kInfinity),
00042 G4Point3D(+kInfinity, +kInfinity, +kInfinity) );
00043
00045
00046 G4BoundingBox3D::G4BoundingBox3D()
00047 {
00048 distance = 0;
00049 test_result = 0;
00050 kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
00051 }
00052
00053 G4BoundingBox3D::G4BoundingBox3D(const G4Point3D& p1, const G4Point3D& p2)
00054 {
00055 Init(p1, p2);
00056 }
00057
00058 G4BoundingBox3D::G4BoundingBox3D(const G4Point3D& p)
00059 {
00060 Init(p);
00061 }
00062
00063 G4BoundingBox3D::~G4BoundingBox3D()
00064 {
00065 }
00066
00067 G4BoundingBox3D::G4BoundingBox3D(const G4BoundingBox3D& right)
00068 : box_min(right.box_min), box_max(right.box_max),
00069 distance(right.distance), test_result(right.test_result),
00070 MiddlePoint(right.MiddlePoint), GeantBox(right.GeantBox),
00071 kCarTolerance(right.kCarTolerance)
00072 {
00073 }
00074
00075 G4BoundingBox3D& G4BoundingBox3D::operator=(const G4BoundingBox3D& right)
00076 {
00077 if (&right == this) return *this;
00078 box_min = right.box_min;
00079 box_max = right.box_max;
00080 distance = right.distance;
00081 test_result = right.test_result;
00082 MiddlePoint = right.MiddlePoint;
00083 GeantBox = right.GeantBox;
00084 kCarTolerance = right.kCarTolerance;
00085
00086 return *this;
00087 }
00088
00089 void G4BoundingBox3D::Init(const G4Point3D& p1, const G4Point3D& p2)
00090 {
00091
00092
00093
00094
00095 kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
00096
00097 box_min.setX( std::min(p1.x(), p2.x()) - kCarTolerance );
00098 box_min.setY( std::min(p1.y(), p2.y()) - kCarTolerance );
00099 box_min.setZ( std::min(p1.z(), p2.z()) - kCarTolerance );
00100 box_max.setX( std::max(p1.x(), p2.x()) + kCarTolerance );
00101 box_max.setY( std::max(p1.y(), p2.y()) + kCarTolerance );
00102 box_max.setZ( std::max(p1.z(), p2.z()) + kCarTolerance );
00103
00104
00105 GeantBox = (box_max - box_min)*0.5;
00106 MiddlePoint = (box_min + box_max)*0.5;
00107
00108 test_result = 0;
00109 distance = 0;
00110 }
00111
00112
00113 void G4BoundingBox3D::Init(const G4Point3D& p)
00114 {
00115 box_min= box_max= MiddlePoint= p;
00116 GeantBox= G4Point3D(0, 0, 0);
00117 test_result = 0;
00118 distance= 0;
00119 kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
00120 }
00121
00122
00124
00125 void G4BoundingBox3D::Extend(const G4Point3D& p)
00126 {
00127
00128
00129
00130
00131
00132 if (p.x() < box_min.x())
00133 box_min.setX( p.x() - kCarTolerance );
00134 else if (p.x() > box_max.x())
00135 box_max.setX( p.x() + kCarTolerance );
00136
00137 if (p.y() < box_min.y())
00138 box_min.setY( p.y() - kCarTolerance );
00139 else if (p.y() > box_max.y())
00140 box_max.setY( p.y() + kCarTolerance );
00141
00142 if (p.z() < box_min.z())
00143 box_min.setZ( p.z() - kCarTolerance );
00144 else if (p.z() > box_max.z())
00145 box_max.setZ( p.z() + kCarTolerance );
00146
00147
00148
00149 GeantBox = (box_max - box_min)*0.5;
00150 MiddlePoint = (box_min + box_max)*0.5;
00151
00152 }
00153
00155
00156
00157 G4int G4BoundingBox3D::Test(const G4Ray& rayref)
00158 {
00159 const G4Point3D& tmp_ray_start = rayref.GetStart();
00160 const G4Vector3D& tmp_ray_dir = rayref.GetDir();
00161
00162 G4Point3D ray_start = tmp_ray_start ;
00163 G4Vector3D ray_dir = tmp_ray_dir ;
00164
00165 G4double rayx,rayy,rayz;
00166 rayx = ray_start.x();
00167 rayy = ray_start.y();
00168 rayz = ray_start.z();
00169
00170
00171 if((rayx < box_min.x()) || (rayx > box_max.x()) ||
00172 (rayy < box_min.y()) || (rayy > box_max.y()) ||
00173 (rayz < box_min.z()) || (rayz > box_max.z()) )
00174 {
00175
00176
00177
00178
00179 const G4Point3D ray_start2 = G4Point3D( ray_start - MiddlePoint );
00180 distance = DistanceToIn(ray_start2, ray_dir);
00181
00182 if(!distance)
00183 test_result = 0;
00184 else
00185 test_result = 1;
00186 }
00187 else
00188 {
00189
00190
00191 test_result = 1;
00192 distance = 0;
00193 }
00194
00195 return test_result;
00196 }
00197
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 G4int G4BoundingBox3D::BoxIntersect(const G4Point3D& ,
00210 const G4Point3D& p ,
00211 const G4Vector3D& v ) const
00212 {
00213 G4double safx, safy, safz;
00214 G4double fdx, fdy, fdz;
00215
00216 fdx = GeantBox.x();
00217 fdy = GeantBox.y();
00218 fdz = GeantBox.z();
00219
00220 safx=std::fabs(p.x())-fdx;
00221 safy=std::fabs(p.y())-fdy;
00222 safz=std::fabs(p.z())-fdz;
00223
00224
00225
00226
00227
00228
00229 if ( ( (p.x()*v.x()>=0.0 ) && safx>0.0 ) ||
00230 ( (p.y()*v.y()>=0.0 ) && safy>0.0 ) ||
00231 ( (p.z()*v.z()>=0.0 ) && safz>0.0 ) )
00232 return 0;
00233 else
00234 return 1;
00235 }
00236
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 G4double G4BoundingBox3D::DistanceToIn(const G4Point3D& p,
00261 const G4Vector3D& v) const
00262 {
00263 G4double safx, safy, safz, snxt = 0;
00264 G4double smin, sminx, sminy, sminz;
00265 G4double smax, smaxx, smaxy, smaxz;
00266 G4double stmp;
00267 G4double kBig = 10e20;
00268 G4double fdx,fdy,fdz;
00269
00270 fdx = GeantBox.x();
00271 fdy = GeantBox.y();
00272 fdz = GeantBox.z();
00273
00274 safx = std::fabs(p.x())-fdx;
00275 safy = std::fabs(p.y())-fdy;
00276 safz = std::fabs(p.z())-fdz;
00277
00278
00279
00280
00281
00282
00283 if ( ( ( p.x()*v.x()>=0.0 ) && safx>0.0) ||
00284 ( ( p.y()*v.y()>=0.0 ) && safy>0.0) ||
00285 ( ( p.z()*v.z()>=0.0 ) && safz>0.0) )
00286 return snxt;
00287
00288
00289 if (safx<0.0)
00290 {
00291
00292 sminx=0.0;
00293 if (v.x())
00294 smaxx = fdx/std::fabs(v.x()) - p.x()/v.x();
00295 else
00296 smaxx = kBig;
00297 }
00298 else
00299 {
00300
00301 if (v.x()==0)
00302 return snxt;
00303 else
00304 {
00305 stmp = std::fabs(v.x());
00306 sminx = safx/stmp;
00307 smaxx = (fdx+std::fabs(p.x()))/stmp;
00308 }
00309 }
00310
00311 if (safy<0.0)
00312 {
00313
00314 sminy=0.0;
00315 if (v.y())
00316 smaxy = fdy/std::fabs(v.y()) - p.y()/v.y();
00317 else
00318 smaxy = kBig;
00319 }
00320 else
00321 {
00322
00323 if (v.y()==0)
00324 return snxt;
00325 else
00326 {
00327 stmp = std::fabs(v.y());
00328 sminy = safy/stmp;
00329 smaxy = (fdy+std::fabs(p.y()))/stmp;
00330 }
00331 }
00332
00333 if (safz<0.0)
00334 {
00335
00336 sminz=0.0;
00337 if (v.z())
00338 smaxz = fdz/std::fabs(v.z()) - p.z()/v.z();
00339 else
00340 smaxz = kBig;
00341 }
00342 else
00343 {
00344
00345 if (v.z()==0)
00346 return snxt;
00347 else
00348 {
00349 stmp = std::fabs(v.z());
00350 sminz = safz/stmp;
00351 smaxz = (fdz+std::fabs(p.z()))/stmp;
00352 }
00353 }
00354
00355
00356 if (sminx>sminy)
00357 smin = sminx;
00358 else
00359 smin = sminy;
00360
00361 if (sminz>smin)
00362 smin=sminz;
00363
00364 if (smaxx<smaxy)
00365 smax = smaxx;
00366 else
00367 smax = smaxy;
00368
00369 if (smaxz<smax)
00370 smax = smaxz;
00371
00372
00373
00374
00375 if ((smin>0.) && (smin<=smax)) { snxt=smin; }
00376
00377 return snxt;
00378 }
00379
00380
00382
00383 G4int G4BoundingBox3D::Inside(const G4Point3D& Pt) const
00384 {
00385 if( ( Pt.x() >= box_min.x() && Pt.x() <= box_max.x() ) &&
00386 ( Pt.y() >= box_min.y() && Pt.y() <= box_max.y() ) &&
00387 ( Pt.z() >= box_min.z() && Pt.z() <= box_max.z() ) )
00388 return 1;
00389 else
00390 return 0;
00391 }