If radius = 0 then they are two lines.
PHP Code:
double TimeOfSphereIntersection(Vector3 &PStart,Vector3 &PEnd,
Vector3 &QStart, Vector3 &QEnd,
float PRadius, float QRadius, float Epsilon)
{
Vector3 A = PStart - QStart;
Vector3 B = (PEnd - PStart) - (QEnd - QStart); //relative velocity
double ASq = A.BasicLength();
double AdotB = DotProduct(&A,&B);
double AdotB_sq = AdotB * AdotB;
double BSq = B.BasicLength();
double iBSq(0);// = BSq > .0000001f ? (1/BSq) : 1.0f; //Inverse of |B| squared
if(BSq > .000001f)
{
iBSq = 1/ BSq;
}
else //if b_squared is zero, then they cannot collide (both stationary or moving in same direction)
{
SWEPTSPHEREDEBUG( trace << "BSquared is zero, setting to 1.0f" << "\n"; )
return -3.0f;
// iBSq = 1.0f;
}
double sep_dist = PRadius + QRadius + Epsilon;
double sep_dist_sq = sep_dist * sep_dist;
double closest_sep_dist_sq = ASq - (AdotB_sq * iBSq);
if(closest_sep_dist_sq > sep_dist_sq)
{
SWEPTSPHEREDEBUG( trace << "closest_sep_dist_sq > sep_dist_sq, returning -1" << "\n"; )
return -1.0f;
}
double under_root = AdotB_sq - (BSq * (ASq - sep_dist_sq));
if(under_root < 0)
{
SWEPTSPHEREDEBUG( trace << "negative under radical, no sphere intersection, returning -2" << "\n"; )
return -2.0f;
}
double root = sqrt(under_root);
double time = (-AdotB - root) * iBSq;
if(time >= 1.0f)
{
SWEPTSPHEREDEBUG( trace << "Fishy value of time, greater or equal to 1.0f: " << time << "\n"; )
SWEPTSPHEREDEBUG( trace << "Root: " << root << "under_root: " << under_root << "AdotB: " << AdotB << "\n\n"; )
}
else
{
SWEPTSPHEREDEBUG( trace << "Value of time not fish, good" << "\n"; )
}
return time;
}