Determining whether two particles will collide. Suppose you have two particles A and B, and you know their positions at time 0 and their velocities. Initially they are farther apart than the distance r; you want to know if and when they will come within r of each other.
Let's define two 3D vectors R and V. R = the position of B relative to A at time 0, B.position - A.position
, and V = the velocity of B relative to A, B.velocity - A.velocity
. The square of the distance between A and B at time t will be
square_of_distance(t)
= abs(R + V*t)^2
= dot(R + V*t, R + V*t)
= dot(R, R) + 2 * dot(R, V*t) + dot(V*t, V*t)
= dot(R, R) + 2 * dot(R, V) * t + dot(V, V) * t^2
where dot(v1, v2) is the dot product of two vectors and abs(v) is the vector length.
This turns out to be a simple quadratic function of t. Using the quadratic formula, you can find the times t, if any, when square_of_distance(t) = r2. That will tell you if and when the particles approach each other closer than r.
Determining which of a large number of particles will collide first. Of course you can take every possible pair of particles and calculate when they collide. That's O(n2). Improving on that is harder than the simple stuff we've been doing here so far.
Since you only really need to know about the next, say, n seconds, you can calculate a bounding box for each particle's path over that period of time, extend all those boxes by r in each direction, and see which ones, if any, overlap. This can be done using a modified kd-tree. Overlapping bounding boxes do not necessarily indicate actual collisions, only potential collisions. These potential collisions still have to be checked mathematically to see if there are any real collisions; this is just a way to reduce the amount of checking from O(n2) to something more manageable.