Advertisement
programcreator

Bezier Stuff

Oct 16th, 2016
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.78 KB | None | 0 0
  1. --[[
  2.     Class: Bezier
  3.     Author: Wasil Janssen a.k.a. Creator
  4. ]]--
  5.  
  6. local Engine = ...
  7.  
  8. function splineMax(Sx, helpA, Ex)
  9.  
  10.     helpC = Sx - helpA
  11.     helpD = helpC + Ex - helpA
  12.     max=Sx
  13.  
  14.     if Ex>Sx then
  15.         max = Ex
  16.     end
  17.     if helpD ~= 0 then
  18.         F=helpC/helpD
  19.         if F>0 and F<1 then
  20.             X=Sx-helpC*F;
  21.             if X>max then max=X end
  22.         end
  23.     end
  24.     return max
  25. end
  26.  
  27. function splineMin(Sx, helpA, Ex)
  28.  
  29.     helpC = Sx - helpA
  30.     helpD = helpC + Ex - helpA
  31.     max=Sx
  32.  
  33.     if Ex<Sx then
  34.         max = Ex
  35.     end
  36.     if helpD ~= 0 then
  37.         F=helpC/helpD
  38.         if F>0 and F<1 then
  39.             X=Sx-helpC*F;
  40.             if X<max then max=X end
  41.         end
  42.     end
  43.   return max
  44. end
  45.  
  46. --print = Internal.Debug.print
  47.  
  48. local function Bezier(x1,y1,x2,y2,x3,y3)
  49.     --Private
  50.     local x1 = x1
  51.     local y1 = y1
  52.     local x2 = x2
  53.     local y1 = y1
  54.     local x2 = x2
  55.     local y3 = y3
  56.     local ind
  57.  
  58.     local maxY = y1 > y2 and (y1 > y3 and y1 or y3) or y2 > y3 and y2 or y3
  59.     local minY = y1 < y2 and (y1 < y3 and y1 or y3) or y2 < y3 and y2 or y3
  60.  
  61.     local maxX = x1 > x2 and (x1 > x3 and x1 or x3) or x2 > x3 and x2 or x3
  62.     local minX = x1 < x2 and (x1 < x3 and x1 or x3) or x2 < x3 and x2 or x3
  63.  
  64.     local bMaxY = splineMax(y1,y2,y3)
  65.     local bMinY = splineMin(y1,y2,y3)
  66.  
  67.     local bMaxX = splineMax(x1,x2,x3)
  68.     local bMinX = splineMin(x1,x2,x3)
  69.  
  70.     local xa = (x3 - 2*x2 + x1)
  71.     local xb = 2*(x2 - x1)
  72.     local ya = (y3 - 2*y2 + y1)
  73.     local yb = 2*(y2 - y1)
  74.     local yaByTwo = 2*ya
  75.    
  76.     --Public
  77.     local self = {}
  78.  
  79.     --Render
  80.     self.render = function(resolution)
  81.         local path = {}
  82.         local num = 1
  83.         for index=0, 1, 1/resolution do
  84.             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}
  85.             num = num + 1
  86.         end
  87.         return path
  88.     end
  89.     --Point
  90.     function self.point(index)
  91.         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}
  92.     end
  93.     --Get x of patricular y
  94.     self.getX = ya ~= 0 and function(y)
  95.         if y > maxY or y < minY then
  96.             return
  97.         end
  98.         if y == y1 or y == bMaxY or y == bMinY or y == y3 then
  99.             y = y + 0.001
  100.         end
  101.         local c = y1 - y
  102.         local b = yb
  103.         local a = ya
  104.         local discriminant = (b^2 - 4*a*c )
  105.  
  106.         if discriminant < 0 then
  107.             return
  108.         else
  109.             if discriminant == 0 then
  110.                 local index1 = -b/yaByTwo
  111.                 if 0 < index1 and index1 < 1 then
  112.                     return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
  113.                 end
  114.             else
  115.                 local theSQRT = math.sqrt(discriminant)
  116.                 local index1, index2 = (-b -theSQRT)/yaByTwo, (-b +theSQRT)/yaByTwo
  117.                 if 0 < index1 and index1 < 1 then
  118.                     if 0 < index2 and index2 < 1 then
  119.                         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
  120.                     else
  121.                         return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
  122.                     end
  123.                 elseif 0 < index2 and index2 < 1 then
  124.                     return (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
  125.                 end
  126.             end
  127.         end    
  128.     end or function(y)
  129.         if y > maxY or y < minY or yb == 0 then
  130.             return
  131.         end
  132.         if y == y1 or y == bMaxY or y == bMinY or y == y3 then
  133.             y = y + 0.001
  134.         end
  135.         index1 = -(y1-y)/yb
  136.         if 0 < index1 and index1 < 1 then
  137.             return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
  138.         end
  139.     end
  140.     --Get y of patricular x
  141.     function self.getY(x)
  142.         if x > maxX or x < minX then
  143.             return
  144.         end
  145.         if maxX == minX and x == minX then
  146.             return minY, maxY
  147.         end
  148.         local index1, index2, buffer1, buffer2
  149.         local a = (x1 - x)
  150.         if a == 0 then
  151.             return
  152.         end
  153.         local b = xb
  154.         local c = xc
  155.         local discriminant = b^2 - 4*a*c
  156.         if discriminant < 0 then
  157.             return
  158.         else
  159.             local aByTwo = 2*a
  160.             local theSQRT = math.sqrt(discriminant)
  161.             if discriminant == 0 then
  162.                 local index1 = -b/aByTwo
  163.                 return (1-index1)^2*y1+2*(1-index1)*index1*y2+index1^2*y3
  164.             else
  165.                 local index1, index2 = (-b - theSQRT)/aByTwo, (-b + theSQRT)/aByTwo
  166.                 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
  167.             end
  168.         end
  169.     end
  170.     --Scanline render
  171.     function self.scanRender()
  172.         local path = {}
  173.         local counter = 1
  174.         local fX, sX
  175.         local a = (y3 - 2*y2 + y1)
  176.         local b = 2*(y2 - y1)
  177.         for i=minY, maxY do
  178.             fX, sX = self.getX(i,a,b)
  179.             if fX then
  180.                 path[counter] = fX
  181.                 path[counter+1] = i
  182.                 counter = counter + 2
  183.                 if sX then
  184.                     path[counter] = sX
  185.                     path[counter+1] = i
  186.                     counter = counter + 2
  187.                 end
  188.             end
  189.         end
  190.         return path
  191.     end
  192.  
  193.     function self.ind(u)
  194.         ind = u
  195.     end
  196.  
  197.     function self.info()
  198.         print("maxY",maxY)
  199.         print("minY",minY)
  200.         print("yb",yb)
  201.         print("ya",ya)
  202.         print("x1",x1,"y1",y1)
  203.         print("x2",x2,"y2",y2)
  204.         print("x3",x3,"y3",y3)
  205.         print("bMaxY",bMaxY)
  206.         print("bMinY",bMinY)
  207.         print("maxDiscri",yb^2 - 4*ya*(y1 - bMaxY))
  208.         print("minDiscri",yb^2 - 4*ya*(y1 - bMinY))
  209.     end
  210.     --Self
  211.     return self
  212. end
  213.  
  214. return Bezier
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement