79 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
80 fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
81 fCubicVolume(0.), fSurfaceArea(0.),
82 fRebuildPolyhedron(false), fpPolyhedron(0)
86 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
90 G4double sinhalftwist = std::sin(0.5 * twistedangle);
92 G4double endinnerradX = endinnerrad * sinhalftwist;
93 G4double innerrad = std::sqrt( endinnerrad * endinnerrad
94 - endinnerradX * endinnerradX );
96 G4double endouterradX = endouterrad * sinhalftwist;
97 G4double outerrad = std::sqrt( endouterrad * endouterrad
98 - endouterradX * endouterradX );
101 SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
113 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
114 fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
115 fCubicVolume(0.), fSurfaceArea(0.),
116 fRebuildPolyhedron(false), fpPolyhedron(0)
121 std::ostringstream message;
122 message <<
"Invalid number of segments." <<
G4endl
123 <<
" nseg = " << nseg;
124 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
129 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
133 G4double sinhalftwist = std::sin(0.5 * twistedangle);
135 G4double endinnerradX = endinnerrad * sinhalftwist;
136 G4double innerrad = std::sqrt( endinnerrad * endinnerrad
137 - endinnerradX * endinnerradX );
139 G4double endouterradX = endouterrad * sinhalftwist;
140 G4double outerrad = std::sqrt( endouterrad * endouterrad
141 - endouterradX * endouterradX );
144 fDPhi = totphi / nseg;
145 SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
157 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
158 fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
159 fCubicVolume(0.), fSurfaceArea(0.),
160 fRebuildPolyhedron(false), fpPolyhedron(0)
164 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
168 SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
181 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
182 fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
183 fCubicVolume(0.), fSurfaceArea(0.),
184 fRebuildPolyhedron(false), fpPolyhedron(0)
188 std::ostringstream message;
189 message <<
"Invalid number of segments." <<
G4endl
190 <<
" nseg = " << nseg;
191 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
196 G4Exception(
"G4TwistedTubs::G4TwistedTubs()",
"GeomSolids0002",
200 fDPhi = totphi / nseg;
201 SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
209 :
G4VSolid(a), fPhiTwist(0.), fInnerRadius(0.), fOuterRadius(0.), fDPhi(0.),
210 fZHalfLength(0.), fInnerStereo(0.), fOuterStereo(0.), fTanInnerStereo(0.),
211 fTanOuterStereo(0.), fKappa(0.), fInnerRadius2(0.), fOuterRadius2(0.),
212 fTanInnerStereo2(0.), fTanOuterStereo2(0.), fLowerEndcap(0), fUpperEndcap(0),
213 fLatterTwisted(0), fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
214 fCubicVolume(0.), fSurfaceArea(0.),
215 fRebuildPolyhedron(false), fpPolyhedron(0)
224 if (fLowerEndcap) {
delete fLowerEndcap; }
225 if (fUpperEndcap) {
delete fUpperEndcap; }
226 if (fLatterTwisted) {
delete fLatterTwisted; }
227 if (fFormerTwisted) {
delete fFormerTwisted; }
228 if (fInnerHype) {
delete fInnerHype; }
229 if (fOuterHype) {
delete fOuterHype; }
230 if (fpPolyhedron) {
delete fpPolyhedron; fpPolyhedron = 0; }
237 :
G4VSolid(rhs), fPhiTwist(rhs.fPhiTwist),
238 fInnerRadius(rhs.fInnerRadius), fOuterRadius(rhs.fOuterRadius),
239 fDPhi(rhs.fDPhi), fZHalfLength(rhs.fZHalfLength),
240 fInnerStereo(rhs.fInnerStereo), fOuterStereo(rhs.fOuterStereo),
241 fTanInnerStereo(rhs.fTanInnerStereo), fTanOuterStereo(rhs.fTanOuterStereo),
242 fKappa(rhs.fKappa), fInnerRadius2(rhs.fInnerRadius2),
243 fOuterRadius2(rhs.fOuterRadius2), fTanInnerStereo2(rhs.fTanInnerStereo2),
244 fTanOuterStereo2(rhs.fTanOuterStereo2),
245 fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0), fFormerTwisted(0),
246 fInnerHype(0), fOuterHype(0),
247 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
248 fRebuildPolyhedron(false), fpPolyhedron(0),
249 fLastInside(rhs.fLastInside), fLastNormal(rhs.fLastNormal),
250 fLastDistanceToIn(rhs.fLastDistanceToIn),
251 fLastDistanceToOut(rhs.fLastDistanceToOut),
252 fLastDistanceToInWithV(rhs.fLastDistanceToInWithV),
253 fLastDistanceToOutWithV(rhs.fLastDistanceToOutWithV)
255 for (
size_t i=0; i<2; ++i)
257 fEndZ[i] = rhs.fEndZ[i];
258 fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
259 fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
260 fEndPhi[i] = rhs.fEndPhi[i];
261 fEndZ2[i] = rhs.fEndZ2[i];
274 if (
this == &rhs) {
return *
this; }
282 fPhiTwist= rhs.fPhiTwist;
283 fInnerRadius= rhs.fInnerRadius; fOuterRadius= rhs.fOuterRadius;
284 fDPhi= rhs.fDPhi; fZHalfLength= rhs.fZHalfLength;
285 fInnerStereo= rhs.fInnerStereo; fOuterStereo= rhs.fOuterStereo;
286 fTanInnerStereo= rhs.fTanInnerStereo; fTanOuterStereo= rhs.fTanOuterStereo;
287 fKappa= rhs.fKappa; fInnerRadius2= rhs.fInnerRadius2;
288 fOuterRadius2= rhs.fOuterRadius2; fTanInnerStereo2= rhs.fTanInnerStereo2;
289 fTanOuterStereo2= rhs.fTanOuterStereo2;
290 fLowerEndcap= fUpperEndcap= fLatterTwisted= fFormerTwisted= 0;
291 fInnerHype= fOuterHype= 0;
292 fCubicVolume= rhs.fCubicVolume; fSurfaceArea= rhs.fSurfaceArea;
293 fLastInside= rhs.fLastInside; fLastNormal= rhs.fLastNormal;
294 fLastDistanceToIn= rhs.fLastDistanceToIn;
295 fLastDistanceToOut= rhs.fLastDistanceToOut;
296 fLastDistanceToInWithV= rhs.fLastDistanceToInWithV;
297 fLastDistanceToOutWithV= rhs.fLastDistanceToOutWithV;
299 for (
size_t i=0; i<2; ++i)
301 fEndZ[i] = rhs.fEndZ[i];
302 fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
303 fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
304 fEndPhi[i] = rhs.fEndPhi[i];
305 fEndZ2[i] = rhs.fEndZ2[i];
309 fRebuildPolyhedron =
false;
310 delete fpPolyhedron; fpPolyhedron = 0;
324 "G4TwistedTubs does not support Parameterisation.");
333 G4double maxEndOuterRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ?
334 fEndOuterRadius[0] : fEndOuterRadius[1]);
335 pMin.
set(-maxEndOuterRad,-maxEndOuterRad,-fZHalfLength);
336 pMax.
set( maxEndOuterRad, maxEndOuterRad, fZHalfLength);
340 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
342 std::ostringstream message;
343 message <<
"Bad bounding box (min >= max) for solid: "
345 <<
"\npMin = " << pMin
346 <<
"\npMax = " << pMax;
387 if (fLastInside.p == p)
389 return fLastInside.inside;
394 tmpinside =
const_cast<EInside*
>(&(fLastInside.inside));
395 tmpp->
set(p.
x(), p.
y(), p.
z());
402 if ((outerhypearea ==
kOutside) || (distanceToOut < -halftol))
412 if (distanceToOut <= halftol)
422 return fLastInside.inside;
437 if (fLastNormal.p == p)
439 return fLastNormal.vec;
447 tmpp->
set(p.
x(), p.
y(), p.
z());
452 surfaces[0] = fLatterTwisted;
453 surfaces[1] = fFormerTwisted;
454 surfaces[2] = fInnerHype;
455 surfaces[3] = fOuterHype;
456 surfaces[4] = fLowerEndcap;
457 surfaces[5] = fUpperEndcap;
466 if (tmpdistance < distance)
468 distance = tmpdistance;
474 tmpsurface[0] = surfaces[besti];
475 *tmpnormal = tmpsurface[0]->
GetNormal(bestxx,
true);
477 return fLastNormal.vec;
500 if ((fLastDistanceToInWithV.p == p) && (fLastDistanceToInWithV.vec == v))
502 return fLastDistanceToIn.value;
506 tmpp =
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.p));
507 tmpv =
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.vec));
508 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToInWithV.value));
509 tmpp->
set(p.
x(), p.
y(), p.
z());
510 tmpv->
set(v.
x(), v.
y(), v.
z());
533 return fLastDistanceToInWithV.value;
547 surfaces[0] = fLowerEndcap;
548 surfaces[1] = fUpperEndcap;
549 surfaces[2] = fLatterTwisted;
550 surfaces[3] = fFormerTwisted;
551 surfaces[4] = fInnerHype;
552 surfaces[5] = fOuterHype;
560 if (tmpdistance < distance)
562 distance = tmpdistance;
568 return fLastDistanceToInWithV.value;
586 if (fLastDistanceToIn.p == p)
588 return fLastDistanceToIn.value;
593 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToIn.value));
594 tmpp->
set(p.
x(), p.
y(), p.
z());
610 return fLastDistanceToIn.value;
619 surfaces[0] = fLowerEndcap;
620 surfaces[1] = fUpperEndcap;
621 surfaces[2] = fLatterTwisted;
622 surfaces[3] = fFormerTwisted;
623 surfaces[4] = fInnerHype;
624 surfaces[5] = fOuterHype;
632 if (tmpdistance < distance)
634 distance = tmpdistance;
639 return fLastDistanceToIn.value;
643 G4Exception(
"G4TwistedTubs::DistanceToIn(p)",
"GeomSolids0003",
673 if ((fLastDistanceToOutWithV.p == p) && (fLastDistanceToOutWithV.vec == v) )
675 return fLastDistanceToOutWithV.value;
679 tmpp =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.p));
680 tmpv =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.vec));
681 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOutWithV.value));
682 tmpp->
set(p.
x(), p.
y(), p.
z());
683 tmpv->
set(v.
x(), v.
y(), v.
z());
708 *norm = (blockedsurface->
GetNormal(p,
true));
712 return fLastDistanceToOutWithV.value;
726 surfaces[0] = fLatterTwisted;
727 surfaces[1] = fFormerTwisted;
728 surfaces[2] = fInnerHype;
729 surfaces[3] = fOuterHype;
730 surfaces[4] = fLowerEndcap;
731 surfaces[5] = fUpperEndcap;
740 if (tmpdistance < distance)
742 distance = tmpdistance;
752 *norm = (surfaces[besti]->
GetNormal(p,
true));
759 return fLastDistanceToOutWithV.value;
778 if (fLastDistanceToOut.p == p)
780 return fLastDistanceToOut.value;
785 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOut.value));
786 tmpp->
set(p.
x(), p.
y(), p.
z());
803 return fLastDistanceToOut.value;
812 surfaces[0] = fLatterTwisted;
813 surfaces[1] = fFormerTwisted;
814 surfaces[2] = fInnerHype;
815 surfaces[3] = fOuterHype;
816 surfaces[4] = fLowerEndcap;
817 surfaces[5] = fUpperEndcap;
825 if (tmpdistance < distance)
827 distance = tmpdistance;
833 return fLastDistanceToOut.value;
837 G4Exception(
"G4TwistedTubs::DistanceToOut(p)",
"GeomSolids0003",
853 G4int oldprc = os.precision(16);
854 os <<
"-----------------------------------------------------------\n"
855 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
856 <<
" ===================================================\n"
857 <<
" Solid type: G4TwistedTubs\n"
859 <<
" -ve end Z : " << fEndZ[0]/
mm <<
" mm \n"
860 <<
" +ve end Z : " << fEndZ[1]/
mm <<
" mm \n"
861 <<
" inner end radius(-ve z): " << fEndInnerRadius[0]/
mm <<
" mm \n"
862 <<
" inner end radius(+ve z): " << fEndInnerRadius[1]/
mm <<
" mm \n"
863 <<
" outer end radius(-ve z): " << fEndOuterRadius[0]/
mm <<
" mm \n"
864 <<
" outer end radius(+ve z): " << fEndOuterRadius[1]/
mm <<
" mm \n"
865 <<
" inner radius (z=0) : " << fInnerRadius/
mm <<
" mm \n"
866 <<
" outer radius (z=0) : " << fOuterRadius/
mm <<
" mm \n"
867 <<
" twisted angle : " << fPhiTwist/
degree <<
" degrees \n"
868 <<
" inner stereo angle : " << fInnerStereo/
degree <<
" degrees \n"
869 <<
" outer stereo angle : " << fOuterStereo/
degree <<
" degrees \n"
870 <<
" phi-width of a piece : " << fDPhi/
degree <<
" degrees \n"
871 <<
"-----------------------------------------------------------\n";
872 os.precision(oldprc);
893 G4double maxEndOuterRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ?
894 fEndOuterRadius[0] : fEndOuterRadius[1]);
895 return G4VisExtent( -maxEndOuterRad, maxEndOuterRad,
896 -maxEndOuterRad, maxEndOuterRad,
897 -fZHalfLength, fZHalfLength );
913 const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;
914 const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)*(k-1) ;
918 typedef G4int G4int4[4];
919 G4double3* xyz =
new G4double3[nnodes];
920 G4int4* faces =
new G4int4[nfaces] ;
921 fLowerEndcap->
GetFacets(k,k,xyz,faces,0) ;
922 fUpperEndcap->
GetFacets(k,k,xyz,faces,1) ;
924 fFormerTwisted->
GetFacets(k,n,xyz,faces,3) ;
926 fLatterTwisted->
GetFacets(k,n,xyz,faces,5) ;
942 fRebuildPolyhedron ||
949 fRebuildPolyhedron =
false;
958 void G4TwistedTubs::CreateSurfaces()
966 fEndInnerRadius, fEndOuterRadius,
967 fDPhi, fEndPhi, fEndZ, -1) ;
970 fEndInnerRadius, fEndOuterRadius,
971 fDPhi, fEndPhi, fEndZ, 1) ;
974 rotHalfDPhi.
rotateZ(0.5*fDPhi);
977 fEndInnerRadius, fEndOuterRadius,
978 fDPhi, fEndPhi, fEndZ,
979 fInnerRadius, fOuterRadius, fKappa,
982 fEndInnerRadius, fEndOuterRadius,
983 fDPhi, fEndPhi, fEndZ,
984 fInnerRadius, fOuterRadius, fKappa,
988 fEndInnerRadius, fEndOuterRadius,
989 fDPhi, fEndPhi, fEndZ,
990 fInnerRadius, fOuterRadius,fKappa,
991 fTanInnerStereo, fTanOuterStereo, -1) ;
993 fEndInnerRadius, fEndOuterRadius,
994 fDPhi, fEndPhi, fEndZ,
995 fInnerRadius, fOuterRadius,fKappa,
996 fTanInnerStereo, fTanOuterStereo, 1) ;
1002 fOuterHype, fFormerTwisted);
1004 fOuterHype, fFormerTwisted);
1006 fOuterHype, fUpperEndcap);
1008 fOuterHype, fUpperEndcap);
1010 fFormerTwisted, fUpperEndcap);
1012 fFormerTwisted, fUpperEndcap);
1037 if(fCubicVolume != 0.) {;}
1038 else { fCubicVolume = fDPhi*fZHalfLength*(fOuterRadius*fOuterRadius
1039 -fInnerRadius*fInnerRadius); }
1040 return fCubicVolume;
1048 if(fSurfaceArea != 0.) {;}
1050 return fSurfaceArea;
1083 else if ( (chose >= a1) && (chose < a1 + a2 ) )
1093 else if ( (chose >= a1 + a2 ) && (chose < a1 + a2 + a3 ) )
1103 else if ( (chose >= a1 + a2 + a3 ) && (chose < a1 + a2 + a3 + a4 ) )
1112 else if( (chose >= a1 + a2 + a3 + a4 )&&(chose < a1 + a2 + a3 + a4 + a5 ) )
void set(double x, double y, double z)
ThreeVector shoot(const G4int Ap, const G4int Af)
static constexpr double mm
G4double GetEndInnerRadius() const
static const G4double kInfinity
G4ThreeVector GetPointOnSurface() const
virtual G4ThreeVector GetNormal(const G4ThreeVector &xx, G4bool isGlobal)=0
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
std::ostream & StreamInfo(std::ostream &os) const
G4Polyhedron * CreatePolyhedron() const
EInside Inside(const G4ThreeVector &p) const
virtual void AddSolid(const G4Box &)=0
void ComputeDimensions(G4VPVParameterisation *, const G4int, const G4VPhysicalVolume *)
#define G4MUTEX_INITIALIZER
G4bool IsValidNorm() const
G4GeometryType GetEntityType() const
virtual G4double DistanceToIn(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
static constexpr double twopi
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
G4double GetEndOuterRadius() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
static double normal(HepRandomEngine *eptr)
virtual G4double GetSurfaceArea()=0
void SetNeighbours(G4VTwistSurface *axis0min, G4VTwistSurface *axis1min, G4VTwistSurface *axis0max, G4VTwistSurface *axis1max)
virtual G4double DistanceTo(const G4ThreeVector &gp, G4ThreeVector &gxx)
void DescribeYourselfTo(G4VGraphicsScene &scene) const
static constexpr double degree
virtual G4double DistanceToOut(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
virtual G4ThreeVector SurfacePoint(G4double, G4double, G4bool isGlobal=false)=0
G4double GetRadialTolerance() const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcnorm=G4bool(false), G4bool *validnorm=0, G4ThreeVector *n=0) const
void Extent(G4ThreeVector &pMin, G4ThreeVector &pMax) const
virtual G4double GetBoundaryMax(G4double)=0
G4double GetSurfaceArea()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
virtual void GetFacets(G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)=0
virtual G4double GetBoundaryMin(G4double)=0
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
static G4int GetNumberOfRotationSteps()
T max(const T t1, const T t2)
brief Return the largest of the two arguments
HepRotation & rotateZ(double delta)
G4TwistedTubs(const G4String &pname, G4double twistedangle, G4double endinnerrad, G4double endouterrad, G4double halfzlen, G4double dphi)
G4VSolid & operator=(const G4VSolid &rhs)
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
G4double GetCubicVolume()
G4VisExtent GetExtent() const
virtual G4double GetSurfaceArea()
static G4GeometryTolerance * GetInstance()
G4Polyhedron * GetPolyhedron() const
G4TwistedTubs & operator=(const G4TwistedTubs &rhs)