# How do I utilise this module to create a projectile along a Bezier curve with a constant speed

So I have been working to create bezier curve projectiles and while I’ve had some luck, I’ve been facing an issue where the projectile will not run a fixed speed along the bezier curve, often slowing down and speeding up at different points across a curve, obviously for a projectile this motion is unrealistic (e.g a fireball or a basketball) and not the result I require.

I did some reading on this guide which was quite helpful but a little confusing.

It says I have to perform something called "Arc Length Parameterization on the bezier curve, but with the module they give I am unsure on how to implement the module, especially as they did not give an example.

For reference, this is the module they provided and I would like to know if anyone can help me out, preferably providing an example of this module in use to help my understanding of this module.

``````local bezier = {}

function length(n, func, ...)
local sum, ranges, sums = 0, {}, {}
for i = 0, n-1 do
local p1, p2 = func(i/n, ...), func((i+1)/n, ...)
local dist = (p2 - p1).magnitude
ranges[sum] = {dist, p1, p2}
table.insert(sums, sum)
sum = sum + dist
end
return sum, ranges, sums
end

function bezier.new(func, n, ...)
local self = setmetatable({}, {__index = bezier})
local sum, ranges, sums = length(n, func, ...)
self.func = func
self.n = n
self.points = {...}
self.length = sum
self.ranges = ranges
self.sums = sums
return self
end

function bezier:setPoints(...)
-- only update the length when the control points are changed
local sum, ranges, sums = length(self.n, self.func, ...)
self.points = {...}
self.length = sum
self.ranges = ranges
self.sums = sums
end

function bezier:calc(t)
-- if you don't need t to be a percentage of distance
return self.func(t, unpack(self.points))
end

function bezier:calcFixed(t)
local T, near = t * self.length, 0
for _, n in next, self.sums do
if (T - n) < 0 then break end
near = n
end
local set = self.ranges[near]
local percent = (T - near)/set[1]
return set[2], set[3], percent
end

return bezier

``````

note: this was intended for a module script ^

Thank you for reading, I appreciate any response as I have been figuring this out for a while.

You cannot make a bezier curve have a specific speed over its whole length. Try a Hermite spline instead, which lets you specify the start and end speed.

that article pushing the use of oop is overkill and unnecessary

i had the exact same issue a few months ago and i made a bezier curve function:

``````--variable *a* is number within -> [0, 1]
local function Bezier(P0: CFrame | Vector3, P1: CFrame | Vector3, P2: CFrame | Vector3, a: number): CFrame | Vector3
local L0 = P0:Lerp(P1,a)
local L1 = P1:Lerp(P2,a)
return L0:Lerp(L1,a)
end
``````

i use this in conjunction with RunService.Heartbeat, constantly adding the elapsed time (total time + deltaTime) per frame to achieve uniform movement for my Bezier projectiles