Thanks for your reply. I am enclosing my code for your perusal. I think I have included everything I've seen from your posts. In other words, I believe I have "moved" the balls back in time properly. I see your point about the velocities possibly being too large. I will experiment with that. The initial directional velocities are randomly between 13 and 20 per time step. The radii are randomly between 15 and 50. Even though I have multiple balls moving simultaneously, the situation arises with 2-ball collisions and no other ball nearby. Perhaps you can spot something I missed.

[code]
private boolean collision(Circle c1, Circle c2)
{
double x1 = c1.getX(), y1 = c1.getY();
double x2 = c2.getX(), y2 = c2.getY();

double dx = x2 - x1;
double dy = y2 - y1;
double d = Math.sqrt(dx*dx + dy*dy);

if(d <= r1 + r2)
{
double vx1 = c1.getXdir(), vy1 = c1.getXdir();
double vx2 = c2.getXdir(), vy2 = c2.getXdir();
double mass1 = c1.getMass(), mass2 = c2.getMass();

// velocity in the direction of (dx, dy)
double vp1 = (vx1*dx + vy1*dy) / d;
double vp2 = (vx2*dx + vy2*dy) / d;

// collision should have happened dt before
double dt = (r1 + r2 - d) / (vp1 - vp2);

// move the circles backward in time
x1 -= vx1 * dt;
y1 -= vy1 * dt;
x2 -= vx2 * dt;
y2 -= vy2 * dt;

// new collision calculations at impact
dx = x2 - x1;
dy = y2 - y1;
d = Math.sqrt(dx*dx + dy*dy);

// unit vector in the direction of the collision
double ax = dx/d;
double ay = dy/d;

// projection of the velocities in these axes
double va1 =  vx1*ax + vy1*ay;
double vb1 = -vx1*ay + vy1*ax;
double va2 =  vx2*ax + vy2*ay;
double vb2 = -vx2*ay + vy2*ax;

// calculate new velocity after collision
double ed = 1;
double vaP1 = va1 + (1 + ed) * (va2 - va1) / (1 + mass1/mass2);
double vaP2 = va2 + (1 + ed) * (va1 - va2) / (1 + mass2/mass1);

// undo projections
vx1 = vaP1*ax - vb1*ay;
vy1 = vaP1*ay + vb1*ax;
vx2 = vaP2*ax - vb2*ay;
vy2 = vaP2*ay + vb2*ax;

// move time dt forward
x1 += vx1 * dt;
y1 += vy1 * dt;
x2 += vx2 * dt;
y2 += vy2 * dt;

// update locations and velocities
if (!Double.isNaN(x1)) c1.setX(x1);
if (!Double.isNaN(y1)) c1.setY(y1);
if (!Double.isNaN(x2)) c2.setX(x2);
if (!Double.isNaN(y2)) c2.setY(y2);
if (!Double.isNaN(vx1)) c1.setXdir(vx1);
if (!Double.isNaN(vy1)) c1.setYdir(vy1);
if (!Double.isNaN(vx2)) c2.setXdir(vx2);
if (!Double.isNaN(vy2)) c2.setYdir(vy2);

return true;
}
else
return false;
}
[/code]