53 : fMin(pMin), fMax(pMax), fPolygons(0)
66 : fPolygons(&polygons)
70 CheckBoundingPolygons();
76 std::vector<const G4ThreeVectorList*>::const_iterator ibase;
77 for (ibase = fPolygons->begin(); ibase != fPolygons->end(); ibase++)
79 std::vector<G4ThreeVector>::const_iterator ipoint;
80 for (ipoint = (*ibase)->begin(); ipoint != (*ibase)->end(); ipoint++)
83 if (x < xmin) xmin =
x;
84 if (x > xmax) xmax =
x;
86 if (y < ymin) ymin = y;
87 if (y > ymax) ymax = y;
89 if (z < zmin) zmin =
z;
90 if (z > zmax) zmax =
z;
93 fMin.
set(xmin,ymin,zmin);
94 fMax.
set(xmax,ymax,zmax);
108 const std::vector<const G4ThreeVectorList*>& polygons)
109 : fMin(pMin), fMax(pMax), fPolygons(&polygons)
114 CheckBoundingPolygons();
129 void G4BoundingEnvelope::CheckBoundingBox()
131 if (fMin.
x() >= fMax.
x() || fMin.
y() >= fMax.
y() || fMin.
z() >= fMax.
z())
133 std::ostringstream message;
134 message <<
"Badly defined bounding box (min >= max)!"
135 <<
"\npMin = " << fMin
136 <<
"\npMax = " << fMax;
137 G4Exception(
"G4BoundingEnvelope::CheckBoundingBox()",
147 void G4BoundingEnvelope::CheckBoundingPolygons()
149 G4int nbases = fPolygons->size();
152 std::ostringstream message;
153 message <<
"Wrong number of polygons in the sequence: " << nbases
154 <<
"\nShould be at least two!";
155 G4Exception(
"G4BoundingEnvelope::CheckBoundingPolygons()",
160 G4int nsize =
std::max((*fPolygons)[0]->size(),(*fPolygons)[1]->size());
163 std::ostringstream message;
164 message <<
"Badly constructed polygons!"
165 <<
"\nNumber of polygons: " << nbases
166 <<
"\nPolygon #0 size: " << (*fPolygons)[0]->size()
167 <<
"\nPolygon #1 size: " << (*fPolygons)[1]->size()
169 G4Exception(
"G4BoundingEnvelope::CheckBoundingPolygons()",
174 for (
G4int k=0; k<nbases; ++k)
176 G4int np = (*fPolygons)[k]->size();
177 if (np == nsize)
continue;
178 if (np == 1 && k==0)
continue;
179 if (np == 1 && k==nbases-1)
continue;
180 std::ostringstream message;
181 message <<
"Badly constructed polygons!"
182 <<
"\nNumber of polygons: " << nbases
183 <<
"\nPolygon #" << k <<
" size: " << np
184 <<
"\nexpected size: " << nsize;
185 G4Exception(
"G4BoundingEnvelope::SetBoundingPolygons()",
214 if (pTransform3D.
xx()==1 && pTransform3D.
yy()==1 && pTransform3D.
zz()==1)
230 if (xmin >= xminlim && xmax <= xmaxlim &&
231 ymin >= yminlim && ymax <= ymaxlim &&
232 zmin >= zminlim && zmax <= zmaxlim)
258 G4double scale = FindScaleFactor(pTransform3D);
264 G4double radius = 0.5*scale*(fMax-fMin).mag() + delta;
269 if (center.
x()-radius > xmaxlim)
return true;
270 if (center.
y()-radius > ymaxlim)
return true;
271 if (center.
z()-radius > zmaxlim)
return true;
272 if (center.
x()+radius < xminlim)
return true;
273 if (center.
y()+radius < yminlim)
return true;
274 if (center.
z()+radius < zminlim)
return true;
299 if (pTransform3D.
xx()==1 && pTransform3D.
yy()==1 && pTransform3D.
zz()==1)
341 G4double scale = FindScaleFactor(pTransform3D);
347 G4double radius = 0.5*scale*(fMax-fMin).mag() + delta;
352 if (center.
x()-radius >= xminlim && center.
x()+radius <= xmaxlim &&
353 center.
y()-radius >= yminlim && center.
y()+radius <= ymaxlim &&
354 center.
z()-radius >= zminlim && center.
z()+radius <= zmaxlim )
359 cx = pTransform3D.
xx();
360 cy = pTransform3D.
xy();
361 cz = pTransform3D.
xz();
362 cd = pTransform3D.
dx();
366 cx = pTransform3D.
yx();
367 cy = pTransform3D.
yy();
368 cz = pTransform3D.
yz();
369 cd = pTransform3D.
dy();
373 cx = pTransform3D.
zx();
374 cy = pTransform3D.
zy();
375 cz = pTransform3D.
zz();
376 cd = pTransform3D.
dz();
386 coor = cx*fMin.
x() + cy*fMin.
y() + cz*fMin.
z() +
cd;
387 if (coor < emin) emin = coor;
388 if (coor > emax) emax = coor;
389 coor = cx*fMax.
x() + cy*fMin.
y() + cz*fMin.
z() +
cd;
390 if (coor < emin) emin = coor;
391 if (coor > emax) emax = coor;
392 coor = cx*fMax.
x() + cy*fMax.
y() + cz*fMin.
z() +
cd;
393 if (coor < emin) emin = coor;
394 if (coor > emax) emax = coor;
395 coor = cx*fMin.
x() + cy*fMax.
y() + cz*fMin.
z() +
cd;
396 if (coor < emin) emin = coor;
397 if (coor > emax) emax = coor;
398 coor = cx*fMin.
x() + cy*fMin.
y() + cz*fMax.
z() +
cd;
399 if (coor < emin) emin = coor;
400 if (coor > emax) emax = coor;
401 coor = cx*fMax.
x() + cy*fMin.
y() + cz*fMax.
z() +
cd;
402 if (coor < emin) emin = coor;
403 if (coor > emax) emax = coor;
404 coor = cx*fMax.
x() + cy*fMax.
y() + cz*fMax.
z() +
cd;
405 if (coor < emin) emin = coor;
406 if (coor > emax) emax = coor;
407 coor = cx*fMin.
x() + cy*fMax.
y() + cz*fMax.
z() +
cd;
408 if (coor < emin) emin = coor;
409 if (coor > emax) emax = coor;
413 std::vector<const G4ThreeVectorList*>::const_iterator ibase;
414 for (ibase = fPolygons->begin(); ibase != fPolygons->end(); ibase++)
416 G4ThreeVectorList::const_iterator ipoint;
417 for (ipoint = (*ibase)->begin(); ipoint != (*ibase)->end(); ipoint++)
419 G4double coor = ipoint->x()*cx + ipoint->y()*cy + ipoint->z()*cz +
cd;
420 if (coor < emin) emin = coor;
421 if (coor > emax) emax = coor;
433 if (center.
x()-radius > xmaxlim)
return false;
434 if (center.
y()-radius > ymaxlim)
return false;
435 if (center.
z()-radius > zmaxlim)
return false;
436 if (center.
x()+radius < xminlim)
return false;
437 if (center.
y()+radius < yminlim)
return false;
438 if (center.
z()+radius < zminlim)
return false;
442 G4int nbases = (fPolygons == 0) ? 2 : fPolygons->size();
443 std::vector<G4Polygon3D*> bases(nbases);
451 for (
G4int i=0; i<nbases; ++i)
453 bases[i] =
new G4Polygon3D((*fPolygons)[i]->size());
459 TransformVertices(pTransform3D, bases);
467 for (
G4int i=0; i<3; ++i)
473 limits.
AddLimit(axis[i], emin, emax);
482 for (
G4int k=0; k<nbases-1; ++k)
488 GetPrismAABB(*baseA, *baseB, prismAABB);
498 if (extent.first.x() > prismAABB.first.x())
499 extent.first.setX( prismAABB.first.x() );
500 if (extent.first.y() > prismAABB.first.y())
501 extent.first.setY( prismAABB.first.y() );
502 if (extent.first.z() > prismAABB.first.z())
503 extent.first.setZ( prismAABB.first.z() );
504 if (extent.second.x() < prismAABB.second.x())
505 extent.second.setX(prismAABB.second.x());
506 if (extent.second.y() < prismAABB.second.y())
507 extent.second.setY(prismAABB.second.y());
508 if (extent.second.z() < prismAABB.second.z())
509 extent.second.setZ(prismAABB.second.z());
522 std::vector<G4Segment3D> vecEdges;
523 CreateListOfEdges(*baseA, *baseB, vecEdges);
524 if (ClipEdgesByVoxel(vecEdges, limits, extent))
continue;
544 if (bits == 0xFFF)
continue;
546 std::vector<G4Plane3D> vecPlanes;
547 CreateListOfPlanes(*baseA, *baseB, vecPlanes);
548 ClipVoxelByPlanes(bits, limits, vecPlanes, prismAABB, extent);
553 for (
G4int i=0; i<nbases; ++i) {
delete bases[i]; bases[i] = 0; }
558 if (pAxis ==
kXAxis) { emin = extent.first.x();
emax = extent.second.x(); }
559 if (pAxis ==
kYAxis) { emin = extent.first.y();
emax = extent.second.y(); }
560 if (pAxis ==
kZAxis) { emin = extent.first.z();
emax = extent.second.z(); }
562 if (emin >
emax)
return false;
578 G4BoundingEnvelope::FindScaleFactor(
const G4Transform3D& pTransform3D)
const
580 if (pTransform3D.
xx() == 1. &&
581 pTransform3D.
yy() == 1. &&
582 pTransform3D.
zz() == 1.)
return 1.;
587 G4double sxsx = xx*xx + yx*yx + zx*zx;
591 G4double sysy = xy*xy + yy*yy + zy*zy;
595 G4double szsz = xz*xz + yz*yz + zz*zz;
597 return (ss <= 1.) ? 1. : std::sqrt(ss);
605 G4BoundingEnvelope::TransformVertices(
const G4Transform3D& pTransform3D,
606 std::vector<G4Polygon3D*>& pBases)
const
609 std::vector<const G4ThreeVectorList*> aabb(2);
610 aabb[0] = &baseA; aabb[1] = &baseB;
613 baseA[0].set(fMin.
x(),fMin.
y(),fMin.
z());
614 baseA[1].set(fMax.
x(),fMin.
y(),fMin.
z());
615 baseA[2].set(fMax.
x(),fMax.
y(),fMin.
z());
616 baseA[3].set(fMin.
x(),fMax.
y(),fMin.
z());
617 baseB[0].set(fMin.
x(),fMin.
y(),fMax.
z());
618 baseB[1].set(fMax.
x(),fMin.
y(),fMax.
z());
619 baseB[2].set(fMax.
x(),fMax.
y(),fMax.
z());
620 baseB[3].set(fMin.
x(),fMax.
y(),fMax.
z());
622 std::vector<const G4ThreeVectorList*>::const_iterator ia, iaend;
623 std::vector<G4Polygon3D*>::iterator ib = pBases.begin();
624 ia = (fPolygons == 0) ? aabb.begin() : fPolygons->begin();
625 iaend = (fPolygons == 0) ? aabb.end() : fPolygons->end();
627 if (pTransform3D.
xx()==1 && pTransform3D.
yy()==1 && pTransform3D.
zz()==1)
630 for ( ; ia != iaend; ia++, ib++)
632 G4ThreeVectorList::const_iterator ka = (*ia)->begin();
633 G4Polygon3D::iterator kb = (*ib)->begin();
634 for ( ; ka != (*ia)->end(); ka++, kb++) { (*kb) = (*ka) + offset; }
639 for ( ; ia != iaend; ia++, ib++)
641 G4ThreeVectorList::const_iterator ka = (*ia)->begin();
642 G4Polygon3D::iterator kb = (*ib)->begin();
643 for ( ; ka != (*ia)->end(); ka++, kb++)
656 G4BoundingEnvelope::GetPrismAABB(
const G4Polygon3D& pBaseA,
662 G4Polygon3D::const_iterator it;
666 for (it = pBaseA.begin(); it != pBaseA.end(); it++)
669 if (x < xmin) xmin =
x;
670 if (x > xmax) xmax =
x;
672 if (y < ymin) ymin = y;
673 if (y > ymax) ymax = y;
675 if (z < zmin) zmin =
z;
676 if (z > zmax) zmax =
z;
681 for (it = pBaseB.begin(); it != pBaseB.end(); it++)
684 if (x < xmin) xmin =
x;
685 if (x > xmax) xmax =
x;
687 if (y < ymin) ymin = y;
688 if (y > ymax) ymax = y;
690 if (z < zmin) zmin =
z;
691 if (z > zmax) zmax =
z;
697 pAABB.second =
G4Point3D(xmax,ymax,zmax);
705 G4BoundingEnvelope::CreateListOfEdges(
const G4Polygon3D& baseA,
707 std::vector<G4Segment3D>& pEdges)
const
709 G4int na = baseA.size();
710 G4int nb = baseB.size();
716 for (
G4int i=0; i<na; ++i)
728 for (
G4int i=0; i<na; ++i)
739 for (
G4int i=0; i<nb; ++i)
753 G4BoundingEnvelope::CreateListOfPlanes(
const G4Polygon3D& baseA,
755 std::vector<G4Plane3D>& pPlanes)
const
759 G4int na = baseA.size();
760 G4int nb = baseB.size();
761 G4Point3D pa(0.,0.,0.), pb(0.,0.,0.), p0;
763 for (
G4int i=0; i<na; ++i) pa += baseA[i];
764 for (
G4int i=0; i<nb; ++i) pb += baseB[i];
765 pa /= na; pb /= nb; p0 = (pa+pb)/2.;
773 for (
G4int i=0; i<na; ++i)
775 norm = (baseB[k]-baseA[i]).cross(baseA[k]-baseB[i]);
778 pPlanes.push_back(
G4Plane3D(norm,baseA[i]));
782 norm = (baseA[2]-baseA[0]).cross(baseA[1]-pa);
787 norm = (baseB[2]-baseB[0]).cross(baseB[1]-pb);
796 for (
G4int i=0; i<na; ++i)
798 norm = (baseA[i]-baseB[0]).cross(baseA[k]-baseB[0]);
801 pPlanes.push_back(
G4Plane3D(norm,baseB[0]));
805 norm = (baseA[2]-baseA[0]).cross(baseA[1]-pa);
814 for (
G4int i=0; i<nb; ++i)
816 norm = (baseB[i]-baseA[0]).cross(baseB[k]-baseA[0]);
819 pPlanes.push_back(
G4Plane3D(norm,baseA[0]));
823 norm = (baseB[2]-baseB[0]).cross(baseB[1]-pb);
832 G4int nplanes = pPlanes.size();
833 for (
G4int i=0; i<nplanes; ++i)
835 pPlanes[i].normalize();
836 if (pPlanes[i].distance(p0) > 0)
838 pPlanes[i] =
G4Plane3D(-pPlanes[i].
a(),-pPlanes[i].
b(),
839 -pPlanes[i].
c(),-pPlanes[i].d());
851 G4BoundingEnvelope::ClipEdgesByVoxel(
const std::vector<G4Segment3D>& pEdges,
859 G4int nedges = pEdges.size();
860 for (
G4int k=0; k<nedges; ++k)
864 if (std::abs(p1.
x()-p2.
x())+
865 std::abs(p1.
y()-p2.
y())+
873 if (d2 > 0.0) { done =
false;
continue; }
874 p1 = (p2*d1-p1*
d2)/(d1-d2);
878 if (d2 > 0.0) { p2 = (p1*d2-p2*
d1)/(d2-d1); }
886 if (d2 > 0.) { done =
false;
continue; }
887 p1 = (p2*d1-p1*
d2)/(d1-d2);
891 if (d2 > 0.) { p2 = (p1*d2-p2*
d1)/(d2-d1); }
899 if (d2 > 0.) { done =
false;
continue; }
900 p1 = (p2*d1-p1*
d2)/(d1-d2);
904 if (d2 > 0.) { p2 = (p1*d2-p2*
d1)/(d2-d1); }
912 if (d2 > 0.) { done =
false;
continue; }
913 p1 = (p2*d1-p1*
d2)/(d1-d2);
917 if (d2 > 0.) { p2 = (p1*d2-p2*
d1)/(d2-d1); }
925 if (d2 > 0.) { done =
false;
continue; }
926 p1 = (p2*d1-p1*
d2)/(d1-d2);
930 if (d2 > 0.) { p2 = (p1*d2-p2*
d1)/(d2-d1); }
938 if (d2 > 0.) { done =
false;
continue; }
939 p1 = (p2*d1-p1*
d2)/(d1-d2);
943 if (d2 > 0.) { p2 = (p1*d2-p2*
d1)/(d2-d1); }
958 pExtent.first = emin;
959 pExtent.second =
emax;
969 G4BoundingEnvelope::ClipVoxelByPlanes(
G4int pBits,
971 const std::vector<G4Plane3D>& pPlanes,
990 std::vector<G4Segment3D> edges(12);
991 G4int i = 0, bits = pBits;
994 edges[i ].first.set( xmin,ymin,zmin);
995 edges[i++].second.set(xmax,ymin,zmin);
999 edges[i ].first.set( xmax,ymin,zmin);
1000 edges[i++].second.set(xmax,ymax,zmin);
1002 if (!(bits & 0x004))
1004 edges[i ].first.set( xmax,ymax,zmin);
1005 edges[i++].second.set(xmin,ymax,zmin);
1007 if (!(bits & 0x008))
1009 edges[i ].first.set( xmin,ymax,zmin);
1010 edges[i++].second.set(xmin,ymin,zmin);
1013 if (!(bits & 0x010))
1015 edges[i ].first.set( xmin,ymin,zmax);
1016 edges[i++].second.set(xmax,ymin,zmax);
1018 if (!(bits & 0x020))
1020 edges[i ].first.set( xmax,ymin,zmax);
1021 edges[i++].second.set(xmax,ymax,zmax);
1023 if (!(bits & 0x040))
1025 edges[i ].first.set( xmax,ymax,zmax);
1026 edges[i++].second.set(xmin,ymax,zmax);
1028 if (!(bits & 0x080))
1030 edges[i ].first.set( xmin,ymax,zmax);
1031 edges[i++].second.set(xmin,ymin,zmax);
1034 if (!(bits & 0x100))
1036 edges[i ].first.set( xmin,ymin,zmin);
1037 edges[i++].second.set(xmin,ymin,zmax);
1039 if (!(bits & 0x200))
1041 edges[i ].first.set( xmax,ymin,zmin);
1042 edges[i++].second.set(xmax,ymin,zmax);
1044 if (!(bits & 0x400))
1046 edges[i ].first.set( xmax,ymax,zmin);
1047 edges[i++].second.set(xmax,ymax,zmax);
1049 if (!(bits & 0x800))
1051 edges[i ].first.set( xmin,ymax,zmin);
1052 edges[i++].second.set(xmin,ymax,zmax);
1058 std::vector<G4Segment3D>::const_iterator iedge;
1059 for (iedge = edges.begin(); iedge != edges.end(); iedge++)
1064 std::vector<G4Plane3D>::const_iterator iplane;
1065 for (iplane = pPlanes.begin(); iplane != pPlanes.end(); iplane++)
1068 G4double d1 = iplane->distance(p1);
1069 G4double d2 = iplane->distance(p2);
1072 if (d2 > 0.0) { exist =
false;
break; }
1073 p1 = (p2*d1-p1*
d2)/(d1-d2);
1077 if (d2 > 0.0) { p2 = (p1*d2-p2*
d1)/(d2-d1); }
1095 pExtent.first = emin;
1096 pExtent.second =
emax;
void set(double x, double y, double z)
G4BoundingEnvelope(const G4ThreeVector &pMin, const G4ThreeVector &pMax)
static const G4double kInfinity
G4double GetMinYExtent() const
std::vector< ExP01TrackerHit * > a
G4double GetSurfaceTolerance() const
HepGeom::Point3D< G4double > G4Point3D
G4double GetMaxXExtent() const
void AddLimit(const EAxis pAxis, const G4double pMin, const G4double pMax)
G4double GetMinZExtent() const
std::vector< G4Point3D > G4Polygon3D
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
const G4double kCarTolerance
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static const G4double emax
G4double GetMinXExtent() const
G4double GetMaxZExtent() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
std::pair< G4Point3D, G4Point3D > G4Segment3D
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
HepGeom::Plane3D< G4double > G4Plane3D
G4double GetMaxYExtent() const
G4double GetMaxExtent(const EAxis pAxis) const
G4double GetMinExtent(const EAxis pAxis) const
static G4GeometryTolerance * GetInstance()