99 lines
2.5 KiB
Lua
99 lines
2.5 KiB
Lua
local Vector2 = require("Vector2")
|
|
local BezierCurve = {}
|
|
local width = 5
|
|
local interval = 1/10
|
|
BezierCurve.maxDepth = -1
|
|
BezierCurve.randSeed = love.math.random()
|
|
BezierCurve.__index = BezierCurve
|
|
|
|
local function dist(x1,y1,x2,y2)
|
|
return ((x1-x2)^2+(y1-y2)^2)^0.5
|
|
end
|
|
|
|
local function linearBezier(p1, p2)
|
|
return (1-t)*p1 + t*p2
|
|
end
|
|
|
|
function BezierCurve.new(class, points)
|
|
return setmetatable({
|
|
_curve = love.math.newBezierCurve(points or {100,180,250,250,200,500}),
|
|
selectedPoint = false
|
|
}, class)
|
|
end
|
|
|
|
function BezierCurve:draw(drawPoints, drawLines, drawFinal)
|
|
love.graphics.setLineJoin("bevel")
|
|
love.graphics.setLineStyle("smooth")
|
|
|
|
if drawLines then
|
|
love.graphics.setLineWidth(width*0.25)
|
|
local p = {}
|
|
for i=1, self._curve:getControlPointCount() do
|
|
table.insert(p, Vector2(self._curve:getControlPoint(i)))
|
|
end
|
|
BezierCurve.stringArt(p, 0)
|
|
end
|
|
|
|
if drawFinal then
|
|
love.graphics.setLineWidth(width)
|
|
love.graphics.setColor(0.8,0,0)
|
|
love.graphics.line(self._curve:render())
|
|
end
|
|
|
|
if drawPoints then
|
|
love.graphics.setColor(0,0,0.8)
|
|
for i=1,self._curve:getControlPointCount() do
|
|
local x,y = self._curve:getControlPoint(i)
|
|
love.graphics.circle("fill",x,y,width*1.25)
|
|
end
|
|
end
|
|
end
|
|
|
|
function BezierCurve:mousemoved(x, y)
|
|
if self.selectedPoint then
|
|
self._curve:setControlPoint(self.selectedPoint, x, y)
|
|
end
|
|
end
|
|
|
|
function BezierCurve:mousepressed(x, y, button)
|
|
if button == 1 then
|
|
local isCtrl = love.keyboard.isDown("lctrl", "rctrl")
|
|
for i=1,self._curve:getControlPointCount() do
|
|
if dist(x,y,self._curve:getControlPoint(i)) < width*1.25 then
|
|
if isCtrl then
|
|
self._curve:removeControlPoint(i)
|
|
else
|
|
self.selectedPoint = i
|
|
end
|
|
return
|
|
end
|
|
end
|
|
if isCtrl then
|
|
self._curve:insertControlPoint(x, y)
|
|
end
|
|
end
|
|
end
|
|
|
|
function BezierCurve:mousereleased(_, _, button)
|
|
if button == 1 then
|
|
self.selectedPoint = false
|
|
end
|
|
end
|
|
|
|
function BezierCurve.stringArt(points, depth)
|
|
if #points > 2 and (BezierCurve.maxDepth < 0 or depth < BezierCurve.maxDepth) then
|
|
for t=0,1,interval do
|
|
love.graphics.setColor(0.3,0.5,0.1)
|
|
local p = {}
|
|
for pointI=1, #points-1 do
|
|
table.insert(p, (1-t)*points[pointI] + t*points[pointI+1])
|
|
end
|
|
for pointI=1, #p-1 do
|
|
love.graphics.line(p[pointI].x, p[pointI].y, p[pointI+1].x, p[pointI+1].y)
|
|
end
|
|
BezierCurve.stringArt(p, depth+1)
|
|
end
|
|
end
|
|
end
|
|
|
|
return BezierCurve |