50 double signed_vol = fV21.
Cross(fV31).
Dot(fV41);
60 fCubicVolume = std::fabs(signed_vol) / 6.;
73 fDx = (fXMax - fXMin) * 0.5;
74 fDy = (fYMax - fYMin) * 0.5;
75 fDz = (fZMax - fZMin) * 0.5;
77 fMiddle =
UVector3(fXMax + fXMin, fYMax + fYMin, fZMax + fZMin) * 0.5;
79 (p2 - fMiddle).Mag()),
80 (p3 - fMiddle).Mag()),
81 (p4 - fMiddle).Mag());
83 bool degenerate = std::fabs(signed_vol) < 1e-9 * fMaxSize * fMaxSize * fMaxSize;
85 if (degeneracyFlag) *degeneracyFlag = degenerate;
89 "Degenerate tetrahedron not allowed.");
92 fTol = 1e-9 * (std::fabs(fXMin) + std::fabs(fXMax) + std::fabs(fYMin)
93 + std::fabs(fYMax) + std::fabs(fZMin) + std::fabs(fZMax));
101 UVector3 fCenter123 = (anchor + p2 + p3) * (1.0 / 3.0);
102 UVector3 fCenter134 = (anchor + p4 + p3) * (1.0 / 3.0);
103 UVector3 fCenter142 = (anchor + p4 + p2) * (1.0 / 3.0);
104 UVector3 fCenter234 = (p2 + p3 + p4) * (1.0 / 3.0);
121 fNormal123 = normal123.
Unit();
122 fNormal134 = normal134.
Unit();
123 fNormal142 = normal142.
Unit();
124 fNormal234 = normal234.
Unit();
126 fCdotN123 = fCenter123.
Dot(fNormal123);
127 fCdotN134 = fCenter134.
Dot(fNormal134);
128 fCdotN142 = fCenter142.
Dot(fNormal142);
129 fCdotN234 = fCenter234.
Dot(fNormal234);
148 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
149 fAnchor(rhs.fAnchor),
150 fP2(rhs.fP2), fP3(rhs.fP3), fP4(rhs.fP4), fMiddle(rhs.fMiddle),
151 fNormal123(rhs.fNormal123), fNormal142(rhs.fNormal142),
152 fNormal134(rhs.fNormal134), fNormal234(rhs.fNormal234),
153 warningFlag(rhs.warningFlag), fCdotN123(rhs.fCdotN123),
154 fCdotN142(rhs.fCdotN142), fCdotN134(rhs.fCdotN134),
155 fCdotN234(rhs.fCdotN234), fXMin(rhs.fXMin), fXMax(rhs.fXMax),
156 fYMin(rhs.fYMin), fYMax(rhs.fYMax), fZMin(rhs.fZMin), fZMax(rhs.fZMax),
157 fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz), fTol(rhs.fTol),
158 fMaxSize(rhs.fMaxSize)
178 VUSolid::operator=(rhs);
182 fCubicVolume = rhs.fCubicVolume;
183 fSurfaceArea = rhs.fSurfaceArea;
184 fAnchor = rhs.fAnchor;
188 fMiddle = rhs.fMiddle;
189 fNormal123 = rhs.fNormal123;
190 fNormal142 = rhs.fNormal142;
191 fNormal134 = rhs.fNormal134;
192 fNormal234 = rhs.fNormal234;
193 warningFlag = rhs.warningFlag;
194 fCdotN123 = rhs.fCdotN123;
195 fCdotN142 = rhs.fCdotN142;
196 fCdotN134 = rhs.fCdotN134;
197 fCdotN234 = rhs.fCdotN234;
208 fMaxSize = rhs.fMaxSize;
219 double r123, r134, r142, r234;
224 if ((r123 = p.
Dot(fNormal123) - fCdotN123) > fTol ||
225 (r134 = p.
Dot(fNormal134) - fCdotN134) > fTol ||
226 (r142 = p.
Dot(fNormal142) - fCdotN142) > fTol ||
227 (r234 = p.
Dot(fNormal234) - fCdotN234) > fTol)
231 else if ((r123 < -fTol) && (r134 < -fTol) && (r142 < -fTol) && (r234 < -fTol))
249 double r123 = std::fabs(p.
Dot(fNormal123) - fCdotN123);
250 double r134 = std::fabs(p.
Dot(fNormal134) - fCdotN134);
251 double r142 = std::fabs(p.
Dot(fNormal142) - fCdotN142);
252 double r234 = std::fabs(p.
Dot(fNormal234) - fCdotN234);
254 static const double delta = 0.5 * fTol;
261 sumnorm = fNormal123;
267 sumnorm += fNormal134;
273 sumnorm += fNormal142;
278 sumnorm += fNormal234;
297 if ((r123 <= r134) && (r123 <= r142) && (r123 <= r234))
301 else if ((r134 <= r142) && (r134 <= r234))
305 else if (r142 <= r234)
326 double vdotn, t, tmin = UUtils::kInfinity;
328 double extraDistance = 10.0 * fTol;
330 vdotn = -vu.Dot(fNormal123);
334 t = (p.
Dot(fNormal123) - fCdotN123) / vdotn;
335 if ((t >= -fTol) && (t < tmin))
338 hp = p + vu * (t + extraDistance);
339 if ((hp.Dot(fNormal134) - fCdotN134 < 0.0) &&
340 (hp.Dot(fNormal142) - fCdotN142 < 0.0) &&
341 (hp.Dot(fNormal234) - fCdotN234 < 0.0))
348 vdotn = -vu.
Dot(fNormal134);
352 t = (p.
Dot(fNormal134) - fCdotN134) / vdotn;
353 if ((t >= -fTol) && (t < tmin))
356 hp = p + vu * (t + extraDistance);
357 if ((hp.Dot(fNormal123) - fCdotN123 < 0.0) &&
358 (hp.Dot(fNormal142) - fCdotN142 < 0.0) &&
359 (hp.Dot(fNormal234) - fCdotN234 < 0.0))
366 vdotn = -vu.
Dot(fNormal142);
370 t = (p.
Dot(fNormal142) - fCdotN142) / vdotn;
371 if ((t >= -fTol) && (t < tmin))
374 hp = p + vu * (t + extraDistance);
375 if ((hp.Dot(fNormal123) - fCdotN123 < 0.0) &&
376 (hp.Dot(fNormal134) - fCdotN134 < 0.0) &&
377 (hp.Dot(fNormal234) - fCdotN234 < 0.0))
384 vdotn = -vu.
Dot(fNormal234);
388 t = (p.
Dot(fNormal234) - fCdotN234) / vdotn;
389 if ((t >= -fTol) && (t < tmin))
392 hp = p + vu * (t + extraDistance);
393 if ((hp.Dot(fNormal123) - fCdotN123 < 0.0) &&
394 (hp.Dot(fNormal134) - fCdotN134 < 0.0) &&
395 (hp.Dot(fNormal142) - fCdotN142 < 0.0))
413 double dd = (p - fMiddle).Mag() - fMaxSize - fTol;
423 UVector3&
n,
bool& convex,
double )
const
426 double t1 = UUtils::kInfinity,
t2 = UUtils::kInfinity, t3 = UUtils::kInfinity, t4 = UUtils::kInfinity, vdotn, tt;
428 vdotn = vu.Dot(fNormal123);
431 t1 = (fCdotN123 - p.
Dot(fNormal123)) / vdotn;
434 vdotn = vu.Dot(fNormal134);
437 t2 = (fCdotN134 - p.
Dot(fNormal134)) / vdotn;
440 vdotn = vu.Dot(fNormal142);
443 t3 = (fCdotN142 - p.
Dot(fNormal142)) / vdotn;
446 vdotn = vu.Dot(fNormal234);
449 t4 = (fCdotN234 - p.
Dot(fNormal234)) / vdotn;
454 if (warningFlag && (tt == UUtils::kInfinity || tt < -fTol))
457 std::ostringstream message;
458 message <<
"No good intersection found or already outside!?" << std::endl
459 <<
"p = " << p << std::endl
460 <<
"v = " << v << std::endl
462 << t1 <<
", " << t2 <<
", " << t3 <<
", " << t4;
465 Warning, 1, message.str().c_str());
507 double t1,
t2, t3, t4;
508 t1 = fCdotN123 - p.
Dot(fNormal123);
509 t2 = fCdotN134 - p.
Dot(fNormal134);
510 t3 = fCdotN142 - p.
Dot(fNormal142);
511 t4 = fCdotN234 - p.
Dot(fNormal234);
517 return (tmin < fTol) ? 0 : tmin;
527 int oldprc = os.precision(16);
528 os <<
"-----------------------------------------------------------\n"
529 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
530 <<
" ===================================================\n"
531 <<
" Solid type: UTet\n"
533 <<
" anchor: " << fAnchor <<
" \n"
534 <<
" p2: " << fP2 <<
" \n"
535 <<
" p3: " << fP3 <<
" \n"
536 <<
" p4: " << fP4 <<
" \n"
537 <<
" normal123: " << fNormal123 <<
" \n"
538 <<
" normal134: " << fNormal134 <<
" \n"
539 <<
" normal142: " << fNormal142 <<
" \n"
540 <<
" normal234: " << fNormal234 <<
" \n"
541 <<
"-----------------------------------------------------------\n";
542 os.precision(oldprc);
557 double lambda1, lambda2;
566 area = 0.5 * (v.
Cross(w)).Mag();
567 return (p2 + lambda1 * w + lambda2 * v);
576 double chose, aOne, aTwo, aThree, aFour;
579 p1 = GetPointOnFace(fAnchor, fP2, fP3, aOne);
580 p2 = GetPointOnFace(fAnchor, fP4, fP3, aTwo);
581 p3 = GetPointOnFace(fAnchor, fP4, fP2, aThree);
582 p4 = GetPointOnFace(fP4, fP3, fP2, aFour);
585 if ((chose >= 0.) && (chose < aOne))
589 else if ((chose >= aOne) && (chose < aOne + aTwo))
593 else if ((chose >= aOne + aTwo) && (chose < aOne + aTwo + aThree))
606 std::vector<UVector3> vertices(4);
607 vertices[0] = fAnchor;
628 aArray[0] = fAnchor.
x;
629 aArray[1] = fAnchor.
y;
630 aArray[2] = fAnchor.
z;
UVector3 GetPointOnSurface() const
const std::string & GetName() const
UVector3 Cross(const UVector3 &) const
UGeometryType GetEntityType() const
double DistanceToIn(const UVector3 &aPoint, const UVector3 &aDirection, double aPstep=UUtils::kInfinity) const
void Extent(UVector3 &aMin, UVector3 &aMax) const
bool Normal(const UVector3 &aPoint, UVector3 &aNormal) const
double SafetyFromOutside(const UVector3 &aPoint, bool aAccurate=false) const
std::ostream & StreamInfo(std::ostream &os) const
double DistanceToOut(const UVector3 &aPoint, const UVector3 &aDirection, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const
UTet & operator=(const UTet &rhs)
double Dot(const UVector3 &) const
double SafetyFromInside(const UVector3 &aPoint, bool aAccurate=false) const
void GetParametersList(int aNumber, double *aArray) const
std::vector< UVector3 > GetVertices() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
std::string UGeometryType
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
UTet(const std::string &name, UVector3 anchor, UVector3 p2, UVector3 p3, UVector3 p4, bool *degeneracyFlag=0)
EnumInside Inside(const UVector3 &p) const
double Random(double min=0.0, double max=1.0)