1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
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
|