38 const double zPlane[],
39 const double rInner[],
40 const double rOuter[])
45 Init(phiStart, phiTotal, numZPlanes, zPlane, rInner, rOuter);
68 std::ostringstream message;
69 message <<
"Polycone " <<
GetName() <<
"cannot be converted" << std::endl
70 <<
"to Polycone with (Rmin,Rmaz,Z) parameters! Use GenericPolycone" ;
78 std::cout <<
"INFO: Converting polycone " <<
GetName() << std::endl
79 <<
"to optimized polycone with (Rmin,Rmaz,Z) parameters !"
86 for (
int i = 0; i < num; i++)
94 Init(phiStart, phiTotal, num, Z, R1, R2);
110 const double zPlane[],
111 const double rInner[],
112 const double rOuter[])
116 if (phiTotal <= 0 || phiTotal > UUtils::kTwoPi-1E-10)
131 endPhi = phiStart+phiTotal;
143 double prevZ = 0, prevRmax = 0, prevRmin = 0;
145 if (zPlane[1] < zPlane[0])dirZ = -1;
149 for (i = 0; i < numZPlanes; i++)
151 if ((i < numZPlanes - 1) && (zPlane[i] == zPlane[i + 1]))
153 if ((rInner[i] > rOuter[i + 1])
154 || (rInner[i + 1] > rOuter[i]))
157 std::ostringstream message;
158 message <<
"Cannot create a Polycone with no contiguous segments."
160 <<
" Segments are not contiguous !" << std::endl
161 <<
" rMin[" << i <<
"] = " << rInner[i]
162 <<
" -- rMax[" << i + 1 <<
"] = " << rOuter[i + 1] << std::endl
163 <<
" rMin[" << i + 1 <<
"] = " << rInner[i + 1]
164 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
172 double rMin = rInner[i];
173 double rMax = rOuter[i];
174 double z = zPlane[i];
182 std::ostringstream message;
183 message <<
"Cannot create a Polycone with different Z directions.Use GenericPolycone."
185 <<
" ZPlane is changing direction !" << std::endl
186 <<
" zPlane[0] = " << zPlane[0]
187 <<
" -- zPlane[1] = " << zPlane[1] << std::endl
188 <<
" zPlane[" << i - 1 <<
"] = " << zPlane[i - 1]
189 <<
" -- rPlane[" << i <<
"] = " << zPlane[i];
197 double dz = (z - prevZ) / 2;
199 bool tubular = (rMin == prevRmin && prevRmax == rMax);
205 solid =
new UTubs(
"", rMin, rMax, dz, phiStart, phiTotal);
209 solid =
new UCons(
"", prevRmin, prevRmax, rMin, rMax, dz, phiStart, phiTotal);
219 int zi =
fZs.size() - 1;
220 double shift =
fZs[zi - 1] + 0.5 * (
fZs[zi] -
fZs[zi - 1]);
223 section.
shift = shift;
225 section.
solid = solid;
236 else fZs.push_back(z);
254 double mxy = rz->
Amax();
257 double r = rz->
Amax();
261 if (rz->
Amin() < 0.0)
263 std::ostringstream message;
264 message <<
"Illegal input parameters - " <<
GetName() << std::endl
265 <<
" All R values must be >= 0 !";
337 int oldprc = os.precision(16);
338 os <<
"-----------------------------------------------------------\n"
339 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
340 <<
" ===================================================\n"
341 <<
" Solid type: UPolycone3\n"
343 <<
" starting phi angle : " <<
startPhi / (UUtils::kPi / 180.0) <<
" degrees \n"
344 <<
" ending phi angle : " <<
endPhi / (UUtils::kPi / 180.0) <<
" degrees \n";
347 os <<
" number of Z planes: " << numPlanes <<
"\n"
349 for (i = 0; i < numPlanes; i++)
351 os <<
" Z plane " << i <<
": "
354 os <<
" Tangent distances to inner surface (Rmin): \n";
355 for (i = 0; i < numPlanes; i++)
357 os <<
" Z plane " << i <<
": "
360 os <<
" Tangent distances to outer surface (Rmax): \n";
361 for (i = 0; i < numPlanes; i++)
363 os <<
" Z plane " << i <<
": "
366 os <<
"-----------------------------------------------------------\n";
367 os.precision(oldprc);
380 double rMinPlus, rMaxPlus;
387 rMinPlus = tubs->
GetRMin() + halfTolerance;
388 rMaxPlus = tubs->
GetRMax() + halfTolerance;
401 double ratio = (ps.
z + dz) / (2 * dz);
402 rMinPlus = rMin1 + (rMin2 - rMin1) * ratio + halfTolerance;
403 rMaxPlus = rMax1 + (rMax2 - rMax1) * ratio + halfTolerance;
409 double r2 = p.
x * p.
x + p.
y * p.
y;
411 if (r2 < rMinMinus * rMinMinus || r2 > rMaxPlus * rMaxPlus)
return eOutside;
412 if (r2 < rMinPlus * rMinPlus || r2 > rMaxMinus * rMaxMinus)
return eSurface;
416 if (ps.
z < -dz + halfTolerance || ps.
z > dz - halfTolerance)
421 if (r2 < 1e-10)
return eInside;
423 double phi = std::atan2(p.
y, p.
x);
424 if (phi < 0) phi += UUtils::kTwoPi;
426 if (ddp < 0) ddp += UUtils::kTwoPi;
429 if (ps.
z < -dz + halfTolerance || ps.
z > dz - halfTolerance)
448 static const double htolerance = 0.5 *
fgTolerance;
457 if (index > 0 && p.
z -
fZs[index] < htolerance)
459 nextSection = index - 1;
464 nextSection = index + 1;
500 if (idistance >= UUtils::kInfinity)
return idistance;
510 pb = p + idistance *
v;
513 int increment = (v.z > 0) ? 1 : -1;
516 double distance = UUtils::kInfinity;
522 if (distance < UUtils::kInfinity || !increment)
533 UVector3&
n,
bool& convex,
double )
const
543 double totalDistance = 0;
544 int increment = (v.
z > 0) ? 1 : -1;
550 if (totalDistance != 0)
552 pn = p + (totalDistance ) * v;
560 else pn.
z -= section.
shift;
588 totalDistance += distance;
603 return totalDistance;
612 if (minSafety == UUtils::kInfinity)
return 0;
613 if (minSafety < 1e-6)
return 0;
615 double zbase =
fZs[index + 1];
618 double dz =
fZs[i] - zbase;
619 if (dz >= minSafety)
break;
621 if (safety < minSafety) minSafety = safety;
626 zbase =
fZs[index - 1];
627 for (
int i = index - 1; i >= 0; --i)
629 double dz = zbase -
fZs[i];
630 if (dz >= minSafety)
break;
632 if (safety < minSafety) minSafety = safety;
646 if (minSafety < 1e-6)
return minSafety;
648 double zbase =
fZs[index + 1];
651 double dz =
fZs[i] - zbase;
652 if (dz >= minSafety)
break;
654 if (safety < minSafety) minSafety = safety;
657 zbase =
fZs[index - 1];
658 for (
int i = index - 1; i >= 0; --i)
660 double dz = zbase -
fZs[i];
661 if (dz >= minSafety)
break;
663 if (safety < minSafety) minSafety = safety;
676 if (index > 0 && p.
z -
fZs[index] < htolerance)
678 nextSection = index - 1;
683 nextSection = index + 1;
742 if (pos !=
eSurface) index = nextSection;
756 aMin.
Set(-r, -r,
fZs.front());
757 aMax.
Set(r, r,
fZs.back());
785 double Area = 0, totArea = 0;
790 std::vector<double> areas;
791 std::vector<UVector3> points;
796 for (i = 0; i < numPlanes - 1; i++)
821 areas.push_back(Area);
828 totArea += (areas[0] + areas[numPlanes]);
845 double fRmin2,
double fRmax2,
846 double zOne,
double zTwo,
847 double& totArea)
const
851 double Aone, Atwo, Afive, phi, zRand, fDPhi, cosu, sinu;
852 double rRand1, rmin, rmax, chose, rone, rtwo, qone, qtwo;
853 double fDz = (zTwo - zOne) / 2., afDz = std::fabs(fDz);
856 rone = (fRmax1 - fRmax2) / (2.*fDz);
857 rtwo = (fRmin1 - fRmin2) / (2.*fDz);
858 if (fRmax1 == fRmax2)
864 qone = fDz * (fRmax1 + fRmax2) / (fRmax1 - fRmax2);
866 if (fRmin1 == fRmin2)
872 qtwo = fDz * (fRmin1 + fRmin2) / (fRmin1 - fRmin2);
876 Afive = fDz * (fRmax1 - fRmin1 + fRmax2 - fRmin2);
877 totArea = Aone + Atwo + 2.*Afive;
880 cosu = std::cos(phi);
881 sinu = std::sin(phi);
884 if ((startPhi == 0) && (
endPhi == 2 * UUtils::kPi))
889 if ((chose >= 0) && (chose < Aone))
891 if (fRmax1 != fRmax2)
894 point =
UVector3(rone * cosu * (qone - zRand),
895 rone * sinu * (qone - zRand), zRand);
899 point =
UVector3(fRmax1 * cosu, fRmax1 * sinu,
904 else if (chose >= Aone && chose < Aone + Atwo)
906 if (fRmin1 != fRmin2)
909 point =
UVector3(rtwo * cosu * (qtwo - zRand),
910 rtwo * sinu * (qtwo - zRand), zRand);
915 point =
UVector3(fRmin1 * cosu, fRmin1 * sinu,
919 else if ((chose >= Aone + Atwo + Afive) && (chose < Aone + Atwo + 2.*Afive))
922 rmin = fRmin2 - ((zRand - fDz) / (2.*fDz)) * (fRmin1 - fRmin2);
923 rmax = fRmax2 - ((zRand - fDz) / (2.*fDz)) * (fRmax1 - fRmax2);
925 point =
UVector3(rRand1 * std::cos(startPhi),
926 rRand1 * std::sin(startPhi), zRand);
931 rmin = fRmin2 - ((zRand - fDz) / (2.*fDz)) * (fRmin1 - fRmin2);
932 rmax = fRmax2 - ((zRand - fDz) / (2.*fDz)) * (fRmax1 - fRmax2);
935 rRand1 * std::sin(
endPhi), zRand);
939 return point + offset;
949 double zOne,
double zTwo,
950 double& totArea)
const
952 double xRand, yRand, zRand, phi, cosphi, sinphi, chose,
953 aOne, aTwo, aFou, rRand, fDz, fSPhi, fDPhi;
954 fDz = std::fabs(0.5 * (zTwo - zOne));
958 aOne = 2.*fDz * fDPhi * fRMax;
959 aTwo = 2.*fDz * fDPhi * fRMin;
960 aFou = 2.*fDz * (fRMax - fRMin);
961 totArea = aOne + aTwo + 2.*aFou;
963 cosphi = std::cos(phi);
964 sinphi = std::sin(phi);
967 if (startPhi == 0 &&
endPhi == 2 * UUtils::kPi)
971 if ((chose >= 0) && (chose < aOne))
973 xRand = fRMax * cosphi;
974 yRand = fRMax * sinphi;
976 return UVector3(xRand, yRand, zRand + 0.5 * (zTwo + zOne));
978 else if ((chose >= aOne) && (chose < aOne + aTwo))
980 xRand = fRMin * cosphi;
981 yRand = fRMin * sinphi;
983 return UVector3(xRand, yRand, zRand + 0.5 * (zTwo + zOne));
985 else if ((chose >= aOne + aTwo) && (chose < aOne + aTwo + aFou))
987 xRand = rRand * std::cos(fSPhi + fDPhi);
988 yRand = rRand * std::sin(fSPhi + fDPhi);
990 return UVector3(xRand, yRand, zRand + 0.5 * (zTwo + zOne));
995 xRand = rRand * std::cos(fSPhi + fDPhi);
996 yRand = rRand * std::sin(fSPhi + fDPhi);
998 return UVector3(xRand, yRand, zRand + 0.5 * (zTwo + zOne));
1008 double fRMin2,
double fRMax2,
1011 double xRand, yRand, phi, cosphi, sinphi, rRand1, rRand2, A1, Atot, rCh;
1013 cosphi = std::cos(phi);
1014 sinphi = std::sin(phi);
1016 if (fRMin1 == fRMin2)
1024 A1 = std::fabs(fRMin2 * fRMin2 - fRMin1 * fRMin1);
1026 if (fRMax1 == fRMax2)
1034 Atot = A1 + std::fabs(fRMax2 * fRMax2 - fRMax1 * fRMax1);
1043 xRand = rRand1 * cosphi;
1044 yRand = rRand1 * sinphi;
1046 return UVector3(xRand, yRand, zOne);
1056 double fRMin2,
double fRMax2,
1057 double zOne,
double zTwo,
1058 double& totArea)
const
1064 if ((fRMin1 == fRMin2) && (fRMax1 == fRMax2))
1068 return GetPointOnCone(fRMin1, fRMax1, fRMin2, fRMax2, zOne, zTwo, totArea);
1077 double Area = 0, totArea = 0, Achose1 = 0, Achose2 = 0, phi, cosphi, sinphi, rRand;
1082 cosphi = std::cos(phi);
1083 sinphi = std::sin(phi);
1089 std::vector<double> areas;
1090 std::vector<UVector3> points;
1095 for (i = 0; i < numPlanes - 1; i++)
1120 areas.push_back(Area);
1127 totArea += (areas[0] + areas[numPlanes]);
1130 if ((chose >= 0.) && (chose < areas[0]))
1132 return UVector3(rRand * cosphi, rRand * sinphi,
1136 for (i = 0; i < numPlanes - 1; i++)
1138 Achose1 += areas[i];
1139 Achose2 = (Achose1 + areas[i + 1]);
1140 if (chose >= Achose1 && chose < Achose2)
1155 return UVector3(rRand * cosphi, rRand * sinphi,
1165 : fStartAngle(0.), fOpeningAngle(0.), fNumZPlanes(0),
1166 fZValues(0), Rmin(0), Rmax(0)
1196 if (&right ==
this)
return *
this;
1236 if (
this == &source)
return *
this;
1284 bool isConvertible =
true;
1290 std::vector<double>
Z;
1291 std::vector<double> Rmin;
1292 std::vector<double> Rmax;
1294 int countPlanes = 1;
1301 double Zprev = Z[0];
1308 else if (Zprev ==
corners[numPlanes - 1].z)
1310 Rmin.push_back(
corners[numPlanes - 1].
r);
1312 icurl = numPlanes - 1;
1322 int inextr = 0, inextl = 0;
1323 for (
int i = 0; i < numPlanes - 2; i++)
1326 inextl = (icurl <= 0) ? numPlanes - 1 : icurl - 1;
1346 Rmin.push_back(
corners[icurl].r);
1347 Rmax.push_back(Rmax[countPlanes - 2]);
1348 Rmax[countPlanes - 2] =
corners[icurl].
r;
1352 Rmin.push_back(
corners[inextl].r);
1353 Rmax.push_back(
corners[icurl].r);
1359 Rmax.push_back(
corners[icurr].r + (Zleft -
corners[icurr].z) / difZr
1364 isConvertible =
false;
1367 icurl = (icurl == 0) ? numPlanes - 1 : icurl - 1;
1375 icurl = (icurl == 0) ? numPlanes - 1 : icurl - 1;
1378 Rmax.push_back(
corners[inextr].r);
1382 Z.push_back(Zright);
1391 Rmin.push_back(
corners[icurr].r);
1392 Rmax.push_back(
corners[inextr].r);
1396 Rmin.push_back(
corners[inextr].r);
1397 Rmax.push_back(
corners[icurr].r);
1398 Rmax[countPlanes - 2] =
corners[inextr].
r;
1407 Rmin.push_back(
corners[icurr].r);
1412 Rmin.push_back(
corners[icurl].r + (Zright -
corners[icurl].z) / difZl
1419 isConvertible =
false;
1430 inextl = (icurl <= 0) ? numPlanes - 1 : icurl - 1;
1435 Rmin.push_back(
corners[inextl].r);
1440 Rmin.push_back(
corners[inextl].r);
1452 for (
int j = 0; j < countPlanes; j++)
1465 std::ostringstream message;
1466 message <<
"Polycone " <<
GetName() << std::endl
1467 <<
"cannot be converted to Polycone with (Rmin,Rmaz,Z) parameters!";
1469 Warning, 1,
"can not convert");
1477 for (
int j = 0; j < numPlanes; j++)
1487 return isConvertible;
1502 double*
Z, *R1, *R2;
1504 Z =
new double[num];
1505 R1 =
new double[num];
1506 R2 =
new double[num];
1507 for (
int i = 0; i < num; i++)
double SafetyFromOutside(const UVector3 &p) const
double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const
std::vector< double > Rmin
static double frTolerance
std::vector< double > fZValues
UVector3 GetPointOnTubs(double fRMin, double fRMax, double zOne, double zTwo, double &totArea) const
double SafetyFromInsideSection(int index, const UVector3 &p) const
bool NormalSection(int index, const UVector3 &p, UVector3 &n) const
int GetSection(double z) const
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
const std::string & GetName() const
static double fgTolerance
void CopyStuff(const UPolycone &source)
std::vector< UPolyconeSection > fSections
UVector3 GetPointOnCut(double fRMin1, double fRMax1, double fRMin2, double fRMax2, double zOne, double zTwo, double &totArea) const
std::ostream & StreamInfo(std::ostream &os) const
UPolyconeHistorical & operator=(const UPolyconeHistorical &right)
virtual bool Normal(const UVector3 &aPoint, UVector3 &aNormal) const =0
virtual EnumInside Inside(const UVector3 &aPoint) const =0
VUSolid::EnumInside Inside(const UVector3 &p) const
std::vector< double > Rmax
bool Normal(const UVector3 &aPoint, UVector3 &aNormal) const
static int BinarySearch(const std::vector< T > &vec, T value)
double SafetyFromOutsideSection(int index, const UVector3 &p) const
virtual double DistanceToIn(const UVector3 &aPoint, const UVector3 &aDirection, double aPstep=UUtils::kInfinity) const =0
UVector3 GetPointOnSurface() const
void Init(double phiStart, double phiTotal, int numZPlanes, const double zPlane[], const double rInner[], const double rOuter[])
UPolyconeHistorical * fOriginalParameters
UPolyconeSideRZ * corners
UGeometryType GetEntityType() const
double DistanceToIn(const UVector3 &aPoint, const UVector3 &aDirection, double aPstep=UUtils::kInfinity) const
double GetZHalfLength() const
void SetOriginalParameters()
VUSolid::EnumInside InsideSection(int index, const UVector3 &p) const
void Set(double xx, double yy, double zz)
double SafetyFromOutside(const UVector3 &aPoint, bool aAccurate=false) const
double SafetyFromInside(const UVector3 &aPoint, bool aAccurate=false) const
void Set(double dx, double dy, double dz)
std::string UGeometryType
EnumInside Inside(const UVector3 &aPoint) const
UVector3 GetPointOnRing(double fRMin, double fRMax, double fRMin2, double fRMax2, double zOne) const
UVector3 GetPointOnCone(double fRmin1, double fRmax1, double fRmin2, double fRmax2, double zOne, double zTwo, double &totArea) const
virtual double DistanceToOut(const UVector3 &aPoint, const UVector3 &aDirection, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const =0
UPolycone & operator=(const UPolycone &source)
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
std::vector< double > fZs
UEnclosingCylinder * enclosingCylinder
void Extent(UVector3 &aMin, UVector3 &aMax) const
double Random(double min=0.0, double max=1.0)
double DistanceToOut(const UVector3 &aPoint, const UVector3 &aDirection, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const
UPolycone(const std::string &name)
virtual double Capacity()=0