local function V(V)if V.Magnitude==0 then return Vector3.zero end return V.Unit end local function K(V,K,s,P)local g=P-V local o=g:Dot(K)o=math.clamp(o,-s,s)return V+K*o,o end local function s(V,K,s)local P=s-V local g=P:Dot(K)local o=s-g*K return o end local function P(P,g,o)local p=(g.Y<g.Z and g.Y or g.Z)*.5 local I=g.X*.5 local y,e=K(P.Position,P.RightVector,I,o)local S=P.Position+-P.RightVector*I local t=P.Position+P.RightVector*I local f=-P.RightVector local N=P.RightVector local W=s(S,f,o)local R=s(t,N,o)local function m(K,s)local P=V(K-s)local g=(K-s).Magnitude return s+P*(g<p and g or p)end W=m(W,S)R=m(R,t)local F=(y-o).Magnitude local T=V(o-y)local z=F<=p local n=y+T*p local Q=(R-o).Magnitude local Y=(W-o).Magnitude local w=(n-o).Magnitude local C=math.min(Q,Y,w)if e==I or C==Q then local K=(V(o-R)):Dot(N)return K<0,R,N elseif e==-I or C==Y then local K=(V(o-W)):Dot(f)return K<0,W,f end return z,n,T end return function(V,K,s,g)do end local o,p,I=P(V,K,s)if o then return o,p,I end local y=(p-s).Magnitude o=y<g do end return o,p,I end
--!native
local function SafeUnit(v3)
	if v3.Magnitude == 0 then
		return Vector3.zero
	end

	return v3.Unit
end

local function solve(p0, d0, len, p1)
	local v = p1 - p0
	local k = v:Dot(d0)
	k = math.clamp(k, -len, len)
	return p0 + d0 * k, k
end

local function ProjectOnPlane(pos, normal, point)
	local d = point - pos
	local v_dot = d:Dot(normal)
	local v = point - v_dot * normal

	return v
end

local function ClosestPointFunc(cframe, size, point)
	local radius = (size.Y < size.Z and size.Y or size.Z) * 0.5
	local length = size.X * 0.5
	local l0, k = solve(cframe.Position, cframe.RightVector, length, point)

	local endPlane = cframe.Position + -cframe.RightVector * length
	local topPlane = cframe.Position + cframe.RightVector * length

	local endPlaneN = -cframe.RightVector
	local topPlaneN = cframe.RightVector

	local projEnd = ProjectOnPlane(endPlane, endPlaneN, point)
	local projTop = ProjectOnPlane(topPlane, topPlaneN, point)

	local function GetFinalProj(proj, o)
		local projDir = SafeUnit(proj - o)
		local projDistance = (proj - o).Magnitude
		return o + projDir * (projDistance < radius and projDistance or radius)
	end

	projEnd = GetFinalProj(projEnd, endPlane)
	projTop = GetFinalProj(projTop, topPlane)

	local radiusDistance = (l0 - point).Magnitude
	local radiusNormal = SafeUnit(point - l0)
	local radiusInside = (radiusDistance <= radius)
	local radiusPosition = l0 + (radiusNormal * radius)

	local d0 = (projTop - point).Magnitude
	local d1 = (projEnd - point).Magnitude
	local d2 = (radiusPosition - point).Magnitude

	local d = math.min(d0, d1, d2)

	if k == length or d == d0 then
		local dot = SafeUnit(point - projTop):Dot(topPlaneN)
		return dot < 0, projTop, topPlaneN
	elseif k == -length or d == d1 then
		local dot = SafeUnit(point - projEnd):Dot(endPlaneN)
		return dot < 0, projEnd, endPlaneN
	end

	return radiusInside, radiusPosition, radiusNormal
end

return function(CylinderCFrame, CylinderSize, Point, Radius) -- IsInside, PushPosition, PushNormal
do end	
local IsInside, PushPosition, PushNormal = ClosestPointFunc(CylinderCFrame, CylinderSize, Point)

	if IsInside then
		return IsInside, PushPosition, PushNormal
	end

	local PointDistance = (PushPosition - Point).Magnitude

	IsInside = PointDistance < Radius
do end	
return IsInside, PushPosition, PushNormal
end
