Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Class: Bezier
- Author: Wasil Janssen a.k.a. Creator
- ]]--
- local Engine = ...
- function splineMax(Sx, helpA, Ex)
- helpC = Sx - helpA
- helpD = helpC + Ex - helpA
- max=Sx
- if Ex>Sx then
- max = Ex
- end
- if helpD ~= 0 then
- F=helpC/helpD
- if F>0 and F<1 then
- X=Sx-helpC*F;
- if X>max then max=X end
- end
- end
- return max
- end
- function splineMin(Sx, helpA, Ex)
- helpC = Sx - helpA
- helpD = helpC + Ex - helpA
- max=Sx
- if Ex<Sx then
- max = Ex
- end
- if helpD ~= 0 then
- F=helpC/helpD
- if F>0 and F<1 then
- X=Sx-helpC*F;
- if X<max then max=X end
- end
- end
- return max
- end
- --print = Internal.Debug.print
- local function Bezier(x1,y1,x2,y2,x3,y3)
- --Private
- local x1 = x1
- local y1 = y1
- local x2 = x2
- local y1 = y1
- local x2 = x2
- local y3 = y3
- local ind
- 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 bMaxY = splineMax(y1,y2,y3)
- local bMinY = splineMin(y1,y2,y3)
- local bMaxX = splineMax(x1,x2,x3)
- local bMinX = splineMin(x1,x2,x3)
- local xa = (x3 - 2*x2 + x1)
- local xb = 2*(x2 - x1)
- local ya = (y3 - 2*y2 + y1)
- local yb = 2*(y2 - y1)
- local yaByTwo = 2*ya
- --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
- self.getX = ya ~= 0 and function(y)
- if y > maxY or y < minY then
- return
- end
- if y == y1 or y == bMaxY or y == bMinY or y == y3 then
- y = y + 0.001
- end
- local c = y1 - y
- local b = yb
- local a = ya
- local discriminant = (b^2 - 4*a*c )
- if discriminant < 0 then
- return
- else
- if discriminant == 0 then
- local index1 = -b/yaByTwo
- if 0 < index1 and index1 < 1 then
- 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)/yaByTwo, (-b +theSQRT)/yaByTwo
- if 0 < index1 and index1 < 1 then
- if 0 < index2 and index2 < 1 then
- 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
- return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
- end
- elseif 0 < index2 and index2 < 1 then
- return (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
- end
- end
- end
- end or function(y)
- if y > maxY or y < minY or yb == 0 then
- return
- end
- if y == y1 or y == bMaxY or y == bMinY or y == y3 then
- y = y + 0.001
- end
- index1 = -(y1-y)/yb
- if 0 < index1 and index1 < 1 then
- return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
- 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
- function self.ind(u)
- ind = u
- end
- function self.info()
- print("maxY",maxY)
- print("minY",minY)
- print("yb",yb)
- print("ya",ya)
- print("x1",x1,"y1",y1)
- print("x2",x2,"y2",y2)
- print("x3",x3,"y3",y3)
- print("bMaxY",bMaxY)
- print("bMinY",bMinY)
- print("maxDiscri",yb^2 - 4*ya*(y1 - bMaxY))
- print("minDiscri",yb^2 - 4*ya*(y1 - bMinY))
- end
- --Self
- return self
- end
- return Bezier
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement