local class = require 'class' local hsluv = require 'hsluv' local catenary = require 'catenary' local tau = 2*math.pi local ZOOM = 200 local G = love.graphics local function write_at(text,x,y) G.push() G.translate(x,y) G.scale(1/ZOOM) G.print(text,0,0) G.pop() end local Port = class() Port.R = 0.1 function Port.make(cls, x,y, num) return setmetatable({x=x,y=y,n=num,wires={}},cls) end function Port.draw(self, istate) local c = {0,0,0} if istate == 'hover' then c[1] = 1 elseif istate == 'selected' then c[2] = 1 end love.graphics.setColor(c) G.circle('line',self.x,self.y,self.R) write_at(self.n, self.x, self.y) end function Port.contains(self, px,py) local d = math.sqrt((self.x - px)^2 + (self.y - py)^2) return d <= self.R end local ports = {} local n = 10 for i = 1,n do local theta = tau * i/n table.insert(ports, Port:make(math.cos(theta), math.sin(theta), i)) end ports[3].wires = {ports[6]} ports[5].wires = {ports[7],ports[2]} local function wire_color(n) local phi = (1+math.sqrt(5))/2 local h = (360*phi*n)%360 return hsluv.hsluv_to_rgb({h, 80, 60}) end local state = 'normal' local selected = nil local function hovering_port(mx,my) for i,p in ipairs(ports) do if p:contains(mx,my) then return p end end return nil end function love.mousepressed(x,y,b) if b == 2 then state = 'normal' selected = nil return end local mx,my = G.inverseTransformPoint(x,y) local p = hovering_port(mx,my) if p then if state == 'normal' then state = 'joining' selected = p.n elseif state == 'joining' then table.insert(ports[selected].wires, p) state = 'normal' selected = nil end end end local L = 2 function love.wheelmoved(x,y) L = L + (y/15) 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(ZOOM) local mx,my = G.inverseTransformPoint(love.mouse.getPosition()) local wn = 0 for i,p in ipairs(ports) do local istate = 'normal' if p:contains(mx,my) then istate = 'hover' end if state ~= 'normal' and selected == i then istate = 'selected' end p:draw(istate) for _,q in ipairs(p.wires) do G.setColor(wire_color(wn)) wn = wn + 1 G.line(catenary.catenary(p.x,p.y,q.x,q.y)) end end if state == 'joining' then G.setColor(wire_color(wn)) local p = ports[selected] G.line(catenary.catenary(p.x,p.y,mx,my)) end end