45 lines
1.5 KiB
Plaintext
45 lines
1.5 KiB
Plaintext
|
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 then
|
||
|
if sy > c.sy then
|
||
|
return {sx=sx, sy=Edge.source.y + h + 10}
|
||
|
else
|
||
|
return {sx=sx, sy=Edge.source.y - 10}
|
||
|
end
|
||
|
end
|
||
|
-- collect nearest intersection with all 4 boundaries
|
||
|
local 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 then
|
||
|
table.insert(candidates, {sx=Edge.source.x-10, sy=y})
|
||
|
end
|
||
|
y = 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 then
|
||
|
table.insert(candidates, {sx=Edge.source.x+Edge.source.w+10, sy=y})
|
||
|
end
|
||
|
local 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 then
|
||
|
table.insert(candidates, {sx=x, sy=Edge.source.y-10})
|
||
|
end
|
||
|
x = 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 then
|
||
|
table.insert(candidates, {sx=x, sy=Edge.source.y+h+10})
|
||
|
end
|
||
|
if #candidates == 0 then
|
||
|
-- no intersection; just return the same point
|
||
|
return {sx=sx, sy=sy}
|
||
|
end
|
||
|
if #candidates == 1 then
|
||
|
return candidates[1]
|
||
|
end
|
||
|
assert(#candidates == 2)
|
||
|
if distance_sq(sx,sy, candidates[1].sx, candidates[1].sy) < distance_sq(sx,sy, candidates[2].sx, candidates[2].sy) then
|
||
|
return candidates[1]
|
||
|
else
|
||
|
return candidates[2]
|
||
|
end
|
||
|
end
|