fork download
  1. function VectorMovementCollision(startPoint1, endPoint1, v1, startPoint2, v2, delay)
  2. local sP1x, sP1y, eP1x, eP1y, sP2x, sP2y = startPoint1.x, startPoint1.z or startPoint1.y, endPoint1.x, endPoint1.z or endPoint1.y, startPoint2.x, startPoint2.z or startPoint2.y
  3. --v2 * t = Distance(P, A + t * v1 * (B-A):Norm())
  4. --(v2 * t)^2 = (r+S*t)^2+(j+K*t)^2 and v2 * t >= 0
  5. --0 = (S*S+K*K-v2*v2)*t^2+(-r*S-j*K)*2*t+(r*r+j*j) and v2 * t >= 0
  6. local d, e = eP1x-sP1x, eP1y-sP1y
  7. local dist, t1, t2 = math.sqrt(d*d+e*e), nil, nil
  8. local S, K = dist~=0 and v1*d/dist or 0, dist~=0 and v1*e/dist or 0
  9. local function GetCollisionPoint(t) return t and {x = sP1x+S*t, y = sP1y+K*t} or nil end
  10. if delay and delay~=0 then sP1x, sP1y = sP1x+S*delay, sP1y+K*delay end
  11. local r, j = sP2x-sP1x, sP2y-sP1y
  12. local c = r*r+j*j
  13. if dist>0 then
  14. if v1 == math.huge then
  15. local t = dist/v1
  16. t1 = v2*t>=0 and t or nil
  17. elseif v2 == math.huge then
  18. t1 = 0
  19. else
  20. local a, b = S*S+K*K-v2*v2, -r*S-j*K
  21. if a==0 then
  22. if b==0 then --c=0->t variable
  23. t1 = c==0 and 0 or nil
  24. else --2*b*t+c=0
  25. local t = -c/(2*b)
  26. t1 = v2*t>=0 and t or nil
  27. end
  28. else --a*t*t+2*b*t+c=0
  29. local sqr = b*b-a*c
  30. if sqr>=0 then
  31. local nom = math.sqrt(sqr)
  32. local t = (-nom-b)/a
  33. t1 = v2*t>=0 and t or nil
  34. t = (nom-b)/a
  35. t2 = v2*t>=0 and t or nil
  36. end
  37. end
  38. end
  39. elseif dist==0 then
  40. t1 = 0
  41. end
  42. return t1, GetCollisionPoint(t1), t2, GetCollisionPoint(t2), dist
  43. end
  44.  
  45. local A = { x = 1, y = 5} -- Alice's initial position
  46. local B = { x = 4,y = 1 } -- Rabbit's initial position
  47. local H = { x = 6, y = 7 } -- Hole's coordinates
  48. local Sa = 1.1 -- Alice's speed
  49. local Sb = 1.0 -- Rabbit's speed
  50. local t1, p1, t2, p2 = VectorMovementCollision(B, H, Sb, A, Sa, 0)
  51. if t1 and p1 then
  52. print("Time: " .. t1 .. " Position {" .. p1.x .. "," .. p1.y .. "}")
  53. end
  54. if t2 and p2 then
  55. print("Time: " .. t2 .. " Position {" .. p2.x .. "," .. p2.y .. "}")
  56. end
  57.  
Success #stdin #stdout 0.02s 2540KB
stdin
Standard input is empty
stdout
Time: 3.8462632720832 Position {5.2162952420435,4.6488857261305}