44 #if !defined(G4GEOM_USE_UTRD)
54 using namespace CLHEP;
77 if ( pdx1>0&&pdx2>0&&pdy1>0&&pdy2>0&&pdz>0 )
85 if ( pdx1>=0 && pdx2>=0 && pdy1>=0 && pdy2>=0 && pdz>=0 )
99 std::ostringstream message;
100 message <<
"Invalid negative dimensions for Solid: " <<
GetName()
102 <<
" X - " << pdx1 <<
", " << pdx2 <<
G4endl
103 <<
" Y - " << pdy1 <<
", " << pdy2 <<
G4endl
120 :
G4CSGSolid(a), fDx1(0.), fDx2(0.), fDy1(0.), fDy2(0.), fDz(0.)
137 :
G4CSGSolid(rhs), fDx1(rhs.fDx1), fDx2(rhs.fDx2),
138 fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz)
150 if (
this == &rhs) {
return *
this; }
158 fDx1 = rhs.fDx1; fDx2 = rhs.fDx2;
159 fDy1 = rhs.fDy1; fDy2 = rhs.fDy2;
233 xMax = xoffset+(fDx1+fDx2)/2+(zMax-zoffset)*(fDx2-fDx1)/(2*fDz) ;
234 xMin = 2*xoffset - xMax ;
238 xMax = xoffset+(fDx1+fDx2)/2+(zMin-zoffset)*(fDx2-fDx1)/(2*fDz) ;
239 xMin = 2*xoffset - xMax ;
263 yMax = yoffset+(fDy2+fDy1)/2+(zMax-zoffset)*(fDy2-fDy1)/(2*fDz) ;
264 yMin = 2*yoffset - yMax ;
268 yMax = yoffset+(fDy2+fDy1)/2+(zMin-zoffset)*(fDy2-fDy1)/(2*fDz) ;
269 yMin = 2*yoffset - yMax ;
320 G4bool existsAfterClip=
false;
333 if (pMin!=kInfinity||pMax!=-kInfinity)
335 existsAfterClip=
true;
357 existsAfterClip=
true;
363 return existsAfterClip;
384 if (std::fabs(p.
x())<=x)
387 if (std::fabs(p.
y())<=y)
401 if (std::fabs(p.
y())<=y)
417 if (std::fabs(p.
x())<=x)
437 G4int noSurfaces = 0;
438 G4double z = 2.0*fDz, tanx, secx, newpx, widx;
443 tanx = (fDx2 - fDx1)/z;
444 secx = std::sqrt(1.0+tanx*tanx);
445 newpx = std::fabs(p.
x())-p.
z()*tanx;
446 widx = fDx2 - fDz*tanx;
448 tany = (fDy2 - fDy1)/z;
449 secy = std::sqrt(1.0+tany*tany);
450 newpy = std::fabs(p.
y())-p.
z()*tany;
451 widy = fDy2 - fDz*tany;
453 distx = std::fabs(newpx-widx)/secx;
454 disty = std::fabs(newpy-widy)/secy;
455 distz = std::fabs(std::fabs(p.
z())-fDz);
469 if ( p.
x() >= 0.) sumnorm += nX;
475 if ( p.
y() >= 0.) sumnorm += nY;
481 if ( p.
z() >= 0.) sumnorm += nZ;
484 if ( noSurfaces == 0 )
488 "Point p is not on surface !?" );
492 else if ( noSurfaces == 1 ) norm = sumnorm;
493 else norm = sumnorm.
unit();
513 secx=std::sqrt(1.0+tanx*tanx);
514 newpx=std::fabs(p.
x())-p.
z()*tanx;
518 secy=std::sqrt(1.0+tany*tany);
519 newpy=std::fabs(p.
y())-p.
z()*tany;
522 distx=std::fabs(newpx-widx)/secx;
523 disty=std::fabs(newpy-widy)/secy;
524 distz=std::fabs(std::fabs(p.
z())-fDz);
602 G4double ss1,ss2,sn1=0.,sn2=0.,Dist;
613 smin = -(fDz + p.
z())/v.
z() ;
624 smin = (fDz - p.
z())/v.
z() ;
628 if (smin < 0 ) smin = 0 ;
632 if (std::fabs(p.
z()) >= fDz )
return snxt ;
644 tanxz = (fDx2 - fDx1)*0.5/fDz ;
645 s1 = 0.5*(fDx1+fDx2) + tanxz*p.
z() ;
646 ds1 = v.
x() - tanxz*v.
z() ;
647 ds2 = v.
x() + tanxz*v.
z() ;
653 if (ss1 < 0 && ss2 <= 0 )
659 if ( ds2 < 0 ) sn2 = ss2/ds2 ;
660 else sn2 = kInfinity ;
664 else if ( ss1 >= 0 && ss2 > 0 )
670 if (ds1 > 0) sn2 = ss1/ds1 ;
671 else sn2 = kInfinity;
676 else if (ss1 >= 0 && ss2 <= 0 )
689 else sn2 = kInfinity ;
696 if ( Dist < sn2 ) sn2 = Dist ;
701 else if (ss1 < 0 && ss2 > 0 )
705 if ( ds1 >= 0 || ds2 <= 0 )
713 if (Dist > sn1 ) sn1 = Dist ;
720 if ( sn1 > smin ) smin = sn1 ;
721 if ( sn2 < smax ) smax = sn2 ;
726 if ( smax < smin )
return snxt ;
731 tanyz = (fDy2-fDy1)*0.5/fDz ;
732 s2 = 0.5*(fDy1+fDy2) + tanyz*p.
z() ;
733 ds1 = v.
y() - tanyz*v.
z() ;
734 ds2 = v.
y() + tanyz*v.
z() ;
738 if ( ss1 < 0 && ss2 <= 0 )
743 if ( ds2 < 0 ) sn2 = ss2/ds2 ;
744 else sn2 = kInfinity ;
748 else if ( ss1 >= 0 && ss2 > 0 )
753 if ( ds1 > 0 ) sn2 = ss1/ds1 ;
754 else sn2 = kInfinity ;
758 else if (ss1 >= 0 && ss2 <= 0 )
771 else sn2 = kInfinity ;
778 if (Dist < sn2) sn2=Dist;
783 else if (ss1 < 0 && ss2 > 0 )
787 if (ds1 >= 0 || ds2 <= 0 )
795 if (Dist > sn1 ) sn1 = Dist ;
802 if ( sn1 > smin) smin = sn1 ;
803 if ( sn2 < smax) smax = sn2 ;
808 if ( smax > smin ) snxt = smin ;
829 safe=std::fabs(p.
z())-fDz;
837 tanxz=(fDx2-fDx1)*0.5/fDz;
840 distx=std::fabs(p.
x())-(fDx1+tanxz*zbase);
843 safx=distx/std::sqrt(1.0+tanxz*tanxz);
844 if (safx>safe) safe=safx;
848 tanyz=(fDy2-fDy1)*0.5/fDz;
851 disty=std::fabs(p.
y())-(fDy1+tanyz*zbase);
854 safy=disty/std::sqrt(1.0+tanyz*tanyz);
855 if (safy>safe) safe=safy;
877 G4double central,ss1,ss2,ds1,ds2,sn=0.,sn2=0.;
878 G4double tanxz=0.,cosxz=0.,tanyz=0.,cosyz=0.;
880 if (calcNorm) *validNorm=
true;
925 tanxz=(fDx2-fDx1)*0.5/fDz;
926 central=0.5*(fDx1+fDx2);
930 ss1=central+tanxz*p.
z()-p.
x();
932 ds1=v.
x()-tanxz*v.
z();
936 ss2=-tanxz*p.
z()-p.
x()-central;
938 ds2=tanxz*v.
z()+v.
x();
956 else if (ds1>0&&ds2>=0)
969 else if (ds1>0&&ds2<0)
1007 else if (ss1<=0&&ss2<0)
1034 else if (ss1>0&&ss2>=0)
1073 tanyz=(fDy2-fDy1)*0.5/fDz;
1074 central=0.5*(fDy1+fDy2);
1078 ss1=central+tanyz*p.
z()-p.
y();
1080 ds1=v.
y()-tanyz*v.
z();
1084 ss2=-tanyz*p.
z()-p.
y()-central;
1086 ds2=tanyz*v.
z()+v.
y();
1105 else if (ds1>0&&ds2>=0)
1118 else if (ds1>0&&ds2<0)
1156 else if (ss1<=0&&ss2<0)
1183 else if (ss1>0&&ss2>=0)
1224 cosxz=1.0/std::sqrt(1.0+tanxz*tanxz);
1228 cosxz=-1.0/std::sqrt(1.0+tanxz*tanxz);
1232 cosyz=1.0/std::sqrt(1.0+tanyz*tanyz);
1236 cosyz=-1.0/std::sqrt(1.0+tanyz*tanyz);
1249 "Undefined side for valid surface normal to solid.");
1278 G4cout.precision(oldprc) ;
1280 "Point p is outside !?" );
1284 safe=fDz-std::fabs(p.
z());
1291 tanxz=(fDx2-fDx1)*0.5/fDz;
1292 xdist=fDx1+tanxz*zbase-std::fabs(p.
x());
1293 saf1=xdist/std::sqrt(1.0+tanxz*tanxz);
1296 tanyz=(fDy2-fDy1)*0.5/fDz;
1297 ydist=fDy1+tanyz*zbase-std::fabs(p.
y());
1298 saf2=ydist/std::sqrt(1.0+tanyz*tanyz);
1302 if (safe>saf1) safe=saf1;
1303 if (safe>saf2) safe=saf2;
1325 vertices->reserve(8);
1349 "Error in allocation of vertices. Out of memory !");
1369 return new G4Trd(*
this);
1378 G4int oldprc = os.precision(16);
1379 os <<
"-----------------------------------------------------------\n"
1380 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1381 <<
" ===================================================\n"
1382 <<
" Solid type: G4Trd\n"
1383 <<
" Parameters: \n"
1384 <<
" half length X, surface -dZ: " << fDx1/
mm <<
" mm \n"
1385 <<
" half length X, surface +dZ: " << fDx2/
mm <<
" mm \n"
1386 <<
" half length Y, surface -dZ: " << fDy1/
mm <<
" mm \n"
1387 <<
" half length Y, surface +dZ: " << fDy2/
mm <<
" mm \n"
1388 <<
" half length Z : " << fDz/
mm <<
" mm \n"
1389 <<
"-----------------------------------------------------------\n";
1390 os.precision(oldprc);
1405 G4double px, py, pz, tgX, tgY, secX, secY, select, sumS,
tmp;
1406 G4double Sxy1, Sxy2, Sxy, Sxz, Syz;
1408 tgX = 0.5*(fDx2-fDx1)/fDz;
1409 secX = std::sqrt(1+tgX*tgX);
1410 tgY = 0.5*(fDy2-fDy1)/fDz;
1411 secY = std::sqrt(1+tgY*tgY);
1418 Sxz = (fDx1 + fDx2)*fDz*secY;
1419 Syz = (fDy1 + fDy2)*fDz*secX;
1420 sumS = Sxy + Sxz + Syz;
1439 else if ( ( select - Sxy ) < Sxz )
1442 tmp = fDx1 + (pz + fDz)*tgX;
1444 tmp = fDy1 + (pz + fDz)*tgY;
1452 tmp = fDy1 + (pz + fDz)*tgY;
1454 tmp = fDx1 + (pz + fDz)*tgX;
void DescribeYourselfTo(G4VGraphicsScene &scene) const
void SetAllParameters(G4double pdx1, G4double pdx2, G4double pdy1, G4double pdy2, G4double pdz)
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform) const
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
G4double GetMinYExtent() const
CLHEP::Hep3Vector G4ThreeVector
G4bool IsYLimited() const
std::ostream & StreamInfo(std::ostream &os) const
G4GeometryType GetEntityType() const
G4bool IsXLimited() const
G4double fcos(G4double arg)
virtual void AddSolid(const G4Box &)=0
G4ThreeVector GetPointOnSurface() const
G4ThreeVector ApproxSurfaceNormal(const G4ThreeVector &p) const
G4double GetMaxXExtent() const
G4double GetMinZExtent() const
G4GLOB_DLL std::ostream G4cout
G4Polyhedron * CreatePolyhedron() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4Polyhedron * fpPolyhedron
std::vector< G4ThreeVector > G4ThreeVectorList
EInside Inside(const G4ThreeVector &p) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinXExtent() const
G4double GetMaxZExtent() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
void CheckAndSetAllParameters(G4double pdx1, G4double pdx2, G4double pdy1, G4double pdy2, G4double pdz)
G4Trd & operator=(const G4Trd &rhs)
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4double GetMaxYExtent() const
G4Trd(const G4String &pName, G4double pdx1, G4double pdx2, G4double pdy1, G4double pdy2, G4double pdz)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
G4double GetMaxExtent(const EAxis pAxis) const
G4CSGSolid & operator=(const G4CSGSolid &rhs)
G4bool IsZLimited() const
void ClipBetweenSections(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
G4double GetMinExtent(const EAxis pAxis) const