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);
1143void 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);
1152 fSide180 =
new G4TwistBoxSide(
"180deg", fPhiTwist, fDz, fTheta, fPhi+pi,
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) ;
CLHEP::Hep3Vector G4ThreeVector
std::vector< G4ThreeVector > G4ThreeVectorList
G4DLLIMPORT std::ostream G4cout
void set(double x, double y, double z)
static G4GeometryTolerance * GetInstance()
G4double GetAngularTolerance() const
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
virtual void AddSolid(const G4Box &)=0
void ClipBetweenSections(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
G4VSolid & operator=(const G4VSolid &rhs)
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
virtual void GetFacets(G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)=0
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
void SetNeighbours(G4VTwistSurface *axis0min, G4VTwistSurface *axis1min, G4VTwistSurface *axis0max, G4VTwistSurface *axis1max)
virtual G4double GetBoundaryMax(G4double)=0
virtual G4ThreeVector GetNormal(const G4ThreeVector &xx, G4bool isGlobal)=0
virtual G4double GetSurfaceArea()=0
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcnorm=false, G4bool *validnorm=0, G4ThreeVector *n=0) const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4VTwistedFaceted & operator=(const G4VTwistedFaceted &rhs)
virtual G4Polyhedron * GetPolyhedron() const
G4ThreeVector GetPointOnSurface() const
virtual G4GeometryType GetEntityType() const
G4ThreeVector GetPointInSolid(G4double z) const
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) 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
virtual G4NURBS * CreateNURBS() const
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform) 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
G4double GetMinExtent(const EAxis pAxis) const
G4bool IsYLimited() const
G4double GetMinZExtent() const
G4bool IsXLimited() const
G4double GetMaxExtent(const EAxis pAxis) const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMinYExtent() const
G4double GetMinXExtent() const
G4bool IsZLimited() const
G4double GetMaxXExtent() const
static G4int GetNumberOfRotationSteps()
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)