22 double R = cyl.radius();
25 const double sraightLineCutoff = 1.e-7;
26 if (fabs(rho)*R < sraightLineCutoff &&
27 fabs(rho)*startingPos.
perp() < sraightLineCutoff) {
30 cyl.toLocal(startingDir), propDir);
31 std::pair<bool,double> pl = slc.
pathLength( cyl);
43 double pt = startingDir.
perp();
44 Point center( startingPos.
x()-startingDir.
y()/(pt*
rho),
45 startingPos.
y()+startingDir.
x()/(pt*
rho));
46 double p2 = startingPos.
perp2();
49 if (fabs(center.
x()) > fabs(center.
y())) {
51 E = (R2cyl -
p2) / (2.*center.
x());
52 F = center.
y()/center.
x();
53 B = 2.*( startingPos.
y() - F*startingPos.
x() - E*
F);
54 C = 2.*E*startingPos.
x() + E*E + p2 - R2cyl;
58 E = (R2cyl -
p2) / (2.*center.
y());
59 F = center.
x()/center.
y();
60 B = 2.*( startingPos.
x() - F*startingPos.
y() - E*
F);
61 C = 2.*E*startingPos.
y() + E*E + p2 - R2cyl;
84 std::tie(theD,theActualDir) =
chooseSolution(d1, d2, startingPos, startingDir, propDir);
87 float ipabs = 1.f/startingDir.
mag();
88 float sinTheta = float(pt) * ipabs;
89 float cosTheta = startingDir.
z() * ipabs;
95 auto dMag = theD.
mag();
96 float tmp = 0.5f * float(dMag * rho);
97 if (
std::abs(tmp)>1.
f) tmp = std::copysign(1.
f,tmp);
98 theS = theActualDir * 2.f* std::asin( tmp ) / (float(rho)*sinTheta);
100 startingPos.
y() + theD.
y(),
101 startingPos.
z() +
theS*cosTheta);
106 auto sinPhi = 2.f*tmp*
sqrt(1.
f-tmp*tmp);
107 auto cosPhi = 1.f-2.f*tmp*
tmp;
109 startingDir.
x()*sinPhi+startingDir.
y()*cosPhi,
124 auto dMag1 = d1.
mag();
125 auto tmp1 = 0.5f * dMag1 * float(rho);
126 if (
std::abs(tmp1)>1.
f) tmp1 = std::copysign(1.
f,tmp1);
127 auto theS1 = theActualDir1 * 2.f* std::asin( tmp1 ) / (rho*sinTheta);
129 startingPos.
y() + d1.
y(),
130 startingPos.
z() + theS1*cosTheta);
133 auto dMag2 = d2.
mag();
134 auto tmp2 = 0.5f * dMag2 * float(rho);
135 if (
std::abs(tmp2)>1.
f) tmp2 = std::copysign(1.
f,tmp2);
136 auto theS2 = theActualDir2 * 2.f* std::asin( tmp2 ) / (float(rho)*sinTheta);
138 startingPos.
y() + d2.
y(),
139 startingPos.
z() + theS2*cosTheta);
152 auto momProj1 = startingDir.
x()*d1.
x() + startingDir.
y()*d1.
y();
153 auto momProj2 = startingDir.
x()*d2.
x() + startingDir.
y()*d2.
y();
159 theActualDir = (momProj1 > 0) ? 1 : -1;
163 theActualDir = (momProj2 > 0) ? 1 : -1;
168 if (momProj1*momProj2 < 0) {
171 theD = (momProj1*propSign > 0) ? d1 : d2;
172 theActualDir = propSign;
174 else if (momProj1*propSign > 0) {
177 theD = (d1.
mag2()<d2.
mag2()) ? d1 : d2;
178 theActualDir = propSign;
183 return std::pair<Vector,int>(theD,theActualDir);
HelixBarrelCylinderCrossing(const GlobalPoint &startingPos, const GlobalVector &startingDir, double rho, PropagationDirection propDir, const Cylinder &cyl, Solution sol=bothSol)
GlobalVector DirectionType
std::pair< Vector, int > chooseSolution(const Point &p1, const Point &p2, const PositionType &startingPos, const DirectionType &startingDir, PropagationDirection propDir) dso_internal
std::pair< bool, double > pathLength(const Cylinder &cyl) const
Global3DPoint GlobalPoint
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Basic2DVector< TmpType > Point
Abs< T >::type abs(const T &t)
T y() const
Cartesian y coordinate.
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
std::vector< std::vector< double > > tmp
Square< F >::type sqr(const F &f)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
T x() const
Cartesian x coordinate.