# Calculate which frame collides most

Hello, the question is fairly simple - I have 1 frame and a table of a few frames (5). I need to detect with which frame does my given frame overlap most. I got it working to check if it collides at all.

``````function areFramesOverlapping(mainFrame, frames)
local collidingFrames = {}

local mainFrame_topLeft = mainFrame.AbsolutePosition
local mainFrame_bottomRight = mainFrame_topLeft + mainFrame.AbsoluteSize

for _, frame in ipairs(frames) do
local frame_topLeft = frame.AbsolutePosition
local frame_bottomRight = frame_topLeft + frame.AbsoluteSize

if (mainFrame_topLeft.x < frame_bottomRight.x and mainFrame_bottomRight.x > frame_topLeft.x) and (mainFrame_topLeft.y < frame_bottomRight.y and mainFrame_bottomRight.y > frame_topLeft.y) then
table.insert(collidingFrames, frame)
end
end

return collidingFrames
end
``````

This currently returns a table of frames which over a given frame collides with. Now how could I remake this to return the frame with which frame1 collides the most? I am happy to answer any more questions

What do you mean by â€śmostâ€ť? Given a rectangular area of overlap for each frame, should the one with the largest area of overlap win, or the one with longest diagonal, or the one with the longest side length?

Overally the most area. I can give you an example :

Here you can see I have 5 frames and I main frame (Item 11) and it collides most with the frame 3 because its total area of collision is bigger then with any other frame. Now how would I go about it to implement it in the code?

i think this post will work for you 2 Dimensional Collisions | Fundamentals & Techniques

function DetectCollision(A, B)
if (B.AbsolutePosition.x <= A.AbsolutePosition.x + A.AbsoluteSize.x) then
return true â€“ colliding
end

``````return false
``````

end

This is what i think i already have - it just checks for collision and doesnt check which frame collides most

while this is not what your asking here is a more simple method

``````local frames = script.xxxxxxx:GetChildren()

local draggingFrame = xxxxxx
local draggingCenter = draggingFrame.AbsolutePosition + (draggingFrame.AbsoluteSize * 0.5)

local function GetClosestFrame()
local closestFrame = nil
local closestMagnitude = math.huge
for i, frame in ipairs(frames) do
local center = frame.AbsolutePosition + (frame.AbsoluteSize * 0.5)
local magnitude = (center - draggingCenter).Magnitude
if magnitude >= closestMagnitude then continue end
closestFrame = frame
closestMagnitude = magnitude
end
return closestFrame, closestMagnitude
end

local frame, magnitude = GetClosestFrame()
print(frame, magnitude)

local minDistance = math.max(draggingFrame.AbsoluteSize.X, draggingFrame.AbsoluteSize.Y) * 2

if magnitude <= minDistance then
print("In range")
else
print("Out of range")
end

``````

Hm yes itâ€™s very similar and maybe more clear but does anyone know how could I at least calculate the area of the collision? @5uphi wouldnâ€™t I just multiply the difference in X and difference in Y if it collides and then compare this to other colliding frame?

I think comparing the colliding areas would work just fine but how could I get `A2`, `B2`, `A3`, `B3`? (see screenshot)

i have not tested this code

``````local function Area(frame1, frame2)
local f1 = {
frame1.AbsolutePosition.X,
frame1.AbsolutePosition.Y,
frame1.AbsolutePosition.X + frame1.AbsoluteSize.X
frame1.AbsolutePosition.Y + frame1.AbsoluteSize.Y
}
local f2 = {
frame2.AbsolutePosition.X,
frame2.AbsolutePosition.Y,
frame2.AbsolutePosition.X + frame2.AbsoluteSize.X
frame2.AbsolutePosition.Y + frame2.AbsoluteSize.Y
}
local dx = math.max(math.max(f1[1], f2[1]) - math.min(f1[3], f2[3]), 0)
local dy = math.max(math.max(f1[2], f2[2]) - math.min(f1[4], f2[4]), 0)
return dx * dy
end
``````

The final code

``````-- To get the frames which collide with the mainFrame
function areFramesOverlapping(mainFrame, frames)
local collidingFrames = {}

local mainFrame_topLeft = mainFrame.AbsolutePosition
local mainFrame_bottomRight = mainFrame_topLeft + mainFrame.AbsoluteSize

for _, frame in ipairs(frames) do
local frame_topLeft = frame.AbsolutePosition
local frame_bottomRight = frame_topLeft + frame.AbsoluteSize

if (mainFrame_topLeft.x < frame_bottomRight.x and mainFrame_bottomRight.x > frame_topLeft.x) and (mainFrame_topLeft.y < frame_bottomRight.y and mainFrame_bottomRight.y > frame_topLeft.y) then
table.insert(collidingFrames, frame)
end
end

return collidingFrames
end
-- To get closest frame of colliding frames
local function GetClosestFrame(draggingFrame, frames)
local draggingCenter = draggingFrame.AbsolutePosition + (draggingFrame.AbsoluteSize * 0.5)
local closestFrame = nil
local closestMagnitude = math.huge
for i, frame in ipairs(frames) do
local center = frame.AbsolutePosition + (frame.AbsoluteSize * 0.5)
local magnitude = (center - draggingCenter).Magnitude
if magnitude >= closestMagnitude then continue end
closestFrame = frame
closestMagnitude = magnitude
end
return closestFrame
end
``````

Calling the functions â†’

``````local closestFrame = GetClosestFrame(dragFrame.Object, areFramesOverlapping(dragFrame.Object, pets))
print(closestFrame)
``````

(I know the codeâ€™s a mess and can be simpler/prettier)
Iâ€™ve split it to 2 functions like this to also check the Y axis
(`pets` here is a table of frames)