I stumbled across this by accident while trying to find a way to select the *edge* of a part:
local function NumNormal(n)
return n == 0 and 0 or n/math.abs(n)
end
local function GetSurfaceNormal(part,point)
local p = part.CFrame:toObjectSpace(CFrame.new(point)).p
local s = part.Size
local ax,ay,az = math.abs(p.x/s.x),math.abs(p.y/s.y),math.abs(p.z/s.z)
return Vector3.new(NumNormal(p.x),NumNormal(p.y),NumNormal(p.z)) * Vector3.new(
(ax>ay and ax>az) and 1 or 0,
(ay>ax and ay>az) and 1 or 0,
(az>ax and az>ay) and 1 or 0
)
end
Here's the nearest edge function as well, if you're interested:
local function GetNearestEdge(part,point)
local p = part.CFrame:toObjectSpace(CFrame.new(point)).p
local s = part.Size
local ax,ay,az = math.abs(p.x/s.x),math.abs(p.y/s.y),math.abs(p.z/s.z)
return Vector3.new(NumNormal(p.x),NumNormal(p.y),NumNormal(p.z)) * Vector3.new(
(ax>ay or ax>az) and s.x or math.abs(p.x),
(ay>ax or ay>az) and s.y or math.abs(p.y),
(az>ax or az>ay) and s.z or math.abs(p.z)
)
end |