All good im also going to bed so ill see your tomorrow, i cant express how thankful i am for your help.
function lerp(p0, p1, t)
return p0 + t * (p1 - p0)
end
local points = {}
points[1] = {
["Position"] = Vector3.new(), -- starting point
["Distance"] = 0
}
for t = 0.01, 1, 0.01 do
local position = bezierPoint(t, ...) -- get unweighted position
local previous = points[#points]
local gap = (position - previous.Position).Magnitude
local distance = previous.Distance + gap
-- store the vector3 as position, total distance as distance
-- and distance from the previous point as gap
points[#points+1] = {
["Position"] = position,
["Distance"] = distance,
["Gap"] = gap
}
end
-- total curve length
local length = points[#points].Distance
local bezier = {}
for t = 0.01, 1, 0.01 do
local target = length * t
-- find the first point that is >= target and the one before it
-- that means the target length is in between these two points
local p0, p1
for i, point in pairs(points) do
if point.Distance >= target then
p0 = points[i-1]
p1 = point
break
end
end
bezier[#bezier+1] = lerp(
p0.Position,
p1.Position,
(target - p0.Distance) / p1.Gap
)
end
return bezier
note, I stored p1.Distance - p0.Distance
as "Gap"
so it doesn’t have to calculate twice. I also didn’t use binary search to keep it simple. haven’t tested, ask me about any problems.
Sorry for the delay, so how do I know when to use each bezier point? it just returns them all in 1 table right?
yeah. if you want, instead of storing them in a table you can put a part there or something.
also FYI, it doesn’t include the first point. did that on purpose so you can chain them, if you want to add the first point then change it to t=0
for the second loop.
i changed the t thing but it does this for some reason it does this: https://i.gyazo.com/aba6882287af761868706e4f84808a31.gif
what’s the issue? is it because it stops early before reaching the top right square?
it looks like the spacing works, at least.
That and it begins at 0,0,0 for some reason
at the first part when you do points[1]=… change Vector3.new() to the starting point.
edit: looks like an error on my part. you need to change points[#points] to points[1]!
I have it to the starting unweighted position already
local Bezierpoints = {}
for t = 0, 1, 0.01 do
local v3 = cubic(p0.Position, p1.Position, p2.Position, p3.Position, t)
Bezierpoints[t] = v3
end
for t = 0, 1, 0.01 do
local position = Bezierpoints[t] -- get unweighted position
local previous = points[#points]
local gap = (position - previous.Position).Magnitude
local distance = previous.Distance + gap
-- store the vector3 as position, total distance as distance
-- and distance from the previous point as gap
points[#points+1] = {
["Position"] = position,
["Distance"] = distance,
["Gap"] = gap
}
end
Not full code btw
alright… what happens when you print out the bezier before adjusting it. does it start at (0,0,0)?
it might be a problem with something else because I can’t think a place the stuff I wrote ever refers to (0,0,0). I can test it tomorrow.
for the reason it ends early, maybe t doesn’t reach 1. I don’t remember if the for loops include the last number in lua, maybe it only gets to 0.99.
I see now, t at the very beginning is 0 and doesn’t reach 1, thats what our problem is I just need to change the for loops.
can’t say I understand but ignorance is bliss! let’s hope it works
It didnt work, im not sure why. I changed all the for loops from
for t = 0, 1, 0.01 do -- this means 0 will always be lower than or equal to t and t will always be lower than or equal to 1
to
for t = 0.01, 1, 0.01 do -- this means 0.01 will always be lower than or equal to t and t will always be lower than or equal to 1
this still has the same results thought and I have no idea why
no it prints the correct position
I found it, the starting point position was set to Vector.new() which is 0,0,0 i fixed it by switching it to p0.Position
Now I just need to find out why its not finishing
sounds familiar
tell me, in your unweighted curve, is the final point at the right position? additionally, is there the same number of points in the unweighted curve as there is in the new one?
my bad
No its off by like 1 stud
idk but I dont think so, when i try to print #Bezierpoints (unweighted) it returns 0 and all of the time values in the unweighted points are weird. Example from output when i print unweighted points:
Anyways im gonna get off now as its getting late, we can fix this part in the morning
Also here is the script in case you wanna test something while im gone
function lerp(p0, p1, t)
return (1 - t) * p0 + t * p1
end
function lerp2(p0, p1, t)
return p0 + t * (p1 - p0)
end
local function quadratic(p0, p1, p2, t)
local L1 = lerp(p0, p1, t)
local L2 = lerp(p1, p2, t)
return lerp(L1, L2, t)
end
local function cubic(p0, p1, p2, p3, t)
local Q1 = quadratic(p0, p1, p2, t)
local Q2 = quadratic(p1, p2, p3, t)
return lerp(Q1, Q2, t)
end
local function GetBezier(p0, p1, p2, p3, cart)
local points = {}
points[#points] = {
["Position"] = p0.Position, -- starting point
["Distance"] = 0
}
local Bezierpoints = {}
for t = 0, 1, 0.01 do
local v3 = cubic(p0.Position, p1.Position, p2.Position, p3.Position, t)
Bezierpoints[t] = v3
end
print(Bezierpoints)
for t = 0, 1, 0.01 do
local position = Bezierpoints[t] -- get unweighted position
local previous = points[#points]
local gap = (position - previous.Position).Magnitude
local distance = previous.Distance + gap
-- store the vector3 as position, total distance as distance
-- and distance from the previous point as gap
points[#points+1] = {
["Position"] = position,
["Distance"] = distance,
["Gap"] = gap
}
end
-- total curve length
local length = points[#points].Distance
local bezier = {}
for t = 0, 1, 0.01 do
local target = length * t
-- find the first point that is >= target and the one before it
-- that means the target length is in between these two points
local p0, p1
for i, point in pairs(points) do
if point.Distance >= target then
p0 = points[i-1]
p1 = point
break
end
end
bezier[#bezier+1] = lerp(
p0.Position,
p1.Position,
(target - p0.Distance) / p1.Gap
)
end
return bezier
end
local bezier = GetBezier(workspace.p0, workspace.p1, workspace.p2, workspace.p3, workspace.cart)
print(bezier)
for i,v in pairs(bezier) do
workspace.cart.Position = v
local newpart = Instance.new("Part")
newpart.Material = "Neon"
newpart.BrickColor = BrickColor.White()
newpart.Position = workspace.cart.Position
newpart.Size = Vector3.new(0.25, 0.25, 0.25)
newpart.Anchored = true
newpart.CanCollide = false
newpart.Parent = workspace
wait(0.01)
end
your output looks mostly normal.
both of the lerp functions do the same thing… just choose one. I think the first one might be faster.
points[#points]
at the beginning should be points[1]
. that was a mistake I made.
after you do that, it must be a problem with your cubic
function. which is weird because I’m guessing that comes from the wiki itself. make sure that your cubic
function ends with the last point when t=1
.
When I change it, the script breaks
It doesn’t, it ends with t = 0.9900000000000007