Closest point that has been between two objects

I’ve created a live size shooting simulator (using projectors and cameras), all working well, but in which looks like a simple function, giving me a really hard time…

an object is moving at a speed of 26 units/second (m/s).
I’m shooting a sphere at it, moving at 400 units/second(m/s).

I need to account for lead etc, which is the way I have to do if I shoot at the range.
I got all that working, it’s as in real life.

Now I want to check, if I miss, how far off was I?

The problem is that the framerate even using FixedUpdate for such fast encounter is not enough.
At an fixedupdate of 1ms that still result in 400mm of movement of the shot and a 26mm factor on the target.

So, what other options do I have for this task?

When two point-like objects are moving at constant speed, computing their closest distance is equivalent to finding the minimum value of a quadratic polynomial. You can compute the closest distance with the following formula (written in the form of code for clarity)

Vector3 posDiff = pos1 - pos2; // difference in initial position
Vector3 velDiff = vel1 - vel2; // difference in initial velocity
float dot = Vector3.Dot(posDiff, velDiff); // helper variable
float minT = -dot / velDiff.sqrMagnitude;
float minDist = Mathf.Sqrt(posDiff.sqrMagnitude + 2 * dot * minT + velDiff.sqrMagnitude * minT * minT);

The difference in position between the two objects at any time t is given by posDiff + t * velDiff

You want to find the smallest magnitude of the above expression over all values of t. For this, you just need a little bit of calculus. Recall that the square magnitude of a vector is the same as the dot product of the vector with itself. Let ∆ denote posDiff and ∆ with a dot over it denote velDiff. Now you can compute:

This means that the square distance is a quadratic function of time. In other words, it’s a parabola. Then you can simply use the quadratic formula to find the t for which it is minimized (ax^2 + bx + c is minimized by x = -b / 2a for positive a) and plug that in.

This is only the closest distance between two points moving at constant velocity. It gets complicated for other shapes that aren’t simply spheres. For spheres, note that the distance between two spheres is just the distance between their centers minus the sum of their radii.

You can use Vector3.Project(). The normal direction will be the direction the bullet is travelling and the other vector will be position of the target. The returned vector is the position at which the bullet passed the target. So Vector3.Distance() will give you the distance between the 2 points as a float.

Hope that’s helpful.