You want to pass either the pair (-vy, vx) or the pair (vy, -vx), depending on which side of the line your ball is.
Your line will have a normal pointing out of it at 90 degrees. You get this the same way: turn your line into a ray, (x2 - x1, y2 - y1), or (rx, ry) for short, then choose one of the two perpendiculars, say (-ry, rx). You can normalize this vector, although for this purpose it doesn’t matter. Now, you have another ray, the one from the impact point to part of your object (like the center; obviously not the part that impacted, or your vector will be 0-length
), so (center x - impact x, center y - impact y), or (dx, dy) for short.
You can use the dot product to find the angle between two vectors: cos(angle) = (vx * wx + vy * wy) / (length(v) * (length(w))
The cosine will be positive if the angle is less than 90 degrees, 0 if it’s exactly 90 degrees, negative if more than 90 degrees.
Going back to your case, if the impact-to-center array dotted with the normal is greater than 0, it’s on one side of the line, if it’s 0, it hit the line perfectly parallel, it’s on the other side of the line.
So something like:
local linex, liney = endx - startx, endy - starty local rx, ry = -liney, linex local dx, dy = centerx - impactx, centery - impacty if rx \* dx + ry \* dy \> 0 then object:setLinearVelocity(-vy, vx) -- Untested, may be backwards :) else -- just handle the 0 case here too object:setLinearVelocity(vy, -vx) end
The lengths will both be positive and thus can be ignored. You never actually use the cosine, except to formulate the solution.