54 const double zPlane[],
55 const double rInner[],
56 const double rOuter[])
59 Init(phiStart, thePhiTotal, thefNumSide, numZPlanes, zPlane, rInner, rOuter);
72 const double zPlane[],
73 const double rInner[],
74 const double rOuter[])
80 std::ostringstream message;
81 message <<
"Solid must have at least one side - " <<
GetName() << std::endl
82 <<
" No sides specified !";
90 double phiTotal = thePhiTotal;
95 double convertRad = std::cos(0.5 * phiTotal / thefNumSide);
111 for (i = 0; i < numZPlanes; i++)
113 if ((i < numZPlanes - 1) && (zPlane[i] == zPlane[i + 1]))
115 if ((rInner[i] > rOuter[i + 1])
116 || (rInner[i + 1] > rOuter[i]))
119 std::ostringstream message;
120 message <<
"Cannot create a Polyhedra with no contiguous segments."
122 <<
" Segments are not contiguous !" << std::endl
123 <<
" rMin[" << i <<
"] = " << rInner[i]
124 <<
" -- rMax[" << i + 1 <<
"] = " << rOuter[i + 1] << std::endl
125 <<
" rMin[" << i + 1 <<
"] = " << rInner[i + 1]
126 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
142 rz->
ScaleA(1 / convertRad);
147 Create(phiStart, phiTotal, thefNumSide, rz);
167 Create(phiStart, phiTotal, thefNumSide, rz);
191 if (rz->
Amin() < 0.0)
193 std::ostringstream message;
194 message <<
"Illegal input parameters - " <<
GetName() << std::endl
195 <<
" All R values must be >= 0 !";
200 double rzArea = rz->
Area();
206 std::ostringstream message;
207 message <<
"Illegal input parameters - " <<
GetName() << std::endl
208 <<
" R/Z Cross section is zero or near zero: " << rzArea;
216 std::ostringstream message;
217 message <<
"Illegal input parameters - " <<
GetName() << std::endl
218 <<
" Too few unique R/Z values !";
225 std::ostringstream message;
226 message <<
"Illegal input parameters - " <<
GetName() << std::endl
227 <<
" R/Z segments Cross !";
275 next->
r = iterRZ.
GetA();
276 next->
z = iterRZ.
GetB();
278 while (++next, iterRZ.
Next());
332 while (prev = corner, corner = next, corner >
fCorners);
406 if (
this == &source)
return *
this;
468 std::ostringstream message;
469 message <<
"Solid " <<
GetName() <<
" built using generic construct."
470 << std::endl <<
"Not applicable to the generic construct !";
472 UWarning, 1, message.str().c_str());
534 return std::string(
"Polyhedra");
552 int oldprc = os.precision(16);
553 os <<
"-----------------------------------------------------------\n"
554 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
555 <<
" ===================================================\n"
556 <<
" Solid type: UPolyhedra\n"
564 os <<
" number of Z planes: " << numPlanes <<
"\n"
566 for (i = 0; i < numPlanes; i++)
568 os <<
" Z plane " << i <<
": "
571 os <<
" Tangent distances to inner surface (Rmin): \n";
572 for (i = 0; i < numPlanes; i++)
574 os <<
" Z plane " << i <<
": "
577 os <<
" Tangent distances to outer surface (Rmax): \n";
578 for (i = 0; i < numPlanes; i++)
580 os <<
" Z plane " << i <<
": "
584 os <<
" number of RZ points: " <<
fNumCorner <<
"\n"
585 <<
" RZ values (fCorners): \n";
591 os <<
"-----------------------------------------------------------\n";
592 os.precision(oldprc);
606 double lambda1, lambda2, chose, aOne, aTwo;
617 if ((chose >= 0.) && (chose < aOne))
621 return (p2 + lambda1 * v + lambda2 * w);
626 return (p0 + lambda1 * t + lambda2 * u);
639 double lambda1, lambda2;
645 return (p2 + lambda1 * w + lambda2 * v);
657 double chose, totArea = 0., Achose1, Achose2,
658 rad1, rad2, sinphi1, sinphi2, cosphi1, cosphi2;
659 double a, b, l2, rang, totalPhi, ksi,
660 area, aTop = 0., aBottom = 0., zVal = 0.;
663 std::vector<double> aVector1;
664 std::vector<double> aVector2;
665 std::vector<double> aVector3;
669 double cosksi = std::cos(ksi / 2.);
673 for (j = 0; j < numPlanes - 1; j++)
679 area = std::sqrt(l2 -
UUtils::sqr((a - b) * cosksi)) * (a + b) * cosksi;
680 aVector1.push_back(area);
683 for (j = 0; j < numPlanes - 1; j++)
689 area = std::sqrt(l2 -
UUtils::sqr((a - b) * cosksi)) * (a + b) * cosksi;
690 aVector2.push_back(area);
693 for (j = 0; j < numPlanes - 1; j++)
706 aVector3.push_back(0.);
710 for (j = 0; j < numPlanes - 1; j++)
712 totArea +=
fNumSides * (aVector1[j] + aVector2[j]) + 2.*aVector3[j];
722 aTop = std::sqrt(l2 -
UUtils::sqr((a - b) * cosksi)) * (a + b) * cosksi;
730 aBottom = std::sqrt(l2 -
UUtils::sqr((a - b) * cosksi)) * (a + b) * cosksi;
734 Achose2 =
fNumSides * (aVector1[0] + aVector2[0]) + 2.*aVector3[0];
737 if ((chose >= 0.) && (chose < aTop + aBottom))
740 rang = std::floor((chose -
fStartPhi) / ksi - 0.01);
745 rang = std::fabs(rang);
746 sinphi1 = std::sin(
fStartPhi + rang * ksi);
747 sinphi2 = std::sin(
fStartPhi + (rang + 1) * ksi);
748 cosphi1 = std::cos(
fStartPhi + rang * ksi);
749 cosphi2 = std::cos(
fStartPhi + (rang + 1) * ksi);
751 if (chose >= 0. && chose < aTop)
763 p0 =
UVector3(rad1 * cosphi1, rad1 * sinphi1, zVal);
764 p1 =
UVector3(rad2 * cosphi1, rad2 * sinphi1, zVal);
765 p2 =
UVector3(rad2 * cosphi2, rad2 * sinphi2, zVal);
766 p3 =
UVector3(rad1 * cosphi2, rad1 * sinphi2, zVal);
771 for (j = 0; j < numPlanes - 1; j++)
773 if (((chose >= Achose1) && (chose < Achose2)) || (j == numPlanes - 2))
778 Achose1 +=
fNumSides * (aVector1[j] + aVector2[j]) + 2.*aVector3[j];
779 Achose2 = Achose1 +
fNumSides * (aVector1[j + 1] + aVector2[j + 1])
780 + 2.*aVector3[j + 1];
789 totArea =
fNumSides * (aVector1[j] + aVector2[j]) + 2.*aVector3[j];
792 if ((chose >= 0.) && (chose <
fNumSides * aVector1[j]))
795 rang = std::floor((chose -
fStartPhi) / ksi - 0.01);
800 rang = std::fabs(rang);
803 sinphi1 = std::sin(
fStartPhi + rang * ksi);
804 sinphi2 = std::sin(
fStartPhi + (rang + 1) * ksi);
805 cosphi1 = std::cos(
fStartPhi + rang * ksi);
806 cosphi2 = std::cos(
fStartPhi + (rang + 1) * ksi);
809 p0 =
UVector3(rad1 * cosphi1, rad1 * sinphi1, zVal);
810 p1 =
UVector3(rad1 * cosphi2, rad1 * sinphi2, zVal);
814 p2 =
UVector3(rad2 * cosphi2, rad2 * sinphi2, zVal);
815 p3 =
UVector3(rad2 * cosphi1, rad2 * sinphi1, zVal);
818 else if ((chose >=
fNumSides * aVector1[j])
819 && (chose <=
fNumSides * (aVector1[j] + aVector2[j])))
822 rang = std::floor((chose -
fStartPhi) / ksi - 0.01);
827 rang = std::fabs(rang);
830 sinphi1 = std::sin(
fStartPhi + rang * ksi);
831 sinphi2 = std::sin(
fStartPhi + (rang + 1) * ksi);
832 cosphi1 = std::cos(
fStartPhi + rang * ksi);
833 cosphi2 = std::cos(
fStartPhi + (rang + 1) * ksi);
836 p0 =
UVector3(rad1 * cosphi1, rad1 * sinphi1, zVal);
837 p1 =
UVector3(rad1 * cosphi2, rad1 * sinphi2, zVal);
841 p2 =
UVector3(rad2 * cosphi2, rad2 * sinphi2, zVal);
842 p3 =
UVector3(rad2 * cosphi1, rad2 * sinphi1, zVal);
847 if ((chose >= 0.) && (chose < 1.))
856 cosphi1 = std::cos(rang);
858 sinphi1 = std::sin(rang);
861 p0 =
UVector3(rad1 * cosphi1, rad1 * sinphi1,
863 p1 =
UVector3(rad2 * cosphi1, rad2 * sinphi1,
869 p2 =
UVector3(rad1 * cosphi1, rad1 * sinphi1,
871 p3 =
UVector3(rad2 * cosphi1, rad2 * sinphi1,
885 : fStartAngle(0.), fOpeningAngle(0.), fNumSide(0), fNumZPlanes(0),
886 fZValues(0), Rmin(0), Rmax(0)
910 if (&right ==
this)
return *
this;
936 const UVector3& v,
double aPstep)
const
std::ostream & StreamInfo(std::ostream &os) const
bool RemoveRedundantVertices(double tolerance)
UVector3 GetPointOnPlane(UVector3 p0, UVector3 p1, UVector3 p2, UVector3 p3) const
bool MustBeOutside(const UVector3 &p) const
const std::string & GetName() const
UPolyhedraHistorical & operator=(const UPolyhedraHistorical &right)
std::vector< double > fZValues
bool RemoveDuplicateVertices(double tolerance)
void Extent(UVector3 &aMin, UVector3 &aMax) const
static double Tolerance()
void CopyStuff(const UPolyhedra &source)
static double normal(HepRandomEngine *eptr)
UPolyhedra & operator=(const UPolyhedra &source)
UVector3 GetPointOnTriangle(UVector3 p0, UVector3 p1, UVector3 p2) const
static const double kInfinity
void InitVoxels(UReduciblePolygon &z, double radius)
void ScaleA(double scale)
UVCSGfaceted & operator=(const UVCSGfaceted &source)
UVector3 GetPointOnSurface() const
double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const
std::vector< double > Rmin
double SafetyFromOutside(const UVector3 &aPoint, bool aAccurate=false) const
UEnclosingCylinder * fEnclosingCylinder
UGeometryType GetEntityType() const
UPolyhedraSideRZ * fCorners
void SetOriginalParameters()
bool ShouldMiss(const UVector3 &p, const UVector3 &v) const
bool CrossesItself(double tolerance)
void Exception(const char *originOfException, const char *exceptionCode, UExceptionSeverity severity, int level, const char *description)
void Init(double phiStart, double phiTotal, int numSide, int numZPlanes, const double zPlane[], const double rInner[], const double rOuter[])
UPolyhedra(const std::string &name)
void Create(double phiStart, double phiTotal, int numSide, UReduciblePolygon *rz)
std::string UGeometryType
std::vector< double > Rmax
UPolyhedraHistorical fOriginalParameters
void Extent(UVector3 &aMin, UVector3 &aMax) const
UVector3 GetPointOnSurfaceGeneric() const
virtual double SafetyFromOutside(const UVector3 &aPoint, bool aAccurate=false) const
virtual double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const
double Random(double min=0.0, double max=1.0)
virtual VUSolid::EnumInside Inside(const UVector3 &p) const
VUSolid::EnumInside Inside(const UVector3 &p) const