74 fLowerEndcap(0), fUpperEndcap(0), fSide0(0),
75 fSide90(0), fSide180(0), fSide270(0)
95 fDxDown = ( fDx1 > fDx2 ? fDx1 : fDx2 ) ;
96 fDxUp = ( fDx3 > fDx4 ? fDx3 : fDx4 ) ;
97 fDx = ( fDxUp > fDxDown ? fDxUp : fDxDown ) ;
98 fDy = ( fDy1 > fDy2 ? fDy1 : fDy2 ) ;
102 if ( fDx1 != fDx2 && fDx3 != fDx4 )
104 pDytmp = fDy1 * ( fDx3 - fDx4 ) / ( fDx1 - fDx2 ) ;
107 std::ostringstream message;
108 message <<
"Not planar surface in untwisted Trapezoid: "
110 <<
"fDy2 is " << fDy2 <<
" but should be "
112 G4Exception(
"G4VTwistedFaceted::G4VTwistedFaceted()",
"GeomSolids0002",
118 if ( fDx1 == fDx2 && fDx3 == fDx4 )
125 if ( ( fDx1 == fDx2 && fDx3 != fDx4 ) || ( fDx1 != fDx2 && fDx3 == fDx4 ) )
127 std::ostringstream message;
128 message <<
"Not planar surface in untwisted Trapezoid: "
130 <<
"One endcap is rectangular, the other is a trapezoid." <<
G4endl
131 <<
"For planarity reasons they have to be rectangles or trapezoids "
133 G4Exception(
"G4VTwistedFaceted::G4VTwistedFaceted()",
"GeomSolids0002",
139 fPhiTwist = PhiTwist ;
144 fTAlph = std::tan(fAlph) ;
151 fdeltaX = 2 * fDz * std::tan(fTheta) * std::cos(fPhi) ;
155 fdeltaY = 2 * fDz * std::tan(fTheta) * std::sin(fPhi) ;
164 && ( std::fabs(fPhiTwist) > 2*kAngTolerance )
165 && ( std::fabs(fPhiTwist) < pi/2 )
166 && ( std::fabs(fAlph) < pi/2 )
167 && ( fTheta < pi/2 && fTheta >= 0 ) )
170 std::ostringstream message;
171 message <<
"Invalid dimensions. Too small, or twist angle too big: "
173 <<
"fDx 1-4 = " << fDx1/cm <<
", " << fDx2/cm <<
", "
174 << fDx3/cm <<
", " << fDx4/cm <<
" cm" <<
G4endl
175 <<
"fDy 1-2 = " << fDy1/cm <<
", " << fDy2/cm <<
", "
177 <<
"fDz = " << fDz/cm <<
" cm" <<
G4endl
178 <<
" twistangle " << fPhiTwist/deg <<
" deg" <<
G4endl
179 <<
" phi,theta = " << fPhi/deg <<
", " << fTheta/deg <<
" deg";
184 fCubicVolume = 2 * fDz * ( ( fDx1 + fDx2 ) * fDy1 + ( fDx3 + fDx4 ) * fDy2 );
193 fTheta(0.), fPhi(0.), fDy1(0.),
194 fDx1(0.), fDx2(0.), fDy2(0.), fDx3(0.), fDx4(0.),
195 fDz(0.), fDx(0.), fDy(0.), fAlph(0.),
196 fTAlph(0.), fdeltaX(0.), fdeltaY(0.), fPhiTwist(0.),
197 fLowerEndcap(0), fUpperEndcap(0), fSide0(0), fSide90(0), fSide180(0),
208 if (fLowerEndcap) {
delete fLowerEndcap ; }
209 if (fUpperEndcap) {
delete fUpperEndcap ; }
211 if (fSide0) {
delete fSide0 ; }
212 if (fSide90) {
delete fSide90 ; }
213 if (fSide180) {
delete fSide180 ; }
214 if (fSide270) {
delete fSide270 ; }
224 fTheta(rhs.fTheta), fPhi(rhs.fPhi),
225 fDy1(rhs.fDy1), fDx1(rhs.fDx1), fDx2(rhs.fDx2), fDy2(rhs.fDy2),
226 fDx3(rhs.fDx3), fDx4(rhs.fDx4), fDz(rhs.fDz), fDx(rhs.fDx), fDy(rhs.fDy),
227 fAlph(rhs.fAlph), fTAlph(rhs.fTAlph), fdeltaX(rhs.fdeltaX),
228 fdeltaY(rhs.fdeltaY), fPhiTwist(rhs.fPhiTwist), fLowerEndcap(0),
229 fUpperEndcap(0), fSide0(0), fSide90(0), fSide180(0), fSide270(0),
230 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
231 fLastInside(rhs.fLastInside), fLastNormal(rhs.fLastNormal),
232 fLastDistanceToIn(rhs.fLastDistanceToIn),
233 fLastDistanceToOut(rhs.fLastDistanceToOut),
234 fLastDistanceToInWithV(rhs.fLastDistanceToInWithV),
235 fLastDistanceToOutWithV(rhs.fLastDistanceToOutWithV)
248 if (
this == &rhs) {
return *
this; }
256 fTheta = rhs.fTheta; fPhi = rhs.fPhi;
257 fDy1= rhs.fDy1; fDx1= rhs.fDx1; fDx2= rhs.fDx2; fDy2= rhs.fDy2;
258 fDx3= rhs.fDx3; fDx4= rhs.fDx4; fDz= rhs.fDz; fDx= rhs.fDx; fDy= rhs.fDy;
259 fAlph= rhs.fAlph; fTAlph= rhs.fTAlph; fdeltaX= rhs.fdeltaX;
260 fdeltaY= rhs.fdeltaY; fPhiTwist= rhs.fPhiTwist; fLowerEndcap= 0;
261 fUpperEndcap= 0; fSide0= 0; fSide90= 0; fSide180= 0; fSide270= 0;
262 fCubicVolume= rhs.fCubicVolume; fSurfaceArea= rhs.fSurfaceArea;
265 fLastInside= rhs.fLastInside; fLastNormal= rhs.fLastNormal;
266 fLastDistanceToIn= rhs.fLastDistanceToIn;
267 fLastDistanceToOut= rhs.fLastDistanceToOut;
268 fLastDistanceToInWithV= rhs.fLastDistanceToInWithV;
269 fLastDistanceToOutWithV= rhs.fLastDistanceToOutWithV;
284 G4Exception(
"G4VTwistedFaceted::ComputeDimensions()",
286 "G4VTwistedFaceted does not support Parameterisation.");
296 G4double maxRad = std::sqrt(fDx*fDx + fDy*fDy);
297 pMin.
set(-maxRad,-maxRad,-fDz);
298 pMax.
set( maxRad, maxRad, fDz);
331 if (fLastInside.p == p)
333 return fLastInside.inside;
338 tmpin =
const_cast<EInside*
>(&(fLastInside.inside));
339 tmpp->
set(p.
x(), p.
y(), p.
z());
344 G4double phi = p.
z()/(2*fDz) * fPhiTwist ;
348 G4double px = p.
x() + fdeltaX * ( -phi/fPhiTwist) ;
349 G4double py = p.
y() + fdeltaY * ( -phi/fPhiTwist) ;
352 G4double posx = px * cphi - py * sphi ;
353 G4double posy = px * sphi + py * cphi ;
376 G4cout <<
"phi,theta = " << fPhi <<
" , " << fTheta <<
G4endl ;
419 return fLastInside.inside;
436 if (fLastNormal.p == p)
438 return fLastNormal.vec;
445 tmpp->
set(p.
x(), p.
y(), p.
z());
451 surfaces[0] = fSide0 ;
452 surfaces[1] = fSide90 ;
453 surfaces[2] = fSide180 ;
454 surfaces[3] = fSide270 ;
455 surfaces[4] = fLowerEndcap;
456 surfaces[5] = fUpperEndcap;
465 if (tmpdistance < distance)
467 distance = tmpdistance;
473 tmpsurface[0] = surfaces[besti];
474 *tmpnormal = tmpsurface[0]->
GetNormal(bestxx,
true);
476 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());
531 return fLastDistanceToInWithV.value;
545 surfaces[0] = fSide0;
546 surfaces[1] = fSide90 ;
547 surfaces[2] = fSide180 ;
548 surfaces[3] = fSide270 ;
549 surfaces[4] = fLowerEndcap;
550 surfaces[5] = fUpperEndcap;
554 for (
auto i=0; i < 6 ; ++i)
561 G4cout <<
"Solid DistanceToIn : distance = " << tmpdistance <<
G4endl ;
564 if (tmpdistance < distance)
566 distance = tmpdistance;
577 return fLastDistanceToInWithV.value;
597 if (fLastDistanceToIn.p == p)
599 return fLastDistanceToIn.value;
604 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToIn.value));
605 tmpp->
set(p.
x(), p.
y(), p.
z());
623 return fLastDistanceToIn.value;
636 surfaces[0] = fSide0;
637 surfaces[1] = fSide90 ;
638 surfaces[2] = fSide180 ;
639 surfaces[3] = fSide270 ;
640 surfaces[4] = fLowerEndcap;
641 surfaces[5] = fUpperEndcap;
645 for (
auto i=0; i< 6; ++i)
648 if (tmpdistance < distance)
650 distance = tmpdistance;
655 return fLastDistanceToIn.value;
660 G4Exception(
"G4VTwistedFaceted::DistanceToIn(p)",
"GeomSolids0003",
692 if (fLastDistanceToOutWithV.p == p && fLastDistanceToOutWithV.vec == v )
694 return fLastDistanceToOutWithV.value;
698 tmpp =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.p));
699 tmpv =
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.vec));
700 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOutWithV.value));
701 tmpp->
set(p.
x(), p.
y(), p.
z());
702 tmpv->
set(v.
x(), v.
y(), v.
z());
725 *norm = (blockedsurface->
GetNormal(p,
true));
730 return fLastDistanceToOutWithV.value;
742 surfaces[0] = fSide0;
743 surfaces[1] = fSide90 ;
744 surfaces[2] = fSide180 ;
745 surfaces[3] = fSide270 ;
746 surfaces[4] = fLowerEndcap;
747 surfaces[5] = fUpperEndcap;
752 for (
auto i=0; i<6 ; ++i)
755 if (tmpdistance < distance)
757 distance = tmpdistance;
767 *norm = (surfaces[besti]->
GetNormal(p,
true));
773 return fLastDistanceToOutWithV.value;
793 if (fLastDistanceToOut.p == p)
795 return fLastDistanceToOut.value;
800 tmpdist =
const_cast<G4double*
>(&(fLastDistanceToOut.value));
801 tmpp->
set(p.
x(), p.
y(), p.
z());
823 G4cout.precision(oldprc) ;
824 G4Exception(
"G4VTwistedFaceted::DistanceToOut(p)",
"GeomSolids1002",
832 retval = fLastDistanceToOut.value;
846 surfaces[0] = fSide0;
847 surfaces[1] = fSide90 ;
848 surfaces[2] = fSide180 ;
849 surfaces[3] = fSide270 ;
850 surfaces[4] = fLowerEndcap;
851 surfaces[5] = fUpperEndcap;
855 for (
auto i=0; i<6; ++i)
858 if (tmpdistance < distance)
860 distance = tmpdistance;
866 retval = fLastDistanceToOut.value;
872 G4Exception(
"G4VTwistedFaceted::DistanceToOut(p)",
"GeomSolids0003",
890 G4int oldprc = os.precision(16);
891 os <<
"-----------------------------------------------------------\n"
892 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
893 <<
" ===================================================\n"
894 <<
" Solid type: G4VTwistedFaceted\n"
896 <<
" polar angle theta = " << fTheta/degree <<
" deg" <<
G4endl
897 <<
" azimuthal angle phi = " << fPhi/degree <<
" deg" <<
G4endl
898 <<
" tilt angle alpha = " << fAlph/degree <<
" deg" <<
G4endl
899 <<
" TWIST angle = " << fPhiTwist/degree <<
" deg" <<
G4endl
900 <<
" Half length along y (lower endcap) = " << fDy1/cm <<
" cm"
902 <<
" Half length along x (lower endcap, bottom) = " << fDx1/cm <<
" cm"
904 <<
" Half length along x (lower endcap, top) = " << fDx2/cm <<
" cm"
906 <<
" Half length along y (upper endcap) = " << fDy2/cm <<
" cm"
908 <<
" Half length along x (upper endcap, bottom) = " << fDx3/cm <<
" cm"
910 <<
" Half length along x (upper endcap, top) = " << fDx4/cm <<
" cm"
912 <<
"-----------------------------------------------------------\n";
913 os.precision(oldprc);
933 G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
944void G4VTwistedFaceted::CreateSurfaces()
949 if ( fDx1 == fDx2 && fDx3 == fDx4 )
952 fDy1, fDx1, fDx1, fDy2, fDx3, fDx3, fAlph, 0.*deg);
953 fSide180 =
new G4TwistBoxSide(
"180deg", fPhiTwist, fDz, fTheta, fPhi+pi,
954 fDy1, fDx1, fDx1, fDy2, fDx3, fDx3, fAlph, 180.*deg);
959 fPhi, fDy1, fDx1, fDx2, fDy2, fDx3, fDx4, fAlph, 0.*deg);
961 fPhi+pi, fDy1, fDx2, fDx1, fDy2, fDx4, fDx3, fAlph, 180.*deg);
967 fPhi, fDy1, fDx1, fDx2, fDy2, fDx3, fDx4, fAlph, 0.*deg);
969 fPhi+pi, fDy1, fDx2, fDx1, fDy2, fDx4, fDx3, fAlph, 180.*deg);
974 fDz, fAlph, fPhi, fTheta, 1 );
976 fDz, fAlph, fPhi, fTheta, -1 );
980 fSide0->
SetNeighbours( fSide270 , fLowerEndcap , fSide90 , fUpperEndcap );
981 fSide90->
SetNeighbours( fSide0 , fLowerEndcap , fSide180 , fUpperEndcap );
982 fSide180->
SetNeighbours(fSide90 , fLowerEndcap , fSide270 , fUpperEndcap );
983 fSide270->
SetNeighbours(fSide180 , fLowerEndcap , fSide0 , fUpperEndcap );
984 fUpperEndcap->
SetNeighbours( fSide180, fSide270 , fSide0 , fSide90 );
985 fLowerEndcap->
SetNeighbours( fSide180, fSide270 , fSide0 , fSide90 );
995 return G4String(
"G4VTwistedFaceted");
1030 if ( z == fDz ) z -= 0.1*fDz ;
1031 if ( z == -fDz ) z += 0.1*fDz ;
1033 G4double phi = z/(2*fDz)*fPhiTwist ;
1035 return G4ThreeVector(fdeltaX * phi/fPhiTwist, fdeltaY * phi/fPhiTwist, z ) ;
1045 G4double phi = G4RandFlat::shoot(-fPhiTwist/2.,fPhiTwist/2.);
1070 G4double chose = G4RandFlat::shoot(0.,a1 + a2 + a3 + a4 + a5 + a6) ;
1076 u = G4RandFlat::shoot(umin,umax) ;
1081 else if( (chose >= a1) && (chose < a1 + a2 ) )
1086 u = G4RandFlat::shoot(umin,umax) ;
1090 else if( (chose >= a1 + a2 ) && (chose < a1 + a2 + a3 ) )
1094 u = G4RandFlat::shoot(umin,umax) ;
1098 else if( (chose >= a1 + a2 + a3 ) && (chose < a1 + a2 + a3 + a4 ) )
1102 u = G4RandFlat::shoot(umin,umax) ;
1105 else if( (chose >= a1 + a2 + a3 + a4 ) && (chose < a1 + a2 + a3 + a4 + a5 ) )
1107 y = G4RandFlat::shoot(-fDy1,fDy1) ;
1110 u = G4RandFlat::shoot(umin,umax) ;
1116 y = G4RandFlat::shoot(-fDy2,fDy2) ;
1119 u = G4RandFlat::shoot(umin,umax) ;
1135 std::abs(fPhiTwist) / twopi) + 2;
1138 const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;
1139 const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)*(k-1) ;
1143 typedef G4int G4int4[4];
1144 G4double3* xyz =
new G4double3[nnodes];
1145 G4int4* faces =
new G4int4[nfaces] ;
1147 fLowerEndcap->
GetFacets(k,k,xyz,faces,0) ;
1148 fUpperEndcap->
GetFacets(k,k,xyz,faces,1) ;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
static G4GeometryTolerance * GetInstance()
G4double GetAngularTolerance() const
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
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
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4VTwistedFaceted & operator=(const G4VTwistedFaceted &rhs)
G4Polyhedron * fpPolyhedron
virtual G4Polyhedron * GetPolyhedron() const
G4ThreeVector GetPointOnSurface() const
virtual G4GeometryType GetEntityType() const
G4bool fRebuildPolyhedron
G4ThreeVector GetPointInSolid(G4double z) const
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcnorm=false, G4bool *validnorm=nullptr, G4ThreeVector *n=nullptr) const
virtual EInside Inside(const G4ThreeVector &p) const
virtual std::ostream & StreamInfo(std::ostream &os) const
virtual ~G4VTwistedFaceted()
virtual void ComputeDimensions(G4VPVParameterisation *, const G4int, const G4VPhysicalVolume *)
virtual G4VisExtent GetExtent() const
virtual G4Polyhedron * CreatePolyhedron() const
G4VTwistedFaceted(const G4String &pname, G4double PhiTwist, G4double pDz, G4double pTheta, G4double pPhi, G4double pDy1, G4double pDx1, G4double pDx2, G4double pDy2, G4double pDx3, G4double pDx4, G4double pAlph)
virtual void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4double GetValueB(G4double phi) const
G4double Xcoef(G4double u, G4double phi, G4double ftg) const
static G4int GetNumberOfRotationSteps()
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])