16
$\begingroup$

I am trying to create a simple split tree.

split tree

The growth should be only upwards, the vertical element length constant (1), the size of the horizontal bars should be halved in each iteration and the number of split levels should be freely chosen.

I found a very similar question Using Mathematica to create an H-Tree, but I cannot adopt the answers to solve my problem. I guess NestList is doing the job, but I didn't get further than:

drawT[{x_, y_}, size_] :=
 Line[{{{x + size, y}, {x - size, y}}, {{x + size, 
     y + size}, {x + size, y}}, {{x - size, y + size}, {x - size, 
     y}}}]

I basically don't know how to use the above function drawT, that creates the U-shaped geometry to be iterated in NestList.

Grateful for any help.

$\endgroup$
13
$\begingroup$

I like recursion so I've written a recursive solution.

Helper function for doing the drawing the basic u-shaped element of the tree

draw[x0_, x1_, y0_, y1_] := Line[{{x0, y1}, {x0, y0}, {x1, y0}, {x1, y1}}]

Helper function for doing the recursion

treeF[lvls_, lvl_, xy_, w_, h_] :=
  Module[{x0, x1, y0, y1},
    {x0, x1} = xy[[1]] + w {-1, 1}/2;
    {y0, y1} = xy[[2]] + {0, h};
    tree = {tree, draw[x0, x1, y0, y1]};
    If[lvl < lvls,
      treeF[lvls, lvl + 1, {x0, y1}, w/2, h];
      treeF[lvls, lvl + 1, {x1, y1}, w/2, h]]]

The main function

splitTree[levels_Integer?Positive, minW_: 1, ht_: 1] :=
  Block[{tree = {}},
    treeF[levels, 1, {0, 0}, baseW = 2^(levels - 1) minW, ht];
    Graphics[tree]]

Examples of use

splitTree[5]

tree5

Show[splitTree[7, 1, 5], ImageSize -> 600]

tree7.1.5

| improve this answer | |
$\endgroup$
13
$\begingroup$

One idea is to use Dendrogram on a KaryTree. Here is a function that does this:

splitTree[n_Integer?Positive] := Dendrogram @ KaryTree[
    2^(n+1) - 1,
    VertexWeight -> Floor @ Log2[Range[2^(n+1) - 1]]
]

An example:

splitTree[4]

enter image description here

One can use Graphics options to control the size. For example:

Show[splitTree[6], ImageSize->{300, 30}, AspectRatio->Full]

enter image description here

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you for the answer. I still accepted the other one, because I always find custom modifying KaryTrees in Mathematica is a pain. $\endgroup$ – Niki Oct 30 '17 at 13:56
2
$\begingroup$

Repeated scaling + translation is another possibility:

With[{n = 7},
     Graphics[Flatten[NestList[(# /. Line[l_] :> 
                                With[{c = -Mean[l[[{2, -2}]]]}, 
                                     Line /@ Outer[TranslationTransform[#2][#1] &,
                                                   l[[{-1, 1}]], 
                                                   TranslationTransform[c][l].
                                                   DiagonalMatrix[{1/2, 1}], 1]]) &,
                               {Line[{{-16, 1}, {-16, 0}, {16, 0}, {16, 1}}]}, n]]]]

tree

| improve this answer | |
$\endgroup$
2
$\begingroup$

Iterative version

n = 6;
s = 8;
m = {{{1/2, 0}, {0, 1}}, {#, 1}} & /@ {-s, s};
L = Line[{{-s, 1}, {-s, 0}, {s, 0}, {s, 1}}];
Graphics[NestList[GeometricTransformation[#, m] &, L, n]]

enter image description here

| improve this answer | |
$\endgroup$
  • $\begingroup$ You don't have to map TranslationTransform[]: TranslationTransform[{0, h}][With[{d = (A - B)/4}, {{A - d, A + d}, {B - d, B + d}}]] $\endgroup$ – J. M.'s discontentment Oct 31 '17 at 8:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.