59const char G4Tet::CVSVers[]=
"$Id: G4Tet.cc,v 1.16 2010-10-20 08:54:18 gcosmo Exp $";
94 :
G4VSolid(pName), fpPolyhedron(0), warningFlag(0)
114 fCubicVolume = std::fabs(signed_vol) / 6.;
120 fXMin=std::min(std::min(std::min(anchor.
x(), p2.
x()),p3.
x()),p4.
x());
121 fXMax=std::max(std::max(std::max(anchor.
x(), p2.
x()),p3.
x()),p4.
x());
122 fYMin=std::min(std::min(std::min(anchor.
y(), p2.
y()),p3.
y()),p4.
y());
123 fYMax=std::max(std::max(std::max(anchor.
y(), p2.
y()),p3.
y()),p4.
y());
124 fZMin=std::min(std::min(std::min(anchor.
z(), p2.
z()),p3.
z()),p4.
z());
125 fZMax=std::max(std::max(std::max(anchor.
z(), p2.
z()),p3.
z()),p4.
z());
127 fDx=(fXMax-fXMin)*0.5; fDy=(fYMax-fYMin)*0.5; fDz=(fZMax-fZMin)*0.5;
129 fMiddle=
G4ThreeVector(fXMax+fXMin, fYMax+fYMin, fZMax+fZMin)*0.5;
130 fMaxSize=std::max(std::max(std::max((anchor-fMiddle).mag(),
135 G4bool degenerate=std::fabs(signed_vol) < 1e-9*fMaxSize*fMaxSize*fMaxSize;
137 if(degeneracyFlag) *degeneracyFlag=degenerate;
141 "Degenerate tetrahedron not allowed.");
144 fTol=1e-9*(std::fabs(fXMin)+std::fabs(fXMax)+std::fabs(fYMin)
145 +std::fabs(fYMax)+std::fabs(fZMin)+std::fabs(fZMax));
173 fNormal123=normal123.
unit();
174 fNormal134=normal134.
unit();
175 fNormal142=normal142.
unit();
176 fNormal234=normal234.
unit();
178 fCdotN123=fCenter123.
dot(fNormal123);
179 fCdotN134=fCenter134.
dot(fNormal134);
180 fCdotN142=fCenter142.
dot(fNormal142);
181 fCdotN234=fCenter234.
dot(fNormal234);
190 :
G4VSolid(a), fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0),
191 fAnchor(0,0,0), fP2(0,0,0), fP3(0,0,0), fP4(0,0,0), fMiddle(0,0,0),
192 fNormal123(0,0,0), fNormal142(0,0,0), fNormal134(0,0,0),
193 fNormal234(0,0,0), warningFlag(0),
194 fCdotN123(0.), fCdotN142(0.), fCdotN134(0.), fCdotN234(0.),
195 fXMin(0.), fXMax(0.), fYMin(0.), fYMax(0.), fZMin(0.), fZMax(0.),
196 fDx(0.), fDy(0.), fDz(0.), fTol(0.), fMaxSize(0.)
215 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
216 fpPolyhedron(0), fAnchor(rhs.fAnchor),
217 fP2(rhs.fP2), fP3(rhs.fP3), fP4(rhs.fP4), fMiddle(rhs.fMiddle),
218 fNormal123(rhs.fNormal123), fNormal142(rhs.fNormal142),
219 fNormal134(rhs.fNormal134), fNormal234(rhs.fNormal234),
220 warningFlag(rhs.warningFlag), fCdotN123(rhs.fCdotN123),
221 fCdotN142(rhs.fCdotN142), fCdotN134(rhs.fCdotN134),
222 fCdotN234(rhs.fCdotN234), fXMin(rhs.fXMin), fXMax(rhs.fXMax),
223 fYMin(rhs.fYMin), fYMax(rhs.fYMax), fZMin(rhs.fZMin), fZMax(rhs.fZMax),
224 fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz), fTol(rhs.fTol),
225 fMaxSize(rhs.fMaxSize)
238 if (
this == &rhs) {
return *
this; }
246 fCubicVolume = rhs.fCubicVolume; fSurfaceArea = rhs.fSurfaceArea;
247 fpPolyhedron = 0; fAnchor = rhs.fAnchor;
248 fP2 = rhs.fP2; fP3 = rhs.fP3; fP4 = rhs.fP4; fMiddle = rhs.fMiddle;
249 fNormal123 = rhs.fNormal123; fNormal142 = rhs.fNormal142;
250 fNormal134 = rhs.fNormal134; fNormal234 = rhs.fNormal234;
251 warningFlag = rhs.warningFlag; fCdotN123 = rhs.fCdotN123;
252 fCdotN142 = rhs.fCdotN142; fCdotN134 = rhs.fCdotN134;
253 fCdotN234 = rhs.fCdotN234; fXMin = rhs.fXMin; fXMax = rhs.fXMax;
254 fYMin = rhs.fYMin; fYMax = rhs.fYMax; fZMin = rhs.fZMin; fZMax = rhs.fZMax;
255 fDx = rhs.fDx; fDy = rhs.fDy; fDz = rhs.fDz; fTol = rhs.fTol;
256 fMaxSize = rhs.fMaxSize;
271 G4Tet *
object=
new G4Tet(
"temp",anchor,p2,p3,p4,&result);
307 xMin = std::min(std::min(std::min(pp0.
x(), pp1.
x()),pp2.
x()),pp3.
x());
308 xMax = std::max(std::max(std::max(pp0.
x(), pp1.
x()),pp2.
x()),pp3.
x());
309 yMin = std::min(std::min(std::min(pp0.
y(), pp1.
y()),pp2.
y()),pp3.
y());
310 yMax = std::max(std::max(std::max(pp0.
y(), pp1.
y()),pp2.
y()),pp3.
y());
311 zMin = std::min(std::min(std::min(pp0.
z(), pp1.
z()),pp2.
z()),pp3.
z());
312 zMax = std::max(std::max(std::max(pp0.
z(), pp1.
z()),pp2.
z()),pp3.
z());
318 xMin = xoffset + fXMin;
319 xMax = xoffset + fXMax;
321 yMin = yoffset + fYMin;
322 yMax = yoffset + fYMax;
324 zMin = zoffset + fZMin;
325 zMax = zoffset + fZMax;
331 (xMax < pVoxelLimit.
GetMinXExtent()-fTol) ) {
return false; }
342 (yMax < pVoxelLimit.
GetMinYExtent()-fTol) ) {
return false; }
353 (zMax < pVoxelLimit.
GetMinZExtent()-fTol) ) {
return false; }
393 if ( (r123=p.
dot(fNormal123)-fCdotN123) > fTol ||
394 (r134=p.
dot(fNormal134)-fCdotN134) > fTol ||
395 (r142=p.
dot(fNormal142)-fCdotN142) > fTol ||
396 (r234=p.
dot(fNormal234)-fCdotN234) > fTol )
400 else if( (r123 < -fTol)&&(r134 < -fTol)&&(r142 < -fTol)&&(r234 < -fTol) )
419 G4double r123=std::fabs(p.
dot(fNormal123)-fCdotN123);
420 G4double r134=std::fabs(p.
dot(fNormal134)-fCdotN134);
421 G4double r142=std::fabs(p.
dot(fNormal142)-fCdotN142);
422 G4double r234=std::fabs(p.
dot(fNormal234)-fCdotN234);
424 if( (r123<=r134) && (r123<=r142) && (r123<=r234) ) {
return fNormal123; }
425 else if ( (r134<=r142) && (r134<=r234) ) {
return fNormal134; }
426 else if (r142 <= r234) {
return fNormal142; }
444 vdotn=-vu.dot(fNormal123);
447 t=(p.
dot(fNormal123)-fCdotN123)/vdotn;
448 if( (t>=-fTol) && (t<tmin) )
450 hp=p+vu*(t+extraDistance);
451 if ( ( hp.
dot(fNormal134)-fCdotN134 < 0.0 ) &&
452 ( hp.
dot(fNormal142)-fCdotN142 < 0.0 ) &&
453 ( hp.
dot(fNormal234)-fCdotN234 < 0.0 ) )
460 vdotn=-vu.
dot(fNormal134);
463 t=(p.
dot(fNormal134)-fCdotN134)/vdotn;
464 if( (t>=-fTol) && (t<tmin) )
466 hp=p+vu*(t+extraDistance);
467 if ( ( hp.
dot(fNormal123)-fCdotN123 < 0.0 ) &&
468 ( hp.
dot(fNormal142)-fCdotN142 < 0.0 ) &&
469 ( hp.
dot(fNormal234)-fCdotN234 < 0.0 ) )
476 vdotn=-vu.
dot(fNormal142);
479 t=(p.
dot(fNormal142)-fCdotN142)/vdotn;
480 if( (t>=-fTol) && (t<tmin) )
482 hp=p+vu*(t+extraDistance);
483 if ( ( hp.
dot(fNormal123)-fCdotN123 < 0.0 ) &&
484 ( hp.
dot(fNormal134)-fCdotN134 < 0.0 ) &&
485 ( hp.
dot(fNormal234)-fCdotN234 < 0.0 ) )
492 vdotn=-vu.
dot(fNormal234);
495 t=(p.
dot(fNormal234)-fCdotN234)/vdotn;
496 if( (t>=-fTol) && (t<tmin) )
498 hp=p+vu*(t+extraDistance);
499 if ( ( hp.
dot(fNormal123)-fCdotN123 < 0.0 ) &&
500 ( hp.
dot(fNormal134)-fCdotN134 < 0.0 ) &&
501 ( hp.
dot(fNormal142)-fCdotN142 < 0.0 ) )
508 return std::max(0.0,tmin);
519 G4double dd=(p-fMiddle).mag() - fMaxSize - fTol;
520 return std::max(0.0, dd);
534 G4double t1=kInfinity,t2=kInfinity,t3=kInfinity,t4=kInfinity, vdotn, tt;
536 vdotn=vu.
dot(fNormal123);
539 t1=(fCdotN123-p.
dot(fNormal123))/vdotn;
542 vdotn=vu.
dot(fNormal134);
545 t2=(fCdotN134-p.
dot(fNormal134))/vdotn;
548 vdotn=vu.
dot(fNormal142);
551 t3=(fCdotN142-p.
dot(fNormal142))/vdotn;
554 vdotn=vu.
dot(fNormal234);
557 t4=(fCdotN234-p.
dot(fNormal234))/vdotn;
560 tt=std::min(std::min(std::min(t1,t2),t3),t4);
562 if (warningFlag && (tt == kInfinity || tt < -fTol))
565 std::ostringstream message;
566 message <<
"No good intersection found or already outside!?" <<
G4endl
567 <<
"p = " << p / mm <<
"mm" <<
G4endl
569 <<
"t1, t2, t3, t4 (mm) "
570 << t1/mm <<
", " << t2/mm <<
", " << t3/mm <<
", " << t4/mm;
571 G4Exception(
"G4Tet::DistanceToOut(p,v,...)",
"GeomSolids1002",
578 else if(calcNorm && n)
581 if(tt==t1) { normal=fNormal123; }
582 else if (tt==t2) { normal=fNormal134; }
583 else if (tt==t3) { normal=fNormal142; }
584 else if (tt==t4) { normal=fNormal234; }
586 if(validNorm) { *validNorm=
true; }
589 return std::max(tt,0.0);
601 t1=fCdotN123-p.
dot(fNormal123);
602 t2=fCdotN134-p.
dot(fNormal134);
603 t3=fCdotN142-p.
dot(fNormal142);
604 t4=fCdotN234-p.
dot(fNormal234);
609 G4double tmin=std::min(std::min(std::min(t1,t2),t3),t4);
610 return (tmin < fTol)? 0:tmin;
625 vertices->reserve(4);
641 "Error in allocation of vertices. Out of memory !");
661 return new G4Tet(*
this);
670 G4int oldprc = os.precision(16);
671 os <<
"-----------------------------------------------------------\n"
672 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
673 <<
" ===================================================\n"
674 <<
" Solid type: G4Tet\n"
676 <<
" anchor: " << fAnchor/mm <<
" mm \n"
677 <<
" p2: " << fP2/mm <<
" mm \n"
678 <<
" p3: " << fP3/mm <<
" mm \n"
679 <<
" p4: " << fP4/mm <<
" mm \n"
680 <<
" normal123: " << fNormal123 <<
" \n"
681 <<
" normal134: " << fNormal134 <<
" \n"
682 <<
" normal142: " << fNormal142 <<
" \n"
683 <<
" normal234: " << fNormal234 <<
" \n"
684 <<
"-----------------------------------------------------------\n";
685 os.precision(oldprc);
709 area = 0.5*(v.
cross(w)).mag();
711 return (p2 + lambda1*w + lambda2*v);
720 G4double chose,aOne,aTwo,aThree,aFour;
723 p1 = GetPointOnFace(fAnchor,fP2,fP3,aOne);
724 p2 = GetPointOnFace(fAnchor,fP4,fP3,aTwo);
725 p3 = GetPointOnFace(fAnchor,fP4,fP2,aThree);
726 p4 = GetPointOnFace(fP4,fP3,fP2,aFour);
729 if( (chose>=0.) && (chose <aOne) ) {
return p1;}
730 else if( (chose>=aOne) && (chose < aOne+aTwo) ) {
return p2;}
731 else if( (chose>=aOne+aTwo) && (chose<aOne+aTwo+aThree) ) {
return p3;}
741 std::vector<G4ThreeVector> vertices(4);
742 vertices[0] = fAnchor;
785 return G4VisExtent (fXMin, fXMax, fYMin, fYMax, fZMin, fZMax);
796 static G4int faces[4][4]={{1,3,2,0},{1,4,3,0},{1,2,4,0},{2,3,4,0}};
797 xyz[0][0]=fAnchor.
x(); xyz[0][1]=fAnchor.
y(); xyz[0][2]=fAnchor.
z();
798 xyz[1][0]=fP2.
x(); xyz[1][1]=fP2.
y(); xyz[1][2]=fP2.
z();
799 xyz[2][0]=fP3.
x(); xyz[2][1]=fP3.
y(); xyz[2][2]=fP3.
z();
800 xyz[3][0]=fP4.
x(); xyz[3][1]=fP4.
y(); xyz[3][2]=fP4.
z();
CLHEP::Hep3Vector G4ThreeVector
std::vector< G4ThreeVector > G4ThreeVectorList
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4Tet(const G4String &pName, G4ThreeVector anchor, G4ThreeVector p2, G4ThreeVector p3, G4ThreeVector p4, G4bool *degeneracyFlag=0)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4Tet & operator=(const G4Tet &rhs)
G4Polyhedron * GetPolyhedron() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4GeometryType GetEntityType() const
G4ThreeVector GetPointOnSurface() const
G4double GetSurfaceArea()
std::ostream & StreamInfo(std::ostream &os) const
static G4bool CheckDegeneracy(G4ThreeVector anchor, G4ThreeVector p2, G4ThreeVector p3, G4ThreeVector p4)
G4double GetCubicVolume()
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
G4Polyhedron * CreatePolyhedron() const
std::vector< G4ThreeVector > GetVertices() const
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform) const
G4VisExtent GetExtent() const
EInside Inside(const G4ThreeVector &p) const
G4NURBS * CreateNURBS() const
void DescribeYourselfTo(G4VGraphicsScene &scene) const
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
G4bool IsYLimited() const
G4double GetMinZExtent() const
G4bool IsXLimited() const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMinYExtent() const
G4double GetMinXExtent() const
G4bool IsZLimited() const
G4double GetMaxXExtent() const
static G4int GetNumberOfRotationSteps()
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)