function VectorMovementCollision( startPoint1, endPoint1, v1, startPoint2, v2, delay)
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
--v2 * t = Distance(P, A + t * v1 * (B-A):Norm())
--(v2 * t)^2 = (r+S*t)^2+(j+K*t)^2 and v2 * t >= 0
--0 = (S*S+K*K-v2*v2)*t^2+(-r*S-j*K)*2*t+(r*r+j*j) and v2 * t >= 0
local d, e = eP1x- sP1x, eP1y- sP1y
local dist, t1, t2 = math.sqrt ( d* d+ e* e) , nil , nil
local S, K = dist~= 0 and v1* d/ dist or 0 , dist~= 0 and v1* e/ dist or 0
local function GetCollisionPoint( t) return t and { x = sP1x+ S* t, y = sP1y+ K* t} or nil end
if delay and delay~= 0 then sP1x, sP1y = sP1x+ S* delay, sP1y+ K* delay end
local r, j = sP2x- sP1x, sP2y- sP1y
local c = r* r+ j* j
if dist> 0 then
if v1 == math . huge then
local t = dist/ v1
t1 = v2* t>= 0 and t or nil
elseif v2 == math . huge then
t1 = 0
else
local a, b = S* S+ K* K- v2* v2, - r* S- j* K
if a== 0 then
if b== 0 then --c=0->t variable
t1 = c== 0 and 0 or nil
else --2*b*t+c=0
local t = - c/ ( 2 * b)
t1 = v2* t>= 0 and t or nil
end
else --a*t*t+2*b*t+c=0
local sqr = b* b- a* c
if sqr>= 0 then
local nom = math.sqrt ( sqr)
local t = ( - nom- b) / a
t1 = v2* t>= 0 and t or nil
t = ( nom- b) / a
t2 = v2* t>= 0 and t or nil
end
end
end
elseif dist== 0 then
t1 = 0
end
return t1, GetCollisionPoint( t1) , t2, GetCollisionPoint( t2) , dist
end
local A = { x = 1 , y = 5 } -- Alice's initial position
local B = { x = 4 , y = 1 } -- Rabbit's initial position
local H = { x = 6 , y = 7 } -- Hole's coordinates
local Sa = 1.1 -- Alice's speed
local Sb = 1.0 -- Rabbit's speed
local t1, p1, t2, p2 = VectorMovementCollision( B, H, Sb, A, Sa, 0 )
if t1 and p1 then
print ( "Time: " .. t1 .. " Position {" .. p1. x .. "," .. p1. y .. "}" )
end
if t2 and p2 then
print ( "Time: " .. t2 .. " Position {" .. p2. x .. "," .. p2. y .. "}" )
end
ZnVuY3Rpb24gVmVjdG9yTW92ZW1lbnRDb2xsaXNpb24oc3RhcnRQb2ludDEsIGVuZFBvaW50MSwgdjEsIHN0YXJ0UG9pbnQyLCB2MiwgZGVsYXkpCiAgICBsb2NhbCBzUDF4LCBzUDF5LCBlUDF4LCBlUDF5LCBzUDJ4LCBzUDJ5ID0gc3RhcnRQb2ludDEueCwgc3RhcnRQb2ludDEueiBvciBzdGFydFBvaW50MS55LCBlbmRQb2ludDEueCwgZW5kUG9pbnQxLnogb3IgZW5kUG9pbnQxLnksIHN0YXJ0UG9pbnQyLngsIHN0YXJ0UG9pbnQyLnogb3Igc3RhcnRQb2ludDIueQogICAgLS12MiAqIHQgPSBEaXN0YW5jZShQLCBBICsgdCAqIHYxICogKEItQSk6Tm9ybSgpKQogICAgLS0odjIgKiB0KV4yID0gKHIrUyp0KV4yKyhqK0sqdCleMiBhbmQgdjIgKiB0ID49IDAKICAgIC0tMCA9IChTKlMrSypLLXYyKnYyKSp0XjIrKC1yKlMtaipLKSoyKnQrKHIqcitqKmopIGFuZCB2MiAqIHQgPj0gMAogICAgbG9jYWwgZCwgZSA9IGVQMXgtc1AxeCwgZVAxeS1zUDF5CiAgICBsb2NhbCBkaXN0LCB0MSwgdDIgPSBtYXRoLnNxcnQoZCpkK2UqZSksIG5pbCwgbmlsCiAgICBsb2NhbCBTLCBLID0gZGlzdH49MCBhbmQgdjEqZC9kaXN0IG9yIDAsIGRpc3R+PTAgYW5kIHYxKmUvZGlzdCBvciAwCiAgICBsb2NhbCBmdW5jdGlvbiBHZXRDb2xsaXNpb25Qb2ludCh0KSByZXR1cm4gdCBhbmQge3ggPSBzUDF4K1MqdCwgeSA9IHNQMXkrSyp0fSBvciBuaWwgZW5kCiAgICBpZiBkZWxheSBhbmQgZGVsYXl+PTAgdGhlbiBzUDF4LCBzUDF5ID0gc1AxeCtTKmRlbGF5LCBzUDF5K0sqZGVsYXkgZW5kCiAgICBsb2NhbCByLCBqID0gc1AyeC1zUDF4LCBzUDJ5LXNQMXkKICAgIGxvY2FsIGMgPSByKnIraipqCiAgICBpZiBkaXN0PjAgdGhlbgogICAgICAgIGlmIHYxID09IG1hdGguaHVnZSB0aGVuCiAgICAgICAgICAgIGxvY2FsIHQgPSBkaXN0L3YxCiAgICAgICAgICAgIHQxID0gdjIqdD49MCBhbmQgdCBvciBuaWwKICAgICAgICBlbHNlaWYgdjIgPT0gbWF0aC5odWdlIHRoZW4KICAgICAgICAgICAgdDEgPSAwCiAgICAgICAgZWxzZQogICAgICAgICAgICBsb2NhbCBhLCBiID0gUypTK0sqSy12Mip2MiwgLXIqUy1qKksKICAgICAgICAgICAgaWYgYT09MCB0aGVuIAogICAgICAgICAgICAgICAgaWYgYj09MCB0aGVuIC0tYz0wLT50IHZhcmlhYmxlCiAgICAgICAgICAgICAgICAgICAgdDEgPSBjPT0wIGFuZCAwIG9yIG5pbAogICAgICAgICAgICAgICAgZWxzZSAtLTIqYip0K2M9MAogICAgICAgICAgICAgICAgICAgIGxvY2FsIHQgPSAtYy8oMipiKQogICAgICAgICAgICAgICAgICAgIHQxID0gdjIqdD49MCBhbmQgdCBvciBuaWwKICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICBlbHNlIC0tYSp0KnQrMipiKnQrYz0wCiAgICAgICAgICAgICAgICBsb2NhbCBzcXIgPSBiKmItYSpjCiAgICAgICAgICAgICAgICBpZiBzcXI+PTAgdGhlbgogICAgICAgICAgICAgICAgICAgIGxvY2FsIG5vbSA9IG1hdGguc3FydChzcXIpCiAgICAgICAgICAgICAgICAgICAgbG9jYWwgdCA9ICgtbm9tLWIpL2EKICAgICAgICAgICAgICAgICAgICB0MSA9IHYyKnQ+PTAgYW5kIHQgb3IgbmlsCiAgICAgICAgICAgICAgICAgICAgdCA9IChub20tYikvYQogICAgICAgICAgICAgICAgICAgIHQyID0gdjIqdD49MCBhbmQgdCBvciBuaWwKICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICBlbmQKICAgICAgICBlbmQKICAgIGVsc2VpZiBkaXN0PT0wIHRoZW4KICAgICAgICB0MSA9IDAKICAgIGVuZAogICAgcmV0dXJuIHQxLCBHZXRDb2xsaXNpb25Qb2ludCh0MSksIHQyLCBHZXRDb2xsaXNpb25Qb2ludCh0MiksIGRpc3QKZW5kCgpsb2NhbCBBID0geyB4ID0gMSwgeSA9IDV9IC0tIEFsaWNlJ3MgaW5pdGlhbCBwb3NpdGlvbgpsb2NhbCBCID0geyB4ID0gNCx5ID0gMSB9IC0tIFJhYmJpdCdzIGluaXRpYWwgcG9zaXRpb24KbG9jYWwgSCA9ICB7IHggPSA2LCB5ID0gNyB9IC0tIEhvbGUncyBjb29yZGluYXRlcwpsb2NhbCBTYSA9IDEuMSAtLSBBbGljZSdzIHNwZWVkCmxvY2FsIFNiID0gMS4wIC0tIFJhYmJpdCdzIHNwZWVkCmxvY2FsIHQxLCBwMSwgdDIsIHAyID0gVmVjdG9yTW92ZW1lbnRDb2xsaXNpb24oQiwgSCwgU2IsIEEsIFNhLCAwKQppZiB0MSBhbmQgcDEgdGhlbgoJcHJpbnQoIlRpbWU6ICIgLi4gdDEgLi4gIiBQb3NpdGlvbiB7IiAuLiBwMS54IC4uICIsIiAuLiBwMS55IC4uICJ9IikKZW5kCmlmIHQyIGFuZCBwMiB0aGVuCglwcmludCgiVGltZTogIiAuLiB0MiAuLiAiIFBvc2l0aW9uIHsiIC4uIHAyLnggLi4gIiwiIC4uIHAyLnkgLi4gIn0iKQplbmQK