This had some dead ends. I spent some time trying to use the parametric equation of a line. But the parameter is not comparable across two lines.
KA3WML5YL2EKXNDNL2GP4GVVCPZYAAZBOQLVJH3GD2LEXUI4OB6AC 5N57VOATVSATXDBSRBNNPQU3BHONGN22EOMHZAD3DV5367WJRSLQC VOSTX4QHUMVJNSCP34WPRESQRN4OBXK7PILA2RMODRFEAU5LJV2QC R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC C2REOTRMF7EY6E3DAEL4ICI4O2AFAURWNQ7QCDMEZRNVM6ERM2UQC J62CVGNGJZSN7TMTE2SG53O47YG4SJGJFTUFKVOZY4TM4KAC566QC SMZJGK56DYOP2CYIYDV3QXVHL5P52IEF34GFBESNMULJDMDLJR2AC JNS2ATVJRXCIBGRFRPPN63OAOQRVV7GE2VRAL3T6YNRXFX6YYMQAC ZUXG2RU4WF5WF7EYU2XQJ6AERLJLOMGDEXWRMGWHT5DR3B7X7MWQC YUQ4YINAT5YTK3CAY4VK3HSYQ4D63FXLLPMC4R3DUFHIZIUQO7WQC GE7YT55JWPF5YGO2UPE6JDDBUKCP27CPHAE75XQ77IJWGFM2AJIQC UJ2RZ43LIVRIBWIXHXMLIQIQTL32VVEN4CVU7PEBTITQFPO4EXXQC T7T66GEUFLP3YHZN5UNOVBYK33KISJWJQKCPZU6MQH45KSU7CZZQC BBJCF6PTCLGQJ37LINJKTG3BBFYTLB6AV3NFJOEWNZYONQYQXU2QC QFUZ53WLZETJ7SQTEHL7NLTEXDPX2WX2S3Y7VO53SSSIFADGUTNQC distance_sq = function(x1,y1, x2,y2)return (x2-x1)^2+(y2-y1)^2end
x_at_y = function(startx,starty, endx,endy, y)-- x at a given y on a line-- Could be nil when the line is parallel to the x axis.if starty == endy thenreturnendreturn (endx-startx)/(endy-starty)*(y-starty) + startxend
y_at_x = function(startx,starty, endx,endy, x)-- y at a given x on a line-- Could be nil when the line is parallel to the y axis.if startx == endx thenreturnendreturn (endy-starty)/(endx-startx)*(x-startx) + startyend
intersect_with_centroid = function(node, sx,sy)local h = node_height(Edge.source)local c = {sx=Edge.source.x + Edge.source.w/2,sy=Edge.source.y + h/2}if c.sx == sx thenif sy > c.sy thenreturn {sx=sx, sy=Edge.source.y + h + 10}elsereturn {sx=sx, sy=Edge.source.y - 10}endend-- collect nearest intersection with all 4 boundarieslocal candidates = {}local y = y_at_x(sx,sy, c.sx,c.sy, Edge.source.x-10)if y and y >= Edge.source.y-10 and y < Edge.source.x+h+10 thentable.insert(candidates, {sx=Edge.source.x-10, sy=y})endy = y_at_x(sx,sy, c.sx,c.sy, Edge.source.x + Edge.source.w + 10)if y and y >= Edge.source.y-10 and y < Edge.source.x+h+10 thentable.insert(candidates, {sx=Edge.source.x+Edge.source.w+10, sy=y})endlocal x = x_at_y(sx,sy, c.sx,c.sy, Edge.source.y-10)if x and x >= Edge.source.x-10 and x < Edge.source.x + Edge.source.w + 10 thentable.insert(candidates, {sx=x, sy=Edge.source.y-10})endx = x_at_y(sx,sy, c.sx,c.sy, Edge.source.y+h+10)if x and x >= Edge.source.x-10 and x < Edge.source.x + Edge.source.w + 10 thentable.insert(candidates, {sx=x, sy=Edge.source.y+h+10})endif #candidates == 0 then-- no intersection; just return the same pointreturn {sx=sx, sy=sy}endif #candidates == 1 thenreturn candidates[1]endassert(#candidates == 2)if distance_sq(sx,sy, candidates[1].sx, candidates[1].sy) < distance_sq(sx,sy, candidates[2].sx, candidates[2].sy) thenreturn candidates[1]elsereturn candidates[2]endend
node_height = function(node)-- we store the node's height internally, but it can be too smallreturn math.max(node.h, 3*node.editor.line_height)end
table.length = function(h)-- length of a table (not just the array side)local result = 0for _ in pairs(h) doresult = result+1endreturn resultend
if Border thenApp.color{r=0,g=1,b=1}love.graphics.circle('fill', vx(Border.sx),vy(Border.sy), 5)
if Edge thenApp.color{r=0,g=0,b=1}if Edge.s.debug_info thenfor _,p in ipairs(Edge.s.debug_info) dolove.graphics.circle('line', vx(p.sx), vy(p.sy), 5)endendApp.color{r=0,g=0,b=0}love.graphics.line(vx(Edge.s.sx),vy(Edge.s.sy), vx(Edge.e.sx),vy(Edge.e.sy))love.graphics.circle('fill', vx(Edge.s.sx),vy(Edge.s.sy), 5)love.graphics.circle('fill', vx(Edge.e.sx),vy(Edge.e.sy), 5)
elseif Border thenBorder = nil
elseif Edge thenlocal src = Edge.sourcelocal line_height = Edge.source.editor.line_heightlocal dest = {id=next_key(), type='text', x=sx(x)-60,y=sy(y)-1.5*line_height, margin=0, width=120, outgoing_edges={}, incoming_edges={src.id}}Nodes[dest.id] = desttable.insert(Nodes[src.id].outgoing_edges, dest.id)Edge = nilA()