There is also a good blog post about same subject: http://playtechs.blogspot.kr/2007/04/aiming-at-moving-target.html. It also contains more complex samples that include gravity.
The author has done more simplification, which results in more compact code:
double time_of_impact(double px, double py, double vx, double vy, double s)
{
double a = s * s - (vx * vx + vy * vy);
double b = px * vx + py * vy;
double c = px * px + py * py;
double d = b*b + a*c;
double t = 0;
if (d >= 0)
{
t = (b - sqrt(d)) / a;
if (t < 0)
{
t = (b + sqrt(d)) / a;
if (t < 0)
t = 0;
}
}
return t;
}
Update: Original author took into account only bigger root. But in case of smaller root being non-negative, it results in better solution, since time of impact is smaller. I have updated the code correspondingly.