0

Circle A is moving right along the x axis. Circle B is moving up along the y axis. I would like to know if they are going to collide. (not when, just if.)

Radii are same, different constant velocities.

This answer seems to address the issue and my question should better have been a followup to that. (Apologies for not having enough reputation to comment.)

I can't seem to solve for t (time) the provided equation (the circles will collide if t exists):

(Oax + t*Dax - Obx - t*Dbx)^2 + (Oay + t*Day - Oby - t*Dby)^2 = (ra + rb)^2

Here again in readable terms:

(CircleA.initialPosition.x + t*CircleA.velocity.x - 
 CircleB.initialPosition.x - t*CircleB.velocity.x)^2
+
(CircleA.initialPosition.y + t*CircleA.velocity.y - 
 CircleB.initialPosition.y - t*CircleB.velocity.y)^2
=
(CircleA.radius + CircleB.radius)^2

Which in my case is a little simpler since the circles are moving along the axes (velocity is 0 on one axis) and the radii are same:

(CircleA.initialPosition.x + t*CircleA.velocity.x - 
 CircleB.initialPosition.x)^2
+
(CircleA.initialPosition.y - CircleB.initialPosition.y - 
 t*CircleB.velocity.y)^2
=
(2*radius)^2

Still I can't solve it, and the provided link to the auto-solver doesn't help my thick head either.

(In particular I don't get

sqrt(-(D4 - D3)^2)

The expression inside sqrt() is always negative, so it always fails. What am I missing?)

Auto-solver aside, I hope someone could show the way to solve the equation for t (and maybe a moderator could combine the questions, sorry for the trouble).

Or, any other way to tackle the issue, maybe using a built-in box2d feature I am not aware of.

Arigato
  • 61
  • 5
  • You can reduce this to a line/circle intersection problem. You can treat two moving circles as one circle moving diagonally (shift your reference frame such that one circle is stationary). Then you want to know when the centers are closer than `r1+r2` apart. Well, that's just a bigger circle with radius `r1+r2`, and the center of the moving circle is moving in a line. Hence, a line/circle intersection problem. – k_ssb Jun 03 '18 at 06:55
  • Interesting approach. The time factor will have to be incorporated since it is a prediction. So if, say, a bigger circle (r1+r2) is moving along the x axis, and a line, or a point rather, is moving along the y axis, then I would have to find t1 and t2 - the times when the circle's right- and left-most edges (circle.x+r and circle.x-r) cross Point.x, then find t3 - the time when Point.y crosses Circle.y (center), and if t3 falls between t1 and t2 then it means there will be a collision. Am I on the right track? Is this really equivalent to a circle-circle prediction? I'm not entirely sure. – Arigato Jun 03 '18 at 10:02
  • If you know the coordinates of everything (starting points and two intersections) and the velocities of moving parts, then you can calculate time by the formula `v = d/t`. And by the way, when I say "line/circle intersection problem", neither the line or the circle are moving. It's a pure algebra problem. The entire point is to reduce your moving-shapes problem into a static non-moving one, which is easier to reason about. – k_ssb Jun 03 '18 at 10:47
  • Yes, all coordinates are known and I use velocity and distance to retrieve time. It is not a static problem because it deals with a future intersection and the objects have to move. Time is a factor. One way to approach this is to simulate box2d world moving forward in time and see if intersection occurs. But this would be a burden on performance and the problem is simple enough to solve another way. I tried the point-circle way - getting inconsistent results. – Arigato Jun 03 '18 at 14:46
  • Are your velocities constant? If so, then it does _become_ a static problem. I know you want the future time of intersection, but this method _will_ let you compute that without simulating anything -- it's all math. – k_ssb Jun 03 '18 at 14:49
  • Velocities are constant, yes. I don't follow you apparently, it would help if you could be more specific with some calcs or code, an actual way. – Arigato Jun 03 '18 at 17:00

2 Answers2

1

The accepted solution is missing something. In order to solve this equation with:

x = (−b ± sqrt(b^2 - 4ac)) / 2a

which means that:

x1 = (−b + sqrt(b^2 - 4ac)) / 2a and x2 = (−b - sqrt(b^2 - 4ac)) / 2a

At least x1 or x2 needs to be positive in order for a collision to be detected correctly. If both are negative, there will be no collision.

  • In my game at the time the prediction is made, the positions and velocities of the balls are such that a collision can only occur in the future, thus the above calculation works. In general you are right. For the detection to be correct in all scenarios, the sign of t has to be checked. I updated the answer. Thank you. – Arigato Jul 16 '19 at 11:05
0

Well, I figured out how to solve the equation for t.

(Oax + t*Dax - Obx - t*Dbx)^2 + (Oay + t*Day - Oby - t*Dby)^2 = (ra + rb)^2


(Oax * (Oax + t*Dax - Obx - t*Dbx) + t*Dax * (Oax + t*Dax - Obx - t*Dbx)
 - Obx * (Oax + t*Dax - Obx - t*Dbx) - t*Dbx * (Oax + t*Dax - Obx - t*Dbx))
+
(Oay * (Oay + t*Day - Oby - t*Dby) + t*Day * (Oay + t*Day - Oby - t*Dby)
 - Oby * (Oay + t*Day - Oby - t*Dby) - t*Dby * (Oay + t*Day - Oby - t*Dby))
=
(ra + rb)^2


Oax^2 + (Oax * t*Dax) - (Oax * Obx) - (Oax * t*Dbx)
 + (t*Dax * Oax) + (t*Dax)^2 - (t*Dax * Obx) - (t*Dax * t*Dbx)
 - (Obx * Oax) - (Obx * t*Dax) + Obx^2 + (Obx * t*Dbx)
 - (t*Dbx * Oax) - (t*Dbx * t*Dax) + (t*Dbx * Obx) + (t*Dbx)^2
+
Oay^2 + (Oay * t*Day) - (Oay * Oby) - (Oay * t*Dby)
 + (t*Day * Oay) + (t*Day)^2 - (t*Day * Oby) - (t*Day * t*Dby)
 - (Oby * Oay) - (Oby * t*Day) + Oby^2 + (Oby * t*Dby)
 - (t*Dby * Oay) - (t*Dby * t*Day) + (t*Dby * Oby) + (t*Dby)^2
=
(ra + rb)^2


t^2 * (Dax^2 +Dbx^2 - (Dax * Dbx) - (Dbx * Dax)
       + Day^2 +Dby^2 - (Day * Dby) - (Dby * Day))
+
t * ((Oax * Dax) - (Oax * Dbx) + (Dax * Oax) - (Dax * Obx)
      - (Obx * Dax) + (Obx * Dbx) - (Dbx * Oax) + (Dbx * Obx)
      + (Oay * Day) - (Oay * Dby) + (Day * Oay) - (Day * Oby)
      - (Oby * Day) + (Oby * Dby) - (Dby * Oay) + (Dby * Oby))
+
Oax^2 - (Oax * Obx) - (Obx * Oax) + Obx^2
  + Oay^2 - (Oay * Oby) - (Oby * Oay) + Oby^2 - (ra + rb)^2
=
0

Now it's a standard form quadratic equation:

ax2 + bx + c = 0

solved like this:

x = (−b ± sqrt(b^2 - 4ac)) / 2a       // this x here is t

where--

a = Dax^2 +Dbx^2 + Day^2 +Dby^2 - (2 * Dax * Dbx) - (2 * Day * Dby)

b = (2 * Oax * Dax) - (2 * Oax * Dbx) - (2 * Obx * Dax) + (2 * Obx * Dbx)
     + (2 * Oay * Day) - (2 * Oay * Dby) - (2 * Oby * Day) + (2 * Oby * Dby)

c = Oax^2 + Obx^2 + Oay^2 + Oby^2
    - (2 * Oax * Obx) - (2 * Oay * Oby) - (ra + rb)^2

t exists (collision will occur) if--

(a != 0) && (b^2 >= 4ac)

UPDATE:

As Moe Amin Allani astutely observed, at least one solution for t has to be positive in order to detect a collision in the future, as opposed to a collision that allegedly took place earlier.

Arigato
  • 61
  • 5