Easiest Bezier Curve function, Automatic control points

I just made this function to create Bezier curves with how many control points as you wish. It involves quite a bit of math and i will not go over all of it because it would be waaay too boring for the majority of users.

The reason this function differs from the other models that i have seen is that its just one for every type you want, Cubic, Quadratic or even Linear.

local function BezierCurve(T, ...)
	local ValuesTable = {...}
	local NumberOfControlPoints = #ValuesTable - 2
	if NumberOfControlPoints < 0 then warn("Not enough Points") return end
	local Value = nil
	print("NumberOfControlPoints", NumberOfControlPoints)
	for i = 1, #ValuesTable do
		local Multiplier = NumberOfControlPoints + 1
		if (i == 1) or (i == #ValuesTable) then
			Multiplier = 1
		end
		local FirstValue = (1 - T)^(NumberOfControlPoints + 1 - (i - 1))
		local FinalValue = T^(NumberOfControlPoints - (-i + NumberOfControlPoints + 1))

		local CurrentValue = (FirstValue * FinalValue) * Multiplier * ValuesTable[i]
		print(CurrentValue)
		if not Value then
			Value = CurrentValue
		else
			Value += CurrentValue
		end
	end
	return Value
end

BezierCurve(0.5, workspace.PartA.Position, workspace.PartB.Position)

Here is an example script i wrote to demonstrate it.

local function BezierCurve(T, ...)
	local ValuesTable = {...}
	local NumberOfControlPoints = #ValuesTable - 2
	if NumberOfControlPoints < 0 then warn("Not enough Points") return end
	local Value = nil
	for i = 1, #ValuesTable do
		local Multiplier = NumberOfControlPoints + 1
		if (i == 1) or (i == #ValuesTable) then
			Multiplier = 1
		end
		local FirstValue = (1 - T)^(NumberOfControlPoints + 1 - (i - 1))
		local FinalValue = T^(NumberOfControlPoints - (-i + NumberOfControlPoints + 1))

		local CurrentValue = (FirstValue * FinalValue) * Multiplier * ValuesTable[i]
		print(CurrentValue)
		if not Value then
			Value = CurrentValue
		else
			Value += CurrentValue
		end
	end
	return Value
end

local TimePassed = 0
while true do 
	TimePassed += task.wait()
	TimePassed = math.clamp(TimePassed, 0, 1)
	
	local ValuesTable = {}
	ValuesTable[1] = workspace.PartA.Position
	for i, v in pairs(workspace.ControlPoints:GetChildren()) do
		ValuesTable[tonumber(v.Name) + 1] = v.Position
	end
	ValuesTable[#ValuesTable + 1] = workspace.PartB.Position
	
	workspace.MovingPart.Position = BezierCurve(TimePassed, unpack(ValuesTable))

	if TimePassed == 1 then
		TimePassed = 0
	end
end

Video Example of the code above: 2023-06-16_13-51-58.mp4

You can add or remove as many values as you want from the arguments and it will work as long as there are at least 2 parts. The starting position is the fist value and the end position is the last one, everything in the middle will be a controlpoint.

Its a waste to use a model with 3 different functions when you can just use one for everything.

4 Likes