How would I Lerp through a Bezier line using a set speed?

Hello there. I will attempt to make this as brief as possible. Yesterday, I made a topic asking for an efficient way to move a brick from Point A to Point B using a set speed. Since the speed would be changed real-time, TweenService would not have worked. In that topic, we established that the most efficient way to do this would be using Lerp in order to move the brick. The code for this was a modification of this:

local part = script.Parent
local part2 = Workspace.Part2

while true do
	local dt = task.wait()
	local distance = (part2.Position - part.Position).Magnitude
	local speed = 10*dt -- distance traveled between elapsed time
	local estimatedTime = speed /distance -- obtain a lerp fraction between distance traveled in a frame divided by the overall distance towards the goal
	local adjustedLerpAlpha = math.min(estimatedTime,1) -- prevent the lerp from going over 1 which is over the lerp goal

	part.CFrame = part.CFrame:Lerp(part2.CFrame,adjustedLerpAlpha) -- lerps the position values at constant speed
end

Now, although this works flawlessly for what it needs, I came across a problem for my implications. In a lot of places throughout my model (which will be a ski lift), I will want the brick to follow a Bezier curve instead of a straight line. These places would be the:

The Station

image
(It will need to be able to do this circular motion)

The Line Between Towers


(The line is not straight, but rather has a bent to it)

That being said, the entire script will probably need to be refined in order to accompany these changes. My question is, how would I able to have a script similar to the above, where an anchored model will move through a Bezier curve using a set speed, and whenever the speed would change, the model would move accordingly? I am a beginner to Bezier curves, so I am unsure where and how to start. Any and all help is appreciated. Thank you for your time and help, I truly appreciate it.

1 Like

Still haven’t figured this out if anyone could assist me in this. Thank you.

I am not too familiar with the terminology when it comes to bezier curves or maths in general, so I apologise if I get anything wrong.

To create a bezier curve (a quadratic bezier curve in this case) you need the equation b(t) = p1+(1-t)^2*(p0 - p1)+t^2*(p2 - p1).

p0, p1, p2 are Vector values with p0 representing the start of your curve, p1 is known as the control point of your curve (i am not sure if this is what it is actually called), and p2 which is your end position. t represents the time step on your curve (kinda like the position?) which is a value from 0 to 1.

First you want to get your control points set up (those are the three vector values), I have arranged mine like this.

Now we have everything we need to make our curve and we just need to generate an array of Vectors that we will use to position your model. We can do this using the equation above. Here is my sample code:

local pointCount = 100 -- this is the amount of points we want on our curve, adjust at will
local curvePositions = table.create(pointCount, nil) -- create an empty array with pointCount values already made, this is a performance thing.

for i = 1, pointCount do -- we do not start at 0 since arrays start at 1 in lua
    local t = i / pointCount -- get a value from 0 to 1
    local newVector = p1 + (1-t)^2 * (p0 - p1) + t^2 * (p2 - p1)
    curvePositions[i] = newVector -- using i lets us order it nicely
end

We now have our array of positions, now we can simply run through this array and we get a result like this (you will want to smoothen this out for your snowlift). Here is my final result (ignore the transparent parts, I added them to help you visualise the curve. You can see my yellow node moving across the curve.)

1 Like

Thank you for your reply. I ended up making a separate path that was generated via a Bezier curve and just looped through all the positions of the parts, like you said. Although I wish I didn’t have to do this, I guess this is the only way to do this as of now without changing the entire system. Again, thank you for your help.