57 using namespace CLHEP;
74 if ( pDx > 0 && pDy > 0 && pDz > 0 )
79 fTalpha = std::tan(pAlpha);
80 fTthetaCphi = std::tan(pTheta)*std::cos(pPhi);
81 fTthetaSphi = std::tan(pTheta)*std::sin(pPhi);
85 std::ostringstream message;
86 message <<
"Invalid Length Parameters for Solid: " << GetName() <<
G4endl
87 <<
" pDx, pDy, pDz = "
88 << pDx <<
", " << pDy <<
", " << pDz;
89 G4Exception(
"G4Para::SetAllParameters()",
"GeomSolids0002",
105 if ((pDx<=0) || (pDy<=0) || (pDz<=0))
107 std::ostringstream message;
108 message <<
"Invalid Length Parameters for Solid: " <<
GetName() <<
G4endl
109 <<
" pDx, pDy, pDz = "
110 << pDx <<
", " << pDy <<
", " << pDz;
127 if (!( pt[0].
z()<0 && pt[0].
z()==pt[1].
z() && pt[0].
z()==pt[2].
z() &&
128 pt[0].
z()==pt[3].
z() && pt[4].
z()>0 && pt[4].
z()==pt[5].
z() &&
129 pt[4].
z()==pt[6].
z() && pt[4].
z()==pt[7].
z() &&
130 (pt[0].
z()+pt[4].
z())==0 &&
131 pt[0].
y()==pt[1].
y() && pt[2].
y()==pt[3].
y() &&
132 pt[4].
y()==pt[5].
y() && pt[6].
y()==pt[7].
y() &&
133 ( pt[0].
y() + pt[2].
y() + pt[4].
y() + pt[6].
y() ) == 0 &&
134 ( pt[0].
x() + pt[1].
x() + pt[4].
x() + pt[5].
x() ) == 0) )
136 std::ostringstream message;
137 message <<
"Invalid vertice coordinates for Solid: " <<
GetName();
141 fDx = ((pt[3]).
x()-(pt[2]).
x())*0.5;
142 fDy = ((pt[2]).
y()-(pt[1]).
y())*0.5;
144 fTalpha = ((pt[2]).
x()+(pt[3]).
x()-(pt[1]).
x()-(pt[0]).
x())*0.25/fDy ;
145 fTthetaCphi = ((pt[4]).
x()+fDy*fTalpha+fDx)/fDz ;
146 fTthetaSphi = ((pt[4]).
y()+fDy)/fDz ;
159 fTalpha(0.), fTthetaCphi(0.), fTthetaSphi(0.)
175 :
G4CSGSolid(rhs), fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz),
176 fTalpha(rhs.fTalpha), fTthetaCphi(rhs.fTthetaCphi),
177 fTthetaSphi(rhs.fTthetaSphi)
189 if (
this == &rhs) {
return *
this; }
197 fDx = rhs.fDx; fDy = rhs.fDy; fDz = rhs.fDz;
198 fTalpha = rhs.fTalpha; fTthetaCphi = rhs.fTthetaCphi;
199 fTthetaSphi = rhs.fTthetaSphi;
246 yoffset-fDz*fTthetaSphi-fDy,zoffset-fDz);
248 yoffset-fDz*fTthetaSphi-fDy,zoffset-fDz);
250 yoffset-fDz*fTthetaSphi+fDy,zoffset-fDz);
252 yoffset-fDz*fTthetaSphi+fDy,zoffset-fDz);
254 yoffset+fDz*fTthetaSphi-fDy,zoffset+fDz);
256 yoffset+fDz*fTthetaSphi-fDy,zoffset+fDz);
258 yoffset+fDz*fTthetaSphi+fDy,zoffset+fDz);
260 yoffset+fDz*fTthetaSphi+fDy,zoffset+fDz);
283 temp[0] = pt[0].
y()+(pt[4].
y()-pt[0].
y())
284 *(zMin-pt[0].
z())/(pt[4].
z()-pt[0].
z()) ;
285 temp[1] = pt[0].
y()+(pt[4].
y()-pt[0].
y())
286 *(zMax-pt[0].
z())/(pt[4].
z()-pt[0].
z()) ;
287 temp[2] = pt[2].
y()+(pt[6].
y()-pt[2].
y())
288 *(zMin-pt[2].
z())/(pt[6].
z()-pt[2].
z()) ;
289 temp[3] = pt[2].
y()+(pt[6].
y()-pt[2].
y())
290 *(zMax-pt[2].
z())/(pt[6].
z()-pt[2].
z()) ;
291 yMax = yoffset - std::fabs(fDz*fTthetaSphi) - fDy - fDy ;
295 if(temp[i] > yMax) yMax = temp[i] ;
296 if(temp[i] < yMin) yMin = temp[i] ;
319 temp[0] = pt[0].
x()+(pt[4].
x()-pt[0].
x())
320 *(zMin-pt[0].
z())/(pt[4].
z()-pt[0].
z()) ;
321 temp[1] = pt[0].
x()+(pt[4].
x()-pt[0].
x())
322 *(zMax-pt[0].
z())/(pt[4].
z()-pt[0].
z()) ;
323 temp[2] = pt[2].
x()+(pt[6].
x()-pt[2].
x())
324 *(zMin-pt[2].
z())/(pt[6].
z()-pt[2].
z()) ;
325 temp[3] = pt[2].
x()+(pt[6].
x()-pt[2].
x())
326 *(zMax-pt[2].
z())/(pt[6].
z()-pt[2].
z()) ;
327 temp[4] = pt[3].
x()+(pt[7].
x()-pt[3].
x())
328 *(zMin-pt[3].
z())/(pt[7].
z()-pt[3].
z()) ;
329 temp[5] = pt[3].
x()+(pt[7].
x()-pt[3].
x())
330 *(zMax-pt[3].
z())/(pt[7].
z()-pt[3].
z()) ;
331 temp[6] = pt[1].
x()+(pt[5].
x()-pt[1].
x())
332 *(zMin-pt[1].
z())/(pt[5].
z()-pt[1].
z()) ;
333 temp[7] = pt[1].
x()+(pt[5].
x()-pt[1].
x())
334 *(zMax-pt[1].
z())/(pt[5].
z()-pt[1].
z()) ;
336 xMax = xoffset - std::fabs(fDz*fTthetaCphi) - fDx - fDx -fDx - fDx;
340 if(temp[i] > xMax) xMax = temp[i] ;
341 if(temp[i] < xMin) xMin = temp[i] ;
390 G4bool existsAfterClip=
false;
403 if (pMin!=kInfinity||pMax!=-kInfinity)
405 existsAfterClip=
true;
426 existsAfterClip=
true;
432 flag = existsAfterClip ;
446 yt1 = p.
y() - fTthetaSphi*p.
z();
447 yt = std::fabs(yt1) ;
451 xt = std::fabs( p.
x() - fTthetaCphi*p.
z() - fTalpha*yt1 );
483 G4int noSurfaces = 0;
491 newpx = p.
x()-fTthetaCphi*p.
z();
492 newpy = p.
y()-fTthetaSphi*p.
z();
494 calpha = 1/std::sqrt(1+fTalpha*fTalpha);
495 if (fTalpha) {salpha = -calpha*fTalpha;}
499 xshift = newpx - newpy*fTalpha;
502 distx = std::fabs(std::fabs(xshift)-fDx);
503 disty = std::fabs(std::fabs(newpy)-fDy);
504 distz = std::fabs(std::fabs(p.
z())-fDz);
506 tntheta = fTthetaCphi*calpha + fTthetaSphi*salpha;
507 cosntheta = 1/std::sqrt(1+tntheta*tntheta);
508 ycomp = 1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
519 if ( xshift >= 0.) {sumnorm += nX;}
520 else {sumnorm -= nX;}
525 if ( newpy >= 0.) {sumnorm += nY;}
526 else {sumnorm -= nY;}
531 if ( p.
z() >= 0.) {sumnorm += nZ;}
532 else {sumnorm -= nZ;}
534 if ( noSurfaces == 0 )
537 G4Exception(
"G4Para::SurfaceNormal(p)",
"GeomSolids1002",
540 norm = ApproxSurfaceNormal(p);
542 else if ( noSurfaces == 1 ) {norm = sumnorm;}
543 else {norm = sumnorm.
unit();}
564 newpx=p.
x()-fTthetaCphi*p.
z();
565 newpy=p.
y()-fTthetaSphi*p.
z();
567 calpha=1/std::sqrt(1+fTalpha*fTalpha);
570 salpha=-calpha/fTalpha;
577 xshift=newpx*calpha+newpy*salpha;
579 distx=std::fabs(std::fabs(xshift)-fDx*calpha);
580 disty=std::fabs(std::fabs(newpy)-fDy);
581 distz=std::fabs(std::fabs(p.
z())-fDz);
585 if (distx<distz) {side=
kNX;}
590 if (disty<distz) {side=
kNY;}
597 tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
600 cosntheta=-1/std::sqrt(1+tntheta*tntheta);
604 cosntheta=1/std::sqrt(1+tntheta*tntheta);
606 norm=
G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
611 ycomp=-1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
615 ycomp=1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
666 smin=(-fDz-p.
z())/v.
z();
670 return snxt=kInfinity;
679 smin=(fDz-p.
z())/v.
z();
683 return snxt=kInfinity;
688 if (std::fabs(p.
z())<=fDz)
695 return snxt=kInfinity;
703 yt=p.
y()-fTthetaSphi*p.
z();
704 vy=v.
y()-fTthetaSphi*v.
z();
716 return snxt=kInfinity;
729 return snxt=kInfinity;
734 if (std::fabs(yt)<=fDy)
741 return snxt=kInfinity;
747 if (tmin>smin) smin=tmin;
748 if (tmax<smax) smax=tmax;
751 return snxt=kInfinity;
758 xt=p.
x()-fTthetaCphi*p.
z()-fTalpha*yt;
759 vx=v.
x()-fTthetaCphi*v.
z()-fTalpha*vy;
770 return snxt=kInfinity;
783 return snxt=kInfinity;
788 if (std::fabs(xt)<=fDx)
795 return snxt=kInfinity;
798 if (tmin>smin) smin=tmin;
799 if (tmax<smax) smax=tmax;
802 if (smax>0&&smin<smax)
828 G4double distz1,distz2,disty1,disty2,distx1,distx2;
844 trany=p.
y()-fTthetaSphi*p.
z();
848 cosy=1.0/std::sqrt(1.0+fTthetaSphi*fTthetaSphi);
849 disty1=(trany-fDy)*cosy;
850 disty2=(-fDy-trany)*cosy;
852 if (disty1>safe) safe=disty1;
853 if (disty2>safe) safe=disty2;
855 tranx=p.
x()-fTthetaCphi*p.
z()-fTalpha*trany;
856 cosx=1.0/std::sqrt(1.0+fTalpha*fTalpha+fTthetaCphi*fTthetaCphi);
857 distx1=(tranx-fDx)*cosx;
858 distx2=(-fDx-tranx)*cosx;
860 if (distx1>safe) safe=distx1;
861 if (distx2>safe) safe=distx2;
881 G4double ycomp,calpha,salpha,tntheta,cosntheta;
932 yt=p.
y()-fTthetaSphi*p.
z();
933 vy=v.
y()-fTthetaSphi*v.
z();
952 ycomp=1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
975 ycomp=-1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
986 xt=p.
x()-fTthetaCphi*p.
z()-fTalpha*yt;
987 vx=v.
x()-fTthetaCphi*v.
z()-fTalpha*vy;
1005 calpha=1/std::sqrt(1+fTalpha*fTalpha);
1008 salpha=-calpha/fTalpha;
1014 tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
1015 cosntheta=1/std::sqrt(1+tntheta*tntheta);
1016 *n=
G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
1038 calpha=1/std::sqrt(1+fTalpha*fTalpha);
1041 salpha=-calpha/fTalpha;
1047 tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
1048 cosntheta=-1/std::sqrt(1+tntheta*tntheta);
1049 *n=
G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
1067 ycomp=-1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
1071 ycomp=1/std::sqrt(1+fTthetaSphi*fTthetaSphi);
1075 calpha=1/std::sqrt(1+fTalpha*fTalpha);
1078 salpha=-calpha/fTalpha;
1084 tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
1085 cosntheta=-1/std::sqrt(1+tntheta*tntheta);
1086 *n=
G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
1089 calpha=1/std::sqrt(1+fTalpha*fTalpha);
1092 salpha=-calpha/fTalpha;
1098 tntheta=fTthetaCphi*calpha+fTthetaSphi*salpha;
1099 cosntheta=1/std::sqrt(1+tntheta*tntheta);
1100 *n=
G4ThreeVector(calpha*cosntheta,salpha*cosntheta,-tntheta*cosntheta);
1106 "Undefined side for valid surface normal to solid.");
1121 G4double distz1,distz2,disty1,disty2,distx1,distx2;
1134 G4cout.precision(oldprc) ;
1135 G4Exception(
"G4Para::DistanceToOut(p)",
"GeomSolids1002",
1153 trany=p.
y()-fTthetaSphi*p.
z();
1157 cosy=1.0/std::sqrt(1.0+fTthetaSphi*fTthetaSphi);
1158 disty1=(fDy-trany)*cosy;
1159 disty2=(fDy+trany)*cosy;
1161 if (disty1<safe) safe=disty1;
1162 if (disty2<safe) safe=disty2;
1164 tranx=p.
x()-fTthetaCphi*p.
z()-fTalpha*trany;
1165 cosx=1.0/std::sqrt(1.0+fTalpha*fTalpha+fTthetaCphi*fTthetaCphi);
1166 distx1=(fDx-tranx)*cosx;
1167 distx2=(fDx+tranx)*cosx;
1169 if (distx1<safe) safe=distx1;
1170 if (distx2<safe) safe=distx2;
1192 vertices->reserve(8);
1194 -fDz*fTthetaSphi-fDy, -fDz);
1196 -fDz*fTthetaSphi-fDy, -fDz);
1198 -fDz*fTthetaSphi+fDy, -fDz);
1200 -fDz*fTthetaSphi+fDy, -fDz);
1202 +fDz*fTthetaSphi-fDy, +fDz);
1204 +fDz*fTthetaSphi-fDy, +fDz);
1206 +fDz*fTthetaSphi+fDy, +fDz);
1208 +fDz*fTthetaSphi+fDy, +fDz);
1224 "Error in allocation of vertices. Out of memory !");
1244 return new G4Para(*
this);
1253 G4int oldprc = os.precision(16);
1254 os <<
"-----------------------------------------------------------\n"
1255 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1256 <<
" ===================================================\n"
1257 <<
" Solid type: G4Para\n"
1258 <<
" Parameters: \n"
1259 <<
" half length X: " << fDx/
mm <<
" mm \n"
1260 <<
" half length Y: " << fDy/
mm <<
" mm \n"
1261 <<
" half length Z: " << fDz/
mm <<
" mm \n"
1262 <<
" std::tan(alpha) : " << fTalpha/
degree <<
" degrees \n"
1263 <<
" std::tan(theta)*std::cos(phi): " << fTthetaCphi/
degree
1265 <<
" std::tan(theta)*std::sin(phi): " << fTthetaSphi/
degree
1267 <<
"-----------------------------------------------------------\n";
1268 os.precision(oldprc);
1283 G4double lambda1, lambda2, chose, aOne, aTwo;
1292 w.
z()*v.
x() - w.
x()*v.
z(),
1293 w.
x()*v.
y() - w.
y()*v.
x());
1295 aOne = 0.5*Area.
mag();
1298 t.
z()*u.
x() - t.
x()*u.
z(),
1299 t.
x()*u.
y() - t.
y()*u.
x());
1301 aTwo = 0.5*Area.
mag();
1307 if( (chose>=0.) && (chose < aOne) )
1311 return (p2+lambda1*v+lambda2*w);
1318 return (p0+lambda1*t+lambda2*u);
1332 G4double chose, aOne, aTwo, aThree, aFour, aFive, aSix;
1335 -fDz*fTthetaSphi-fDy, -fDz);
1337 -fDz*fTthetaSphi-fDy, -fDz);
1339 -fDz*fTthetaSphi+fDy, -fDz);
1341 -fDz*fTthetaSphi+fDy, -fDz);
1343 +fDz*fTthetaSphi-fDy, +fDz);
1345 +fDz*fTthetaSphi-fDy, +fDz);
1347 +fDz*fTthetaSphi+fDy, +fDz);
1349 +fDz*fTthetaSphi+fDy, +fDz);
1353 One = GetPointOnPlane(pt[0],pt[1],pt[3],pt[2], aOne);
1354 Two = GetPointOnPlane(pt[4],pt[5],pt[7],pt[6], aTwo);
1355 Three = GetPointOnPlane(pt[6],pt[7],pt[3],pt[2], aThree);
1356 Four = GetPointOnPlane(pt[4],pt[5],pt[1],pt[0], aFour);
1357 Five = GetPointOnPlane(pt[0],pt[2],pt[6],pt[4], aFive);
1358 Six = GetPointOnPlane(pt[1],pt[3],pt[7],pt[5], aSix);
1362 if( (chose>=0.) && (chose<aOne) )
1364 else if(chose>=aOne && chose<aOne+aTwo)
1366 else if(chose>=aOne+aTwo && chose<aOne+aTwo+aThree)
1368 else if(chose>=aOne+aTwo+aThree && chose<aOne+aTwo+aThree+aFour)
1370 else if(chose>=aOne+aTwo+aThree+aFour && chose<aOne+aTwo+aThree+aFour+aFive)
1386 G4double phi = std::atan2(fTthetaSphi, fTthetaCphi);
1387 G4double alpha = std::atan(fTalpha);
1388 G4double theta = std::atan(std::sqrt(fTthetaCphi*fTthetaCphi
1389 +fTthetaSphi*fTthetaSphi));
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
ThreeVector shoot(const G4int Ap, const G4int Af)
G4ThreeVector GetPointOnSurface() const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
EInside Inside(const G4ThreeVector &p) const
void SetAllParameters(G4double pDx, G4double pDy, G4double pDz, G4double pAlpha, G4double pTheta, G4double pPhi)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
G4double GetMinYExtent() const
CLHEP::Hep3Vector G4ThreeVector
G4bool IsYLimited() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4Para(const G4String &pName, G4double pDx, G4double pDy, G4double pDz, G4double pAlpha, G4double pTheta, G4double pPhi)
G4bool IsXLimited() const
std::ostream & StreamInfo(std::ostream &os) const
G4Para & operator=(const G4Para &rhs)
virtual void AddSolid(const G4Box &)=0
G4Polyhedron * CreatePolyhedron() const
G4double GetMaxXExtent() const
G4double GetMinZExtent() const
G4GLOB_DLL std::ostream G4cout
G4Polyhedron * fpPolyhedron
std::vector< G4ThreeVector > G4ThreeVectorList
G4GeometryType GetEntityType() 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
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4double GetMaxZExtent() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform) const
G4double GetMaxYExtent() 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