39 : fSurfaceArea(0.), triangles(0)
53 bool start = (phiOther > phi);
63 double zSign = start ? 1 : -1;
74 double midPhi = phi + (start ? +0.5 : -0.5) * deltaPhi;
75 double cosMid = std::cos(midPhi),
76 sinMid = std::sin(midPhi);
93 corn->
r = iterRZ.
GetA();
94 corn->
z = iterRZ.
GetB();
113 corn->
next = corn + 1;
122 while (++corn, iterRZ.
Next());
132 double rFact = std::cos(0.5 * deltaPhi);
133 double rFactNormalize = 1.0 / std::sqrt(1.0 + rFact * rFact);
145 double dr = here->
r - prev->
r,
146 dz = here->z - prev->
z;
148 edge->
length = std::sqrt(dr * dr + dz * dz);
160 double zSignOther = start ? -1 : 1;
161 sideNorm =
UVector3(zSignOther * std::sin(phiOther),
162 -zSignOther * std::cos(phiOther), 0);
169 sideNorm *= rFactNormalize;
175 while (edge++, prev = here, ++here <
corners + numEdges);
187 double rPart = prevEdge->
tr + edge->
tr;
188 double zPart = prevEdge->
tz + edge->
tz;
189 double norm = std::sqrt(rPart * rPart + zPart * zPart);
190 double rNorm = +zPart /
norm;
191 double zNorm = -rPart /
norm;
213 double zSignOther = start ? -1 : 1;
214 UVector3 normalOther(zSignOther * std::sin(phiOther),
215 -zSignOther * std::cos(phiOther), 0);
217 xyVector = -
normal - normalOther;
226 xyVector =
UVector3(cosMid, sinMid, 0);
238 while (prevEdge = edge, ++edge <
edges + numEdges);
263 test -= 1E-6 * corner->
norm3D;
280 : numEdges(0), edges(0), corners(0), rMin(0.), rMax(0.), zMin(0.), zMax(0.),
281 allBehind(false), fTolerance(0.), fSurfaceArea(0.), triangles(0)
367 *sourceEdge = source.
edges;
374 while (++sourceEdge, ++edge, prev = here, ++here <
corners + numEdges);
384 double surfTolerance,
386 double& distFromSurface,
390 double normSign = outgoing ? +1 : -1;
402 double dotProd = normSign *
normal.
Dot(v);
404 if (dotProd <= 0)
return false;
411 distFromSurface = -normSign * ps.
Dot(
normal);
413 if (distFromSurface < -surfTolerance)
return false;
419 distance = distFromSurface / dotProd;
440 double normSign = outgoing ? +1 : -1;
445 double distPhi = -normSign *
normal.
Dot(ps);
448 return UUtils::kInfinity;
449 else if (distPhi < 0)
474 return std::sqrt(distPhi * distPhi + distRZ2);
484 double* bestDistance)
505 if (
InsideEdges(r, p.
z, &distRZ2, &base3Dnorm, &head3Dnorm))
510 *bestDistance = std::fabs(distPhi);
525 *bestDistance = std::sqrt(distPhi * distPhi + distRZ2);
534 double normDist = head3Dnorm->
Dot(cc);
535 if (distRZ2 > tolerance * tolerance)
557 double* bestDistance)
580 *bestDistance = std::fabs(distPhi);
587 *bestDistance = std::sqrt(distPhi * distPhi + distRZ2);
601 double max = -UUtils::kInfinity;
606 double here = axis.
x * corner->
r *
radial.
x
608 + axis.
z * corner->
z;
609 if (here > max) max = here;
695 double qx = p.
x + v.
x,
705 prevZ =
ExactZOrder(z, qx, qy, qz, v, normSign, prev);
711 cornZ =
ExactZOrder(z, qx, qy, qz, v, normSign, corn);
715 if (prevZ < 0)
continue;
719 if (prevZ > 0)
continue;
728 if (prevZ == 0)
continue;
745 nextZ =
ExactZOrder(z, qx, qy, qz, v, normSign, next);
752 if (nextZ * prevZ < 0)
continue;
761 UVector3 qa(qx - prev->x, qy - prev->y, qz - prev->z),
762 qb(qx - corn->
x, qy - corn->
y, qz - corn->
z);
764 double aboveOrBelow = normSign * qa.Cross(qb).Dot(v);
766 if (aboveOrBelow > 0)
768 else if (aboveOrBelow < 0)
780 while (prevZ = cornZ, prev = corn, ++corn <
corners + numEdges);
824 if (r < rMin || r >
rMax)
return false;
825 if (z < zMin || z >
zMax)
return false;
846 double bestDistance2 = UUtils::kInfinity;
856 double dr = (r - edge->
v0->
r), dz = (z - edge->
v0->
z);
858 double distOut = dr * edge->
tz - dz * edge->
tr;
859 double distance2 = distOut * distOut;
860 if (distance2 > bestDistance2)
continue;
865 double q = dr * edge->
tr + dz * edge->
tz;
875 else if (q > edge->
length)
877 double s2 = q - edge->
length;
878 distance2 += s2 * s2;
889 if (distance2 < bestDistance2)
891 bestDistance2 = distance2;
894 double distNorm = dr * testMe->
rNorm + dz * testMe->
zNorm;
895 answer = (distNorm <= 0);
898 *base3Dnorm = testMe;
899 *head3Dnorm = &testMe->
norm3D;
904 answer = (distOut <= 0);
907 *base3Dnorm = edge->
v0;
908 *head3Dnorm = &edge->
norm3D;
915 *bestDist2 = bestDistance2;
935 *p4 = p2 + lambda1 * w + lambda2 *
v;
936 return 0.5 * (v.Cross(w)).Mag();
971 return ((b.
x - a.
x) * (c.
y - a.
y) -
972 (c.
x - a.
x) * (b.
y - a.
y));
982 return Area2(a, b, c) > 0;
992 return Area2(a, b, c) >= 0;
1002 return Area2(a, b, c) == 0;
1020 Positive = !(
Left(a, b, c)) ^ !(
Left(a, b, d));
1021 return Positive && (!
Left(c, d, a) ^ !
Left(c, d, b));
1037 return ((a.
x <= c.
x) && (c.
x <= b.
x)) ||
1038 ((a.
x >= c.
x) && (c.
x >= b.
x));
1042 return ((a.
y <= c.
y) && (c.
y <= b.
y)) ||
1043 ((a.
y >= c.
y) && (c.
y >= b.
y));
1085 corner_next = corner->
next;
1089 if ((corner != a) && (corner_next != a)
1090 && (corner != b) && (corner_next != b))
1096 rz4 =
UVector2(corner_next->
r, corner_next->
z);
1102 corner = corner->
next;
1129 if (
LeftOn(arz, arz1, arz0))
1131 return Left(arz, brz, arz0) &&
Left(brz, arz, arz1);
1135 return !(
LeftOn(arz, brz, arz1) &&
LeftOn(brz, arz, arz0));
1161 c_next = corner->
next;
1162 c_prev = corner->
prev;
1167 corner = corner->
next;
1186 std::vector<double> areas;
1187 std::vector<UVector3> points;
1198 triang->
r = helper->
r;
1199 triang->
z = helper->
z;
1200 triang->
x = helper->
x;
1201 triang->
y = helper->
y;
1211 triang->
prev = helper2;
1218 triang->
next = triang + 1;
1225 helper = helper->
next;
1226 triang = triang->
next;
1236 const int max_n_loops =
numEdges * 10000;
1261 points.push_back(p4);
1262 areas.push_back(result1);
1263 area = area + result1;
1287 if (i >= max_n_loops)
1291 "Maximum number of steps is reached for triangulation!");
1304 points.push_back(p4);
1305 areas.push_back(result1);
1306 area = area + result1;
1319 double Achose1, Achose2;
1325 Achose2 += areas[i];
1326 if (chose >= Achose1 && chose < Achose2)
double SurfaceTriangle(UVector3 p1, UVector3 p2, UVector3 p3, UVector3 *p4)
bool InsideEdges(double r, double z)
VUSolid::EnumInside Inside(const UVector3 &p, double tolerance, double *bestDistance)
bool InCone(UPolyPhiFaceVertex *a, UPolyPhiFaceVertex *b)
double Area2(UVector2 a, UVector2 b, UVector2 c)
virtual EnumInside Inside(const UVector3 &aPoint) const =0
bool LeftOn(UVector2 a, UVector2 b, UVector2 c)
double ExactZOrder(double z, double qx, double qy, double qz, const UVector3 &v, double normSign, const UPolyPhiFaceVertex *vert) const
UPolyPhiFaceVertex * prev
double Safety(const UVector3 &p, bool outgoing)
static double Tolerance()
UPolyPhiFaceVertex * corners
UPolyPhiFace & operator=(const UPolyPhiFace &source)
bool Left(UVector2 a, UVector2 b, UVector2 c)
UPolyPhiFaceVertex * next
bool Distance(const UVector3 &p, const UVector3 &v, bool outgoing, double surfTolerance, double &distance, double &distFromSurface, UVector3 &normal, bool &allBehind)
UPolyPhiFaceVertex * triangles
double Dot(const UVector3 &) const
bool Diagonal(UPolyPhiFaceVertex *a, UPolyPhiFaceVertex *b)
bool IntersectProp(UVector2 a, UVector2 b, UVector2 c, UVector2 d)
double Extent(const UVector3 axis)
void CopyStuff(const UPolyPhiFace &source)
UVector3 GetPointOnFace()
bool Collinear(UVector2 a, UVector2 b, UVector2 c)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
bool Between(UVector2 a, UVector2 b, UVector2 c)
UVector3 Normal(const UVector3 &p, double *bestDistance)
bool InsideEdgesExact(double r, double z, double normSign, const UVector3 &p, const UVector3 &v)
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
bool Diagonalie(UPolyPhiFaceVertex *a, UPolyPhiFaceVertex *b)
UPolyPhiFace(const UReduciblePolygon *rz, double phi, double deltaPhi, double phiOther)
double Random(double min=0.0, double max=1.0)
bool Intersect(UVector2 a, UVector2 b, UVector2 c, UVector2 d)
void Diagnose(VUSolid *solid)