I need to find if two round objects will collide and if yes when in time they will.
My approach is this:
if (Vector3.DistanceSquared(a.Position, b.Position) < Math.Pow(a.Radius b.Radius,2))
{
return 0;
}
else
{
float result;
for (int t = 1; t < 150; t )
{
result = Vector3.DistanceSquared(a.Position t * a.LinearVelocity, b.Position t * b.LinearVelocity);
if (float.IsInfinity(result))
{
return float.PositiveInfinity;
}
if (result <= Math.Pow(a.Radius b.Radius,2))
{
return t;
}
}
return float.PositiveInfinity;
}
I am clearly missing something, or I am totally wrong cause the results are not as expected.
I also think performance wise the loop might be wrong but I am not sure how could I avoid it.
CodePudding user response:
If we write squared distance between circle centers:
(x2-x1 t*(vx2-vx1))^2 (y2-y1 t*(vy2-vy1))^2=(r1 r2)^2
let dx = x2-x1, dy = y2-y1, dvx = vx2-vx1, dvy = vy2-vy1, rr = r1 r2
(dx t*dvx)^2 (dy t*dvy)^2=rr^2
dx^2 2*dx*t*dvx t^2*dvx^2 dy^2 2*dy*t*dvy t^2*dvy^2-rr^2=0
t^2*(dvx^2 dvy^2) t*(2*dx*dvx 2*dy*dvy) (dx^2 dy^2-rr^2)=0
t^2*a t*b c =0
This is quadratic equation for unknown t
D = b^2 - 4*a*c
if D<0 there are no collisions
if D=0 there is one touching in moment t = -b/(2*a)
else there are two solutions
t1 = (-b - sqrt(D)) / (2*a)
t2 = (-b sqrt(D)) / (2*a)
One or both times might be negative - means collision "was in the past"
Smaller time is moment of collision, larger time - moment of "leaving", I think it is not needed here