81 fLowerEndcap(0), fUpperEndcap(0), fSide0(0),
82 fSide90(0), fSide180(0), fSide270(0),
83 fSurfaceArea(0.), fpPolyhedron(0)
103 fDxDown = ( fDx1 > fDx2 ? fDx1 : fDx2 ) ;
104 fDxUp = ( fDx3 > fDx4 ? fDx3 : fDx4 ) ;
105 fDx = ( fDxUp > fDxDown ? fDxUp : fDxDown ) ;
106 fDy = ( fDy1 > fDy2 ? fDy1 : fDy2 ) ;
110 if ( fDx1 != fDx2 && fDx3 != fDx4 )
112 pDytmp = fDy1 * ( fDx3 - fDx4 ) / ( fDx1 - fDx2 ) ;
115 std::ostringstream message;
116 message <<
"Not planar surface in untwisted Trapezoid: "
118 <<
"fDy2 is " << fDy2 <<
" but should be "
120 G4Exception(
"G4VTwistedFaceted::G4VTwistedFaceted()",
"GeomSolids0002",
126 if ( fDx1 == fDx2 && fDx3 == fDx4 )
133 if ( ( fDx1 == fDx2 && fDx3 != fDx4 ) || ( fDx1 != fDx2 && fDx3 == fDx4 ) )
135 std::ostringstream message;
136 message <<
"Not planar surface in untwisted Trapezoid: "
138 <<
"One endcap is rectangular, the other is a trapezoid." <<
G4endl
139 <<
"For planarity reasons they have to be rectangles or trapezoids "
141 G4Exception(
"G4VTwistedFaceted::G4VTwistedFaceted()",
"GeomSolids0002",
147 fPhiTwist = PhiTwist ;
152 fTAlph = std::tan(fAlph) ;
159 fdeltaX = 2 * fDz * std::tan(fTheta) * std::cos(fPhi) ;
163 fdeltaY = 2 * fDz * std::tan(fTheta) * std::sin(fPhi) ;
172 && ( std::fabs(fPhiTwist) > 2*kAngTolerance )
173 && ( std::fabs(fPhiTwist) <
pi/2 )
174 && ( std::fabs(fAlph) <
pi/2 )
175 && ( fTheta < pi/2 && fTheta >= 0 ) )
178 std::ostringstream message;
179 message <<
"Invalid dimensions. Too small, or twist angle too big: "
181 <<
"fDx 1-4 = " << fDx1/
cm <<
", " << fDx2/
cm <<
", "
182 << fDx3/
cm <<
", " << fDx4/
cm <<
" cm" <<
G4endl
183 <<
"fDy 1-2 = " << fDy1/
cm <<
", " << fDy2/
cm <<
", "
185 <<
"fDz = " << fDz/
cm <<
" cm" <<
G4endl
186 <<
" twistangle " << fPhiTwist/
deg <<
" deg" <<
G4endl
187 <<
" phi,theta = " << fPhi/
deg <<
", " << fTheta/
deg <<
" deg";
192 fCubicVolume = 2 * fDz * ( ( fDx1 + fDx2 ) * fDy1 + ( fDx3 + fDx4 ) * fDy2 );
200 :
G4VSolid(a), fTheta(0.), fPhi(0.), fDy1(0.), fDx1(0.), fDx2(0.),
201 fDy2(0.), fDx3(0.), fDx4(0.), fDz(0.), fDx(0.), fDy(0.), fAlph(0.),
202 fTAlph(0.), fdeltaX(0.), fdeltaY(0.), fPhiTwist(0.),
203 fLowerEndcap(0), fUpperEndcap(0), fSide0(0), fSide90(0), fSide180(0),
204 fSide270(0), fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
213 if (fLowerEndcap)
delete fLowerEndcap ;
214 if (fUpperEndcap)
delete fUpperEndcap ;
216 if (fSide0)
delete fSide0 ;
217 if (fSide90)
delete fSide90 ;
218 if (fSide180)
delete fSide180 ;
219 if (fSide270)
delete fSide270 ;
220 if (fpPolyhedron)
delete fpPolyhedron;
227 :
G4VSolid(rhs), fTheta(rhs.fTheta), fPhi(rhs.fPhi),
228 fDy1(rhs.fDy1), fDx1(rhs.fDx1), fDx2(rhs.fDx2), fDy2(rhs.fDy2),
229 fDx3(rhs.fDx3), fDx4(rhs.fDx4), fDz(rhs.fDz), fDx(rhs.fDx), fDy(rhs.fDy),
230 fAlph(rhs.fAlph), fTAlph(rhs.fTAlph), fdeltaX(rhs.fdeltaX),
231 fdeltaY(rhs.fdeltaY), fPhiTwist(rhs.fPhiTwist), fLowerEndcap(0),
232 fUpperEndcap(0), fSide0(0), fSide90(0), fSide180(0), fSide270(0),
233 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
235 fLastInside(rhs.fLastInside), fLastNormal(rhs.fLastNormal),
236 fLastDistanceToIn(rhs.fLastDistanceToIn),
237 fLastDistanceToOut(rhs.fLastDistanceToOut),
238 fLastDistanceToInWithV(rhs.fLastDistanceToInWithV),
239 fLastDistanceToOutWithV(rhs.fLastDistanceToOutWithV)
252 if (
this == &rhs) {
return *
this; }
260 fTheta = rhs.fTheta; fPhi = rhs.fPhi;
261 fDy1= rhs.fDy1; fDx1= rhs.fDx1; fDx2= rhs.fDx2; fDy2= rhs.fDy2;
262 fDx3= rhs.fDx3; fDx4= rhs.fDx4; fDz= rhs.fDz; fDx= rhs.fDx; fDy= rhs.fDy;
263 fAlph= rhs.fAlph; fTAlph= rhs.fTAlph; fdeltaX= rhs.fdeltaX;
264 fdeltaY= rhs.fdeltaY; fPhiTwist= rhs.fPhiTwist; fLowerEndcap= 0;
265 fUpperEndcap= 0; fSide0= 0; fSide90= 0; fSide180= 0; fSide270= 0;
266 fCubicVolume= rhs.fCubicVolume; fSurfaceArea= rhs.fSurfaceArea;
268 fLastInside= rhs.fLastInside; fLastNormal= rhs.fLastNormal;
269 fLastDistanceToIn= rhs.fLastDistanceToIn;
270 fLastDistanceToOut= rhs.fLastDistanceToOut;
271 fLastDistanceToInWithV= rhs.fLastDistanceToInWithV;
272 fLastDistanceToOutWithV= rhs.fLastDistanceToOutWithV;
286 G4Exception(
"G4VTwistedFaceted::ComputeDimensions()",
288 "G4VTwistedFaceted does not support Parameterisation.");
301 G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
314 xMin = xoffset - maxRad ;
315 xMax = xoffset + maxRad ;
334 yMin = yoffset - maxRad ;
335 yMax = yoffset + maxRad ;
354 zMin = zoffset - fDz ;
355 zMax = zoffset + fDz ;
397 G4bool existsAfterClip = false ;
410 if (pVoxelLimit.
IsLimited(pAxis) ==
false)
412 if ( pMin != kInfinity || pMax != -kInfinity )
414 existsAfterClip = true ;
429 if ( pMin != kInfinity || pMax != -kInfinity )
431 existsAfterClip = true ;
467 existsAfterClip = true ;
473 return existsAfterClip;
487 vertices->reserve(8);
489 G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
512 G4Exception(
"G4VTwistedFaceted::CreateRotatedVertices()",
514 "Error in allocation of vertices. Out of memory !");
527 if (fLastInside.p == p) {
528 return fLastInside.inside;
531 tmpin =
const_cast<EInside*
>(&(fLastInside.inside));
532 tmpp->
set(p.
x(), p.
y(), p.
z());
537 G4double phi = p.
z()/(2*fDz) * fPhiTwist ;
541 G4double px = p.
x() + fdeltaX * ( -phi/fPhiTwist) ;
542 G4double py = p.
y() + fdeltaY * ( -phi/fPhiTwist) ;
545 G4double posx = px * cphi - py * sphi ;
546 G4double posy = px * sphi + py * cphi ;
569 G4cout <<
"phi,theta = " << fPhi <<
" , " << fTheta <<
G4endl ;
612 return fLastInside.inside;
628 if (fLastNormal.p == p)
630 return fLastNormal.vec;
636 tmpp->
set(p.
x(), p.
y(), p.
z());
642 surfaces[0] = fSide0 ;
643 surfaces[1] = fSide90 ;
644 surfaces[2] = fSide180 ;
645 surfaces[3] = fSide270 ;
646 surfaces[4] = fLowerEndcap;
647 surfaces[5] = fUpperEndcap;
656 if (tmpdistance < distance)
658 distance = tmpdistance;
664 tmpsurface[0] = surfaces[besti];
665 *tmpnormal = tmpsurface[0]->
GetNormal(bestxx,
true);
667 return fLastNormal.vec;
690 if (fLastDistanceToInWithV.p == p && fLastDistanceToInWithV.vec == v)
692 return fLastDistanceToIn.value;
696 tmpp =
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.p));
697 tmpv =
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.vec));
698 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToInWithV.value));
699 tmpp->
set(p.
x(), p.
y(), p.
z());
700 tmpv->
set(v.
x(), v.
y(), v.
z());
721 return fLastDistanceToInWithV.value;
735 surfaces[0] = fSide0;
736 surfaces[1] = fSide90 ;
737 surfaces[2] = fSide180 ;
738 surfaces[3] = fSide270 ;
739 surfaces[4] = fLowerEndcap;
740 surfaces[5] = fUpperEndcap;
745 for (i=0; i < 6 ; i++)
752 G4cout <<
"Solid DistanceToIn : distance = " << tmpdistance <<
G4endl ;
755 if (tmpdistance < distance)
757 distance = tmpdistance;
768 return fLastDistanceToInWithV.value;
785 if (fLastDistanceToIn.p == p)
787 return fLastDistanceToIn.value;
792 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToIn.value));
793 tmpp->
set(p.
x(), p.
y(), p.
z());
811 return fLastDistanceToIn.value;
824 surfaces[0] = fSide0;
825 surfaces[1] = fSide90 ;
826 surfaces[2] = fSide180 ;
827 surfaces[3] = fSide270 ;
828 surfaces[4] = fLowerEndcap;
829 surfaces[5] = fUpperEndcap;
837 if (tmpdistance < distance)
839 distance = tmpdistance;
844 return fLastDistanceToIn.value;
849 G4Exception(
"G4VTwistedFaceted::DistanceToIn(p)",
"GeomSolids0003",
881 if (fLastDistanceToOutWithV.p == p && fLastDistanceToOutWithV.vec == v )
883 return fLastDistanceToOutWithV.value;
887 tmpp =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.p));
888 tmpv =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.vec));
889 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOutWithV.value));
890 tmpp->
set(p.
x(), p.
y(), p.
z());
891 tmpv->
set(v.
x(), v.
y(), v.
z());
914 *norm = (blockedsurface->
GetNormal(p,
true));
919 return fLastDistanceToOutWithV.value;
931 surfaces[0] = fSide0;
932 surfaces[1] = fSide90 ;
933 surfaces[2] = fSide180 ;
934 surfaces[3] = fSide270 ;
935 surfaces[4] = fLowerEndcap;
936 surfaces[5] = fUpperEndcap;
942 for (i=0; i< 6 ; i++) {
944 if (tmpdistance < distance)
946 distance = tmpdistance;
956 *norm = (surfaces[besti]->
GetNormal(p,
true));
963 return fLastDistanceToOutWithV.value;
980 if (fLastDistanceToOut.p == p)
982 return fLastDistanceToOut.value;
987 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOut.value));
988 tmpp->
set(p.
x(), p.
y(), p.
z());
1010 G4cout.precision(oldprc) ;
1011 G4Exception(
"G4VTwistedFaceted::DistanceToOut(p)",
"GeomSolids1002",
1019 retval = fLastDistanceToOut.value;
1033 surfaces[0] = fSide0;
1034 surfaces[1] = fSide90 ;
1035 surfaces[2] = fSide180 ;
1036 surfaces[3] = fSide270 ;
1037 surfaces[4] = fLowerEndcap;
1038 surfaces[5] = fUpperEndcap;
1043 for (i=0; i< 6; i++)
1046 if (tmpdistance < distance)
1048 distance = tmpdistance;
1052 *tmpdist = distance;
1054 retval = fLastDistanceToOut.value;
1060 G4Exception(
"G4VTwistedFaceted::DistanceToOut(p)",
"GeomSolids0003",
1078 G4int oldprc = os.precision(16);
1079 os <<
"-----------------------------------------------------------\n"
1080 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1081 <<
" ===================================================\n"
1082 <<
" Solid type: G4VTwistedFaceted\n"
1083 <<
" Parameters: \n"
1084 <<
" polar angle theta = " << fTheta/
degree <<
" deg" <<
G4endl
1085 <<
" azimuthal angle phi = " << fPhi/
degree <<
" deg" <<
G4endl
1086 <<
" tilt angle alpha = " << fAlph/
degree <<
" deg" <<
G4endl
1087 <<
" TWIST angle = " << fPhiTwist/
degree <<
" deg" <<
G4endl
1088 <<
" Half length along y (lower endcap) = " << fDy1/
cm <<
" cm"
1090 <<
" Half length along x (lower endcap, bottom) = " << fDx1/
cm <<
" cm"
1092 <<
" Half length along x (lower endcap, top) = " << fDx2/
cm <<
" cm"
1094 <<
" Half length along y (upper endcap) = " << fDy2/
cm <<
" cm"
1096 <<
" Half length along x (upper endcap, bottom) = " << fDx3/
cm <<
" cm"
1098 <<
" Half length along x (upper endcap, top) = " << fDx4/
cm <<
" cm"
1100 <<
"-----------------------------------------------------------\n";
1101 os.precision(oldprc);
1120 G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
1133 G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
1143 void G4VTwistedFaceted::CreateSurfaces()
1148 if ( fDx1 == fDx2 && fDx3 == fDx4 )
1150 fSide0 =
new G4TwistBoxSide(
"0deg", fPhiTwist, fDz, fTheta, fPhi,
1151 fDy1, fDx1, fDx1, fDy2, fDx3, fDx3, fAlph, 0.*
deg);
1153 fDy1, fDx1, fDx1, fDy2, fDx3, fDx3, fAlph, 180.*
deg);
1158 fPhi, fDy1, fDx1, fDx2, fDy2, fDx3, fDx4, fAlph, 0.*
deg);
1160 fPhi+
pi, fDy1, fDx2, fDx1, fDy2, fDx4, fDx3, fAlph, 180.*
deg);
1166 fPhi, fDy1, fDx1, fDx2, fDy2, fDx3, fDx4, fAlph, 0.*
deg);
1168 fPhi+
pi, fDy1, fDx2, fDx1, fDy2, fDx4, fDx3, fAlph, 180.*
deg);
1173 fDz, fAlph, fPhi, fTheta, 1 );
1175 fDz, fAlph, fPhi, fTheta, -1 );
1179 fSide0->
SetNeighbours( fSide270 , fLowerEndcap , fSide90 , fUpperEndcap );
1180 fSide90->
SetNeighbours( fSide0 , fLowerEndcap , fSide180 , fUpperEndcap );
1181 fSide180->
SetNeighbours(fSide90 , fLowerEndcap , fSide270 , fUpperEndcap );
1182 fSide270->
SetNeighbours(fSide180 , fLowerEndcap , fSide0 , fUpperEndcap );
1183 fUpperEndcap->
SetNeighbours( fSide180, fSide270 , fSide0 , fSide90 );
1184 fLowerEndcap->
SetNeighbours( fSide180, fSide270 , fSide0 , fSide90 );
1194 return G4String(
"G4VTwistedFaceted");
1203 if (!fpPolyhedron ||
1207 delete fpPolyhedron;
1211 return fpPolyhedron;
1225 if ( z == fDz ) z -= 0.1*fDz ;
1226 if ( z == -fDz ) z += 0.1*fDz ;
1228 G4double phi = z/(2*fDz)*fPhiTwist ;
1230 return G4ThreeVector(fdeltaX * phi/fPhiTwist, fdeltaY * phi/fPhiTwist, z ) ;
1240 G4double phi = G4RandFlat::shoot(-fPhiTwist/2.,fPhiTwist/2.);
1265 G4double chose = G4RandFlat::shoot(0.,a1 + a2 + a3 + a4 + a5 + a6) ;
1272 u = G4RandFlat::shoot(umin,umax) ;
1277 else if( (chose >= a1) && (chose < a1 + a2 ) )
1283 u = G4RandFlat::shoot(umin,umax) ;
1288 else if( (chose >= a1 + a2 ) && (chose < a1 + a2 + a3 ) )
1293 u = G4RandFlat::shoot(umin,umax) ;
1298 else if( (chose >= a1 + a2 + a3 ) && (chose < a1 + a2 + a3 + a4 ) )
1303 u = G4RandFlat::shoot(umin,umax) ;
1308 else if( (chose >= a1 + a2 + a3 + a4 ) && (chose < a1 + a2 + a3 + a4 + a5 ) )
1311 y = G4RandFlat::shoot(-fDy1,fDy1) ;
1314 u = G4RandFlat::shoot(umin,umax) ;
1320 y = G4RandFlat::shoot(-fDy2,fDy2) ;
1323 u = G4RandFlat::shoot(umin,umax) ;
1341 const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;
1342 const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)*(k-1) ;
1346 typedef G4int G4int4[4];
1347 G4double3* xyz =
new G4double3[nnodes];
1348 G4int4* faces =
new G4int4[nfaces] ;
1350 fLowerEndcap->
GetFacets(k,k,xyz,faces,0) ;
1351 fUpperEndcap->
GetFacets(k,k,xyz,faces,1) ;