3
\$\begingroup\$

If you have a stationary circle with radius x, and a moving circle with radius y, when a collision is detected, how can you resolve the collision, such that the moving circle stop?

I.e. What would be the 'resolved' position of the moving circle?

\$\endgroup\$
3
  • \$\begingroup\$ Does it only need to stop at the moment of contact, or do you want to deflect/roll it around the obstacle to some extent? \$\endgroup\$
    – DMGregory
    Commented May 18, 2018 at 18:09
  • \$\begingroup\$ It only needs to stop. \$\endgroup\$
    – 19172281
    Commented May 18, 2018 at 18:10
  • \$\begingroup\$ Although, it may also need to roll around the obstacle. Perhaps you could show both options. \$\endgroup\$
    – 19172281
    Commented May 18, 2018 at 18:11

2 Answers 2

3
\$\begingroup\$

Let's say the moving circle \$A\$ has radius \$r_A\$, starts at position \$ \vec p_A\$, and travels with velocity \$ \vec v \$

And let's say the stationary circle \$ B \$ has radius \$ r_B \$ and sits at \$ \vec p_B \$

We can simplify our work a little by defining:

$$\begin{align} \vec p &= \vec p_A - \vec p_B\\ R &= r_A + r_B \end{align}$$

Now we've reduced the problem to finding where the ray from \$\vec p\$ in direction \$\vec v\$ strikes a circle at the origin with radius \$R\$, ie...

$$ \lVert \vec p + t \cdot \vec v \rVert = R $$

at some time in seconds \$t\$ after the start of the motion. Now we solve for \$t\$:

$$\begin{align} \lVert \vec p + t \cdot \vec v \rVert^2 &= R^2\\ \left(\vec p + t \cdot \vec v\right) \cdot \left(\vec p + t \cdot \vec v\right) &= R^2\\ \left(\vec p \cdot \vec p\right) + 2t\left(\vec p \cdot \vec v\right) + t^2\left(\vec v \cdot \vec v\right) &= R^2 \end{align}$$

which we can solve with the quadratic formula:

$$\begin{align} t &= \frac {-2\left(\vec p \cdot \vec v \right) \pm \sqrt{4 \left(\vec p \cdot \vec v \right)^2- 4 \left(\vec v \cdot \vec v\right)\left(\vec p \cdot \vec p - R^2\right)} }{2\left(\vec v \cdot \vec v\right)}\\ t &= \frac {-\left(\vec p \cdot \vec v \right) \pm \sqrt{\left(\vec p \cdot \vec v \right)^2- \left(\vec v \cdot \vec v\right)\left(\vec p \cdot \vec p - R^2\right)} }{\left(\vec v \cdot \vec v\right)} \end{align}$$

  • If the expression inside the radical is negative, then the circles miss each other.

  • If it's zero, then they have a glancing point contact at the sole solution for \$t\$.

  • If it's positive, then there are two possible solutions (one collision on the way in, one on the way out), so choose the smallest positive value for \$t\$.

    (If all solutions are negative then the collision happened "in the past," and circle \$A\$ is currently moving away from circle \$B\$)

With a positive value for \$t\$, you can form:

$$\vec p_\text{A contact} = \vec p_A + t \cdot \vec v$$

the position of circle \$A\$ the moment it enters contact with circle \$B\$.

\$\endgroup\$
0
0
\$\begingroup\$

function getColl(x1, y1, r1, x2, y2, r2)

local distance = math.sqrt(math.pow(x2 - x1,2) + math.pow(y2 - y1,2))

if distance < r1 + r2 then return true else return false end

end

This is the function to check collision between 2 circles, the r1 and r2 are the radius of the circle

For resolving, it's going to be a bit more complex, and there are multiple ways to do it, I recommend you to learn basic rectangle with rectangle collision resolution first before circle.

if your circle can only move in 8 directions, you can make a variable to predict the next movement, if for example the next movement to the left is colliding with another circle, then you can resist that movement by making the x velocity to zero.

If you circles move in more than 8 directions, you can store the positions in an array, if the circle collide, change the circle position to the previous position.

If you also don't want that you can use the pure math mentioned above

\$\endgroup\$
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .