76 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
77 fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
78 fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
82 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
86 G4double sinhalftwist = std::sin(0.5 * twistedangle);
88 G4double endinnerradX = endinnerrad * sinhalftwist;
89 G4double innerrad = std::sqrt( endinnerrad * endinnerrad
90 - endinnerradX * endinnerradX );
92 G4double endouterradX = endouterrad * sinhalftwist;
93 G4double outerrad = std::sqrt( endouterrad * endouterrad
94 - endouterradX * endouterradX );
97 SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
109 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
110 fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
111 fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
116 std::ostringstream message;
117 message <<
"Invalid number of segments." <<
G4endl
118 <<
" nseg = " << nseg;
119 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
124 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
128 G4double sinhalftwist = std::sin(0.5 * twistedangle);
130 G4double endinnerradX = endinnerrad * sinhalftwist;
131 G4double innerrad = std::sqrt( endinnerrad * endinnerrad
132 - endinnerradX * endinnerradX );
134 G4double endouterradX = endouterrad * sinhalftwist;
135 G4double outerrad = std::sqrt( endouterrad * endouterrad
136 - endouterradX * endouterradX );
139 fDPhi = totphi / nseg;
140 SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
152 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
153 fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
154 fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
158 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
162 SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
175 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
176 fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
177 fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
181 std::ostringstream message;
182 message <<
"Invalid number of segments." <<
G4endl
183 <<
" nseg = " << nseg;
184 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
189 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
193 fDPhi = totphi / nseg;
194 SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
202 :
G4VSolid(a), fPhiTwist(0.), fInnerRadius(0.), fOuterRadius(0.), fDPhi(0.),
203 fZHalfLength(0.), fInnerStereo(0.), fOuterStereo(0.), fTanInnerStereo(0.),
204 fTanOuterStereo(0.), fKappa(0.), fInnerRadius2(0.), fOuterRadius2(0.),
205 fTanInnerStereo2(0.), fTanOuterStereo2(0.), fLowerEndcap(0), fUpperEndcap(0),
206 fLatterTwisted(0), fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
207 fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
209 fEndZ[0] = 0.; fEndZ[1] = 0.;
210 fEndInnerRadius[0] = 0.; fEndInnerRadius[1] = 0.;
211 fEndOuterRadius[0] = 0.; fEndOuterRadius[1] = 0.;
212 fEndPhi[0] = 0.; fEndPhi[1] = 0.;
213 fEndZ2[0] = 0.; fEndZ2[1] = 0.;
221 if (fLowerEndcap) {
delete fLowerEndcap; }
222 if (fUpperEndcap) {
delete fUpperEndcap; }
223 if (fLatterTwisted) {
delete fLatterTwisted; }
224 if (fFormerTwisted) {
delete fFormerTwisted; }
225 if (fInnerHype) {
delete fInnerHype; }
226 if (fOuterHype) {
delete fOuterHype; }
227 if (fpPolyhedron) {
delete fpPolyhedron; }
234 :
G4VSolid(rhs), fPhiTwist(rhs.fPhiTwist),
235 fInnerRadius(rhs.fInnerRadius), fOuterRadius(rhs.fOuterRadius),
236 fDPhi(rhs.fDPhi), fZHalfLength(rhs.fZHalfLength),
237 fInnerStereo(rhs.fInnerStereo), fOuterStereo(rhs.fOuterStereo),
238 fTanInnerStereo(rhs.fTanInnerStereo), fTanOuterStereo(rhs.fTanOuterStereo),
239 fKappa(rhs.fKappa), fInnerRadius2(rhs.fInnerRadius2),
240 fOuterRadius2(rhs.fOuterRadius2), fTanInnerStereo2(rhs.fTanInnerStereo2),
241 fTanOuterStereo2(rhs.fTanOuterStereo2),
242 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0), fFormerTwisted(0),
243 fInnerHype(0), fOuterHype(0),
244 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
245 fpPolyhedron(0), fLastInside(rhs.fLastInside), fLastNormal(rhs.fLastNormal),
246 fLastDistanceToIn(rhs.fLastDistanceToIn),
247 fLastDistanceToOut(rhs.fLastDistanceToOut),
248 fLastDistanceToInWithV(rhs.fLastDistanceToInWithV),
249 fLastDistanceToOutWithV(rhs.fLastDistanceToOutWithV)
251 for (
size_t i=0; i<2; ++i)
253 fEndZ[i] = rhs.fEndZ[i];
254 fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
255 fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
256 fEndPhi[i] = rhs.fEndPhi[i];
257 fEndZ2[i] = rhs.fEndZ2[i];
270 if (
this == &rhs) {
return *
this; }
278 fPhiTwist= rhs.fPhiTwist;
279 fInnerRadius= rhs.fInnerRadius; fOuterRadius= rhs.fOuterRadius;
280 fDPhi= rhs.fDPhi; fZHalfLength= rhs.fZHalfLength;
281 fInnerStereo= rhs.fInnerStereo; fOuterStereo= rhs.fOuterStereo;
282 fTanInnerStereo= rhs.fTanInnerStereo; fTanOuterStereo= rhs.fTanOuterStereo;
283 fKappa= rhs.fKappa; fInnerRadius2= rhs.fInnerRadius2;
284 fOuterRadius2= rhs.fOuterRadius2; fTanInnerStereo2= rhs.fTanInnerStereo2;
285 fTanOuterStereo2= rhs.fTanOuterStereo2;
286 fLowerEndcap= fUpperEndcap= fLatterTwisted= fFormerTwisted= 0;
287 fInnerHype= fOuterHype= 0;
288 fCubicVolume= rhs.fCubicVolume; fSurfaceArea= rhs.fSurfaceArea;
290 fLastInside= rhs.fLastInside; fLastNormal= rhs.fLastNormal;
291 fLastDistanceToIn= rhs.fLastDistanceToIn;
292 fLastDistanceToOut= rhs.fLastDistanceToOut;
293 fLastDistanceToInWithV= rhs.fLastDistanceToInWithV;
294 fLastDistanceToOutWithV= rhs.fLastDistanceToOutWithV;
296 for (
size_t i=0; i<2; ++i)
298 fEndZ[i] = rhs.fEndZ[i];
299 fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
300 fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
301 fEndPhi[i] = rhs.fEndPhi[i];
302 fEndZ2[i] = rhs.fEndZ2[i];
319 "G4TwistedTubs does not support Parameterisation.");
334 G4double maxEndOuterRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ?
335 fEndOuterRadius[0] : fEndOuterRadius[1]);
336 G4double maxEndInnerRad = (fEndInnerRadius[0] > fEndInnerRadius[1] ?
337 fEndInnerRadius[0] : fEndInnerRadius[1]);
338 G4double maxphi = (std::fabs(fEndPhi[0]) > std::fabs(fEndPhi[1]) ?
339 std::fabs(fEndPhi[0]) : std::fabs(fEndPhi[1]));
347 G4double rFudge = 1.0/std::cos(0.5*sigPhi);
348 G4double fudgeEndOuterRad = rFudge * maxEndOuterRad;
378 G4bool splitOuter = (fOuterRadius/maxEndOuterRad < 0.95);
379 G4bool splitInner = (fInnerRadius/maxEndInnerRad < 0.95);
395 G4double phimax = maxphi + 0.5*fDPhi;
396 if ( phimax >
pi/2) { phimax =
pi-phimax; }
412 G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi,
415 G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi,
420 G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi, 0));
437 G4double dr = fZHalfLength * fTanInnerStereo2;
439 zInnerSplit = fZHalfLength + (fInnerRadius - maxEndInnerRad) * dz / dr;
463 cosPhi = std::cos(phimax);
464 sinPhi = std::sin(phimax);
469 G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi,
472 G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi,
480 AddPolyToExtent( v0, v4, w4, w0, voxelLimit, axis, extentList );
481 AddPolyToExtent( v4, v1, w1, w4, voxelLimit, axis, extentList );
485 AddPolyToExtent( v0, v1, w1, w0, voxelLimit, axis, extentList );
506 AddPolyToExtent( v3, v6, w6, w3, voxelLimit, axis, extentList );
507 AddPolyToExtent( v6, v5, w5, w6, voxelLimit, axis, extentList );
508 AddPolyToExtent( v5, v2, w2, w5, voxelLimit, axis, extentList );
520 AddPolyToExtent( v3, v2, w2, w3, voxelLimit, axis, extentList );
526 AddPolyToExtent( v1, v3, w3, w1, voxelLimit, axis, extentList );
527 AddPolyToExtent( v2, v0, w0, w2, voxelLimit, axis, extentList );
539 void G4TwistedTubs::AddPolyToExtent(
const G4ThreeVector &v0,
558 phiPoly.
SetNormal( (v1-v0).cross(w0-v0).unit() );
580 if (fLastInside.p == p)
582 return fLastInside.inside;
587 tmpinside =
const_cast<EInside*
>(&(fLastInside.inside));
588 tmpp->
set(p.
x(), p.
y(), p.
z());
595 if ((outerhypearea ==
kOutside) || (distanceToOut < -halftol))
605 if (distanceToOut <= halftol)
615 return fLastInside.inside;
630 if (fLastNormal.p == p)
632 return fLastNormal.vec;
640 tmpp->
set(p.
x(), p.
y(), p.
z());
645 surfaces[0] = fLatterTwisted;
646 surfaces[1] = fFormerTwisted;
647 surfaces[2] = fInnerHype;
648 surfaces[3] = fOuterHype;
649 surfaces[4] = fLowerEndcap;
650 surfaces[5] = fUpperEndcap;
659 if (tmpdistance < distance)
661 distance = tmpdistance;
667 tmpsurface[0] = surfaces[besti];
668 *tmpnormal = tmpsurface[0]->
GetNormal(bestxx,
true);
670 return fLastNormal.vec;
693 if ((fLastDistanceToInWithV.p == p) && (fLastDistanceToInWithV.vec == v))
695 return fLastDistanceToIn.value;
699 tmpp =
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.p));
700 tmpv =
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.vec));
701 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToInWithV.value));
702 tmpp->
set(p.
x(), p.
y(), p.
z());
703 tmpv->
set(v.
x(), v.
y(), v.
z());
726 return fLastDistanceToInWithV.value;
740 surfaces[0] = fLowerEndcap;
741 surfaces[1] = fUpperEndcap;
742 surfaces[2] = fLatterTwisted;
743 surfaces[3] = fFormerTwisted;
744 surfaces[4] = fInnerHype;
745 surfaces[5] = fOuterHype;
753 if (tmpdistance < distance)
755 distance = tmpdistance;
761 return fLastDistanceToInWithV.value;
779 if (fLastDistanceToIn.p == p)
781 return fLastDistanceToIn.value;
786 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToIn.value));
787 tmpp->
set(p.
x(), p.
y(), p.
z());
803 return fLastDistanceToIn.value;
812 surfaces[0] = fLowerEndcap;
813 surfaces[1] = fUpperEndcap;
814 surfaces[2] = fLatterTwisted;
815 surfaces[3] = fFormerTwisted;
816 surfaces[4] = fInnerHype;
817 surfaces[5] = fOuterHype;
825 if (tmpdistance < distance)
827 distance = tmpdistance;
832 return fLastDistanceToIn.value;
836 G4Exception(
"G4TwistedTubs::DistanceToIn(p)",
"GeomSolids0003",
866 if ((fLastDistanceToOutWithV.p == p) && (fLastDistanceToOutWithV.vec == v) )
868 return fLastDistanceToOutWithV.value;
872 tmpp =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.p));
873 tmpv =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.vec));
874 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOutWithV.value));
875 tmpp->
set(p.
x(), p.
y(), p.
z());
876 tmpv->
set(v.
x(), v.
y(), v.
z());
901 *norm = (blockedsurface->
GetNormal(p,
true));
905 return fLastDistanceToOutWithV.value;
919 surfaces[0] = fLatterTwisted;
920 surfaces[1] = fFormerTwisted;
921 surfaces[2] = fInnerHype;
922 surfaces[3] = fOuterHype;
923 surfaces[4] = fLowerEndcap;
924 surfaces[5] = fUpperEndcap;
933 if (tmpdistance < distance)
935 distance = tmpdistance;
945 *norm = (surfaces[besti]->
GetNormal(p,
true));
952 return fLastDistanceToOutWithV.value;
971 if (fLastDistanceToOut.p == p)
973 return fLastDistanceToOut.value;
978 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOut.value));
979 tmpp->
set(p.
x(), p.
y(), p.
z());
996 return fLastDistanceToOut.value;
1005 surfaces[0] = fLatterTwisted;
1006 surfaces[1] = fFormerTwisted;
1007 surfaces[2] = fInnerHype;
1008 surfaces[3] = fOuterHype;
1009 surfaces[4] = fLowerEndcap;
1010 surfaces[5] = fUpperEndcap;
1015 for (i=0; i< 6; i++)
1018 if (tmpdistance < distance)
1020 distance = tmpdistance;
1024 *tmpdist = distance;
1026 return fLastDistanceToOut.value;
1030 G4Exception(
"G4TwistedTubs::DistanceToOut(p)",
"GeomSolids0003",
1046 G4int oldprc = os.precision(16);
1047 os <<
"-----------------------------------------------------------\n"
1048 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1049 <<
" ===================================================\n"
1050 <<
" Solid type: G4TwistedTubs\n"
1051 <<
" Parameters: \n"
1052 <<
" -ve end Z : " << fEndZ[0]/
mm <<
" mm \n"
1053 <<
" +ve end Z : " << fEndZ[1]/
mm <<
" mm \n"
1054 <<
" inner end radius(-ve z): " << fEndInnerRadius[0]/
mm <<
" mm \n"
1055 <<
" inner end radius(+ve z): " << fEndInnerRadius[1]/
mm <<
" mm \n"
1056 <<
" outer end radius(-ve z): " << fEndOuterRadius[0]/
mm <<
" mm \n"
1057 <<
" outer end radius(+ve z): " << fEndOuterRadius[1]/
mm <<
" mm \n"
1058 <<
" inner radius (z=0) : " << fInnerRadius/
mm <<
" mm \n"
1059 <<
" outer radius (z=0) : " << fOuterRadius/
mm <<
" mm \n"
1060 <<
" twisted angle : " << fPhiTwist/
degree <<
" degrees \n"
1061 <<
" inner stereo angle : " << fInnerStereo/
degree <<
" degrees \n"
1062 <<
" outer stereo angle : " << fOuterStereo/
degree <<
" degrees \n"
1063 <<
" phi-width of a piece : " << fDPhi/
degree <<
" degrees \n"
1064 <<
"-----------------------------------------------------------\n";
1065 os.precision(oldprc);
1086 G4double maxEndOuterRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ? 0 : 1);
1087 return G4VisExtent( -maxEndOuterRad, maxEndOuterRad,
1088 -maxEndOuterRad, maxEndOuterRad,
1089 -fZHalfLength, fZHalfLength );
1099 G4double dA = std::max(fDPhi,fPhiTwist);
1105 const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;
1106 const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)*(k-1) ;
1110 typedef G4int G4int4[4];
1111 G4double3* xyz =
new G4double3[nnodes];
1112 G4int4* faces =
new G4int4[nfaces] ;
1113 fLowerEndcap->
GetFacets(k,k,xyz,faces,0) ;
1114 fUpperEndcap->
GetFacets(k,k,xyz,faces,1) ;
1115 fInnerHype->
GetFacets(k,n,xyz,faces,2) ;
1116 fFormerTwisted->
GetFacets(k,n,xyz,faces,3) ;
1117 fOuterHype->
GetFacets(k,n,xyz,faces,4) ;
1118 fLatterTwisted->
GetFacets(k,n,xyz,faces,5) ;
1133 G4double maxEndOuterRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ? 0 : 1);
1134 G4double maxEndInnerRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ? 0 : 1);
1135 return new G4NURBStube(maxEndInnerRad, maxEndOuterRad, fZHalfLength);
1144 if ((!fpPolyhedron) ||
1148 delete fpPolyhedron;
1151 return fpPolyhedron;
1157 void G4TwistedTubs::CreateSurfaces()
1165 fEndInnerRadius, fEndOuterRadius,
1166 fDPhi, fEndPhi, fEndZ, -1) ;
1169 fEndInnerRadius, fEndOuterRadius,
1170 fDPhi, fEndPhi, fEndZ, 1) ;
1173 rotHalfDPhi.
rotateZ(0.5*fDPhi);
1176 fEndInnerRadius, fEndOuterRadius,
1177 fDPhi, fEndPhi, fEndZ,
1178 fInnerRadius, fOuterRadius, fKappa,
1181 fEndInnerRadius, fEndOuterRadius,
1182 fDPhi, fEndPhi, fEndZ,
1183 fInnerRadius, fOuterRadius, fKappa,
1187 fEndInnerRadius, fEndOuterRadius,
1188 fDPhi, fEndPhi, fEndZ,
1189 fInnerRadius, fOuterRadius,fKappa,
1190 fTanInnerStereo, fTanOuterStereo, -1) ;
1192 fEndInnerRadius, fEndOuterRadius,
1193 fDPhi, fEndPhi, fEndZ,
1194 fInnerRadius, fOuterRadius,fKappa,
1195 fTanInnerStereo, fTanOuterStereo, 1) ;
1201 fOuterHype, fFormerTwisted);
1203 fOuterHype, fFormerTwisted);
1205 fOuterHype, fUpperEndcap);
1207 fOuterHype, fUpperEndcap);
1209 fFormerTwisted, fUpperEndcap);
1211 fFormerTwisted, fUpperEndcap);
1236 if(fCubicVolume != 0.) {;}
1237 else { fCubicVolume = fDPhi*fZHalfLength*(fOuterRadius*fOuterRadius
1238 -fInnerRadius*fInnerRadius); }
1239 return fCubicVolume;
1247 if(fSurfaceArea != 0.) {;}
1249 return fSurfaceArea;
1258 G4double z = G4RandFlat::shoot(fEndZ[0],fEndZ[1]);
1270 G4double chose = G4RandFlat::shoot(0.,a1 + a2 + a3 + a4 + a5 + a6) ;
1277 phi = G4RandFlat::shoot(phimin,phimax) ;
1282 else if ( (chose >= a1) && (chose < a1 + a2 ) )
1287 phi = G4RandFlat::shoot(phimin,phimax) ;
1292 else if ( (chose >= a1 + a2 ) && (chose < a1 + a2 + a3 ) )
1297 x = G4RandFlat::shoot(xmin,xmax) ;
1302 else if ( (chose >= a1 + a2 + a3 ) && (chose < a1 + a2 + a3 + a4 ) )
1307 x = G4RandFlat::shoot(xmin,xmax) ;
1311 else if( (chose >= a1 + a2 + a3 + a4 )&&(chose < a1 + a2 + a3 + a4 + a5 ) )
1315 r = std::sqrt(G4RandFlat::shoot()*(
sqr(rmax)-
sqr(rmin))+
sqr(rmin));
1319 phi = G4RandFlat::shoot(phimin,phimax) ;
1327 r = rmin + (rmax-rmin)*std::sqrt(G4RandFlat::shoot());
1331 phi = G4RandFlat::shoot(phimin,phimax) ;