44 double pTheta,
double pPhi,
45 double pDy1,
double pDx1,
double pDx2,
47 double pDy2,
double pDx3,
double pDx4,
51 if (pDz <= 0 || pDy1 <= 0 || pDx1 <= 0 ||
52 pDx2 <= 0 || pDy2 <= 0 || pDx3 <= 0 || pDx4 <= 0)
54 std::ostringstream message;
55 message <<
"Invalid length parameters for Solid: " <<
GetName() << std::endl
57 << pDx1 <<
", " << pDx2 <<
", " << pDx3 <<
", " << pDx4 << std::endl
58 <<
" Y - " << pDy1 <<
", " << pDy2 << std::endl
105 double pX,
double pLTX)
110 if (pZ <= 0 || pY <= 0 || pX <= 0 || pLTX <= 0 || pLTX > pX)
112 std::ostringstream message;
113 message <<
"Invalid length parameters for Solid: " <<
GetName();
156 std::ostringstream message;
157 message <<
"Face at ~-Y not planar for Solid: " <<
GetName();
167 std::ostringstream message;
168 message <<
"Face at ~+Y not planar for Solid: " <<
GetName();
178 std::ostringstream message;
179 message <<
"Face at ~-X not planar for Solid: " <<
GetName();
189 std::ostringstream message;
190 message <<
"Face at ~+X not planar for Solid: " <<
GetName();
203 double pDx1,
double pDx2,
204 double pDy1,
double pDy2,
210 if (pDz <= 0 || pDy1 <= 0 || pDx1 <= 0 || pDx2 <= 0 || pDy2 <= 0)
212 std::ostringstream message;
213 message <<
"Invalid length parameters for Solid: " <<
GetName();
256 std::ostringstream message;
257 message <<
"Face at ~-Y not planar for Solid: " <<
GetName();
267 std::ostringstream message;
268 message <<
"Face at ~+Y not planar for Solid: " <<
GetName();
277 std::ostringstream message;
278 message <<
"Face at ~-X not planar for Solid: " <<
GetName();
288 std::ostringstream message;
289 message <<
"Face at ~+X not planar for Solid: " <<
GetName();
302 double pDx,
double pDy,
305 double pTheta,
double pPhi)
310 if (pDz <= 0 || pDy <= 0 || pDx <= 0)
312 std::ostringstream message;
313 message <<
"Invalid length parameters for Solid: " <<
GetName();
356 std::ostringstream message;
357 message <<
"Face at ~-Y not planar for Solid: " <<
GetName();
367 std::ostringstream message;
368 message <<
"Face at ~+Y not planar for Solid: " <<
GetName();
378 std::ostringstream message;
379 message <<
"Face at ~-X not planar for Solid: " <<
GetName();
389 std::ostringstream message;
390 message <<
"Face at ~+X not planar for Solid: " <<
GetName();
405 :
VUSolid(pName), fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.),
406 fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.),
407 fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.)
429 fTthetaCphi(rhs.fTthetaCphi), fTthetaSphi(rhs.fTthetaSphi),
430 fDy1(rhs.fDy1), fDx1(rhs.fDx1), fDx2(rhs.fDx2), fTalpha1(rhs.fTalpha1),
431 fDy2(rhs.fDy2), fDx3(rhs.fDx3), fDx4(rhs.fDx4), fTalpha2(rhs.fTalpha2)
433 for (
size_t i = 0; i < 4; ++i)
459 VUSolid::operator=(rhs);
474 for (
size_t i = 0; i < 4; ++i)
503 if (pDz <= 0 || pDy1 <= 0 || pDx1 <= 0 || pDx2 <= 0 || pDy2 <= 0 || pDx3 <= 0 || pDx4 <= 0)
505 std::ostringstream message;
506 message <<
"Invalid Length Parameters for Solid: " <<
GetName() << std::endl
508 << pDx1 <<
", " << pDx2 <<
", " << pDx3 <<
", " << pDx4 << std::endl
509 <<
" Y - " << pDy1 <<
", " << pDy2 << std::endl
541 && pt[0].
z == pt[1].
z && pt[0].
z == pt[2].
z
542 && pt[0].
z == pt[3].
z
544 && pt[4].
z == pt[5].
z && pt[4].
z == pt[6].
z
545 && pt[4].
z == pt[7].
z
547 && pt[0].y == pt[1].y && pt[2].y == pt[3].y
548 && pt[4].y == pt[5].y && pt[6].y == pt[7].y
550 && std::fabs(pt[0].x + pt[1].x + pt[4].x + pt[5].x +
553 std::ostringstream message;
554 message <<
"Invalid vertice coordinates for Solid: " <<
GetName();
567 "Face at ~-Y not planar.");
576 std::ostringstream message;
577 message <<
"Face at ~+Y not planar for Solid: " <<
GetName();
588 std::ostringstream message;
589 message <<
"Face at ~-X not planar for Solid: " <<
GetName();
598 std::ostringstream message;
599 message <<
"Face at ~+X not planar for Solid: " <<
GetName();
605 fDy1 = ((pt[2]).y - (pt[1]).y) * 0.5;
606 fDx1 = ((pt[1]).x - (pt[0]).x) * 0.5;
607 fDx2 = ((pt[3]).x - (pt[2]).x) * 0.5;
608 fTalpha1 = ((pt[2]).x + (pt[3]).x - (pt[1]).x - (pt[0]).x) * 0.25 /
fDy1;
610 fDy2 = ((pt[6]).y - (pt[5]).y) * 0.5;
611 fDx3 = ((pt[5]).x - (pt[4]).x) * 0.5;
612 fDx4 = ((pt[7]).x - (pt[6]).x) * 0.5;
613 fTalpha2 = ((pt[6]).x + (pt[7]).x - (pt[5]).x - (pt[4]).x) * 0.25 /
fDy2;
651 std::ostringstream message;
652 message <<
"Face at ~-Y not planar for Solid: " <<
GetName();
662 std::ostringstream message;
663 message <<
"Face at ~+Y not planar for Solid: " <<
GetName();
673 std::ostringstream message;
674 message <<
"Face at ~-X not planar for Solid: " <<
GetName();
684 std::ostringstream message;
685 message <<
"Face at ~+X not planar for Solid: " <<
GetName();
716 Vcross = v12.
Cross(v13);
738 a = +(p4.
y - p2.
y) * (p3.
z - p1.z)
739 - (p3.
y - p1.y) * (p4.
z - p2.
z);
741 b = -(p4.
x - p2.
x) * (p3.
z - p1.z)
742 + (p3.
x - p1.x) * (p4.
z - p2.
z);
744 c = +(p4.
x - p2.
x) * (p3.
y - p1.y)
745 - (p3.
x - p1.x) * (p4.
y - p2.
y);
747 sd = std::sqrt(a * a + b * b + c * c);
757 std::ostringstream message;
758 message <<
"Invalid parameters: norm.mod() <= 0, for Solid: "
765 plane.
d = -(plane.
a * p1.x + plane.
b * p1.y + plane.
c * p1.z);
788 for (i = 0; i < 4; i++)
802 for (i = 0; i < 4; i++)
822 int i, noSurfaces = 0;
827 for (i = 0; i < 4; i++)
836 distz = std::fabs(std::fabs(p.
z) -
fDz);
879 if (p.
z >= 0.) sumnorm += nZ;
886 Warning, 1,
"Point p is not on surface !?");
890 else if (noSurfaces == 1) norm = sumnorm;
891 else norm = sumnorm.
Unit();
893 return noSurfaces != 0;
905 for (i = 0; i < 4; i++)
915 safez = std::fabs(std::fabs(p.
z) -
fDz);
948 double pdist, Comp, vdist;
959 smin = (-
fDz - p.
z) / v.
z;
972 smin = (
fDz - p.
z) / v.
z;
992 for (i = 0; i < 4; i++)
1008 vdist = -pdist / Comp;
1029 vdist = -pdist / Comp;
1066 double safe = 0.0, Dist;
1068 safe = std::fabs(p.
z) -
fDz;
1069 for (i = 0; i < 4; i++)
1073 if (Dist > safe) safe = Dist;
1075 if (safe < 0) safe = 0;
1088 double pdist, Comp, vdist,
max;
1118 aNormalVector =
UVector3(0, 0, -1);
1149 vdist = -pdist / Comp;
1190 vdist = -pdist / Comp;
1231 vdist = -pdist / Comp;
1272 vdist = -pdist / Comp;
1308 aNormalVector =
UVector3(0, 0, -1);
1316 std::ostringstream message;
1317 int oldprc = message.precision(16);
1318 message <<
"Undefined side for valid surface normal to solid."
1320 <<
"Position:" << std::endl << std::endl
1321 <<
"p.x = " << p.
x <<
" mm" << std::endl
1322 <<
"p.y = " << p.
y <<
" mm" << std::endl
1323 <<
"p.z = " << p.
z <<
" mm" << std::endl << std::endl
1324 <<
"Direction:" << std::endl << std::endl
1325 <<
"v.x = " << v.
x << std::endl
1326 <<
"v.y = " << v.
y << std::endl
1327 <<
"v.z = " << v.
z << std::endl << std::endl
1328 <<
"Proposed distance :" << std::endl << std::endl
1329 <<
"snxt = " << snxt <<
" mm" << std::endl;
1330 message.precision(oldprc);
1332 Warning, 1, message.str().c_str());
1345 double safe = 0.0, Dist;
1351 int oldprc = cout.precision(16) ;
1354 cout <<
"Position:" << std::endl << std::endl ;
1355 cout <<
"p.x = " << p.
x <<
" mm" << std::endl ;
1356 cout <<
"p.y = " << p.
y <<
" mm" << std::endl ;
1357 cout <<
"p.z = " << p.
z <<
" mm" << std::endl << std::endl ;
1358 cout.precision(oldprc) ;
1360 "GeomSolids1002",
Warning, 1,
"Point p is outside !?");
1364 safe =
fDz - std::fabs(p.
z);
1365 if (safe < 0) safe = 0;
1368 for (i = 0; i < 4; i++)
1372 if (Dist < safe) safe = Dist;
1374 if (safe < 0) safe = 0;
1386 return std::string(
"UTrap");
1395 return new UTrap(*
this);
1404 int oldprc = os.precision(16);
1405 os <<
"-----------------------------------------------------------\n"
1406 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1407 <<
" ===================================================\n"
1408 <<
" Solid type: UTrap\n"
1409 <<
" Parameters: \n"
1410 <<
" half length Z: " <<
fDz <<
" mm \n"
1411 <<
" half length Y of face -fDz: " <<
fDy1 <<
" mm \n"
1412 <<
" half length X of side -fDy1, face -fDz: " <<
fDx1 <<
" mm \n"
1413 <<
" half length X of side +fDy1, face -fDz: " <<
fDx2 <<
" mm \n"
1414 <<
" half length Y of face +fDz: " <<
fDy2 <<
" mm \n"
1415 <<
" half length X of side -fDy2, face +fDz: " <<
fDx3 <<
" mm \n"
1416 <<
" half length X of side +fDy2, face +fDz: " <<
fDx4 <<
" mm \n"
1421 <<
" trap side plane equations:\n"
1430 <<
"-----------------------------------------------------------\n";
1431 os.precision(oldprc);
1446 double lambda1, lambda2, chose, aOne, aTwo;
1455 w.
z * v.
x - w.
x * v.
z,
1456 w.
x * v.
y - w.
y * v.
x);
1458 aOne = 0.5 * Area.
Mag();
1461 t.
z * u.
x - t.
x * u.
z,
1462 t.
x * u.
y - t.
y * u.
x);
1464 aTwo = 0.5 * Area.
Mag();
1470 if ((chose >= 0.) && (chose < aOne))
1474 return (p2 + lambda1 * v + lambda2 * w);
1482 return (p0 + lambda1 * t + lambda2 * u);
1491 double aOne, aTwo, aThree, aFour, aFive, aSix, chose;
1492 UVector3 One, Two, Three, Four, Five, Six, test;
1521 chose =
UUtils::Random(0., aOne + aTwo + aThree + aFour + aFive + aSix);
1522 if ((chose >= 0.) && (chose < aOne))
1526 else if ((chose >= aOne) && (chose < aOne + aTwo))
1530 else if ((chose >= aOne + aTwo) && (chose < aOne + aTwo + aThree))
1534 else if ((chose >= aOne + aTwo + aThree) && (chose < aOne + aTwo + aThree + aFour))
1538 else if ((chose >= aOne + aTwo + aThree + aFour)
1539 && (chose < aOne + aTwo + aThree + aFour + aFive))
1573 temp[0] = pt[0].
x+(pt[4].
x-pt[0].
x)
1574 *(aMin.
z-pt[0].
z)/(pt[4].
z-pt[0].
z) ;
1575 temp[1] = pt[0].
x+(pt[4].
x-pt[0].
x)
1576 *(aMax.
z-pt[0].
z)/(pt[4].
z-pt[0].
z) ;
1577 temp[2] = pt[2].
x+(pt[6].
x-pt[2].
x)
1578 *(aMin.
z-pt[2].
z)/(pt[6].
z-pt[2].
z) ;
1579 temp[3] = pt[2].
x+(pt[6].
x-pt[2].
x)
1580 *(aMax.
z-pt[2].
z)/(pt[6].
z-pt[2].
z) ;
1581 temp[4] = pt[3].
x+(pt[7].
x-pt[3].
x)
1582 *(aMin.
z-pt[3].
z)/(pt[7].
z-pt[3].
z) ;
1583 temp[5] = pt[3].
x+(pt[7].
x-pt[3].
x)
1584 *(aMax.
z-pt[3].
z)/(pt[7].
z-pt[3].
z) ;
1585 temp[6] = pt[1].
x+(pt[5].
x-pt[1].
x)
1586 *(aMin.
z-pt[1].
z)/(pt[5].
z-pt[1].
z) ;
1587 temp[7] = pt[1].
x+(pt[5].
x-pt[1].
x)
1588 *(aMax.
z-pt[1].
z)/(pt[5].
z-pt[1].
z) ;
1593 for(
int i = 0 ; i < 8 ; i++ )
1595 if( temp[i] > aMax.
x) aMax.
x = temp[i] ;
1596 if( temp[i] < aMin.
x) aMin.
x = temp[i] ;
1599 temp[0] = pt[0].
y+(pt[4].
y-pt[0].
y)*(aMin.
z-pt[0].
z)
1600 /(pt[4].
z-pt[0].
z) ;
1601 temp[1] = pt[0].
y+(pt[4].
y-pt[0].
y)*(aMax.
z-pt[0].
z)
1602 /(pt[4].
z-pt[0].
z) ;
1603 temp[2] = pt[2].
y+(pt[6].
y-pt[2].
y)*(aMin.
z-pt[2].
z)
1604 /(pt[6].
z-pt[2].
z) ;
1605 temp[3] = pt[2].
y+(pt[6].
y-pt[2].
y)*(aMax.
z-pt[2].
z)
1606 /(pt[6].
z-pt[2].
z) ;
1611 for(
int i = 0 ; i < 4 ; i++ )
1613 if( temp[i] > aMax.
y ) aMax.
y = temp[i] ;
1614 if( temp[i] < aMin.
y ) aMin.
y = temp[i] ;
bool MakePlane(const UVector3 &p1, const UVector3 &p2, const UVector3 &p3, const UVector3 &p4, UTrapSidePlane &plane)
std::ostream & StreamInfo(std::ostream &os) const
UVector3 GetPointOnPlane(UVector3 p0, UVector3 p1, UVector3 p2, UVector3 p3, double &area) const
void SetAllParameters(double pDz, double pTheta, double pPhi, double pDy1, double pDx1, double pDx2, double pAlp1, double pDy2, double pDx3, double pDx4, double pAlp2)
bool Normal(const UVector3 &aPoint, UVector3 &aNormal) const
double SafetyFromOutside(const UVector3 &p, bool precise=false) const
const std::string & GetName() const
UVector3 Cross(const UVector3 &) const
UVector3 ApproxSurfaceNormal(const UVector3 &p) const
static double Tolerance()
static double normal(HepRandomEngine *eptr)
UTrap & operator=(const UTrap &rhs)
static const double kInfinity
const double kCoplanar_Tolerance
UGeometryType GetEntityType() const
double Dot(const UVector3 &) const
UTrapSidePlane fPlanes[4]
UTrap(const std::string &pName, double pDz, double pTheta, double pPhi, double pDy1, double pDx1, double pDx2, double pAlp1, double pDy2, double pDx3, double pDx4, double pAlp2)
virtual void Extent(UVector3 &aMin, UVector3 &aMax) const
double SafetyFromInside(const UVector3 &p, bool precise=false) const
void SetPlanes(const UVector3 pt[8])
UVector3 GetPointOnSurface() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
VUSolid::EnumInside Inside(const UVector3 &p) const
std::string UGeometryType
double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const
double DistanceToOut(const UVector3 &p, const UVector3 &v, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
double Random(double min=0.0, double max=1.0)