double s2NormOfDir = dir.squaredLength();
double s2NormOfOrig = orig.squaredLength();
double dirDotOrig = dir.dot(orig);
double K = s2NormOfOrig - (sqRadius1 + sqRadius2);
Polynomial f = new Polynomial(
K * K - 4.0 * sqRadius1 * (sqRadius2 - orig.y() * orig.y()),
4.0 * dirDotOrig * (s2NormOfOrig - (sqRadius1 + sqRadius2)) + 8.0 * sqRadius1 * dir.y() * orig.y(),
2.0 * s2NormOfDir * (s2NormOfOrig - (sqRadius1 + sqRadius2)) + 4.0 * ((dirDotOrig * dirDotOrig) + sqRadius1 * dir.y() * dir.y()),
4.0 * dirDotOrig * s2NormOfDir,
s2NormOfDir * s2NormOfDir
);
double[] x = f.roots();
if (x.length > 1)
{
Arrays.sort(x);
for (int i = 0; i < x.length; i++)