34#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
46G4UTrap::G4UTrap(
const G4String& pName,
53 : Base_t(pName, pdz, pTheta, pPhi, pdy1, pdx1, pdx2,
54 pAlp1, pdy2, pdx3, pdx4, pAlp2)
62G4UTrap::G4UTrap(
const G4String& pName,
69 || pt[0].z() != pt[1].z()
70 || pt[0].z() != pt[2].z()
71 || pt[0].z() != pt[3].z()
74 || pt[4].z() != pt[5].z()
75 || pt[4].z() != pt[6].z()
76 || pt[4].z() != pt[7].z()
80 || pt[0].y() != pt[1].y()
81 || pt[2].y() != pt[3].y()
82 || pt[4].y() != pt[5].y()
83 || pt[6].y() != pt[7].y()
85 || std::abs(pt[0].y()+pt[2].y()+pt[4].y()+pt[6].y()) >=
kCarTolerance
86 || std::abs(pt[0].x()+pt[1].x()+pt[4].x()+pt[5].x() +
89 std::ostringstream message;
90 message <<
"Invalid vertice coordinates for Solid: " << GetName();
103G4UTrap::G4UTrap(
const G4String& pName,
107 : Base_t(pName, 0.5*pZ, 0, 0, 0.5*pY,
108 0.5*pX, 0.5*pLTX, 0.5*(pLTX - pX)/pY,
109 0.5*pY, 0.5*pX, 0.5*pLTX,
115G4UTrap::G4UTrap(
const G4String& pName,
119 : Base_t(pName, pdx1, pdx2, pdy1, pdy2, pdz)
124G4UTrap::G4UTrap(
const G4String& pName,
127 : Base_t(pName, pdx, pdy, pdz, pAlpha, pTheta, pPhi)
132G4UTrap::G4UTrap(
const G4String& pName )
141G4UTrap::G4UTrap(
const G4UTrap& rhs)
150G4UTrap& G4UTrap::operator = (
const G4UTrap& rhs)
154 if (
this == &rhs) {
return *
this; }
158 Base_t::operator=(rhs);
167G4double G4UTrap::GetZHalfLength()
const
171G4double G4UTrap::GetYHalfLength1()
const
175G4double G4UTrap::GetXHalfLength1()
const
179G4double G4UTrap::GetXHalfLength2()
const
183G4double G4UTrap::GetTanAlpha1()
const
185 return Base_t::GetTanAlpha1();
187G4double G4UTrap::GetYHalfLength2()
const
191G4double G4UTrap::GetXHalfLength3()
const
195G4double G4UTrap::GetXHalfLength4()
const
199G4double G4UTrap::GetTanAlpha2()
const
201 return Base_t::GetTanAlpha2();
205 return Base_t::GetPhi();
209 return Base_t::GetTheta();
213 return Base_t::GetAlpha1();
217 return Base_t::GetAlpha2();
222 plane.
a = GetStruct().GetPlane(n).fA;
223 plane.
b = GetStruct().GetPlane(n).fB;
224 plane.
c = GetStruct().GetPlane(n).fC;
225 plane.
d = GetStruct().GetPlane(n).fD;
230 G4double tanThetaSphi = GetTanThetaSinPhi();
231 G4double tanThetaCphi = GetTanThetaCosPhi();
232 G4double tan2Theta = tanThetaSphi*tanThetaSphi + tanThetaCphi*tanThetaCphi;
233 G4double cosTheta = 1.0 / std::sqrt(1 + tan2Theta);
234 return {tanThetaCphi*cosTheta, tanThetaSphi*cosTheta, cosTheta};
254 SetTanAlpha1(std::tan(pAlp1));
255 SetTanAlpha2(std::tan(pAlp2));
259 fRebuildPolyhedron =
true;
274 for (
unsigned int i=0; i<8; ++i)
276 upt[i] = U3Vector(pt[i].x(), pt[i].y(), pt[i].z());
278 fromCornersToParameters(upt);
279 fRebuildPolyhedron =
true;
286void G4UTrap::CheckParameters()
const
297 fDy1<=0 || fDx1<=0 || fDx2<=0 ||
298 fDy2<=0 || fDx3<=0 || fDx4<=0)
300 std::ostringstream message;
301 message <<
"Invalid Length Parameters for Solid: " << GetName()
302 <<
"\n X - " <<fDx1<<
", "<<fDx2<<
", "<<fDx3<<
", "<<fDx4
303 <<
"\n Y - " <<fDy1<<
", "<<fDy2
305 G4Exception(
"G4UTrap::CheckParameters()",
"GeomSolids0002",
326 G4double DzTthetaCphi = fDz*GetTanThetaCosPhi();
327 G4double DzTthetaSphi = fDz*GetTanThetaSinPhi();
328 G4double Dy1Talpha1 = fDy1*fTalpha1;
329 G4double Dy2Talpha2 = fDy2*fTalpha2;
331 pt[0].
set(-DzTthetaCphi-Dy1Talpha1-fDx1,-DzTthetaSphi-fDy1,-fDz);
332 pt[1].
set(-DzTthetaCphi-Dy1Talpha1+fDx1,-DzTthetaSphi-fDy1,-fDz);
333 pt[2].
set(-DzTthetaCphi+Dy1Talpha1-fDx2,-DzTthetaSphi+fDy1,-fDz);
334 pt[3].
set(-DzTthetaCphi+Dy1Talpha1+fDx2,-DzTthetaSphi+fDy1,-fDz);
335 pt[4].
set( DzTthetaCphi-Dy2Talpha2-fDx3, DzTthetaSphi-fDy2, fDz);
336 pt[5].
set( DzTthetaCphi-Dy2Talpha2+fDx3, DzTthetaSphi-fDy2, fDz);
337 pt[6].
set( DzTthetaCphi+Dy2Talpha2-fDx4, DzTthetaSphi+fDy2, fDz);
338 pt[7].
set( DzTthetaCphi+Dy2Talpha2+fDx4, DzTthetaSphi+fDy2, fDz);
347 constexpr G4int iface[4][4] = { {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3} };
348 const static G4String side[4] = {
"~-Y",
"~+Y",
"~-X",
"~+X" };
350 for (
G4int i=0; i<4; ++i)
354 for (
G4int k=0; k<4; ++k)
357 G4double dist = plane.
a*p.
x() + plane.
b*p.
y() + plane.
c*p.
z() + plane.
d;
358 if (std::abs(dist) > std::abs(dmax)) dmax = dist;
362 std::ostringstream message;
363 message <<
"Side face " << side[i] <<
" is not planar for solid: "
364 << GetName() <<
"\nDiscrepancy: " << dmax/mm <<
" mm\n";
366 G4Exception(
"G4UTrap::CheckPlanarity()",
"GeomSolids0002",
390 return new G4UTrap(*
this);
399 static G4bool checkBBox =
true;
402 for (
G4int i=0; i<4; ++i) { planes[i] = GetSidePlane(i); }
404 G4double xmin = kInfinity, xmax = -kInfinity;
405 G4double ymin = kInfinity, ymax = -kInfinity;
407 for (
G4int i=0; i<8; ++i)
409 G4int iy = (i==0 || i==1 || i==4 || i==5) ? 0 : 1;
410 G4int ix = (i==0 || i==2 || i==4 || i==6) ? 2 : 3;
412 G4double y = -(planes[iy].
c*z + planes[iy].
d)/planes[iy].b;
413 G4double x = -(planes[ix].
b*y + planes[ix].
c*z + planes[ix].
d)/planes[ix].a;
414 if (x < xmin) xmin = x;
415 if (x > xmax) xmax = x;
416 if (y < ymin) ymin = y;
417 if (y > ymax) ymax = y;
420 pMin.
set(xmin,ymin,-dz);
421 pMax.
set(xmax,ymax, dz);
425 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
427 std::ostringstream message;
428 message <<
"Bad bounding box (min >= max) for solid: "
430 <<
"\npMin = " << pMin
431 <<
"\npMax = " << pMax;
432 G4Exception(
"G4UTrap::BoundingLimits()",
"GeomMgt0001",
444 if (std::abs(pMin.
x()-vmin.x()) > tolerance ||
445 std::abs(pMin.
y()-vmin.y()) > tolerance ||
446 std::abs(pMin.
z()-vmin.z()) > tolerance ||
447 std::abs(pMax.
x()-vmax.x()) > tolerance ||
448 std::abs(pMax.
y()-vmax.y()) > tolerance ||
449 std::abs(pMax.
z()-vmax.z()) > tolerance)
451 std::ostringstream message;
452 message <<
"Inconsistency in bounding boxes for solid: "
454 <<
"\nBBox min: wrapper = " << pMin <<
" solid = " << vmin
455 <<
"\nBBox max: wrapper = " << pMax <<
" solid = " << vmax;
456 G4Exception(
"G4UTrap::BoundingLimits()",
"GeomMgt0001",
468G4UTrap::CalculateExtent(
const EAxis pAxis,
478 BoundingLimits(bmin,bmax);
481 if (
true)
return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
483 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
485 return exist = pMin < pMax;
491 for (
G4int i=0; i<4; ++i) { planes[i] = GetSidePlane(i); }
495 for (
G4int i=0; i<8; ++i)
497 G4int iy = (i==0 || i==1 || i==4 || i==5) ? 0 : 1;
498 G4int ix = (i==0 || i==2 || i==4 || i==6) ? 2 : 3;
500 G4double y = -(planes[iy].
c*z + planes[iy].
d)/planes[iy].b;
501 G4double x = -(planes[ix].
b*y + planes[ix].
c*z + planes[ix].
d)/planes[ix].a;
516 std::vector<const G4ThreeVectorList *> polygons(2);
517 polygons[0] = &baseA;
518 polygons[1] = &baseB;
521 exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
533 GetXHalfLength1(), GetXHalfLength2(), GetAlpha1(),
535 GetXHalfLength3(), GetXHalfLength4(), GetAlpha2());
const G4double kCarTolerance
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
G4BoundingEnvelope is a helper class to facilitate calculation of the extent of a solid within the li...
G4Trap is a general trapezoid: the faces perpendicular to the Z planes are trapezia,...
G4VPVParameterisation ia an abstract base class for Parameterisation, able to compute the transformat...
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
G4VSolid is an abstract base class for solids, physical shapes that can be tracked through....
G4VoxelLimits represents limitation/restrictions of space, where restrictions are only made perpendic...