17
$\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$
1

4 Answers 4

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

$\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

$\endgroup$
1
  • $\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
    Commented Oct 30, 2017 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

$\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

$\endgroup$
1
  • $\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$ Commented Oct 31, 2017 at 8:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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