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?
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?
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?
-- 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)
Basing on @5uphi answer