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();
278 std::ostringstream message;
279 message <<
"Face at ~-X not planar for Solid: " <<
GetName();
289 std::ostringstream message;
290 message <<
"Face at ~+X not planar for Solid: " <<
GetName();
303 double pDx,
double pDy,
306 double pTheta,
double pPhi)
311 if (pDz <= 0 || pDy <= 0 || pDx <= 0)
313 std::ostringstream message;
314 message <<
"Invalid length parameters for Solid: " <<
GetName();
357 std::ostringstream message;
358 message <<
"Face at ~-Y not planar for Solid: " <<
GetName();
368 std::ostringstream message;
369 message <<
"Face at ~+Y not planar for Solid: " <<
GetName();
379 std::ostringstream message;
380 message <<
"Face at ~-X not planar for Solid: " <<
GetName();
390 std::ostringstream message;
391 message <<
"Face at ~+X not planar for Solid: " <<
GetName();
406 :
VUSolid(pName), fDz(1.), fTthetaCphi(0.), fTthetaSphi(0.),
407 fDy1(1.), fDx1(1.), fDx2(1.), fTalpha1(0.),
408 fDy2(1.), fDx3(1.), fDx4(1.), fTalpha2(0.)
430 fTthetaCphi(rhs.fTthetaCphi), fTthetaSphi(rhs.fTthetaSphi),
431 fDy1(rhs.fDy1), fDx1(rhs.fDx1), fDx2(rhs.fDx2), fTalpha1(rhs.fTalpha1),
432 fDy2(rhs.fDy2), fDx3(rhs.fDx3), fDx4(rhs.fDx4), fTalpha2(rhs.fTalpha2)
434 for (
size_t i = 0; i < 4; ++i)
460 VUSolid::operator=(rhs);
475 for (
size_t i = 0; i < 4; ++i)
504 if (pDz <= 0 || pDy1 <= 0 || pDx1 <= 0 || pDx2 <= 0 || pDy2 <= 0 || pDx3 <= 0 || pDx4 <= 0)
506 std::ostringstream message;
507 message <<
"Invalid Length Parameters for Solid: " <<
GetName() << std::endl
509 << pDx1 <<
", " << pDx2 <<
", " << pDx3 <<
", " << pDx4 << std::endl
510 <<
" Y - " << pDy1 <<
", " << pDy2 << std::endl
542 && pt[0].
z() == pt[1].
z() && pt[0].
z() == pt[2].
z()
543 && pt[0].
z() == pt[3].
z()
545 && pt[4].
z() == pt[5].
z() && pt[4].
z() == pt[6].
z()
546 && pt[4].
z() == pt[7].
z()
548 && pt[0].y() == pt[1].y() && pt[2].y() == pt[3].y()
549 && pt[4].y() == pt[5].y() && pt[6].y() == pt[7].y()
551 && std::fabs(pt[0].x() + pt[1].x() + pt[4].x() + pt[5].x() +
554 std::ostringstream message;
555 message <<
"Invalid vertice coordinates for Solid: " <<
GetName();
568 "Face at ~-Y not planar.");
577 std::ostringstream message;
578 message <<
"Face at ~+Y not planar for Solid: " <<
GetName();
589 std::ostringstream message;
590 message <<
"Face at ~-X not planar for Solid: " <<
GetName();
600 std::ostringstream message;
601 message <<
"Face at ~+X not planar for Solid: " <<
GetName();
607 fDy1 = ((pt[2]).y() - (pt[1]).y()) * 0.5;
608 fDx1 = ((pt[1]).x() - (pt[0]).x()) * 0.5;
609 fDx2 = ((pt[3]).x() - (pt[2]).x()) * 0.5;
610 fTalpha1 = ((pt[2]).x() + (pt[3]).x() - (pt[1]).x() - (pt[0]).x()) * 0.25 /
fDy1;
612 fDy2 = ((pt[6]).y() - (pt[5]).y()) * 0.5;
613 fDx3 = ((pt[5]).x() - (pt[4]).x()) * 0.5;
614 fDx4 = ((pt[7]).x() - (pt[6]).x()) * 0.5;
615 fTalpha2 = ((pt[6]).x() + (pt[7]).x() - (pt[5]).x() - (pt[4]).x()) * 0.25 /
fDy2;
653 std::ostringstream message;
654 message <<
"Face at ~-Y not planar for Solid: " <<
GetName();
664 std::ostringstream message;
665 message <<
"Face at ~+Y not planar for Solid: " <<
GetName();
675 std::ostringstream message;
676 message <<
"Face at ~-X not planar for Solid: " <<
GetName();
686 std::ostringstream message;
687 message <<
"Face at ~+X not planar for Solid: " <<
GetName();
718 Vcross = v12.
Cross(v13);
740 a = +(p4.
y() - p2.
y()) * (p3.
z() - p1.z())
741 - (p3.
y() - p1.y()) * (p4.
z() - p2.
z());
743 b = -(p4.
x() - p2.
x()) * (p3.
z() - p1.z())
744 + (p3.
x() - p1.x()) * (p4.
z() - p2.
z());
746 c = +(p4.
x() - p2.
x()) * (p3.
y() - p1.y())
747 - (p3.
x() - p1.x()) * (p4.
y() - p2.
y());
749 sd = std::sqrt(a * a + b * b + c * c);
759 std::ostringstream message;
760 message <<
"Invalid parameters: norm.mod() <= 0, for Solid: "
767 plane.
d = -(plane.
a * p1.x() + plane.
b * p1.y() + plane.
c * p1.z());
790 for (i = 0; i < 4; i++)
804 for (i = 0; i < 4; i++)
824 int i, noSurfaces = 0;
829 for (i = 0; i < 4; i++)
838 distz = std::fabs(std::fabs(p.
z()) -
fDz);
881 if (p.
z() >= 0.) sumnorm += nZ;
888 UWarning, 1,
"Point p is not on surface !?");
892 else if (noSurfaces == 1) norm = sumnorm;
893 else norm = sumnorm.
Unit();
895 return noSurfaces != 0;
907 for (i = 0; i < 4; i++)
917 safez = std::fabs(std::fabs(p.
z()) -
fDz);
950 double pdist, Comp, vdist;
961 smin = (-
fDz - p.
z()) / v.
z();
970 max = -
fDz - p.
z() ;
974 smin = (
fDz - p.
z()) / v.
z();
994 for (i = 0; i < 4; i++)
1010 vdist = -pdist / Comp;
1031 vdist = -pdist / Comp;
1068 double safe = 0.0, Dist;
1070 safe = std::fabs(p.
z()) -
fDz;
1071 for (i = 0; i < 4; i++)
1075 if (Dist > safe) safe = Dist;
1077 if (safe < 0) safe = 0;
1090 double pdist, Comp, vdist,
max;
1120 aNormalVector =
UVector3(0, 0, -1);
1151 vdist = -pdist / Comp;
1192 vdist = -pdist / Comp;
1233 vdist = -pdist / Comp;
1274 vdist = -pdist / Comp;
1310 aNormalVector =
UVector3(0, 0, -1);
1318 std::ostringstream message;
1319 int oldprc = message.precision(16);
1320 message <<
"Undefined side for valid surface normal to solid."
1322 <<
"Position:" << std::endl << std::endl
1323 <<
"p.x = " << p.
x() <<
" mm" << std::endl
1324 <<
"p.y = " << p.
y() <<
" mm" << std::endl
1325 <<
"p.z = " << p.
z() <<
" mm" << std::endl << std::endl
1326 <<
"Direction:" << std::endl << std::endl
1327 <<
"v.x = " << v.
x() << std::endl
1328 <<
"v.y = " << v.
y() << std::endl
1329 <<
"v.z = " << v.
z() << std::endl << std::endl
1330 <<
"Proposed distance :" << std::endl << std::endl
1331 <<
"snxt = " << snxt <<
" mm" << std::endl;
1332 message.precision(oldprc);
1334 UWarning, 1, message.str().c_str());
1347 double safe = 0.0, Dist;
1353 int oldprc = cout.precision(16) ;
1356 cout <<
"Position:" << std::endl << std::endl ;
1357 cout <<
"p.x = " << p.
x() <<
" mm" << std::endl ;
1358 cout <<
"p.y = " << p.
y() <<
" mm" << std::endl ;
1359 cout <<
"p.z = " << p.
z() <<
" mm" << std::endl << std::endl ;
1360 cout.precision(oldprc) ;
1362 "GeomSolids1002",
UWarning, 1,
"Point p is outside !?");
1366 safe =
fDz - std::fabs(p.
z());
1367 if (safe < 0) safe = 0;
1370 for (i = 0; i < 4; i++)
1374 if (Dist < safe) safe = Dist;
1376 if (safe < 0) safe = 0;
1388 return std::string(
"Trap");
1397 return new UTrap(*
this);
1406 int oldprc = os.precision(16);
1407 os <<
"-----------------------------------------------------------\n"
1408 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1409 <<
" ===================================================\n"
1410 <<
" Solid type: UTrap\n"
1411 <<
" Parameters: \n"
1412 <<
" half length Z: " <<
fDz <<
" mm \n"
1413 <<
" half length Y of face -fDz: " <<
fDy1 <<
" mm \n"
1414 <<
" half length X of side -fDy1, face -fDz: " <<
fDx1 <<
" mm \n"
1415 <<
" half length X of side +fDy1, face -fDz: " <<
fDx2 <<
" mm \n"
1416 <<
" half length Y of face +fDz: " <<
fDy2 <<
" mm \n"
1417 <<
" half length X of side -fDy2, face +fDz: " <<
fDx3 <<
" mm \n"
1418 <<
" half length X of side +fDy2, face +fDz: " <<
fDx4 <<
" mm \n"
1423 <<
" trap side plane equations:\n"
1432 <<
"-----------------------------------------------------------\n";
1433 os.precision(oldprc);
1448 double lambda1, lambda2, chose, aOne, aTwo;
1457 w.
z() * v.
x() - w.
x() * v.
z(),
1458 w.
x() * v.
y() - w.
y() * v.
x());
1460 aOne = 0.5 * Area.
Mag();
1463 t.
z() * u.
x() - t.
x() * u.
z(),
1464 t.
x() * u.
y() - t.
y() * u.
x());
1466 aTwo = 0.5 * Area.
Mag();
1472 if ((chose >= 0.) && (chose < aOne))
1476 return (p2 + lambda1 * v + lambda2 * w);
1484 return (p0 + lambda1 * t + lambda2 * u);
1493 double aOne, aTwo, aThree, aFour, aFive, aSix, chose;
1494 UVector3 One, Two, Three, Four, Five, Six, test;
1523 chose =
UUtils::Random(0., aOne + aTwo + aThree + aFour + aFive + aSix);
1524 if ((chose >= 0.) && (chose < aOne))
1528 else if ((chose >= aOne) && (chose < aOne + aTwo))
1532 else if ((chose >= aOne + aTwo) && (chose < aOne + aTwo + aThree))
1536 else if ((chose >= aOne + aTwo + aThree) && (chose < aOne + aTwo + aThree + aFour))
1540 else if ((chose >= aOne + aTwo + aThree + aFour)
1541 && (chose < aOne + aTwo + aThree + aFour + aFive))
1575 temp[0] = pt[0].
x()+(pt[4].
x()-pt[0].
x())
1576 *(aMin.
z()-pt[0].
z())/(pt[4].
z()-pt[0].
z()) ;
1577 temp[1] = pt[0].
x()+(pt[4].
x()-pt[0].
x())
1578 *(aMax.
z()-pt[0].
z())/(pt[4].
z()-pt[0].
z()) ;
1579 temp[2] = pt[2].
x()+(pt[6].
x()-pt[2].
x())
1580 *(aMin.
z()-pt[2].
z())/(pt[6].
z()-pt[2].
z()) ;
1581 temp[3] = pt[2].
x()+(pt[6].
x()-pt[2].
x())
1582 *(aMax.
z()-pt[2].
z())/(pt[6].
z()-pt[2].
z()) ;
1583 temp[4] = pt[3].
x()+(pt[7].
x()-pt[3].
x())
1584 *(aMin.
z()-pt[3].
z())/(pt[7].
z()-pt[3].
z()) ;
1585 temp[5] = pt[3].
x()+(pt[7].
x()-pt[3].
x())
1586 *(aMax.
z()-pt[3].
z())/(pt[7].
z()-pt[3].
z()) ;
1587 temp[6] = pt[1].
x()+(pt[5].
x()-pt[1].
x())
1588 *(aMin.
z()-pt[1].
z())/(pt[5].
z()-pt[1].
z()) ;
1589 temp[7] = pt[1].
x()+(pt[5].
x()-pt[1].
x())
1590 *(aMax.
z()-pt[1].
z())/(pt[5].
z()-pt[1].
z()) ;
1593 aMin.
x() = -aMax.
x() ;
1595 for(
int i = 0 ; i < 8 ; i++ )
1597 if( temp[i] > aMax.
x()) aMax.
x() = temp[i] ;
1598 if( temp[i] < aMin.
x()) aMin.
x() = temp[i] ;
1601 temp[0] = pt[0].
y()+(pt[4].
y()-pt[0].
y())*(aMin.
z()-pt[0].
z())
1602 /(pt[4].
z()-pt[0].
z()) ;
1603 temp[1] = pt[0].
y()+(pt[4].
y()-pt[0].
y())*(aMax.
z()-pt[0].
z())
1604 /(pt[4].
z()-pt[0].
z()) ;
1605 temp[2] = pt[2].
y()+(pt[6].
y()-pt[2].
y())*(aMin.
z()-pt[2].
z())
1606 /(pt[6].
z()-pt[2].
z()) ;
1607 temp[3] = pt[2].
y()+(pt[6].
y()-pt[2].
y())*(aMax.
z()-pt[2].
z())
1608 /(pt[6].
z()-pt[2].
z()) ;
1611 aMin.
y() = -aMax.
y() ;
1613 for(
int i = 0 ; i < 4 ; i++ )
1615 if( temp[i] > aMax.
y() ) aMax.
y() = temp[i] ;
1616 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 Exception(const char *originOfException, const char *exceptionCode, UExceptionSeverity severity, int level, const char *description)
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
double Random(double min=0.0, double max=1.0)