A square, a right triangle on its top edge, and two smaller squares on the triangle's other sides — forever.
Pythagoras, drawn
Take a square. Build a right triangle on its top edge. Build a square on each of the
triangle’s other two sides. Repeat on those squares.
Albert Bosman drew this in 1942, and the name is not decoration — the construction is
the theorem. The two child squares have areas a² and b², and the parent has area
c² = a² + b². So every level of the tree has exactly the same total area as the level
above it, and the whole tree of n levels has n + 1 times the area of its trunk.
Three levels. At this size the rule is directly readable.
The angle decides the tree
public float RotAngle { get; init; } = 1.07f;
If the triangle is isoceles — a right angle split evenly — the tree is symmetric and
the two branches are the same size. Any other angle makes one branch larger than the
other, and the tree leans.
At 1.07 radians, about 61°, the split is far from even: one child is markedly larger,
and the tree spirals rather than spreading. That single number is what separates the
familiar broccoli-shaped Pythagoras tree from this one.
Six levels. The asymmetry is unmistakable.
Nine. The square count doubles each level — 2⁹ = 512 at this depth — while the total
area only grows linearly, which is the same statement as the theorem.
Fourteen levels: sixteen thousand squares, and the trunk is now a small feature at the
bottom of a canopy.
Nineteen levels — over half a million squares, subject to the cut-off.
Two things that stop it
The recursion is bounded twice. MaxDepth caps the level count outright, and
CutOffSize discards any square that has shrunk below a threshold. The second matters
more in an asymmetric tree: the smaller branch shrinks much faster than the larger one,
so whole sub-trees terminate early while others carry on.
That is what stops the drawing being a uniform texture at the outside — the depth
reached varies across the canopy, and it varies because of the angle.
Refit at every depth
Each stage measures the tree’s own extent and scales it to the frame:
float scale = 180f / MathF.Max(rangeX, rangeY);
Necessary, because a Pythagoras tree does not keep its aspect ratio as it grows —
particularly an asymmetric one, which leans further with every level. The visible
consequence is that the trunk shrinks as the progression runs; the tree stays the same
size on the page.
Six renderings
| Rendering | Angle | Aspect | Draw | Ink |
|---|
| Ice Blue | 1.07 | 3.5 | outline | ice on black |
| Ember | 1.30 | 2.0 | outline | orange on near-black |
| Aurora | π/4 | 3.5 | outline | violet on near-black |
| Lattice | 1.07 | 3.5 | filled boxes | silver on near-black |
| Solstice | 0.85 | 1.8 | outline | gold on near-black |
| Museum | 1.07 | 3.5 | matted | indigo on ivory |
Each rendering explores a different axis of the generator. Ember pushes RotAngle to a
more extreme lean and compresses Aspect to squat rectangles. Aurora sets RotAngle
to π/4, the isoceles case, producing the symmetric canopy the default deliberately
avoids. Lattice switches to DrawMode 1, where each square is drawn as its own closed
polygon rather than as part of a single continuous outline. Solstice uses
AngleModulo 1, which alternates the lean direction every two depths, combined with
wide rectangles. Museum keeps the same geometry as Ice Blue but inverts the palette —
dark indigo ink on a warm ivory matte — and presents it behind an indigo frame with a
bevel cut line around the opening, like a finished gallery print.
Determinism
Nothing is seeded and nothing is random. Every node’s position and size is a closed form
in its parent’s, and the traversal is an explicit stack in a fixed order.