30 double pdx1,
double pdx2,
31 double pdy1,
double pdy2,
33 :
VUSolid(pName), fCubicVolume(0), fSurfaceArea(0)
39 double pdy1,
double pdy2,
42 if (pdx1 > 0 && pdx2 > 0 && pdy1 > 0 && pdy2 > 0 && pdz > 0)
52 if (pdx1 >= 0 && pdx2 >= 0 && pdy1 >= 0 && pdy2 >= 0 && pdz >= 0)
58 fDx1 =
std::max(pdx1, Minimum_length);
59 fDx2 =
std::max(pdx2, Minimum_length);
60 fDy1 =
std::max(pdy1, Minimum_length);
61 fDy2 =
std::max(pdy2, Minimum_length);
66 std::cout <<
"ERROR - UTrd()::CheckAndSetAllParameters(): " <<
GetName()
68 <<
" Invalid dimensions, some are < 0 !" << std::endl
69 <<
" X - " << pdx1 <<
", " << pdx2 << std::endl
70 <<
" Y - " << pdy1 <<
", " << pdy2 << std::endl
71 <<
" Z - " << pdz << std::endl;
78 double pdy2,
double pdz )
87 double safe, zbase, tanxz, xdist, saf1, tanyz, ydist, saf2;
92 int oldprc = std::cout.precision(16) ;
93 std::cout << std::endl ;
95 std::cout <<
"Position:" << std::endl << std::endl ;
96 std::cout <<
"p.x() = " << p.
x() /
mm <<
" mm" << std::endl ;
97 std::cout <<
"p.y() = " << p.
y() /
mm <<
" mm" << std::endl ;
98 std::cout <<
"p.z() = " << p.
z() /
mm <<
" mm" << std::endl << std::endl ;
99 std::cout.precision(oldprc) ;
101 "Point p is outside !?");
105 safe = fDz - std::fabs(p.
z);
112 tanxz = (fDx2 - fDx1) * 0.5 / fDz;
113 xdist = fDx1 + tanxz * zbase - std::fabs(p.
x);
114 saf1 = xdist / std::sqrt(1.0 + tanxz * tanxz);
117 tanyz = (fDy2 - fDy1) * 0.5 / fDz;
118 ydist = fDy1 + tanyz * zbase - std::fabs(p.
y);
119 saf2 = ydist / std::sqrt(1.0 + tanyz * tanyz);
123 if (safe > saf1) safe = saf1;
124 if (safe > saf2) safe = saf2;
126 if (safe < 0) safe = 0;
140 saf[0] = fDz - std::abs(p.
z);
141 double fx = 0.5 * (fDx1 - fDx2) / fDz;
142 double calf = 1. / std::sqrt(1.0 + fx * fx);
144 double distx = 0.5 * (fDx1 + fDx2) - fx * p.
z;
145 if (distx < 0) saf[1] = UUtils::kInfinity;
146 else saf[1] = (distx - std::abs(p.
x)) * calf;
148 double fy = 0.5 * (fDy1 - fDy2) / fDz;
149 calf = 1. / std::sqrt(1.0 + fy * fy);
151 distx = 0.5 * (fDy1 + fDy2) - fy * p.
z;
152 if (distx < 0) saf[2] = UUtils::kInfinity;
153 else saf[2] = (distx - std::abs(p.
y)) * calf;
175 double tanxz, distx, safx;
176 double tanyz, disty, safy;
179 safe = std::abs(p.
z) - fDz;
180 if (safe < 0) safe = 0;
186 tanxz = (fDx2 - fDx1) * 0.5 / fDz;
189 distx = std::abs(p.
x) - (fDx1 + tanxz * zbase);
192 safx = distx / std::sqrt(1.0 + tanxz * tanxz);
193 if (safx > safe) safe = safx;
197 tanyz = (fDy2 - fDy1) * 0.5 / fDz;
200 disty = std::abs(p.
y) - (fDy1 + tanyz * zbase);
203 safy = disty / std::sqrt(1.0 + tanyz * tanyz);
204 if (safy > safe) safe = safy;
217 saf[0] = fDz - std::abs(p.
z);
218 double fx = 0.5 * (fDx1 - fDx2) / fDz;
219 double calf = 1. / std::sqrt(1.0 + fx * fx);
221 double distx = 0.5 * (fDx1 + fDx2) - fx * p.
z;
222 if (distx < 0) saf[1] = UUtils::kInfinity;
223 else saf[1] = (distx - std::abs(p.
x)) * calf;
225 double fy = 0.5 * (fDy1 - fDy2) / fDz;
226 calf = 1. / std::sqrt(1.0 + fy * fy);
228 distx = 0.5 * (fDy1 + fDy2) - fy * p.
z;
229 if (distx < 0) saf[2] = UUtils::kInfinity;
230 else saf[2] = (distx - std::abs(p.
y)) * calf;
232 for (
int i = 0; i < 3; i++) saf[i] = -saf[i];
258 double x,
y, zbase1, zbase2;
267 x = 0.5 * (fDx2 * zbase1 + fDx1 * zbase2) / fDz -
fgTolerance / 2;
268 if (std::abs(p.
x) <=
x)
270 y = 0.5 * ((fDy2 * zbase1 + fDy1 * zbase2)) / fDz -
fgTolerance / 2;
271 if (std::abs(p.
y) <=
y)
284 y = 0.5 * ((fDy2 * zbase1 + fDy1 * zbase2)) / fDz +
fgTolerance / 2;
285 if (std::abs(p.
y) <=
y)
300 x = 0.5 * (fDx2 * zbase1 + fDx1 * zbase2) / fDz +
fgTolerance / 2;
301 if (std::abs(p.
x) <=
x)
305 y = 0.5 * ((fDy2 * zbase1 + fDy1 * zbase2)) / fDz +
fgTolerance / 2;
326 double snxt = UUtils::kInfinity;
328 double s1, s2, tanxz, tanyz, ds1, ds2;
329 double ss1, ss2, sn1 = 0., sn2 = 0., dist;
340 smin = -(fDz + p.
z) / v.
z;
351 smin = (fDz - p.
z) / v.
z;
355 if (smin < 0) smin = 0 ;
359 if (std::abs(p.
z) >= fDz)
return snxt ;
363 smax = UUtils::kInfinity;
371 tanxz = (fDx2 - fDx1) * 0.5 / fDz ;
372 s1 = 0.5 * (fDx1 + fDx2) + tanxz * p.
z ;
373 ds1 = v.
x - tanxz * v.
z ;
374 ds2 = v.
x + tanxz * v.
z ;
379 if (ss1 < 0 && ss2 <= 0)
385 if (ds2 < 0) sn2 = ss2 / ds2 ;
386 else sn2 = UUtils::kInfinity ;
390 else if (ss1 >= 0 && ss2 > 0)
396 if (ds1 > 0) sn2 = ss1 / ds1 ;
397 else sn2 = UUtils::kInfinity;
402 else if (ss1 >= 0 && ss2 <= 0)
415 else sn2 = UUtils::kInfinity ;
422 if (dist < sn2) sn2 = dist ;
427 else if (ss1 < 0 && ss2 > 0)
431 if (ds1 >= 0 || ds2 <= 0)
439 if (dist > sn1) sn1 = dist ;
440 sn2 = UUtils::kInfinity ;
446 if (sn1 > smin) smin = sn1 ;
447 if (sn2 < smax) smax = sn2 ;
452 if (smax < smin)
return snxt ;
457 tanyz = (fDy2 - fDy1) * 0.5 / fDz ;
458 s2 = 0.5 * (fDy1 + fDy2) + tanyz * p.
z;
459 ds1 = v.
y - tanyz * v.
z;
460 ds2 = v.
y + tanyz * v.
z;
464 if (ss1 < 0 && ss2 <= 0)
469 if (ds2 < 0) sn2 = ss2 / ds2 ;
470 else sn2 = UUtils::kInfinity ;
474 else if (ss1 >= 0 && ss2 > 0)
479 if (ds1 > 0) sn2 = ss1 / ds1 ;
480 else sn2 = UUtils::kInfinity ;
484 else if (ss1 >= 0 && ss2 <= 0)
497 else sn2 = UUtils::kInfinity ;
504 if (dist < sn2) sn2 = dist;
509 else if (ss1 < 0 && ss2 > 0)
513 if (ds1 >= 0 || ds2 <= 0)
521 if (dist > sn1) sn1 = dist ;
522 sn2 = UUtils::kInfinity ;
528 if (sn1 > smin) smin = sn1 ;
529 if (sn2 < smax) smax = sn2 ;
534 if (smax > smin) snxt = smin ;
556 UVector3&
n,
bool& aConvex,
double )
const
558 ESide side = kUndefined, snside = kUndefined;
561 double central, ss1, ss2, ds1, ds2, sn = 0., sn2 = 0.;
562 double tanxz = 0., cosxz = 0., tanyz = 0., cosyz = 0.;
598 snxt = UUtils::kInfinity;
604 tanxz = (fDx2 - fDx1) * 0.5 / fDz;
605 central = 0.5 * (fDx1 + fDx2);
609 ss1 = central + tanxz * p.
z - p.
x;
611 ds1 = v.
x - tanxz * v.
z;
615 ss2 = -tanxz * p.
z - p.
x - central;
617 ds2 = tanxz * v.
z + v.
x;
619 if (ss1 > 0 && ss2 < 0)
622 if (ds1 <= 0 && ds2 < 0)
635 else if (ds1 > 0 && ds2 >= 0)
648 else if (ds1 > 0 && ds2 < 0)
683 sn = UUtils::kInfinity;
686 else if (ss1 <= 0 && ss2 < 0)
709 sn = UUtils::kInfinity;
713 else if (ss1 > 0 && ss2 >= 0)
736 sn = UUtils::kInfinity;
751 tanyz = (fDy2 - fDy1) * 0.5 / fDz;
752 central = 0.5 * (fDy1 + fDy2);
756 ss1 = central + tanyz * p.
z - p.
y;
758 ds1 = v.
y - tanyz * v.
z;
762 ss2 = -tanyz * p.
z - p.
y - central;
764 ds2 = tanyz * v.
z + v.
y;
766 if (ss1 > 0 && ss2 < 0)
770 if (ds1 <= 0 && ds2 < 0)
783 else if (ds1 > 0 && ds2 >= 0)
796 else if (ds1 > 0 && ds2 < 0)
831 sn = UUtils::kInfinity;
834 else if (ss1 <= 0 && ss2 < 0)
857 sn = UUtils::kInfinity;
861 else if (ss1 > 0 && ss2 >= 0)
883 sn = UUtils::kInfinity;
901 cosxz = 1.0 / std::sqrt(1.0 + tanxz * tanxz);
902 n.
Set(cosxz, 0, -tanxz * cosxz);
905 cosxz = -1.0 / std::sqrt(1.0 + tanxz * tanxz);
906 n.
Set(cosxz, 0, tanxz * cosxz);
909 cosyz = 1.0 / std::sqrt(1.0 + tanyz * tanyz);
910 n.
Set(0, cosyz, -tanyz * cosyz);
913 cosyz = -1.0 / std::sqrt(1.0 + tanyz * tanyz);
914 n.
Set(0, cosyz, tanyz * cosyz);
923 UUtils::Exception(
"G4Trd::DistanceToOut(p,v,..)",
"Notification",
Warning, 1,
"Undefined side for valid surface normal to solid.");
936 double z = 2.0 * fDz;
939 double tanx = (fDx2 - fDx1) / z;
940 double secx = std::sqrt(1.0 + tanx * tanx);
941 double newpx = std::abs(p.
x) - p.
z * tanx;
942 double widx = fDx2 - fDz * tanx;
944 double tany = (fDy2 - fDy1) / z;
945 double secy = std::sqrt(1.0 + tany * tany);
946 double newpy = std::abs(p.
y) - p.
z * tany;
947 double widy = fDy2 - fDz * tany;
949 double distx = std::abs(newpx - widx) / secx;
950 double disty = std::abs(newpy - widy) / secy;
951 double distz = std::abs(std::abs(p.
z) - fDz);
955 double fcos = 1.0 / secx;
957 if (p.
x >= 0.) sumnorm.
x +=
fcos;
958 else sumnorm.
x -=
fcos;
959 sumnorm.
z -= tanx *
fcos;
963 double fcos = 1.0 / secy;
965 if (p.
y >= 0.) sumnorm.
y +=
fcos;
966 else sumnorm.
y -=
fcos;
967 sumnorm.
z -= tany *
fcos;
972 sumnorm.
z += (p.
z >= 0.) ? 1.0 : -1.0;
995 norm =
UVector3(fcos, 0, -tanx * fcos);
997 norm =
UVector3(-fcos, 0, -tanx * fcos);
1017 norm =
UVector3(0, fcos, -tany * fcos);
1019 norm =
UVector3(0, -fcos, -tany * fcos);
1038 return noSurfaces > 0;
1050 double z, tanx, secx, newpx, widx;
1051 double tany, secy, newpy, widy;
1052 double distx, disty, distz,
fcos;
1056 tanx = (fDx2 - fDx1) / z;
1057 secx = std::sqrt(1.0 + tanx * tanx);
1058 newpx = std::abs(p.
x) - p.
z * tanx;
1059 widx = fDx2 - fDz * tanx;
1061 tany = (fDy2 - fDy1) / z;
1062 secy = std::sqrt(1.0 + tany * tany);
1063 newpy = std::abs(p.
y) - p.
z * tany;
1064 widy = fDy2 - fDz * tany;
1066 distx = std::abs(newpx - widx) / secx;
1067 disty = std::abs(newpy - widy) / secy;
1068 distz = std::abs(std::abs(p.
z) - fDz);
1081 norm =
UVector3(fcos, 0, -tanx * fcos);
1083 norm =
UVector3(-fcos, 0, -tanx * fcos);
1103 norm =
UVector3(0, fcos, -tany * fcos);
1105 norm =
UVector3(0, -fcos, -tany * fcos);
1139 int oldprc = os.precision(16);
1140 os <<
"-----------------------------------------------------------\n"
1141 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1142 <<
" ===================================================\n"
1143 <<
" Solid type: UTrd\n"
1144 <<
" Parameters: \n"
1145 <<
" half length X, surface -dZ: " << fDx1 <<
" mm \n"
1146 <<
" half length X, surface +dZ: " << fDx2 <<
" mm \n"
1147 <<
" half length Y, surface -dZ: " << fDy1 <<
" mm \n"
1148 <<
" half length Y, surface +dZ: " << fDy2 <<
" mm \n"
1149 <<
" half length Z : " << fDz <<
" mm \n"
1150 <<
"-----------------------------------------------------------\n";
1151 os.precision(oldprc);
1165 double px, py, pz, tgX, tgY, secX, secY, select, sumS,
tmp;
1166 double Sxy1, Sxy2, Sxy, Sxz, Syz;
1168 tgX = 0.5 * (fDx2 - fDx1) / fDz;
1169 secX = std::sqrt(1 + tgX * tgX);
1170 tgY = 0.5 * (fDy2 - fDy1) / fDz;
1171 secY = std::sqrt(1 + tgY * tgY);
1178 Sxz = (fDx1 + fDx2) * fDz * secY;
1179 Syz = (fDy1 + fDy2) * fDz * secX;
1180 sumS = Sxy + Sxz + Syz;
1199 else if ((select - Sxy) < Sxz)
1202 tmp = fDx1 + (pz + fDz) * tgX;
1204 tmp = fDy1 + (pz + fDz) * tgY;
1206 if (UUtils::Random() > 0.5)
1218 tmp = fDy1 + (pz + fDz) * tgY;
1220 tmp = fDx1 + (pz + fDz) * tgX;
1222 if (UUtils::Random() > 0.5)
1239 :
VUSolid(rhs), fDx1(rhs.fDx1), fDx2(rhs.fDx2),
1240 fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz),
1241 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea)
1266 fCubicVolume = rhs.fCubicVolume;
1267 fSurfaceArea = rhs.fSurfaceArea;
virtual double SafetyFromInside(const UVector3 &aPoint, bool aAccurate=false) const
double GetZHalfLength() const
virtual bool Normal(const UVector3 &aPoint, UVector3 &aNormal) const
const std::string & GetName() const
double SafetyFromOutsideAccurate(const UVector3 &aPoint) const
static double fgTolerance
UVector3 GetPointOnSurface() const
double GetXHalfLength2() const
virtual void GetParametersList(int, double *) const
G4double fcos(G4double arg)
double SafetyFromInsideAccurate(const UVector3 &aPoint) const
void CheckAndSetAllParameters(double pdx1, double pdx2, double pdy1, double pdy2, double pdz)
double GetYHalfLength2() const
void SetAllParameters(double pdx1, double pdx2, double pdy1, double pdy2, double pdz)
double GetYHalfLength1() const
EnumInside Inside(const UVector3 &aPoint) const
void Set(double xx, double yy, double zz)
void Extent(UVector3 &aMin, UVector3 &aMax) const
UTrd & operator=(const UTrd &rhs)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
double GetXHalfLength1() const
std::string UGeometryType
UGeometryType GetEntityType() const
virtual double DistanceToOut(const UVector3 &aPoint, const UVector3 &aDirection, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
std::ostream & StreamInfo(std::ostream &os) const
virtual double SafetyFromOutside(const UVector3 &aPoint, bool aAccurate=false) const
double Random(double min=0.0, double max=1.0)
virtual double DistanceToIn(const UVector3 &aPoint, const UVector3 &aDirection, double aPstep=UUtils::kInfinity) const