27 fDz(dz), fCubicVolume(0.), fSurfaceArea(0.)
36 std::ostringstream message;
37 message <<
"Dimensions too small for Solid: " <<
GetName() <<
"!" << std::endl
38 <<
" dx, dy, dz = " << dx <<
", " << dy <<
", " << dz;
64 :
VUSolid(rhs), fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz),
65 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea)
83 VUSolid::operator=(rhs);
90 fCubicVolume = rhs.fCubicVolume;
91 fSurfaceArea = rhs.fSurfaceArea;
106 double ddz = std::abs(aPoint.
z) - fDz;
108 double ddx = std::abs(aPoint.
x) - fDx;
110 double ddy = std::abs(aPoint.
y) - fDy;
112 if (ddx > - delta || ddy > -delta || ddz > -delta)
return eSurface;
133 double safx = std::abs(aPoint.
x) - fDx;
134 double safy = std::abs(aPoint.
y) - fDy;
135 double safz = std::abs(aPoint.
z) - fDz;
136 if ((safx > aPstep) || (safy > aPstep) || (safz > aPstep))
137 return UUtils::kInfinity;
139 bool outside = (safx > 0) || (safy > 0) || (safz > 0);
146 return (aPoint.
x * aDirection.
x > 0) ? UUtils::kInfinity : 0.0;
151 return (aPoint.
y * aDirection.
y > 0) ? UUtils::kInfinity : 0.0;
156 return (aPoint.
z * aDirection.
z > 0) ? UUtils::kInfinity : 0.0;
165 double coordinate = 0.0;
168 if (aPoint.
x * aDirection.
x >= 0)
return UUtils::kInfinity;
169 dist = safx / std::abs(aDirection.
x);
170 coordinate = aPoint.
y + dist * aDirection.
y;
171 if (std::abs(coordinate) < fDy)
173 coordinate = aPoint.
z + dist * aDirection.
z;
174 if (std::abs(coordinate) < fDz)
177 if (dist < 0.5 * delta) dist = 0.;
184 if (aPoint.
y * aDirection.
y >= 0)
return UUtils::kInfinity;
185 dist = safy / std::abs(aDirection.
y);
186 coordinate = aPoint.
x + dist * aDirection.
x;
187 if (std::abs(coordinate) < fDx)
189 coordinate = aPoint.
z + dist * aDirection.
z;
190 if (std::abs(coordinate) < fDz)
193 if (dist < 0.5 * delta) dist = 0.;
200 if (aPoint.
z * aDirection.
z >= 0)
return UUtils::kInfinity;
201 dist = safz / std::abs(aDirection.
z);
202 coordinate = aPoint.
x + dist * aDirection.
x;
203 if (std::abs(coordinate) < fDx)
205 coordinate = aPoint.
y + dist * aDirection.
y;
206 if (std::abs(coordinate) < fDy)
209 if (dist < 0.5 * delta) dist = 0.;
214 return UUtils::kInfinity;
229 double smin = UUtils::kInfinity;
230 double snxt, signDir;
234 if (aDirection.
x != 0.0)
237 aNormal.
Set(signDir, 0., 0.);
238 snxt = (-aPoint.
x + signDir * fDx) / aDirection.
x;
239 if (snxt <= 0)
return 0.0;
243 if (aDirection.
y != 0.0)
246 snxt = (-aPoint.
y + signDir * fDy) / aDirection.
y;
249 aNormal.
Set(0., signDir, 0.);
255 aNormal.
Set(0., signDir, 0.);
259 if (aDirection.
z != 0.0)
262 snxt = (-aPoint.
z + signDir * fDz) / aDirection.
z;
265 aNormal.
Set(0., 0., signDir);
271 aNormal.
Set(0., 0., signDir);
285 double safe, safy, safz;
286 safe = fDx - std::abs(aPoint.
x);
287 safy = fDy - std::abs(aPoint.
y);
288 if (safy < safe) safe = safy;
289 safz = fDz - std::abs(aPoint.
z);
290 if (safz < safe) safe = safz;
296 bool aAccurate)
const
301 double safe, safx, safy, safz;
302 safe = safx = -fDx + std::abs(aPoint.
x);
303 safy = -fDy + std::abs(aPoint.
y);
304 if (safy > safe) safe = safy;
305 safz = -fDz + std::abs(aPoint.
z);
306 if (safz > safe) safe = safz;
307 if (safe < 0.0)
return 0.0;
308 if (!aAccurate)
return safe;
313 safsq += safx * safx;
318 safsq += safy * safy;
323 safsq += safz * safz;
326 if (count == 1)
return safe;
327 return std::sqrt(safsq);
341 static const double kInvSqrt2 = 1. / std::sqrt(2.);
342 static const double kInvSqrt3 = 1. / std::sqrt(3.);
346 double safx = std::abs(std::abs(aPoint.
x) - fDx);
347 double safmin = safx;
349 min_normal = crt_normal;
353 aNormal += crt_normal;
355 double safy = std::abs(std::abs(aPoint.
y) - fDy);
360 aNormal += crt_normal;
364 min_normal = crt_normal;
367 double safz = std::abs(std::abs(aPoint.
z) - fDz);
372 aNormal += crt_normal;
376 min_normal = crt_normal;
384 aNormal = min_normal;
390 aNormal *= kInvSqrt2;
393 aNormal *= kInvSqrt3;
420 double px, py, pz, select, sumS;
421 double Sxy = fDx * fDy, Sxz = fDx * fDz, Syz = fDy * fDz;
423 sumS = Sxy + Sxz + Syz;
431 if (UUtils::Random() > 0.5)
440 else if ((select - Sxy) < Sxz)
445 if (UUtils::Random() > 0.5)
459 if (UUtils::Random() > 0.5)
473 int oldprc = os.precision(16);
474 os <<
"-----------------------------------------------------------\n"
475 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
476 <<
" ===================================================\n"
477 <<
" Solid type: UBox\n"
479 <<
" half length X: " << fDx <<
" mm \n"
480 <<
" half length Y: " << fDy <<
" mm \n"
481 <<
" half length Z: " << fDz <<
" mm \n"
482 <<
"-----------------------------------------------------------\n";
483 os.precision(oldprc);
496 std::ostringstream message;
497 message <<
"Dimension X too small for solid: " <<
GetName() <<
"!"
516 std::ostringstream message;
517 message <<
"Dimension Y too small for solid: " <<
GetName() <<
"!"
536 std::ostringstream message;
537 message <<
"Dimension Z too small for solid: " <<
GetName() <<
"!"
bool Normal(const UVector3 &aPoint, UVector3 &aNormal) const
UVector3 GetPointOnSurface() const
std::ostream & StreamInfo(std::ostream &os) const
const std::string & GetName() const
static double fgTolerance
double DistanceToOut(const UVector3 &aPoint, const UVector3 &aDirection, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const
UGeometryType GetEntityType() const
void SetXHalfLength(double dx)
double DistanceToIn(const UVector3 &aPoint, const UVector3 &aDirection, double aPstep=UUtils::kInfinity) const
double SafetyFromInside(const UVector3 &aPoint, bool aAccurate=false) const
void Set(double xx, double yy, double zz)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
UBox & operator=(const UBox &rhs)
void Set(double dx, double dy, double dz)
std::string UGeometryType
double SafetyFromOutside(const UVector3 &aPoint, bool aAccurate=false) const
EnumInside Inside(const UVector3 &aPoint) const
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
void SetYHalfLength(double dy)
short Sign(short a, short b)
void Extent(UVector3 &aMin, UVector3 &aMax) const
double Random(double min=0.0, double max=1.0)
void SetZHalfLength(double dz)