68 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
69 fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
73 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
77 G4double sinhalftwist = std::sin(0.5 * twistedangle);
79 G4double endinnerradX = endinnerrad * sinhalftwist;
80 G4double innerrad = std::sqrt( endinnerrad * endinnerrad
81 - endinnerradX * endinnerradX );
83 G4double endouterradX = endouterrad * sinhalftwist;
84 G4double outerrad = std::sqrt( endouterrad * endouterrad
85 - endouterradX * endouterradX );
88 SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
100 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
101 fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
106 std::ostringstream message;
107 message <<
"Invalid number of segments." <<
G4endl
108 <<
" nseg = " << nseg;
109 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
114 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
118 G4double sinhalftwist = std::sin(0.5 * twistedangle);
120 G4double endinnerradX = endinnerrad * sinhalftwist;
121 G4double innerrad = std::sqrt( endinnerrad * endinnerrad
122 - endinnerradX * endinnerradX );
124 G4double endouterradX = endouterrad * sinhalftwist;
125 G4double outerrad = std::sqrt( endouterrad * endouterrad
126 - endouterradX * endouterradX );
129 fDPhi = totphi / nseg;
130 SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
142 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
143 fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
147 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
151 SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
164 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
165 fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
169 std::ostringstream message;
170 message <<
"Invalid number of segments." <<
G4endl
171 <<
" nseg = " << nseg;
172 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
177 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
181 fDPhi = totphi / nseg;
182 SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
190 :
G4VSolid(a), fPhiTwist(0.), fInnerRadius(0.), fOuterRadius(0.), fDPhi(0.),
191 fZHalfLength(0.), fInnerStereo(0.), fOuterStereo(0.), fTanInnerStereo(0.),
192 fTanOuterStereo(0.), fKappa(0.), fInnerRadius2(0.), fOuterRadius2(0.),
193 fTanInnerStereo2(0.), fTanOuterStereo2(0.), fLowerEndcap(0), fUpperEndcap(0),
194 fLatterTwisted(0), fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
203 if (fLowerEndcap) {
delete fLowerEndcap; }
204 if (fUpperEndcap) {
delete fUpperEndcap; }
205 if (fLatterTwisted) {
delete fLatterTwisted; }
206 if (fFormerTwisted) {
delete fFormerTwisted; }
207 if (fInnerHype) {
delete fInnerHype; }
208 if (fOuterHype) {
delete fOuterHype; }
209 if (fpPolyhedron) {
delete fpPolyhedron; fpPolyhedron =
nullptr; }
216 :
G4VSolid(rhs), fPhiTwist(rhs.fPhiTwist),
217 fInnerRadius(rhs.fInnerRadius), fOuterRadius(rhs.fOuterRadius),
218 fDPhi(rhs.fDPhi), fZHalfLength(rhs.fZHalfLength),
219 fInnerStereo(rhs.fInnerStereo), fOuterStereo(rhs.fOuterStereo),
220 fTanInnerStereo(rhs.fTanInnerStereo), fTanOuterStereo(rhs.fTanOuterStereo),
221 fKappa(rhs.fKappa), fInnerRadius2(rhs.fInnerRadius2),
222 fOuterRadius2(rhs.fOuterRadius2), fTanInnerStereo2(rhs.fTanInnerStereo2),
223 fTanOuterStereo2(rhs.fTanOuterStereo2),
224 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0), fFormerTwisted(0),
225 fInnerHype(0), fOuterHype(0),
226 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
227 fLastInside(rhs.fLastInside), fLastNormal(rhs.fLastNormal),
228 fLastDistanceToIn(rhs.fLastDistanceToIn),
229 fLastDistanceToOut(rhs.fLastDistanceToOut),
230 fLastDistanceToInWithV(rhs.fLastDistanceToInWithV),
231 fLastDistanceToOutWithV(rhs.fLastDistanceToOutWithV)
233 for (
auto i=0; i<2; ++i)
235 fEndZ[i] = rhs.fEndZ[i];
236 fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
237 fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
238 fEndPhi[i] = rhs.fEndPhi[i];
239 fEndZ2[i] = rhs.fEndZ2[i];
252 if (
this == &rhs) {
return *
this; }
260 fPhiTwist= rhs.fPhiTwist;
261 fInnerRadius= rhs.fInnerRadius; fOuterRadius= rhs.fOuterRadius;
262 fDPhi= rhs.fDPhi; fZHalfLength= rhs.fZHalfLength;
263 fInnerStereo= rhs.fInnerStereo; fOuterStereo= rhs.fOuterStereo;
264 fTanInnerStereo= rhs.fTanInnerStereo; fTanOuterStereo= rhs.fTanOuterStereo;
265 fKappa= rhs.fKappa; fInnerRadius2= rhs.fInnerRadius2;
266 fOuterRadius2= rhs.fOuterRadius2; fTanInnerStereo2= rhs.fTanInnerStereo2;
267 fTanOuterStereo2= rhs.fTanOuterStereo2;
268 fLowerEndcap= fUpperEndcap= fLatterTwisted= fFormerTwisted= 0;
269 fInnerHype= fOuterHype= 0;
270 fCubicVolume= rhs.fCubicVolume; fSurfaceArea= rhs.fSurfaceArea;
271 fLastInside= rhs.fLastInside; fLastNormal= rhs.fLastNormal;
272 fLastDistanceToIn= rhs.fLastDistanceToIn;
273 fLastDistanceToOut= rhs.fLastDistanceToOut;
274 fLastDistanceToInWithV= rhs.fLastDistanceToInWithV;
275 fLastDistanceToOutWithV= rhs.fLastDistanceToOutWithV;
277 for (
auto i=0; i<2; ++i)
279 fEndZ[i] = rhs.fEndZ[i];
280 fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
281 fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
282 fEndPhi[i] = rhs.fEndPhi[i];
283 fEndZ2[i] = rhs.fEndZ2[i];
287 fRebuildPolyhedron =
false;
288 delete fpPolyhedron; fpPolyhedron =
nullptr;
302 "G4TwistedTubs does not support Parameterisation.");
311 G4double maxEndOuterRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ?
312 fEndOuterRadius[0] : fEndOuterRadius[1]);
313 pMin.
set(-maxEndOuterRad,-maxEndOuterRad,-fZHalfLength);
314 pMax.
set( maxEndOuterRad, maxEndOuterRad, fZHalfLength);
318 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
320 std::ostringstream message;
321 message <<
"Bad bounding box (min >= max) for solid: "
323 <<
"\npMin = " << pMin
324 <<
"\npMax = " << pMax;
325 G4Exception(
"G4TwistedTubs::BoundingLimits()",
"GeomMgt0001",
365 if (fLastInside.p == p)
367 return fLastInside.inside;
372 tmpinside =
const_cast<EInside*
>(&(fLastInside.inside));
373 tmpp->
set(p.
x(), p.
y(), p.
z());
380 if ((outerhypearea ==
kOutside) || (distanceToOut < -halftol))
390 if (distanceToOut <= halftol)
400 return fLastInside.inside;
415 if (fLastNormal.p == p)
417 return fLastNormal.vec;
425 tmpp->
set(p.
x(), p.
y(), p.
z());
430 surfaces[0] = fLatterTwisted;
431 surfaces[1] = fFormerTwisted;
432 surfaces[2] = fInnerHype;
433 surfaces[3] = fOuterHype;
434 surfaces[4] = fLowerEndcap;
435 surfaces[5] = fUpperEndcap;
440 for (
auto i=0; i<6; ++i)
443 if (tmpdistance < distance)
445 distance = tmpdistance;
451 tmpsurface[0] = surfaces[besti];
452 *tmpnormal = tmpsurface[0]->
GetNormal(bestxx,
true);
454 return fLastNormal.vec;
477 if ((fLastDistanceToInWithV.p == p) && (fLastDistanceToInWithV.vec == v))
479 return fLastDistanceToIn.value;
483 tmpp =
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.p));
484 tmpv =
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.vec));
485 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToInWithV.value));
486 tmpp->
set(p.
x(), p.
y(), p.
z());
487 tmpv->
set(v.
x(), v.
y(), v.
z());
510 return fLastDistanceToInWithV.value;
524 surfaces[0] = fLowerEndcap;
525 surfaces[1] = fUpperEndcap;
526 surfaces[2] = fLatterTwisted;
527 surfaces[3] = fFormerTwisted;
528 surfaces[4] = fInnerHype;
529 surfaces[5] = fOuterHype;
533 for (
auto i=0; i<6; ++i)
536 if (tmpdistance < distance)
538 distance = tmpdistance;
544 return fLastDistanceToInWithV.value;
562 if (fLastDistanceToIn.p == p)
564 return fLastDistanceToIn.value;
569 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToIn.value));
570 tmpp->
set(p.
x(), p.
y(), p.
z());
586 return fLastDistanceToIn.value;
595 surfaces[0] = fLowerEndcap;
596 surfaces[1] = fUpperEndcap;
597 surfaces[2] = fLatterTwisted;
598 surfaces[3] = fFormerTwisted;
599 surfaces[4] = fInnerHype;
600 surfaces[5] = fOuterHype;
604 for (
auto i=0; i<6; ++i)
607 if (tmpdistance < distance)
609 distance = tmpdistance;
614 return fLastDistanceToIn.value;
618 G4Exception(
"G4TwistedTubs::DistanceToIn(p)",
"GeomSolids0003",
648 if ((fLastDistanceToOutWithV.p == p) && (fLastDistanceToOutWithV.vec == v) )
650 return fLastDistanceToOutWithV.value;
654 tmpp =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.p));
655 tmpv =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.vec));
656 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOutWithV.value));
657 tmpp->
set(p.
x(), p.
y(), p.
z());
658 tmpv->
set(v.
x(), v.
y(), v.
z());
683 *norm = (blockedsurface->
GetNormal(p,
true));
687 return fLastDistanceToOutWithV.value;
701 surfaces[0] = fLatterTwisted;
702 surfaces[1] = fFormerTwisted;
703 surfaces[2] = fInnerHype;
704 surfaces[3] = fOuterHype;
705 surfaces[4] = fLowerEndcap;
706 surfaces[5] = fUpperEndcap;
711 for (
auto i=0; i<6; ++i)
714 if (tmpdistance < distance)
716 distance = tmpdistance;
726 *norm = (surfaces[besti]->
GetNormal(p,
true));
733 return fLastDistanceToOutWithV.value;
752 if (fLastDistanceToOut.p == p)
754 return fLastDistanceToOut.value;
759 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOut.value));
760 tmpp->
set(p.
x(), p.
y(), p.
z());
777 return fLastDistanceToOut.value;
786 surfaces[0] = fLatterTwisted;
787 surfaces[1] = fFormerTwisted;
788 surfaces[2] = fInnerHype;
789 surfaces[3] = fOuterHype;
790 surfaces[4] = fLowerEndcap;
791 surfaces[5] = fUpperEndcap;
795 for (
auto i=0; i<6; ++i)
798 if (tmpdistance < distance)
800 distance = tmpdistance;
806 return fLastDistanceToOut.value;
810 G4Exception(
"G4TwistedTubs::DistanceToOut(p)",
"GeomSolids0003",
826 G4int oldprc = os.precision(16);
827 os <<
"-----------------------------------------------------------\n"
828 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
829 <<
" ===================================================\n"
830 <<
" Solid type: G4TwistedTubs\n"
832 <<
" -ve end Z : " << fEndZ[0]/mm <<
" mm \n"
833 <<
" +ve end Z : " << fEndZ[1]/mm <<
" mm \n"
834 <<
" inner end radius(-ve z): " << fEndInnerRadius[0]/mm <<
" mm \n"
835 <<
" inner end radius(+ve z): " << fEndInnerRadius[1]/mm <<
" mm \n"
836 <<
" outer end radius(-ve z): " << fEndOuterRadius[0]/mm <<
" mm \n"
837 <<
" outer end radius(+ve z): " << fEndOuterRadius[1]/mm <<
" mm \n"
838 <<
" inner radius (z=0) : " << fInnerRadius/mm <<
" mm \n"
839 <<
" outer radius (z=0) : " << fOuterRadius/mm <<
" mm \n"
840 <<
" twisted angle : " << fPhiTwist/degree <<
" degrees \n"
841 <<
" inner stereo angle : " << fInnerStereo/degree <<
" degrees \n"
842 <<
" outer stereo angle : " << fOuterStereo/degree <<
" degrees \n"
843 <<
" phi-width of a piece : " << fDPhi/degree <<
" degrees \n"
844 <<
"-----------------------------------------------------------\n";
845 os.precision(oldprc);
866 G4double maxEndOuterRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ?
867 fEndOuterRadius[0] : fEndOuterRadius[1]);
868 return G4VisExtent( -maxEndOuterRad, maxEndOuterRad,
869 -maxEndOuterRad, maxEndOuterRad,
870 -fZHalfLength, fZHalfLength );
880 G4double absPhiTwist = std::abs(fPhiTwist);
881 G4double dA = std::max(fDPhi,absPhiTwist);
887 const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;
888 const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)*(k-1) ;
892 typedef G4int G4int4[4];
893 G4double3* xyz =
new G4double3[nnodes];
894 G4int4* faces =
new G4int4[nfaces] ;
895 fLowerEndcap->
GetFacets(k,k,xyz,faces,0) ;
896 fUpperEndcap->
GetFacets(k,k,xyz,faces,1) ;
898 fFormerTwisted->
GetFacets(k,n,xyz,faces,3) ;
900 fLatterTwisted->
GetFacets(k,n,xyz,faces,5) ;
915 if (fpPolyhedron ==
nullptr ||
916 fRebuildPolyhedron ||
923 fRebuildPolyhedron =
false;
932void G4TwistedTubs::CreateSurfaces()
940 fEndInnerRadius, fEndOuterRadius,
941 fDPhi, fEndPhi, fEndZ, -1) ;
944 fEndInnerRadius, fEndOuterRadius,
945 fDPhi, fEndPhi, fEndZ, 1) ;
948 rotHalfDPhi.
rotateZ(0.5*fDPhi);
951 fEndInnerRadius, fEndOuterRadius,
952 fDPhi, fEndPhi, fEndZ,
953 fInnerRadius, fOuterRadius, fKappa,
956 fEndInnerRadius, fEndOuterRadius,
957 fDPhi, fEndPhi, fEndZ,
958 fInnerRadius, fOuterRadius, fKappa,
962 fEndInnerRadius, fEndOuterRadius,
963 fDPhi, fEndPhi, fEndZ,
964 fInnerRadius, fOuterRadius,fKappa,
965 fTanInnerStereo, fTanOuterStereo, -1) ;
967 fEndInnerRadius, fEndOuterRadius,
968 fDPhi, fEndPhi, fEndZ,
969 fInnerRadius, fOuterRadius,fKappa,
970 fTanInnerStereo, fTanOuterStereo, 1) ;
976 fOuterHype, fFormerTwisted);
978 fOuterHype, fFormerTwisted);
980 fOuterHype, fUpperEndcap);
982 fOuterHype, fUpperEndcap);
984 fFormerTwisted, fUpperEndcap);
986 fFormerTwisted, fUpperEndcap);
1011 if(fCubicVolume != 0.) {;}
1012 else { fCubicVolume = fDPhi*fZHalfLength*(fOuterRadius*fOuterRadius
1013 -fInnerRadius*fInnerRadius); }
1014 return fCubicVolume;
1022 if(fSurfaceArea != 0.) {;}
1024 return fSurfaceArea;
1033 G4double z = G4RandFlat::shoot(fEndZ[0],fEndZ[1]);
1045 G4double chose = G4RandFlat::shoot(0.,a1 + a2 + a3 + a4 + a5 + a6) ;
1052 phi = G4RandFlat::shoot(phimin,phimax) ;
1057 else if ( (chose >= a1) && (chose < a1 + a2 ) )
1062 phi = G4RandFlat::shoot(phimin,phimax) ;
1067 else if ( (chose >= a1 + a2 ) && (chose < a1 + a2 + a3 ) )
1072 x = G4RandFlat::shoot(xmin,xmax) ;
1077 else if ( (chose >= a1 + a2 + a3 ) && (chose < a1 + a2 + a3 + a4 ) )
1082 x = G4RandFlat::shoot(xmin,xmax) ;
1086 else if( (chose >= a1 + a2 + a3 + a4 )&&(chose < a1 + a2 + a3 + a4 + a5 ) )
1090 r = std::sqrt(G4RandFlat::shoot()*(
sqr(rmax)-
sqr(rmin))+
sqr(rmin));
1094 phi = G4RandFlat::shoot(phimin,phimax) ;
1102 r = rmin + (rmax-rmin)*std::sqrt(G4RandFlat::shoot());
1106 phi = G4RandFlat::shoot(phimin,phimax) ;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
void set(double x, double y, double z)
HepRotation & rotateZ(double delta)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
G4ThreeVector GetPointOnSurface() const
G4double GetSurfaceArea()
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4Polyhedron * CreatePolyhedron() const
void ComputeDimensions(G4VPVParameterisation *, const G4int, const G4VPhysicalVolume *)
G4TwistedTubs & operator=(const G4TwistedTubs &rhs)
G4double GetEndInnerRadius() const
G4double GetEndOuterRadius() const
G4double GetCubicVolume()
G4Polyhedron * GetPolyhedron() const
G4GeometryType GetEntityType() const
G4TwistedTubs(const G4String &pname, G4double twistedangle, G4double endinnerrad, G4double endouterrad, G4double halfzlen, G4double dphi)
EInside Inside(const G4ThreeVector &p) const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcnorm=false, G4bool *validnorm=nullptr, G4ThreeVector *n=nullptr) const
G4VisExtent GetExtent() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
std::ostream & StreamInfo(std::ostream &os) const
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
virtual G4double GetSurfaceArea()
virtual void GetFacets(G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)=0
void SetNeighbours(G4VTwistSurface *ax0min, G4VTwistSurface *ax1min, G4VTwistSurface *ax0max, G4VTwistSurface *ax1max)
virtual G4double GetBoundaryMin(G4double)=0
G4bool IsValidNorm() const
virtual G4double DistanceTo(const G4ThreeVector &gp, G4ThreeVector &gxx)
virtual G4double DistanceToOut(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
virtual G4double DistanceToIn(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
virtual G4ThreeVector SurfacePoint(G4double, G4double, G4bool isGlobal=false)=0
virtual G4double GetBoundaryMax(G4double)=0
virtual G4ThreeVector GetNormal(const G4ThreeVector &xx, G4bool isGlobal)=0
virtual G4double GetSurfaceArea()=0
static G4int GetNumberOfRotationSteps()
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])