Making a radius detection not compare to the center of the part but instead how close the edge of the part is

Sorry for the long title but it explains everything. I’m looking to make my function (below) not use the center of the part for comparing radius (using magnitude) but find the closest parts based on the entire brick.

function module.GetPartsInRadius(point, radius)
    local list = {} 
    local f; function f(x)
        for _,v in pairs(x:GetChildren())do
            f(v)
            if v:IsA("BasePart") and (v.Position - point).Magnitude <= radius then
                list[#list + 1] = v
            end
        end
    end
    f(workspace)
    return list
end

Here is a drawing to explain it better:

3 Likes

Instead of what you have here:

(v.Position - point).Magnitude <= radius

Use this:

-- Convert the point to object-relative coordinates (0,0,0 is the center of the part).
local relativePoint = v.CFrame:ToObjectSpace(point)
-- Get the absolute value of every component. This makes every component a positive value, which is important for the subtraction we're about to do.
relativePoint = Vector3.new(
    math.abs(relativePoint.X),
    math.abs(relativePoint.Y),
    math.abs(relativePoint.Z)
)
-- Subtract half the size from the point. This makes it so if all the components are <= 0, the point is inside the part.
relativePoint = relativePoint - v.Size * 0.5
-- Clamp negative values to 0 so that .Magnitude is always == 0 if the point is inside the part
relativePoint = Vector3.new(
    math.max(0, relativePoint.X),
    math.max(0, relativePoint.Y),
    math.max(0, relativePoint.Z)
)
-- Finally, compute the distance from the edge
local isInsideRadius = (relativePoint.Magnitude <= radius)

You’ll probably want to separate it out into a separate function like pointInRadiusOfPart(part, radius, point) that returns the isInsideRadius.

7 Likes

I know I’m late to this post but can you explain you code, I never seen anyone write it like that @Crystalflxme