How to layout a tree structure

Godot Version

Godot 4.2.1

Question

I have a binary tree which I store in an object hierarchy (so the root node has two children, one of them has one, and so on). These skill nodes store their two possible children and depth, both at the script level and as an attribute.

I want to use a tree layout visualization algorithm to show this skill tree, but I’m stuck with it. I found a relatively simple solution. I traverse the tree and count how many nodes there are at the given depth. After that, I divide the given value by 1 radian.

Then I do another tree traversal to set the position based on the angle and a hard-coded distance, as shown below:

func _set_nodes_position(node: Node2D, target_depth: int, angle: float, distance_from_root: float) -> void:
	if node.depth == target_depth:
	
		var angular_position: float = global_count * angle
		node.position = Vector2( distance_from_root * cos(angular_position), distance_from_root * sin(angular_position))
		global_count += 1
	
	# Recursively set positions for children nodes
	if node.left_child and node.left_child.depth <= target_depth:
		_set_nodes_position(node.left_child, target_depth, angle, distance_from_root * 1)
	if node.right_child and node.right_child.depth <= target_depth:
		_set_nodes_position(node.right_child, target_depth, angle, distance_from_root * 1)

Sometimes the outcome is pretty good:


But other times, nodes overlap each other:

This should be the “goal”:
image

My guess is that the problem comes when I try to set the position of a node because it’s set relative to its own parent, rather than the “origin” of the tree, which is the root node in this case.

Since you may not have restrictions on the final tree layout. I would probably introduce some sort of physics based constraints. Like anti-gravity that repels the nodes from one another. This would allow you to avoid having to code all the rules and allow them to find their own space.