Pull edges towards horizontal, not just out of their own way - #363
Merged
Conversation
The clearance splay only fires once a curve is at risk of hiding behind the bodies at its ends, so it caps an edge at about 75.5 degrees off horizontal and does nothing at all below that. Legal, but not flat: a graph settles with edges at whatever angle the springs and gravity leave them, which in the node editor reads as a tangle. CalculateLinkFlatteningForces now also levels an edge continuously, with a force proportional to the vertical offset between its two ends. On a six-body graph with four edges that takes the mean angle off horizontal from 27.4 to 13.1 degrees, two of the four edges landing within about a degree of flat, and introduces no overlap. A backward edge is exempt. It is still being reordered, and levelling it would fight the vertical slide that the reorder needs to get its endpoints past one another. Neither mechanism can make every edge horizontal at once - a node with several inputs cannot have all of them level with it - so this is a preference that the overlap pass and the springs push back on, not a constraint. LinkFlatteningStrength now scales both it and the clearance splay; 0 still disables both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D2KNUKr1xJPTEdDmeF2tQN
|
This was referenced Sep 8, 2026
This was referenced Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Problem
The clearance splay added in #360 only fires once a curve is at risk of hiding behind the bodies at its own ends. That caps an edge at about 75.5 degrees off horizontal and does nothing at all below that — legal, but never flat. A graph settles with edges at whatever angle the springs and gravity happen to leave them, which in the node editor reads as a tangle.
Fix
CalculateLinkFlatteningForcesnow also levels an edge continuously, with a force proportional to the vertical offset between its two ends. The two mechanisms do different jobs:A backward edge is exempt from levelling. It is still being reordered, and pulling it level would fight the vertical slide that #362's reorder needs to get its endpoints past one another.
Measured
On a six-body graph with four edges, shaped like the editor screenshot that prompted this:
Per-edge after: 36.6°, 13.5°, 1.3°, 0.9° — two of the four land within about a degree of flat.
Neither mechanism can make every edge horizontal at once: a node with several inputs cannot have all of them level with it, so the edges that share a busy node keep some angle. This is a preference the overlap pass and springs push back on, not a constraint.
LinkFlatteningStrengthnow scales both it and the clearance splay;0still disables both.On the overlapping nodes in the same screenshot
I tried to reproduce those and could not. The no-overlap invariant holds at rest both for a two-body pair placed overlapping and for a crowded six-body graph with four backward edges — worst overlap
0pxin every case, before and after this change. The most likely explanations are a frame caught mid-settle, or physics not enabled in that editor. Worth another look if it persists with physics running; I did not want to claim a fix I could not demonstrate.Testing
LinkFlattening_PullsAForwardEdgeTowardsHorizontal— a steep forward edge closes to under a quarter of its starting vertical offset.LinkFlattening_ZeroStrength_LeavesAnEdgeAsSteepAsItStarted— with the preference off, the spring alone leaves the edge steeper than it is wide.ForceDirectedLayout.Tests35/35,ImGui.NodeEditor.Tests71/71, andForceDirectedLayout.Native/ImGuiAppDemobuild clean in Release.Not verified visually — this container is headless and the demo UI suite cannot start here (the repo's PNGs are Git LFS pointers and
git-lfsis not installed). The angles are measured, but whetherLinkFlatteningStrength = 0.5is the right amount of flattening is a judgement worth making in the real editor; the demo slider covers 0–2.🤖 Generated with Claude Code
https://claude.ai/code/session_01D2KNUKr1xJPTEdDmeF2tQN
Generated by Claude Code