You'll basically need something like this:
local function Bezier(x1,y1,x2,y2,x3,y3)
--Private
local inf = 1/0
local x1 = x1
local y1 = y1
local x2 = x2
local y2 = y2
local x3 = x3
local y3 = y3
local maxY = y1 > y2 and (y1 > y3 and y1 or y3) or y2 > y3 and y2 or y3
local minY = y1 < y2 and (y1 < y3 and y1 or y3) or y2 < y3 and y2 or y3
local maxX = x1 > x2 and (x1 > x3 and x1 or x3) or x2 > x3 and x2 or x3
local minX = x1 < x2 and (x1 < x3 and x1 or x3) or x2 < x3 and x2 or x3
local xc = (x3 - 2*x2 + x1)
local xb = 2*(x2 - x1)
local yc = (y3 - 2*y2 + y1)
local yb = 2*(y2 - y1)
--Public
local self = {}
--Render
self.render = function(resolution)
local path = {}
local num = 1
for index=0, 1, 1/resolution do
path[num] = {(1-index)^2*x1+2*(1-index)*index*x2+index^2*x3, (1-index)^2*y1+2*(1-index)*index*y2+index^2*y3}
num = num + 1
end
return path
end
--Point
function self.point(index)
return {(1-index)^2*x1+2*(1-index)*index*x2+index^2*x3, (1-index)^2*y1+2*(1-index)*index*y2+index^2*y3}
end
--Get x of patricular y
function self.getX(y)
if y > maxY or y < minY then
return
end
local a = y1 - y
if a == 0 then
return
end
local b = yb
local c = yc
local discriminant = (b^2 - 4*a*c )
if discriminant < 0 then
return
else
local aByTwo = 2*a
if discriminant == 0 then
local index1 = -b/aByTwo
if 0 < index1 and index1 < 1 then
print("=====",y,1,maxY,minY)
return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
end
else
local theSQRT = math.sqrt(discriminant)
local index1, index2 = (-b -theSQRT)/aByTwo, (-b +theSQRT)/aByTwo
if 0 < index1 and index1 < 1 then
if 0 < index2 and index2 < 1 then
print("=====",y,2,maxY,minY)
return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3, (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
else
print("=====",y,1,maxY,minY)
return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
end
elseif 0 < index2 and index2 < 1 then
print("=====",y,1,maxY,minY)
return (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
end
end
end
end
--Get y of patricular x
function self.getY(x)
if x > maxX or x < minX then
return
end
if maxX == minX and x == minX then
return minY, maxY
end
local index1, index2, buffer1, buffer2
local a = (x1 - x)
if a == 0 then
return
end
local b = xb
local c = xc
local discriminant = b^2 - 4*a*c
if discriminant < 0 then
return
else
local aByTwo = 2*a
local theSQRT = math.sqrt(discriminant)
if discriminant == 0 then
local index1 = -b/aByTwo
return (1-index1)^2*y1+2*(1-index1)*index1*y2+index1^2*y3
else
local index1, index2 = (-b - theSQRT)/aByTwo, (-b + theSQRT)/aByTwo
return (1-index1)^2*y1+2*(1-index1)*index1*y2+index1^2*y3, (1-index2)^2*y1+2*(1-index2)*index2*y2+index2^2*y3
end
end
end
--Scanline render
function self.scanRender()
local path = {}
local counter = 1
local fX, sX
local a = (y3 - 2*y2 + y1)
local b = 2*(y2 - y1)
for i=minY, maxY do
fX, sX = self.getX(i,a,b)
if fX then
path[counter] = fX
path[counter+1] = i
counter = counter + 2
if sX then
path[counter] = sX
path[counter+1] = i
counter = counter + 2
end
end
end
return path
end
--More efficient
--Self
return self
end
By calling bezier, you get a Bezier object. This object will be able to access all the private attributes and the public interface that is in the self table.