local G = love.graphics local function plot(f,x0,xn) local n = 30 x0 = x0 or G.inverseTransformPoint(0,0) xn = xn or G.inverseTransformPoint(G.getDimensions(),0) if xn < x0 then xn,x0 = x0,xn end local h = (xn-x0)/n local ps = {} for i=0,n do local x = x0 + i*h local y = f(x) table.insert(ps,x) table.insert(ps,y) end G.line(ps) end local function atanh(x) return (1/2) * math.log((1+x)/(1-x)) end local function solve_for_A(r) local A if r < 3 then A = math.sqrt(6 * (r-1)) else A = math.log(2*r) + math.log(math.log(2*r)) end for i=1,5 do A = A - (math.sinh(A) - r*A)/(math.cosh(A)-r) end return A end local L = 3 function love.wheelmoved(x,y) L = L + (y/5) end local function catenary0(x1,y1,x2,y2) -- https://math.stackexchange.com/a/3557768 y1 = -y1 y2 = -y2 local dx = x2-x1 local dy = y2-y1 local mx = (x1+x2)/2 local my = (y1+y2)/2 local D = math.sqrt(dx^2+dy^2) -- local L = D+(1/D) local r = math.sqrt(L^2 - dy^2)/dx local A = solve_for_A(r) local a = dx/(2*A) local b = mx - a*atanh(dy/L) local c = my - L/(2*math.tanh(A)) return function(x) return -(a * math.cosh((x-b)/a) + c) end end local function catenary(x1,y1,x2,y2) if x2 < x1 then x1,x2 = x2,x1 y1,y2 = y2,y1 end return catenary0(x1,y1,x2,y2) end local Ps = {{-1,1}, {1,1}} function love.update(dt) for b = 1,2 do if love.mouse.isDown(b) then Ps[b] = {G.inverseTransformPoint(love.mouse.getPosition())} end end end function love.draw() local W,H = G.getDimensions() G.clear(1,1,1) G.setColor(0,0,0) G.origin() G.print(L,10,10) G.setLineWidth(0.01) G.translate(W/2,H/2) G.scale(150) G.setColor(0.8,0.8,0.8) for i=-10,10 do G.line(-10,i,10,i) G.line(i,-10,i,10) end G.circle('line',0,0,1) -- G.setColor(0,0,0) -- -- plot(function(x) return x^2 end) -- plot(math.tanh) -- G.setColor(0,1,0) -- plot(atanh) G.setColor(0,0,0) plot(catenary(Ps[1][1],Ps[1][2], Ps[2][1], Ps[2][2]), Ps[1][1], Ps[2][1]) G.setColor(1,0,0) G.circle('fill',Ps[1][1],Ps[1][2],0.05) G.setColor(0,0,1) G.circle('fill',Ps[2][1],Ps[2][2],0.05) end