38#if !defined(G4GEOM_USE_UTET)
77 *degeneracyFlag = degenerate;
81 std::ostringstream message;
82 message <<
"Degenerate tetrahedron: " <<
GetName() <<
" !\n"
83 <<
" anchor: " << p0 <<
"\n"
84 <<
" p1 : " << p1 <<
"\n"
85 <<
" p2 : " << p2 <<
"\n"
86 <<
" p3 : " << p3 <<
"\n"
88 << std::abs((p1 - p0).cross(p2 - p0).dot(p3 - p0))/6.;
96 Initialize(p0, p1, p2, p3);
115 delete fpPolyhedron; fpPolyhedron =
nullptr;
125 halfTolerance = rhs.halfTolerance;
126 fCubicVolume = rhs.fCubicVolume;
127 fSurfaceArea = rhs.fSurfaceArea;
128 for (
G4int i = 0; i < 4; ++i) { fVertex[i] = rhs.fVertex[i]; }
129 for (
G4int i = 0; i < 4; ++i) { fNormal[i] = rhs.fNormal[i]; }
130 for (
G4int i = 0; i < 4; ++i) { fDist[i] = rhs.fDist[i]; }
131 for (
G4int i = 0; i < 4; ++i) { fArea[i] = rhs.fArea[i]; }
144 if (
this == &rhs) {
return *
this; }
152 halfTolerance = rhs.halfTolerance;
153 fCubicVolume = rhs.fCubicVolume;
154 fSurfaceArea = rhs.fSurfaceArea;
155 for (
G4int i = 0; i < 4; ++i) { fVertex[i] = rhs.fVertex[i]; }
156 for (
G4int i = 0; i < 4; ++i) { fNormal[i] = rhs.fNormal[i]; }
157 for (
G4int i = 0; i < 4; ++i) { fDist[i] = rhs.fDist[i]; }
158 for (
G4int i = 0; i < 4; ++i) { fArea[i] = rhs.fArea[i]; }
161 fRebuildPolyhedron =
false;
162 delete fpPolyhedron; fpPolyhedron =
nullptr;
181 G4double vol = std::abs((p1 - p0).cross(p2 - p0).dot(p3 - p0));
185 ss[0] = ((p1 - p0).cross(p2 - p0)).mag2();
186 ss[1] = ((p2 - p0).cross(p3 - p0)).mag2();
187 ss[2] = ((p3 - p0).cross(p1 - p0)).mag2();
188 ss[3] = ((p2 - p1).cross(p3 - p1)).mag2();
192 for (
G4int i = 1; i < 4; ++i) {
if (ss[i] > ss[k]) k = i; }
195 return (vol*vol <= ss[k]*hmin*hmin);
214 norm[0] = (p2 - p0).cross(p1 - p0);
215 norm[1] = (p3 - p0).cross(p2 - p0);
216 norm[2] = (p1 - p0).cross(p3 - p0);
217 norm[3] = (p2 - p1).cross(p3 - p1);
221 for (
G4int i = 0; i < 4; ++i) { norm[i] = -norm[i]; }
225 for (
G4int i = 0; i < 4; ++i) { fNormal[i] = norm[i].
unit(); }
228 for (
G4int i = 0; i < 3; ++i) { fDist[i] = fNormal[i].
dot(p0); }
229 fDist[3] = fNormal[3].
dot(p1);
232 for (
G4int i = 0; i < 4; ++i) { fArea[i] = 0.5*norm[i].
mag(); }
235 for (
G4int i = 0; i < 3; ++i)
237 fBmin[i] = std::min(std::min(std::min(p0[i], p1[i]), p2[i]), p3[i]);
238 fBmax[i] = std::max(std::max(std::max(p0[i], p1[i]), p2[i]), p3[i]);
242 fCubicVolume = std::abs(volume)/6.;
243 fSurfaceArea = fArea[0] + fArea[1] + fArea[2] + fArea[3];
259 std::ostringstream message;
260 message <<
"Degenerate tetrahedron is not permitted: " <<
GetName() <<
" !\n"
261 <<
" anchor: " << p0 <<
"\n"
262 <<
" p1 : " << p1 <<
"\n"
263 <<
" p2 : " << p2 <<
"\n"
264 <<
" p3 : " << p3 <<
"\n"
266 << std::abs((p1 - p0).cross(p2 - p0).dot(p3 - p0))/6.;
267 G4Exception(
"G4Tet::G4SetVertices()",
"GeomSolids0002",
272 Initialize(p0, p1, p2, p3);
275 fRebuildPolyhedron =
true;
299 std::vector<G4ThreeVector> vertices(4);
300 for (
G4int i = 0; i < 4; ++i) { vertices[i] = fVertex[i]; }
351 return exist = (pMin < pMax) ?
true :
false;
359 anchor[0].set(vec[0].x(),vec[0].y(),vec[0].z());
362 base[0].set(vec[1].x(),vec[1].y(),vec[1].z());
363 base[1].set(vec[2].x(),vec[2].y(),vec[2].z());
364 base[2].set(vec[3].x(),vec[3].y(),vec[3].z());
366 std::vector<const G4ThreeVectorList *> polygons(2);
367 polygons[0] = &anchor;
371 return exists = benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
382 for (
G4int i = 0; i < 4; ++i) { dd[i] = fNormal[i].
dot(p) - fDist[i]; }
384 G4double dist = std::max(std::max(std::max(dd[0], dd[1]), dd[2]), dd[3]);
385 return (dist <= -halfTolerance) ?
396 for (
G4int i = 0; i < 4; ++i)
398 k[i] = std::abs(fNormal[i].dot(p) - fDist[i]) <= halfTolerance;
400 G4double nsurf = k[0] + k[1] + k[2] + k[3];
402 k[0]*fNormal[0] + k[1]*fNormal[1] + k[2]*fNormal[2] + k[3]*fNormal[3];
404 if (nsurf == 1.)
return norm;
405 else if (nsurf > 1.)
return norm.
unit();
408 std::ostringstream message;
409 G4int oldprc = message.precision(16);
410 message <<
"Point p is not on surface (!?) of solid: "
412 message <<
"Position:\n";
413 message <<
" p.x() = " << p.
x()/mm <<
" mm\n";
414 message <<
" p.y() = " << p.
y()/mm <<
" mm\n";
415 message <<
" p.z() = " << p.
z()/mm <<
" mm";
417 G4Exception(
"G4Tet::SurfaceNormal(p)",
"GeomSolids1002",
421 return ApproxSurfaceNormal(p);
434 for (
G4int i = 0; i < 4; ++i)
437 if (d > dist) { dist = d; iside = i; }
439 return fNormal[iside];
451 for (
G4int i = 0; i < 4; ++i)
455 if (dist >= -halfTolerance)
457 if (cosa >= 0.) {
return kInfinity; }
458 tin = std::max(tin, -dist/cosa);
462 tout = std::min(tout, -dist/cosa);
466 return (tout - tin <= halfTolerance) ?
467 kInfinity : ((tin < halfTolerance) ? 0. : tin);
477 for (
G4int i = 0; i < 4; ++i) { dd[i] = fNormal[i].
dot(p) - fDist[i]; }
479 G4double dist = std::max(std::max(std::max(dd[0], dd[1]), dd[2]), dd[3]);
480 return (dist > 0.) ? dist : 0.;
495 G4int ind[4] = {0}, nside = 0;
496 for (
G4int i = 0; i < 4; ++i)
500 ind[nside] = (tmp > 0) * i;
502 dist[i] = fNormal[i].
dot(p) - fDist[i];
508 for (
G4int i = 0; i < nside; ++i)
512 if (dist[k] >= -halfTolerance) { tout = 0.; iside = k;
break; }
515 if (tmp < tout) { tout = tmp; iside = k; }
534 for (
G4int i = 0; i < 4; ++i) { dd[i] = fDist[i] - fNormal[i].
dot(p); }
536 G4double dist = std::min(std::min(std::min(dd[0], dd[1]), dd[2]), dd[3]);
537 return (dist > 0.) ? dist : 0.;
555 return new G4Tet(*
this);
564 G4int oldprc = os.precision(16);
565 os <<
"-----------------------------------------------------------\n"
566 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
567 <<
" ===================================================\n"
570 <<
" anchor: " << fVertex[0]/mm <<
" mm\n"
571 <<
" p1 : " << fVertex[1]/mm <<
" mm\n"
572 <<
" p2 : " << fVertex[2]/mm <<
" mm\n"
573 <<
" p3 : " << fVertex[3]/mm <<
" mm\n"
574 <<
"-----------------------------------------------------------\n";
575 os.precision(oldprc);
585 constexpr G4int iface[4][3] = { {0,1,2}, {0,2,3}, {0,3,1}, {1,2,3} };
590 for ( ; i < 4; ++i) {
if ((select -= fArea[i]) <= 0.)
break; }
600 return (r1 + r2 > 1.) ?
601 p0 + e1*(1. - r1) + e2*(1. - r2) : p0 + e1*r1 + e2*r2;
638 fBmin.
y(), fBmax.
y(),
639 fBmin.
z(), fBmax.
z());
653 G4int k2 = (invert) ? 3 : 2;
654 G4int k3 = (invert) ? 2 : 3;
658 for (
G4int i = 0; i < 3; ++i)
660 xyz[0][i] = fVertex[0][i];
661 xyz[1][i] = fVertex[1][i];
662 xyz[2][i] = fVertex[k2][i];
663 xyz[3][i] = fVertex[k3][i];
667 G4int faces[4][4] = { {1,3,2,0}, {1,4,3,0}, {1,2,4,0}, {2,3,4,0} };
680 if (fpPolyhedron ==
nullptr ||
681 fRebuildPolyhedron ||
688 fRebuildPolyhedron =
false;
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
G4GLOB_DLL std::ostream G4cout
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const
G4Tet & operator=(const G4Tet &rhs)
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4Polyhedron * GetPolyhedron() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4GeometryType GetEntityType() const
void SetVertices(const G4ThreeVector &anchor, const G4ThreeVector &p1, const G4ThreeVector &p2, const G4ThreeVector &p3)
G4Tet(const G4String &pName, const G4ThreeVector &anchor, const G4ThreeVector &p1, const G4ThreeVector &p2, const G4ThreeVector &p3, G4bool *degeneracyFlag=nullptr)
G4ThreeVector GetPointOnSurface() const
G4double GetSurfaceArea()
std::ostream & StreamInfo(std::ostream &os) const
G4double GetCubicVolume()
G4bool CheckDegeneracy(const G4ThreeVector &p0, const G4ThreeVector &p1, const G4ThreeVector &p2, const G4ThreeVector &p3) const
G4Polyhedron * CreatePolyhedron() const
std::vector< G4ThreeVector > GetVertices() const
G4VisExtent GetExtent() const
EInside Inside(const G4ThreeVector &p) const
void DescribeYourselfTo(G4VGraphicsScene &scene) const
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
static G4int GetNumberOfRotationSteps()
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])