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);
162 double coordinate = 0.0;
166 dist = safx / std::abs(aDirection.
x);
167 coordinate = aPoint.
y + dist * aDirection.
y;
168 if (std::abs(coordinate) <
fDy)
170 coordinate = aPoint.
z + dist * aDirection.
z;
171 if (std::abs(coordinate) <
fDz)
174 if (dist < 0.5 * delta) dist = 0.;
182 dist = safy / std::abs(aDirection.
y);
183 coordinate = aPoint.
x + dist * aDirection.
x;
184 if (std::abs(coordinate) <
fDx)
186 coordinate = aPoint.
z + dist * aDirection.
z;
187 if (std::abs(coordinate) <
fDz)
190 if (dist < 0.5 * delta) dist = 0.;
198 dist = safz / std::abs(aDirection.
z);
199 coordinate = aPoint.
x + dist * aDirection.
x;
200 if (std::abs(coordinate) <
fDx)
202 coordinate = aPoint.
y + dist * aDirection.
y;
203 if (std::abs(coordinate) <
fDy)
206 if (dist < 0.5 * delta) dist = 0.;
227 double snxt, signDir;
231 if (aDirection.
x != 0.0)
234 aNormal.
Set(signDir, 0., 0.);
235 snxt = (-aPoint.
x + signDir *
fDx) / aDirection.
x;
236 if (snxt <= 0)
return 0.0;
240 if (aDirection.
y != 0.0)
243 snxt = (-aPoint.
y + signDir *
fDy) / aDirection.
y;
246 aNormal.
Set(0., signDir, 0.);
252 aNormal.
Set(0., signDir, 0.);
256 if (aDirection.
z != 0.0)
259 snxt = (-aPoint.
z + signDir *
fDz) / aDirection.
z;
262 aNormal.
Set(0., 0., signDir);
268 aNormal.
Set(0., 0., signDir);
282 double safe, safy, safz;
283 safe =
fDx - std::abs(aPoint.
x);
284 safy =
fDy - std::abs(aPoint.
y);
285 if (safy < safe) safe = safy;
286 safz =
fDz - std::abs(aPoint.
z);
287 if (safz < safe) safe = safz;
293 bool aAccurate)
const
298 double safe, safx, safy, safz;
299 safe = safx = -
fDx + std::abs(aPoint.
x);
300 safy = -
fDy + std::abs(aPoint.
y);
301 if (safy > safe) safe = safy;
302 safz = -
fDz + std::abs(aPoint.
z);
303 if (safz > safe) safe = safz;
304 if (safe < 0.0)
return 0.0;
305 if (!aAccurate)
return safe;
310 safsq += safx * safx;
315 safsq += safy * safy;
320 safsq += safz * safz;
323 if (count == 1)
return safe;
324 return std::sqrt(safsq);
338 static const double kInvSqrt2 = 1. / std::sqrt(2.);
339 static const double kInvSqrt3 = 1. / std::sqrt(3.);
343 double safx = std::abs(std::abs(aPoint.
x) -
fDx);
344 double safmin = safx;
346 min_normal = crt_normal;
350 aNormal += crt_normal;
352 double safy = std::abs(std::abs(aPoint.
y) -
fDy);
357 aNormal += crt_normal;
361 min_normal = crt_normal;
364 double safz = std::abs(std::abs(aPoint.
z) -
fDz);
369 aNormal += crt_normal;
373 min_normal = crt_normal;
381 aNormal = min_normal;
387 aNormal *= kInvSqrt2;
390 aNormal *= kInvSqrt3;
417 double px, py, pz, select, sumS;
420 sumS = Sxy + Sxz + Syz;
428 if (UUtils::Random() > 0.5)
437 else if ((select - Sxy) < Sxz)
442 if (UUtils::Random() > 0.5)
456 if (UUtils::Random() > 0.5)
470 int oldprc = os.precision(16);
471 os <<
"-----------------------------------------------------------\n"
472 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
473 <<
" ===================================================\n"
474 <<
" Solid type: UBox\n"
476 <<
" half length X: " <<
fDx <<
" mm \n"
477 <<
" half length Y: " <<
fDy <<
" mm \n"
478 <<
" half length Z: " <<
fDz <<
" mm \n"
479 <<
"-----------------------------------------------------------\n";
480 os.precision(oldprc);
493 std::ostringstream message;
494 message <<
"Dimension X too small for solid: " <<
GetName() <<
"!"
513 std::ostringstream message;
514 message <<
"Dimension Y too small for solid: " <<
GetName() <<
"!"
533 std::ostringstream message;
534 message <<
"Dimension Z too small for solid: " <<
GetName() <<
"!"
552 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)