17 using namespace genie;
18 using namespace genie::geometry;
33 stream <<
"RayIntercept: dist in/out " << ri.
fDistIn <<
"/" << ri.
fDistOut
34 <<
" hit=" << ((ri.
fIsHit)?
"true":
"false")
58 d = d - (
a*zero.X() +
b*zero.Y() + c*zero.Z() );
63 void PlaneParam::Print(std::ostream& stream)
const
65 stream <<
"PlaneParam=[" <<
a <<
"," <<
b <<
"," << c <<
"," << d <<
"]";
69 RayIntercept FidSphere::Intercept(
const TVector3& start,
const TVector3&
dir)
const
75 TVector3 oc = fCenter - start;
76 Double_t loc2 = oc.Mag2();
77 Double_t r2 = fSRadius*fSRadius;
80 const TVector3& d =
dir;
81 Double_t d2 = d.Mag2();
82 Double_t tca = oc.Dot(d)/d2;
84 Double_t lhc2 = ( r2 -loc2 )/d2 + tca*tca;
85 if ( lhc2 < 0.0 )
return intercept;
87 Double_t lhc = TMath::Sqrt(lhc2);
104 void FidSphere::Print(std::ostream& stream)
const
106 stream <<
"FidSphere @ ["
107 << fCenter.X() <<
","
108 << fCenter.Y() <<
","
109 << fCenter.Z() <<
"] r = " << fSRadius;
113 RayIntercept FidCylinder::InterceptUncapped(
const TVector3& start,
const TVector3&
dir)
const
120 TVector3 rc = start - fCylBase;
121 TVector3 n = dir.Cross(fCylAxis);
122 Double_t len = n.Mag();
126 dist = rc.Dot(fCylAxis);
127 TVector3 d = rc - dist*fCylAxis;
130 if ( dist <= fCylRadius ) {
138 if ( len != 1.0 ) n.SetMag(1.);
139 dist = TMath::Abs(rc.Dot(n));
141 if ( dist <= fCylRadius ) {
145 TVector3 o = rc.Cross(fCylAxis);
146 Double_t t = - o.Dot(n)/len;
147 o = n.Cross(fCylAxis);
149 Double_t
s = TMath::Abs( TMath::Sqrt(fCylRadius*fCylRadius-dist*dist) /
165 if ( ! intercept.
fIsHit )
return intercept;
166 for (
int icap=1; icap <= 2; ++icap ) {
167 const PlaneParam& cap = (icap==1) ? fCylCap1 : fCylCap2;
168 if ( ! cap.
IsValid() )
continue;
169 Double_t vd = cap.
Vd(dir);
170 Double_t vn = cap.
Vn(start);
175 if ( vn > 0 ) { intercept.
fIsHit =
false;
break; }
177 Double_t t = -vn / vd;
198 fCylCap1.ConvertMaster2Top(rgeom);
199 fCylCap2.ConvertMaster2Top(rgeom);
203 void FidCylinder::Print(std::ostream& stream)
const
205 stream <<
"FidCylinder @ ["
206 << fCylBase.X() <<
","
207 << fCylBase.Y() <<
","
208 << fCylBase.Z() <<
"] dir ["
209 << fCylAxis.X() <<
","
210 << fCylAxis.Y() <<
","
211 << fCylAxis.Z() <<
"] r = " << fCylRadius;
212 stream <<
" cap1=" << fCylCap1 <<
" cap2=" << fCylCap2;
216 RayIntercept FidPolyhedron::Intercept(
const TVector3& start,
const TVector3&
dir)
const
225 Double_t tnear = -DBL_MAX;
226 Double_t tfar = DBL_MAX;
229 Bool_t parallel =
false;
232 for (
size_t iface=0; iface < fPolyFaces.size(); ++iface ) {
234 if ( ! pln.
IsValid() )
continue;
237 Double_t vd = pln.
Vd(dir);
238 Double_t vn = pln.
Vn(start);
248 if ( vn > 0.0 ) { parallel =
true;
break; }
251 Double_t t = -vn / vd;
273 if ( tnear < tfar ) {
298 for (
unsigned int i = 0; i < fPolyFaces.size(); ++i ) {
303 void FidPolyhedron::Print(std::ostream& stream)
const
305 size_t nfaces = fPolyFaces.size();
306 stream <<
"FidPolyhedron n=" << nfaces;
307 for (
size_t i=0; i<nfaces; ++i) {
309 stream << std::endl <<
"[" << setw(2) << i <<
"]" << aface;
Some simple volumes that know how to calculate where a ray intercepts them.
Int_t fSurfOut
what surface was hit on way in
void ConvertMaster2Top(const ROOTGeomAnalyzer *rgeom)
Double_t Vn(const TVector3 &raybase) const
Bool_t fIsHit
distance along ray to exit fid volume
static constexpr double s
static constexpr double b
Int_t fSurfIn
was the volume hit
A ROOT/GEANT4 geometry driver.
virtual void Master2TopDir(TVector3 &v) const
void Print(std::ostream &stream) const
Double_t fDistOut
distance along ray to enter fid volume
virtual void Print(std::ostream &stream) const =0
std::ostream & operator<<(std::ostream &stream, const genie::geometry::PlaneParam &pparam)
virtual void Master2Top(TVector3 &v) const
Double_t Vd(const TVector3 &raycos) const