59 const char G4Tet::CVSVers[]=
"$Id: G4Tet.cc 69790 2013-05-15 12:39:10Z gcosmo $";
78 using namespace CLHEP;
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) < 1
e-9*fMaxSize*fMaxSize*fMaxSize;
137 if(degeneracyFlag) *degeneracyFlag=degenerate;
141 "Degenerate tetrahedron not allowed.");
144 fTol=1
e-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);
437 sumnorm += fNormal134;
443 sumnorm += fNormal142;
448 sumnorm += fNormal234;
453 if( noSurfaces == 1 )
459 return sumnorm.
unit();
465 if( (r123<=r134) && (r123<=r142) && (r123<=r234) ) {
return fNormal123; }
466 else if ( (r134<=r142) && (r134<=r234) ) {
return fNormal134; }
467 else if (r142 <= r234) {
return fNormal142; }
485 vdotn=-vu.dot(fNormal123);
488 t=(p.
dot(fNormal123)-fCdotN123)/vdotn;
489 if( (t>=-fTol) && (t<tmin) )
491 hp=p+vu*(t+extraDistance);
492 if ( ( hp.dot(fNormal134)-fCdotN134 < 0.0 ) &&
493 ( hp.dot(fNormal142)-fCdotN142 < 0.0 ) &&
494 ( hp.dot(fNormal234)-fCdotN234 < 0.0 ) )
501 vdotn=-vu.
dot(fNormal134);
504 t=(p.
dot(fNormal134)-fCdotN134)/vdotn;
505 if( (t>=-fTol) && (t<tmin) )
507 hp=p+vu*(t+extraDistance);
508 if ( ( hp.dot(fNormal123)-fCdotN123 < 0.0 ) &&
509 ( hp.dot(fNormal142)-fCdotN142 < 0.0 ) &&
510 ( hp.dot(fNormal234)-fCdotN234 < 0.0 ) )
517 vdotn=-vu.
dot(fNormal142);
520 t=(p.
dot(fNormal142)-fCdotN142)/vdotn;
521 if( (t>=-fTol) && (t<tmin) )
523 hp=p+vu*(t+extraDistance);
524 if ( ( hp.dot(fNormal123)-fCdotN123 < 0.0 ) &&
525 ( hp.dot(fNormal134)-fCdotN134 < 0.0 ) &&
526 ( hp.dot(fNormal234)-fCdotN234 < 0.0 ) )
533 vdotn=-vu.
dot(fNormal234);
536 t=(p.
dot(fNormal234)-fCdotN234)/vdotn;
537 if( (t>=-fTol) && (t<tmin) )
539 hp=p+vu*(t+extraDistance);
540 if ( ( hp.dot(fNormal123)-fCdotN123 < 0.0 ) &&
541 ( hp.dot(fNormal134)-fCdotN134 < 0.0 ) &&
542 ( hp.dot(fNormal142)-fCdotN142 < 0.0 ) )
549 return std::max(0.0,tmin);
560 G4double dd=(p-fMiddle).mag() - fMaxSize - fTol;
561 return std::max(0.0, dd);
575 G4double t1=kInfinity,
t2=kInfinity,t3=kInfinity,t4=kInfinity, vdotn, tt;
577 vdotn=vu.dot(fNormal123);
580 t1=(fCdotN123-p.
dot(fNormal123))/vdotn;
583 vdotn=vu.dot(fNormal134);
586 t2=(fCdotN134-p.
dot(fNormal134))/vdotn;
589 vdotn=vu.dot(fNormal142);
592 t3=(fCdotN142-p.
dot(fNormal142))/vdotn;
595 vdotn=vu.dot(fNormal234);
598 t4=(fCdotN234-p.
dot(fNormal234))/vdotn;
601 tt=std::min(std::min(std::min(t1,t2),t3),t4);
603 if (warningFlag && (tt == kInfinity || tt < -fTol))
606 std::ostringstream message;
607 message <<
"No good intersection found or already outside!?" <<
G4endl
608 <<
"p = " << p /
mm <<
"mm" <<
G4endl
610 <<
"t1, t2, t3, t4 (mm) "
611 << t1/
mm <<
", " << t2/
mm <<
", " << t3/
mm <<
", " << t4/
mm;
612 G4Exception(
"G4Tet::DistanceToOut(p,v,...)",
"GeomSolids1002",
619 else if(calcNorm && n)
622 if(tt==t1) { normal=fNormal123; }
623 else if (tt==t2) { normal=fNormal134; }
624 else if (tt==t3) { normal=fNormal142; }
625 else if (tt==t4) { normal=fNormal234; }
627 if(validNorm) { *validNorm=
true; }
630 return std::max(tt,0.0);
642 t1=fCdotN123-p.
dot(fNormal123);
643 t2=fCdotN134-p.
dot(fNormal134);
644 t3=fCdotN142-p.
dot(fNormal142);
645 t4=fCdotN234-p.
dot(fNormal234);
650 G4double tmin=std::min(std::min(std::min(t1,t2),t3),t4);
651 return (tmin < fTol)? 0:tmin;
666 vertices->reserve(4);
682 "Error in allocation of vertices. Out of memory !");
702 return new G4Tet(*
this);
711 G4int oldprc = os.precision(16);
712 os <<
"-----------------------------------------------------------\n"
713 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
714 <<
" ===================================================\n"
715 <<
" Solid type: G4Tet\n"
717 <<
" anchor: " << fAnchor/
mm <<
" mm \n"
718 <<
" p2: " << fP2/
mm <<
" mm \n"
719 <<
" p3: " << fP3/
mm <<
" mm \n"
720 <<
" p4: " << fP4/
mm <<
" mm \n"
721 <<
" normal123: " << fNormal123 <<
" \n"
722 <<
" normal134: " << fNormal134 <<
" \n"
723 <<
" normal142: " << fNormal142 <<
" \n"
724 <<
" normal234: " << fNormal234 <<
" \n"
725 <<
"-----------------------------------------------------------\n";
726 os.precision(oldprc);
747 lambda1 = RandFlat::shoot(0.,1.);
748 lambda2 = RandFlat::shoot(0.,lambda1);
750 area = 0.5*(v.
cross(w)).mag();
752 return (p2 + lambda1*w + lambda2*v);
761 G4double chose,aOne,aTwo,aThree,aFour;
764 p1 = GetPointOnFace(fAnchor,fP2,fP3,aOne);
765 p2 = GetPointOnFace(fAnchor,fP4,fP3,aTwo);
766 p3 = GetPointOnFace(fAnchor,fP4,fP2,aThree);
767 p4 = GetPointOnFace(fP4,fP3,fP2,aFour);
769 chose = RandFlat::shoot(0.,aOne+aTwo+aThree+aFour);
770 if( (chose>=0.) && (chose <aOne) ) {
return p1;}
771 else if( (chose>=aOne) && (chose < aOne+aTwo) ) {
return p2;}
772 else if( (chose>=aOne+aTwo) && (chose<aOne+aTwo+aThree) ) {
return p3;}
782 std::vector<G4ThreeVector> vertices(4);
783 vertices[0] = fAnchor;
826 return G4VisExtent (fXMin, fXMax, fYMin, fYMax, fZMin, fZMax);
837 const G4int faces[4][4]={{1,3,2,0},{1,4,3,0},{1,2,4,0},{2,3,4,0}};
838 xyz[0][0]=fAnchor.
x(); xyz[0][1]=fAnchor.
y(); xyz[0][2]=fAnchor.
z();
839 xyz[1][0]=fP2.
x(); xyz[1][1]=fP2.
y(); xyz[1][2]=fP2.
z();
840 xyz[2][0]=fP3.
x(); xyz[2][1]=fP3.
y(); xyz[2][2]=fP3.
z();
841 xyz[3][0]=fP4.
x(); xyz[3][1]=fP4.
y(); xyz[3][2]=fP4.
z();