36#if !defined(G4GEOM_USE_UPARA)
72 fDx = (pt[3].
x() - pt[2].
x())*0.5;
73 fDy = (pt[2].
y() - pt[1].
y())*0.5;
77 fTalpha = (pt[2].
x() + pt[3].
x() - pt[1].
x() - pt[0].
x())*0.25/fDy;
78 fTthetaCphi = (pt[4].
x() + fDy*fTalpha + fDx)/fDz;
79 fTthetaSphi = (pt[4].
y() + fDy)/fDz;
86 G4double DzTthetaSphi = fDz*fTthetaSphi;
87 G4double DzTthetaCphi = fDz*fTthetaCphi;
88 v[0].
set(-DzTthetaCphi-DyTalpha-fDx, -DzTthetaSphi-fDy, -fDz);
89 v[1].
set(-DzTthetaCphi-DyTalpha+fDx, -DzTthetaSphi-fDy, -fDz);
90 v[2].
set(-DzTthetaCphi+DyTalpha-fDx, -DzTthetaSphi+fDy, -fDz);
91 v[3].
set(-DzTthetaCphi+DyTalpha+fDx, -DzTthetaSphi+fDy, -fDz);
92 v[4].
set( DzTthetaCphi-DyTalpha-fDx, DzTthetaSphi-fDy, fDz);
93 v[5].
set( DzTthetaCphi-DyTalpha+fDx, DzTthetaSphi-fDy, fDz);
94 v[6].
set( DzTthetaCphi+DyTalpha-fDx, DzTthetaSphi+fDy, fDz);
95 v[7].
set( DzTthetaCphi+DyTalpha+fDx, DzTthetaSphi+fDy, fDz);
99 for (
G4int i=0; i<8; ++i)
101 G4double delx = std::abs(pt[i].x() - v[i].x());
102 G4double dely = std::abs(pt[i].y() - v[i].y());
103 G4double delz = std::abs(pt[i].z() - v[i].z());
104 G4double discrepancy = std::max(std::max(delx,dely),delz);
107 std::ostringstream message;
108 G4long oldprc = message.precision(16);
109 message <<
"Invalid vertice coordinates for Solid: " <<
GetName()
110 <<
"\nVertix #" << i <<
", discrepancy = " << discrepancy
111 <<
"\n original : " << pt[i]
112 <<
"\n recomputed : " << v[i];
146 :
G4CSGSolid(rhs), halfCarTolerance(rhs.halfCarTolerance),
147 fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz), fTalpha(rhs.fTalpha),
148 fTthetaCphi(rhs.fTthetaCphi),fTthetaSphi(rhs.fTthetaSphi)
150 for (
G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
161 if (
this == &rhs) {
return *
this; }
169 halfCarTolerance = rhs.halfCarTolerance;
173 fTalpha = rhs.fTalpha;
174 fTthetaCphi = rhs.fTthetaCphi;
175 fTthetaSphi = rhs.fTthetaSphi;
176 for (
G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
197 fTalpha = std::tan(pAlpha);
198 fTthetaCphi = std::tan(pTheta)*std::cos(pPhi);
199 fTthetaSphi = std::tan(pTheta)*std::sin(pPhi);
209void G4Para::CheckParameters()
215 std::ostringstream message;
216 message <<
"Invalid (too small or negative) dimensions for Solid: "
221 G4Exception(
"G4Para::CheckParameters()",
"GeomSolids0002",
230void G4Para::MakePlanes()
241 fPlanes[0].b = ynorm.
y();
242 fPlanes[0].c = ynorm.
z();
243 fPlanes[0].d = fPlanes[0].b*fDy;
246 fPlanes[1].b = -fPlanes[0].b;
247 fPlanes[1].c = -fPlanes[0].c;
248 fPlanes[1].d = fPlanes[0].d;
254 fPlanes[2].a = xnorm.
x();
255 fPlanes[2].b = xnorm.
y();
256 fPlanes[2].c = xnorm.
z();
257 fPlanes[2].d = fPlanes[2].a*fDx;
259 fPlanes[3].a = -fPlanes[2].a;
260 fPlanes[3].b = -fPlanes[2].b;
261 fPlanes[3].c = -fPlanes[2].c;
262 fPlanes[3].d = fPlanes[2].d;
327 std::min(-x0-x1-dx,-x0+x1-dx),x0-x1-dx),x0+x1-dx);
331 std::max(-x0-x1+dx,-x0+x1+dx),x0-x1+dx),x0+x1+dx);
334 G4double ymin = std::min(-y0-dy,y0-dy);
335 G4double ymax = std::max(-y0+dy,y0+dy);
337 pMin.
set(xmin,ymin,-dz);
338 pMax.
set(xmax,ymax, dz);
342 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
344 std::ostringstream message;
345 message <<
"Bad bounding box (min >= max) for solid: "
347 <<
"\npMin = " << pMin
348 <<
"\npMax = " << pMax;
349 G4Exception(
"G4Para::BoundingLimits()",
"GeomMgt0001",
376 return exist = (pMin < pMax) ?
true :
false;
390 baseA[0].set(-x0-x1-dx,-y0-dy,-dz);
391 baseA[1].set(-x0-x1+dx,-y0-dy,-dz);
392 baseA[2].set(-x0+x1+dx,-y0+dy,-dz);
393 baseA[3].set(-x0+x1-dx,-y0+dy,-dz);
395 baseB[0].set(+x0-x1-dx, y0-dy, dz);
396 baseB[1].set(+x0-x1+dx, y0-dy, dz);
397 baseB[2].set(+x0+x1+dx, y0+dy, dz);
398 baseB[3].set(+x0+x1-dx, y0+dy, dz);
400 std::vector<const G4ThreeVectorList *> polygons(2);
401 polygons[0] = &baseA;
402 polygons[1] = &baseB;
416 G4double xx = fPlanes[2].a*p.
x()+fPlanes[2].b*p.
y()+fPlanes[2].c*p.
z();
417 G4double dx = std::abs(xx) + fPlanes[2].d;
419 G4double yy = fPlanes[0].b*p.
y()+fPlanes[0].c*p.
z();
420 G4double dy = std::abs(yy) + fPlanes[0].d;
426 if (dist > halfCarTolerance)
return kOutside;
442 if (std::abs(dz) <= halfCarTolerance)
444 nz = (p.
z() < 0) ? -1 : 1;
451 G4double yy = fPlanes[0].b*p.
y()+fPlanes[0].c*p.
z();
452 if (std::abs(fPlanes[0].
d + yy) <= halfCarTolerance)
458 else if (std::abs(fPlanes[1].
d - yy) <= halfCarTolerance)
468 G4double xx = fPlanes[2].a*p.
x()+fPlanes[2].b*p.
y()+fPlanes[2].c*p.
z();
469 if (std::abs(fPlanes[2].
d + xx) <= halfCarTolerance)
476 else if (std::abs(fPlanes[3].
d - xx) <= halfCarTolerance)
493 std::ostringstream message;
494 G4int oldprc = message.precision(16);
495 message <<
"Point p is not on surface (!?) of solid: "
497 message <<
"Position:\n";
498 message <<
" p.x() = " << p.
x()/mm <<
" mm\n";
499 message <<
" p.y() = " << p.
y()/mm <<
" mm\n";
500 message <<
" p.z() = " << p.
z()/mm <<
" mm";
501 G4cout.precision(oldprc) ;
502 G4Exception(
"G4Para::SurfaceNormal(p)",
"GeomSolids1002",
506 return ApproxSurfaceNormal(p);
519 for (
G4int i=0; i<4; ++i)
523 fPlanes[i].c*p.
z() + fPlanes[i].d;
524 if (
d > dist) { dist =
d; iside = i; }
544 if ((std::abs(p.
z()) - fDz) >= -halfCarTolerance && p.
z()*v.
z() >= 0)
547 G4double dz = (invz < 0) ? fDz : -fDz;
553 G4double tmin0 = tzmin, tmax0 = tzmax;
554 G4double cos0 = fPlanes[0].b*v.
y() + fPlanes[0].c*v.
z();
555 G4double disy = fPlanes[0].b*p.
y() + fPlanes[0].c*p.
z();
556 G4double dis0 = fPlanes[0].d + disy;
557 if (dis0 >= -halfCarTolerance)
559 if (cos0 >= 0)
return kInfinity;
561 if (tmin0 < tmp) tmin0 = tmp;
566 if (tmax0 > tmp) tmax0 = tmp;
569 G4double tmin1 = tmin0, tmax1 = tmax0;
571 G4double dis1 = fPlanes[1].d - disy;
572 if (dis1 >= -halfCarTolerance)
574 if (cos1 >= 0)
return kInfinity;
576 if (tmin1 < tmp) tmin1 = tmp;
581 if (tmax1 > tmp) tmax1 = tmp;
586 G4double tmin2 = tmin1, tmax2 = tmax1;
587 G4double cos2 = fPlanes[2].a*v.
x() + fPlanes[2].b*v.
y() + fPlanes[2].c*v.
z();
588 G4double disx = fPlanes[2].a*p.
x() + fPlanes[2].b*p.
y() + fPlanes[2].c*p.
z();
589 G4double dis2 = fPlanes[2].d + disx;
590 if (dis2 >= -halfCarTolerance)
592 if (cos2 >= 0)
return kInfinity;
594 if (tmin2 < tmp) tmin2 = tmp;
599 if (tmax2 > tmp) tmax2 = tmp;
602 G4double tmin3 = tmin2, tmax3 = tmax2;
604 G4double dis3 = fPlanes[3].d - disx;
605 if (dis3 >= -halfCarTolerance)
607 if (cos3 >= 0)
return kInfinity;
609 if (tmin3 < tmp) tmin3 = tmp;
614 if (tmax3 > tmp) tmax3 = tmp;
619 G4double tmin = tmin3, tmax = tmax3;
620 if (tmax <= tmin + halfCarTolerance)
return kInfinity;
621 return (tmin < halfCarTolerance ) ? 0. : tmin;
631 G4double xx = fPlanes[2].a*p.
x()+fPlanes[2].b*p.
y()+fPlanes[2].c*p.
z();
632 G4double dx = std::abs(xx) + fPlanes[2].d;
634 G4double yy = fPlanes[0].b*p.
y()+fPlanes[0].c*p.
z();
635 G4double dy = std::abs(yy) + fPlanes[0].d;
641 return (dist > 0) ? dist : 0.;
656 if ((std::abs(p.
z()) - fDz) >= -halfCarTolerance && p.
z()*v.
z() > 0)
661 n->set(0, 0, (p.
z() < 0) ? -1 : 1);
667 G4int iside = (vz < 0) ? -4 : -2;
671 G4double cos0 = fPlanes[0].b*v.
y() + fPlanes[0].c*v.
z();
674 G4double dis0 = fPlanes[0].b*p.
y() + fPlanes[0].c*p.
z() + fPlanes[0].d;
675 if (dis0 >= -halfCarTolerance)
680 n->set(0, fPlanes[0].
b, fPlanes[0].
c);
685 if (tmax > tmp) { tmax = tmp; iside = 0; }
691 G4double dis1 = fPlanes[1].b*p.
y() + fPlanes[1].c*p.
z() + fPlanes[1].d;
692 if (dis1 >= -halfCarTolerance)
697 n->set(0, fPlanes[1].
b, fPlanes[1].
c);
702 if (tmax > tmp) { tmax = tmp; iside = 1; }
707 G4double cos2 = fPlanes[2].a*v.
x() + fPlanes[2].b*v.
y() + fPlanes[2].c*v.
z();
710 G4double dis2 = fPlanes[2].a*p.
x()+fPlanes[2].b*p.
y()+fPlanes[2].c*p.
z()+fPlanes[2].d;
711 if (dis2 >= -halfCarTolerance)
716 n->set(fPlanes[2].
a, fPlanes[2].
b, fPlanes[2].
c);
721 if (tmax > tmp) { tmax = tmp; iside = 2; }
727 G4double dis3 = fPlanes[3].a*p.
x()+fPlanes[3].b*p.
y()+fPlanes[3].c*p.
z()+fPlanes[3].d;
728 if (dis3 >= -halfCarTolerance)
733 n->set(fPlanes[3].
a, fPlanes[3].
b, fPlanes[3].
c);
738 if (tmax > tmp) { tmax = tmp; iside = 3; }
747 n->set(0, 0, iside + 3);
749 n->set(fPlanes[iside].
a, fPlanes[iside].
b, fPlanes[iside].
c);
764 std::ostringstream message;
765 G4int oldprc = message.precision(16);
766 message <<
"Point p is outside (!?) of solid: " <<
GetName() <<
G4endl;
767 message <<
"Position:\n";
768 message <<
" p.x() = " << p.
x()/mm <<
" mm\n";
769 message <<
" p.y() = " << p.
y()/mm <<
" mm\n";
770 message <<
" p.z() = " << p.
z()/mm <<
" mm";
771 G4cout.precision(oldprc) ;
772 G4Exception(
"G4Para::DistanceToOut(p)",
"GeomSolids1002",
777 G4double xx = fPlanes[2].a*p.
x()+fPlanes[2].b*p.
y()+fPlanes[2].c*p.
z();
778 G4double dx = std::abs(xx) + fPlanes[2].d;
780 G4double yy = fPlanes[0].b*p.
y()+fPlanes[0].c*p.
z();
781 G4double dy = std::abs(yy) + fPlanes[0].d;
787 return (dist < 0) ? -dist : 0.;
814 G4double alpha = std::atan(fTalpha);
815 G4double theta = std::atan(std::sqrt(fTthetaCphi*fTthetaCphi +
816 fTthetaSphi*fTthetaSphi));
817 G4double phi = std::atan2(fTthetaSphi,fTthetaCphi);
819 G4long oldprc = os.precision(16);
820 os <<
"-----------------------------------------------------------\n"
821 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
822 <<
" ===================================================\n"
823 <<
" Solid type: G4Para\n"
825 <<
" half length X: " << fDx/mm <<
" mm\n"
826 <<
" half length Y: " << fDy/mm <<
" mm\n"
827 <<
" half length Z: " << fDz/mm <<
" mm\n"
828 <<
" alpha: " << alpha/degree <<
"degrees\n"
829 <<
" theta: " << theta/degree <<
"degrees\n"
830 <<
" phi: " << phi/degree <<
"degrees\n"
831 <<
"-----------------------------------------------------------\n";
832 os.precision(oldprc);
844 G4double DzTthetaSphi = fDz*fTthetaSphi;
845 G4double DzTthetaCphi = fDz*fTthetaCphi;
850 pt[0].
set(-DzTthetaCphi-DyTalpha-fDx, -DzTthetaSphi-fDy, -fDz);
851 pt[1].
set(-DzTthetaCphi-DyTalpha+fDx, -DzTthetaSphi-fDy, -fDz);
852 pt[2].
set(-DzTthetaCphi+DyTalpha-fDx, -DzTthetaSphi+fDy, -fDz);
853 pt[3].
set(-DzTthetaCphi+DyTalpha+fDx, -DzTthetaSphi+fDy, -fDz);
854 pt[4].
set( DzTthetaCphi-DyTalpha-fDx, DzTthetaSphi-fDy, fDz);
855 pt[5].
set( DzTthetaCphi-DyTalpha+fDx, DzTthetaSphi-fDy, fDz);
856 pt[6].
set( DzTthetaCphi+DyTalpha-fDx, DzTthetaSphi+fDy, fDz);
857 pt[7].
set( DzTthetaCphi+DyTalpha+fDx, DzTthetaSphi+fDy, fDz);
869 G4double sface[6] = { sxy, syz, syz, sxz, sxz, sxy };
870 for (
G4int i=1; i<6; ++i) { sface[i] += sface[i-1]; }
876 if (select <= sface[4]) k = 4;
877 if (select <= sface[3]) k = 3;
878 if (select <= sface[2]) k = 2;
879 if (select <= sface[1]) k = 1;
880 if (select <= sface[0]) k = 0;
884 G4int ip[6][3] = {{0,1,2}, {0,4,1}, {2,3,6}, {0,2,4}, {1,5,3}, {4,6,5}};
887 return (1.-u-v)*pt[ip[k][0]] + u*pt[ip[k][1]] + v*pt[ip[k][2]];
901 G4double phi = std::atan2(fTthetaSphi, fTthetaCphi);
902 G4double alpha = std::atan(fTalpha);
903 G4double theta = std::atan(std::sqrt(fTthetaCphi*fTthetaCphi +
904 fTthetaSphi*fTthetaSphi));
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
Hep3Vector cross(const Hep3Vector &) const
void set(double x, double y, double z)
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool fRebuildPolyhedron
G4CSGSolid & operator=(const G4CSGSolid &rhs)
G4GeometryType GetEntityType() const
G4Polyhedron * CreatePolyhedron() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4double GetTanAlpha() const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const
G4double GetSurfaceArea()
G4Para & operator=(const G4Para &rhs)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
std::ostream & StreamInfo(std::ostream &os) const
G4Para(const G4String &pName, G4double pDx, G4double pDy, G4double pDz, G4double pAlpha, G4double pTheta, G4double pPhi)
void SetAllParameters(G4double pDx, G4double pDy, G4double pDz, G4double pAlpha, G4double pTheta, G4double pPhi)
G4double GetCubicVolume()
G4double GetYHalfLength() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4double GetZHalfLength() const
EInside Inside(const G4ThreeVector &p) const
G4double GetXHalfLength() const
G4ThreeVector GetPointOnSurface() const
virtual void AddSolid(const G4Box &)=0
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const