Closed fedarko closed 7 years ago
So I sorta implemented some code that does this for at least interior source nodes, and it seemed to produce invalid B-splines (Cytoscape.js won't render the edges as beziers, at least). I'm guessing this is because my code just linearly extends control points, which isn't really a valid thing to do?
Here's my code right now (to find where it belongs in collate.py
, search for the first line given here (if source_id != e[0]
) --
if source_id != e[0]:
# TODO
# Add control points from source to the first current control pt.
# The first new control point is at the "tailport" of the source
tailx = source.xdot_x + (source.xdot_width / 2)
taily = source.xdot_y + (source.xdot_height / 2)
new_points = "%g %g" % (tailx, taily)
dx3 = (coord_list[0] - tailx) / 3.0
dy3 = (coord_list[1] - taily) / 3.0
# Add two more control points, one 1/3 of the distance
# and another 2/3 of the distance
for i in range(1, 3):
new_x = tailx + (i * dx3)
new_y = taily + (i * dy3)
new_points += " %g %g" % (new_x, new_y)
new_points += " "
# Update the current edge's attributes accordingly
curr_edge.xdot_ctrl_pt_str= new_points + curr_edge.xdot_ctrl_pt_str
new_point_coord_list = [float(c) for c in new_points.split()]
coord_list = new_point_coord_list + coord_list
curr_edge.xdot_ctrl_pt_count += 3
A possible workaround: see this paper.
Update: actually, after doing some digging, this paper (by Shetty and White) seems to present a simpler solution? Update again -- never mind, that auto-generates the control points to extend to via reflection. Looks like the approach of the first-mentioned paper here is what we should go with.
WAIT never mind, so it turns out my code used inches (via the .xdot_height
variable) where points should have been used. Fixing the values makes things alright, and produces ostensibly valid B-splines or at least control points that form acceptable cubic Beziers.
And it's actually valid + a lot easier than the method shown in the code above to just change the initial control point to just be the tail/head position of the interior node in question. At least from testing this out on the salmonella and simplified Shakya assembly graphs, this produces nicer, more natural-looking edges.
TODOs left: clean up code, apply this approach to target, test, commit changes then close this
This works with targets now. It looks a lot better -- screenshots of before/after (for component 2 of the simplified Shakya assembly graph):
Currently, during backfilling (#80), edges are drawn to/from the node groups themselves rather than the individual child node(s) in particular. The resulting control points are then used in Cytoscape.js for the actual edges to child nodes, resulting in some inaccuracy/odd-looking edges.
For edges to child nodes: I'm thinking we can rectify this problem by adding 3 more control points (creating another "bezier curve" on the B-spline) -- one starting at the last control point of the previous B-spline, another one halfway to the child node target, and another one at the child node target. We could apply the same logic for edges from child nodes, and we could apply both approaches for edges to/from child nodes (e.g. an edge that starts and originates in two different node groups).