Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Bézier curves script from wiki not working?

So, i've been trying to learn Bézier curves, but i just don't understand what they are trying to explain. I've copied pasted final code, but that doesn't even work, and gives errors.. So can someone please try to explain what is what it does and how to fix it. Please not too hard, i'm trying to learn it :/

Wiki page

The code i tried

-- bzs is table with bezier urves in it in order traveled
function travelPath(t, bzs)
	local totalLength, sums = 0, {}
	-- get total length of all curves, also order sums for sorting
	for _, bz in next, bzs do
		table.insert(sums, totalLength);
		totalLength = totalLength + bz.length; 
	end;
	-- get percentage of total distance and find the bezier curve we're on
	local T, near, bz = t * totalLength, 0, bzs[1];
	for i, n in ipairs(sums) do
		if (T - n) < 0 then break; end;
		near, bz = n, bzs[i];
	end;
	-- get relative percentage traveled on given bezier curve
	local percent = (T - near)/bz.length;
	-- lerp across curve by percentage
	local a, b, c = bz:calcFixed(percent);
	return a + (b - a) * c; 
end;

Please help D:

1 answer

Basically, they're just putting multiple beizer curves together; then travelling through them as if they were one in the code you gave.

Use this code in a ModuleScript to get one beizer curve:

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;

If you need help with ModuleScripts, you can always refer to these examples on the wiki.

1 comment

0

How would i set the points to use? And i'm trying to learn it, i still don't understand it fully :/

This discussion is preserved as it was. New answers, comments, and votes are closed.