Glad you've found it useful so far
The formulas in the Wikipedia article are for single-variable functions: y as a function of x. What would be more appropriate (and simpler) is a parametric approach: x and y as functions of t.
The x and y positions of an actor t seconds in the future should be:
x(t) = x0 + k * xvel * t
y(t) = y0 + k * yvel * t
where (x0, y0) is the current position of the actor, xvel and yvel the x and y velocities respectively, and k = 0.01. I think that is the right value for k. I'm a little rusty on this, but k should be the number of seconds per engine tick: 0.01.
You can use linear splines to accommodate for changes in direction. Suppose at time t0 the velocities were xvel0 and yvel0; and at time t1 the velocities changed to xvel1 and yvel1. Define range(a,b,c) as max(a, min( b, c ) ). Then
x(t) = x0 + k * xvel0 * range( 0, t - t0, t1 ) + k * xvel1 * max( 0, t - t1 )
y(t) = x0 + k * yvel0* range( 0, t - t0, t1 ) + k * xvel1 * max( 0, t - t1 )
If we define t2 to be some time in the far off future (+infinity or some arbitrary large number), we can modify the formula
x(t) = x0 + k * xvel0 * range( 0, t - t0, t1 - t0 ) + k * xvel1 * range( 0, t - t1, t2 - t1 )
y(t) = x0 + k * yvel0 * range( 0, t - t0, t1 - t0 ) + k * xvel1 * range( 0, t - t1, t2 - t1 )
This doesn't change the value, but would allow embedding it in a loop since both terms now use the same range( ) function. Suppose you now have a sequence of trajectories and corresponding velocities: (t0, xvel0, yvel0), (t1, xvel1, yvel1), (t2, xvel2, yvel2), ... Then use a loop to compute the positions
N = number of trajectories in (t0, xvel0, yvel0), (t1, xvel1, yvel1), (t2, xvel2, yvel2)
t_N = infinity or some arbitrarily large number
predicted_x = x0
predicted_y = y0
For each trajectory i:
predicted_x = predicted_x + k * xvel_i * range( 0, t - t_i, t_(i + 1) - t_i )
predicted_y = predicted_y + k * yvel_i * range( 0, t - t_i, t_(i + 1) - t_i )
I haven't tested the formulas, so at this point I can't guarantee they're correct. I just sketched them out over a few minutes. One nice feature is you would just need to sync the trajectory sequences between the client and server. Unfortunately, there is one significant issue I can think of: computing the time of collision.
If I remember correctly, when a collision occurs, Box2D will compute a time offset. If you use a collision event to stamp the time, chances are that time would place the ball into the wall. The collision data would have the offset you would want to add to time you recorded to obtain the proper t_i value. In your gifs, it looks like the sync is getting worse every time a ball bounces. This might be the reason why.