Heh, everyones thinking too hard on this. The real problem is that your ball moves too deep into the water in a single time step, and if you calculate what happens from there, it will of course fly back up (think of dropping a beach ball onto water, it doesn't go 'in' at all!). A much easier solution is whenever you find out something has collided with water, back up to the point of first contact, then figure out how deep it is supposed to go. Then figure out if the 'time of maximum depth' is within the current time step (if it is, you have this special case, if not, then let it go like normal). Then from there you can handle it smarter. If the turnaround point is within the current timestep, just turn it around and make it go the other way. Anyway, the downside is it makes you treat collisions with water as a special case, but I think preventing it from going too deep in the first place is probably the way to go.