Как равномерно визуализировать узлы дерева?

Есть произвольное дерево, узлы-братья удалены друг от друга на динамически задаваемое значение (в данном случаи 20), так же как и узлы-соседи (в данном случаи 40). В тот момент, когда самая левая ветвь формируется, вызывается метод расстановка узлов в который передается самый верхний-левый и самый верхний-правый и разница на которую увеличился промежуток между ними (в данном случаи 20).
Вот что происходит в методе расстановка узлов -
fe5c671d1f25467babd1b1390554a363.png

1. в цикле проходим от верхний-левой до верхней-правой и считаем промежутки (в данном случаи это шесть пустых клеточек, которые как говорил ранее по 20, то есть сумма 120);
2. делю сумму полученную на предыдущем шаге на кол-во узлов плюс один (120 / 3 = 40);
3. проверяю на сколько текущий узел (я начинаю с лева на право и по этому текущий узел это тот у которого два ребенка) удален от левого узла-брата (в данном случаи это 80).
4. теперь я вычитаю из 80 - 40 = 40, это значение расстояние на которое я смещу текущую ноду чтобы оказаться в нужном месте.
5. если это значение (40) больше чем то на которое увеличилось расстояние между двумя крайними нодами, то это значение становится меньшим. То есть рассчитал что 40, но оно больше позволенного и по этому значение меняется на 20.
6. перемещаю ноду.
9cdcbffac161439890b465d5500b94d9.png

Повторяю шесть предыдущих шагов для следующей ноды -
1. получаю 60
2. 60 / 2 = 30
3. 40
4. 30
5. 10
6. ...
a65a008b156944b683936c4d08c78aa3.png

Видите как я усреднил? Сначала выяснил что сдвинуть нужно на сорок, но так как на сорок сдвинуть я не могу (нарушится правило для нижних детей, они будут ближе чем на сорок), я сдвигаю на максиму возможное, это двадцать. А потом я сдвигаю уже на десять.
Для примера, если бы у первой обрабатываемой ноды не было детей, то картина была бы следующей -
95f91e2f82e346b697c7a42d9de966a1.png

На тот случай, если у меня сначала идет узел который можно сдвинуть на "сколько-то" (без детей), а после тот который уже нельзя сдвинуть на "сколько-то", то второй я снова сдвигаю на максимум, но при этом выполняю алгоритм с самого начала (точнее с самой последней удачной точки), но на время подменяю самый верхний-правый текущим.

Я бы показал код, но я не хочу чтобы Вы смотрели его недочеты, а лишь хочу чтобы Вы поняли смысл.

Вот. Но дальше я столкнулся с следующей проблемой, да и возможно это только одна из ...
ba8a5dc35828492aa9af1d8ad951eaae.png
Входные данные те же, но все ломается. Алгоритма, как я хотел, не получилось, да и придумать я не могу.

Что есть у нод
indent - значение на которое текущая нода удалена от предыдущей |_|->|_|
leftOffset - это значение на которое я смещаю влево. В самом начале оно ноль
rightOffset = это то значение на которое смещаю вправо. И тоже по дефолту ноль.

Вот. Сами ноды, как обычные ноды, ссыдка на парента, в котором они хранятся в индексированном массиве. Есть методы для получения ноды по индексу и получение самого индекса.

Если есть какие-то идеи я буду рад выслушать, у самого просто вселенская пустота в голове.
  • Вопрос задан
  • 556 просмотров
Пригласить эксперта
Ответы на вопрос 1
@throughtheether
human after all
Спасибо, что "призвали", помогу чем смогу.

узлы-братья удалены друг от друга на динамически задаваемое значение (в данном случаи 20), так же как и узлы-соседи (в данном случаи 40)
Давайте с терминологией определимся, под соседями подразумеваются узлы на одном уровне дерева, не имеющие общего непосредственного родителя (не братья)?

Ваш алгоритм, к сожалению, до конца не понял, при наличии времени попробую повторить попозже. Но идея двигать отдельные ноды "вручную" мне не импонирует.

Если есть какие-то идеи я буду рад выслушать
Идея такая. Дерево, как правило, имеет на нижних уровнях больше узлов, чем на верхних. Больше узлов - меньше свободы в плане сколь-нибудь равномерного их размещения. Так и начинайте снизу. Из готовых алгоритмов навскидку могу только вспомнить Tidier drawing of trees (за авторством Reingold, Tilford), вполне возможно, что удастся его адаптировать под ваши требования.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы