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);
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))
139 bool outside = (safx > 0) || (safy > 0) || (safz > 0);
165 double coordinate = 0.0;
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.;
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.;
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.;
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;
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() <<
"!"
555 return new UBox(*
this);
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
static const double kInfinity
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)