10 HelixBarrelPlaneCrossingByCircle::
11 HelixBarrelPlaneCrossingByCircle(
const PositionType& pos,
12 const DirectionType&
dir,
14 theStartingPos( pos), theStartingDir(dir),
15 theRho(rho), thePropDir(propDir) {
init();}
17 HelixBarrelPlaneCrossingByCircle::
18 HelixBarrelPlaneCrossingByCircle(
const GlobalPoint& pos,
21 theStartingPos( pos.basicVector()), theStartingDir(dir.basicVector()),
22 theRho(rho), thePropDir(propDir) {
init();}
26 double pabsI = 1./theStartingDir.mag();
27 double pt = theStartingDir.perp();
28 theCosTheta = theStartingDir.z()*pabsI;
29 theSinTheta = pt*pabsI;
32 const double sraightLineCutoff = 1.e-7;
33 if (fabs(theRho) < sraightLineCutoff &&
34 fabs(theRho)*theStartingPos.perp() < sraightLineCutoff) {
35 useStraightLine =
true;
40 double o = 1./(pt*theRho);
41 theXCenter = theStartingPos.x() - theStartingDir.y()*
o;
42 theYCenter = theStartingPos.y() + theStartingDir.x()*
o;
43 useStraightLine =
false;
47 std::pair<bool,double>
48 HelixBarrelPlaneCrossingByCircle::pathLength(
const Plane& plane)
50 typedef std::pair<bool,double> ResultType;
55 theStartingDir, thePropDir);
56 return slc.pathLength( plane);
67 double distCx = theStartingPos.x() - theXCenter;
68 double distCy = theStartingPos.y() - theYCenter;
73 if (fabs(nx) > fabs(ny)) {
76 dfac = distToPlane/nx;
77 B = distCy - nfac*distCx;
78 C = (2.*distCx + dfac)*dfac;
83 dfac = distToPlane/ny;
84 B = distCx - nfac*distCy;
85 C = (2.*distCy + dfac)*dfac;
87 B -= nfac*dfac; B *= 2;
90 double dx1, dx2, dy1, dy2;
92 if (!equation.hasSolution)
return ResultType(
false, 0.);
96 dx2 = equation.second;
97 dy1 = dfac - nfac*dx1;
98 dy2 = dfac - nfac*dx2;
101 dy1 = equation.first;
102 dy2 = equation.second;
103 dx1 = dfac - nfac*dy1;
104 dx2 = dfac - nfac*dy2;
107 bool solved = chooseSolution( Vector2D(dx1, dy1), Vector2D(dx2, dy2));
109 theDmag = theD.mag();
111 double sinAlpha = 0.5*theDmag*theRho;
112 if ( sinAlpha>(1.-10*DBL_EPSILON) ) sinAlpha = 1.-10*DBL_EPSILON;
113 else if ( sinAlpha<-(1.-10*DBL_EPSILON) ) sinAlpha = -(1.-10*DBL_EPSILON);
114 theS = theActualDir*2./(theRho*theSinTheta) * asin( sinAlpha);
115 return ResultType(
true, theS);
117 else return ResultType(
false, 0.);
121 HelixBarrelPlaneCrossingByCircle::chooseSolution(
const Vector2D& d1,
125 double momProj1 = theStartingDir.x()*d1.x() + theStartingDir.y()*d1.y();
126 double momProj2 = theStartingDir.x()*d2.x() + theStartingDir.y()*d2.y();
130 if (d1.mag2()<d2.mag2()) {
132 theActualDir = (momProj1 > 0) ? 1. : -1.;
136 theActualDir = (momProj2 > 0) ? 1. : -1.;
146 theActualDir = propSign;
151 theD = (d1.mag2()<d2.mag2()) ? d1 : d2;
152 theActualDir = propSign;
163 return PositionType(theStartingPos+s*theStartingDir.unit());
167 theStartingPos.y() + theD.y(),
168 theStartingPos.z() + s*theCosTheta);
171 double phi = s*theSinTheta*theRho;
172 double x1Shift = theStartingPos.x() - theXCenter;
173 double y1Shift = theStartingPos.y() - theYCenter;
176 x1Shift*
sin(phi)+y1Shift*
cos(phi) + theYCenter,
177 theStartingPos.z() + s*theCosTheta);
183 HelixBarrelPlaneCrossingByCircle::direction(
double s)
const
185 if(useStraightLine){
return theStartingDir;}
187 double sinPhi, cosPhi;
189 double tmp = 0.5*theDmag*theRho;
190 if (s < 0) tmp = -
tmp;
192 sinPhi = 1.-(tmp*
tmp);
193 if ( sinPhi<0 ) sinPhi = 0.;
194 sinPhi = 2.*tmp*
sqrt(sinPhi);
195 cosPhi = 1.-2.*(tmp*
tmp);
198 double phi = s*theSinTheta*theRho;
202 return DirectionType(theStartingDir.x()*cosPhi-theStartingDir.y()*sinPhi,
203 theStartingDir.x()*sinPhi+theStartingDir.y()*cosPhi,
GlobalVector normalVector() const
Sin< T >::type sin(const T &t)
Global3DPoint GlobalPoint
float localZ(const GlobalPoint &gp) const
static int position[TOTALCHAMBERS][3]
Point3DBase< Scalar, GlobalTag > PositionType
Cos< T >::type cos(const T &t)
std::vector< std::vector< double > > tmp
bool samesign(T rh, T lh)