Why do the results of SweepTest differ from the actual collision contact?

I want to predict the outcome of a very simple collision in Unity, but I’m having trouble.

I’m throwing a sphere at a capsule. The sphere strikes the middle of the capsule and both are constrained so that the collision is essentially two 2D circles colliding.

To predict the outcome of such a collision I need the point of contact and the normal at the point of contact. I’ve tried getting these values from Physics.SphereCast and rigidBody.SweepTest, the results of which I am sure are valid and accurate, but the prediction based on the values differed from Unity’s physics simulation.

I have discovered a possible origin of the problem: the point of contact returned from SweepTest and SphereCast are the same, but different from the point of contact from collisionInfo.contacts in the OnCollisionEnter method. Why is this and how can I predict Unity’s physics calculations?

Does anyone have any insight about the difference between casting/sweeping and how the physics system works?