damn it, this might be my fault, I think it’s the way I worded it.
by “closest point” I don’t mean the point that is closest to the i’th point. forget about the original curve for a second, just think in distances.
you need the closest distance that is <= target. noticed how I put the distances and vectors in the same little tables. each distance has a corresponding point, and that’s the one you’re looking for.
in your second loop don’t iterate the points, iterate by t like you did in the first one, use it to find the target, then get the matching point using that.
ok… might need to start from the top. first off, in the second loop that I wrote, you need points[#points+1] = {…}. forgot the +1. otherwise it’s overwriting the same thing every time.
yeah, that’s to fall back on when using previous. by the end it should be n+1 points long. to that end, you can start t at 0.01 instead of 0 or it will get added twice. right now it just ends with one point added.
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.
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.