This article will explain how to do Instantenous Circle-Circle Collision.
DISCLAIMER: Note that "Instantenous" means that it is solved at the current instant with no information from the past or the future, which means velocity will not be taken into account. Thus questions like "what if my object is moving too fast?" is irrelevent.
First, let's define our circles. In this article, we will use two circles, we will call them \(s\) and \(k\).
Circles are represented by a center of origin and a radius. The center of origins for our circles \(s\) and \(k\) centers are denoted with \(\dot{s_o}\) and \(\dot{k_o}\) respectively, and their radiuses are \(s_r\) and \(k_r\) respectively.
Finding whether two circles are overlapping is simple: we take the distance \(d\) between their center of origins and compare it to their combined radius. If the distance is less than their combined radius, then they are colliding.
The distance between our two circles is simply the distance between two points:
$$ d = \sqrt{(\dot{s_o} - \dot{k_o})^2_x + (\dot{s_o} - \dot{k_o})^2_y} $$So to check if two circles are overlapping, we just need to check that:
$$ d < (s_r + k_r) $$Personally, I tend to compare the difference against zero like so:
$$ d - (s_r + k_r) < 0 $$The difference can be useful in other calculations.
In programming, there can be instances where square root is not avaliable or argued to be 'expensive'.
If checking for overlapping is all you need, a common trick is to square both sides.
$$ d^2 < (s_r + k_r)^2 $$This will avoid any use of square root.
Here we are going to show the common collision response between two circles where we push them away from each other.
We need to find the penetration vector \(\vec{p}\) that pushes one circle out of the other. We can solve this by seperating the vector into its basic components: its normalized direction \(\vec{p_{dir}}\) and its magnitude \(|\vec{p}|\). In other words:
$$ \vec{p} = \vec{p_{dir}} * |\vec{p}| $$The normalized direction is simply the vector between the two circle's origins normalized:
$$ \vec{p_{dir}} = \frac{\vec{(\dot{s_o} - \dot{k_o})}}{d} $$The magnitude is simply the difference between the distance of the two circles and their combined radius, which we did earlier:
$$ |\vec{p}| = d - (s_r + k_r) $$Observe the demo below and drag the circles around. Let the purple circle be \(s\) and the orange circle be \(k\). The black line represents the distance between them, the purple line represents \(s_r\), the orange line represents \(k_r\). When the circles are overlapping, you will see a red line appear representing \(|\vec{p}|\).
Now that we have our penetration vector \(\vec{p}\), how we want to push our circles back is really up to us. We can divide the vector into half and push both circles away from each other equally, or make it so that one circle moves out of the other circle completely while the other circle remains static.
The demo below shows an example of how you can use the ratios of both circle's 'mass' value to affect how much to push our circles back, giving the illusion of weight.