// ---------------------------------------------------- // This file belongs to the ray tracing framework // for the use with Cherenkov detectors // // created 2007 //----------------------------------------------------- #include "PndDrcEffiAbs.h" #include "PndDrcSurfPolyFlatFocus.h" #include "PndDrcPhoton.h" //#include "PndDrcOptReflAbs.h" //#include "PndDrcSurfAbs.h" //#include "PndDrcOptMatAbs.h" //#include "PndDrcOptDev.h" // //#include "TObject.h" #include "TVector3.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 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 "TPolyLine3D.h" //---------------------------------------------------------------------- PndDrcSurfPolyFlatFocus::PndDrcSurfPolyFlatFocus() { fFocalPoint = XYZPoint(0,0,0); } //---------------------------------------------------------------------- PndDrcSurfPolyFlatFocus* PndDrcSurfPolyFlatFocus::Clone() const { return new PndDrcSurfPolyFlatFocus(*this); } //---------------------------------------------------------------------- void PndDrcSurfPolyFlatFocus::Copy(const PndDrcSurfPolyFlatFocus& s) { fP = s.fP; fNormal = s.fNormal; fRadius = s.fRadius; fConConst = s.fConConst; fFocalPoint = s.fFocalPoint; } //---------------------------------------------------------------------- PndDrcSurfPolyFlatFocus::PndDrcSurfPolyFlatFocus(const PndDrcSurfPolyFlatFocus& s) : PndDrcSurfAbs(s) { if (s.fVerbosity>=1) cout<<" PndDrcSurfPolyFlatFocus::PndDrcSurfPolyFlatFocus" <<"(const PndDrcSurfPolyFlatFocus&) name,copy: " <=1) cout<<" PndDrcSurfPolyFlatFocus::operator=" <<"(const PndDrcSurfPolyFlatFocus&) name,copy: " <((*this)) = s; // assignment of base class part. Copy(s); } return *this; } //---------------------------------------------------------------------- void PndDrcSurfPolyFlatFocus::SetFocalPoint(XYZPoint point) { fFocalPoint = point; } //---------------------------------------------------------------------- void PndDrcSurfPolyFlatFocus::AddPoint(XYZPoint point) { fP.push_back(point); int isize = fP.size(); // search normal vector from point differences with largest absolute // cross product. if (isize > 2) { double length2 = 0; for (int i=2; i length2) { length2 = normal.Mag2(); fNormal = normal.Unit(); } } } if (Verbosity()>=5) { cout<<" PndDrcSurfPolyFlatFocus::addPoint: vector size = "<0) { return ( fNormal + (fFocalPoint-point).Unit()).Unit(); } else { return (-fNormal + (fFocalPoint-point).Unit()).Unit(); } } //---------------------------------------------------------------------- bool PndDrcSurfPolyFlatFocus::LineCross(const XYZPoint& pa, const XYZPoint& pb, const XYZPoint& qa, const XYZPoint& qb) const { const double kEps = 1.0e-9; TVector3 p((pb-pa).x(), (pb-pa).y(), (pb-pa).z()); TVector3 q((qb-qa).x(), (qb-qa).y(), (qb-qa).z()); // Mag instead of Mag2 otherwise this contraint cannot be true if (fabs(p.Dot(q)/(p.Mag2()*q.Mag2())) > 1.0L-kEps) return false; // directions parallel // calculate closest distance TVector3 n0 = (p.Cross(q)).Unit(); double dist = fabs((pb-qb).Dot(n0)); // ??? n0 is only perpendicular to pb-qb if pa is in the plane (qb,qa) and hence also the coord. origin if (dist>kEps) return false; // return if pb-qb is not perpendicular to n0 TVector3 pp(pa.x(),pa.y(),pa.z()); TVector3 qq(qa.x(),qa.y(),qa.z()); // solve // P + p*s = Q + q*t // // d**2 = ((P+ps) - (Q+qt))**2 // // d/ds d**2 = d/dt d**2 => (P-Q) + (sp-tq) = 0 // // This linear equation is for the minimum distance between both lines // We prefer minimum distance over equality of both lines due to numerical // uncertainties. // // Solve linear equation // // px -qx s Qx-Px // py -qy t = Qy-Py // pz -qz Qz-Pz // TMatrixD mat_a(3,2); mat_a(0,0) = p.X(); mat_a(1,0) = p.Y(); mat_a(2,0) = p.Z(); mat_a(0,1) = -q.X(); mat_a(1,1) = -q.Y(); mat_a(2,1) = -q.Z(); TVectorD vec_b(3); vec_b(0) = qq.X()-pp.X(); vec_b(1) = qq.Y()-pp.Y(); vec_b(2) = qq.Z()-pp.Z(); TDecompSVD svd(mat_a); if (!svd.Solve(vec_b)) return false; //cout<<" crossing "<-kEps && vec_b[0]<1+kEps && vec_b[1]>-kEps && vec_b[1]<1+kEps) return true; return false; } //---------------------------------------------------------------------- bool PndDrcSurfPolyFlatFocus::SurfaceHit(PndDrcPhoton& ph, XYZPoint& pos_new, double& path_length) const { if (Verbosity()>=4) { cout<<" PndDrcSurfPolyFlatFocus::surfaceHit: name="<=4) { cout<<" PndDrcSurfPolyFlatFocus::surfaceHit:"<=4) { cout<<" PndDrcSurfPolyFlatFocus::withinSurface:"<SetPoint("<SetPoint("<SetLineColor("<Draw();"<SetPoint(i, fP[i].X(), fP[i].Y(), fP[i].Z()); l->SetPoint(isize, fP[0].X(), fP[0].Y(), fP[0].Z()); l->SetLineColor(fPrintColor); l->Draw(); } //---------------------------------------------------------------------- void PndDrcSurfPolyFlatFocus::Print() const { unsigned int isize = fP.size(); cout<<" Coordinates of surface "<