#include using std::cout; using std::cerr; using std::cin; using std::endl; #include using std::valarray; #include using std::fstream; #include using std::string; #include using std::list; #include using std::vector; #include "TVector3.h" #include "TRotation.h" #include "TRandom.h" #include "TMatrixD.h" #include "TVectorD.h" #include "TDecompSVD.h" #include "Math/Vector3D.h" using ROOT::Math::XYZVector; #include "Math/Point3D.h" using ROOT::Math::XYZPoint; #include "Math/Transform3D.h" using ROOT::Math::Transform3D; #include "Math/RotationX.h" using ROOT::Math::RotationX; #include "Math/RotationY.h" using ROOT::Math::RotationY; #include "Math/RotationZ.h" using ROOT::Math::RotationZ; #include "Math/Rotation3D.h" using ROOT::Math::Rotation3D; #include "DrcPhoton.h" #include "DrcOptReflAbs.h" #include "DrcSurfAbs.h" #include "DrcSurfPolyFlat.h" #include "DrcSurfPolySphere.h" #include "DrcOptMatAbs.h" #include "DrcOptDev.h" //---------------------------------------------------------------------- DrcSurfPolySphere::DrcSurfPolySphere() { m_radius = -999; m_checked = false; } //---------------------------------------------------------------------- DrcSurfPolySphere* DrcSurfPolySphere::clone() const { return new DrcSurfPolySphere(*this); } //---------------------------------------------------------------------- void DrcSurfPolySphere::copy(const DrcSurfPolySphere& s) { m_radius = s.m_radius; m_checked = s.m_checked; m_trans = s.m_trans; m_transInv = s.m_transInv; } //---------------------------------------------------------------------- DrcSurfPolySphere::DrcSurfPolySphere(const DrcSurfPolySphere& s) : DrcSurfPolyFlat(s) { if (s.m_verbosity>=1) cout<<" DrcSurfPolySphere::DrcSurfPolySphere" <<"(const DrcSurfPolySphere&) name,copy: " <=1) cout<<" DrcSurfPolySphere::operator=" <<"(const DrcSurfPolySphere&) name,copy: " <((*this)) = s; // assignment of base class part. copy(s); } return *this; } //---------------------------------------------------------------------- XYZVector DrcSurfPolySphere::normal(const XYZPoint& point) const { if (!m_checked) m_checked = check();// check dimensions // transform point back, where sphere was defined. XYZPoint point0(m_transInv*point); // normal vector points from origin (0,0,0) to point of surface. XYZVector pn(point0); // transform back return m_trans(pn).Unit();//p1.Unit(); } //---------------------------------------------------------------------- bool DrcSurfPolySphere::surfaceHit(DrcPhoton& ph, XYZPoint& pos_new, double& path_length) const { if (!m_checked) m_checked = check();// check dimensions // transform back in sphere definitions space XYZPoint pos(m_transInv*ph.position()); XYZVector dir(m_transInv*ph.direction()); //if (/*pos.Z()<0 && */ dir.Z()<0) return false; // wrong direction### // check if the photon hits the full sphere // double costh = sqrt((dir.X()*dir.X()+dir.Y()*dir.Y())/dir.Mag2()); // double theta = fabs(acos(costh)); // if (tan(theta)* -dir.Z() >= m_radius) return false; // angle too steep // compute hit position // // line : x = pos + lambda*dir // // sphere: x^2 = r^2 // // pos^2 + lambda^2*dir^2 + 2 pos lambda dir = r^2 // // // lambda^2 + lambda*2*pos*dir + pos^2-r^2 = 0; // // lambda12 = -pos*dir + sqrt((pos*dir)^2 - (pos^2-r^2) // // the other (-) solution is the wrong one. // // path_length = lambda since dir is normalized double posdir = pos.Dot(dir); double diff = pos.Mag2() - m_radius*m_radius; double root2 = posdir*posdir - diff; if (m_verbosity>=4) cout<<" DrcSurfPolySphere::surfaceHit root2="<=4) cout<<" DrcSurfPolySphere::surfaceHit lambda_1,2=" <eps && lambda2>eps) { // check both lambdas XYZPoint pos_new1 = pos + lambda1*dir; XYZPoint pos_check(pos_new1); bool hit1 = (pos_new1.Z()>0); pos_check.SetZ(0); if (hit1) hit1 = withinSurface(pos_check); XYZPoint pos_new2 = pos + lambda2*dir; pos_check = pos_new2; bool hit2 = (pos_new2.Z()>0); pos_check.SetZ(0); if (hit2) hit2 = withinSurface(pos_check); if (hit1 && hit2) { // take closest double lambda = (lambda1eps && lambda2<=eps) { path_length = lambda1; } else if (lambda1<=eps && lambda2>eps) { path_length = lambda2; } else { //cout<<" not taken"<=4) cout<<" DrcSurfPolySphere::surfaceHit pos_new_z=" <=4) cout<<" DrcSurfPolySphere::surfaceHit false"<(isize-1) || i<0) { cerr<<" *** DrcSurfPolySphere::limitingPoint: index out of range, i="<=3) cout<<" DrcSurfPolySphere::addTransform() name="<SetPoint("<<(icnt++)<<"," <SetPoint("<<(icnt++)<<"," <SetLineColor("<Draw();"<