local class = require 'class' local hsluv = require 'hsluv' 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 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]} for i = 1,15 do local r1,r2 = math.random(10), math.random(10) if r1 ~= r2 then table.insert(ports[r1].wires, ports[r2]) end end local function catenary(x1,y1,x2,y2) -- https://math.stackexchange.com/questions/3557767/how-to-construct-a-catenary-of-a-specified-length-through-two-specified-points end 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' function love.draw() local W,H = G.getDimensions() G.clear(1,1,1) G.setColor(0,0,0) G.origin() 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 = p:contains(mx,my) and 'hover' or 'normal' p:draw(istate) for _,q in ipairs(p.wires) do G.setColor(wire_color(wn)) wn = wn + 1 catenary(p.x,p.y,q.x,q.y) end end end