summaryrefslogtreecommitdiff
path: root/info/laan/paradigm/paradigm.lin
blob: 332b591ad82f6c8a201c90751ab5ea5a03a7f80e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
%July 1995, modified Feb 1996
%Paradigma: line bundle
%C.G. van der laan, cgl@rc.service.rug.nl
\input blue.tex 
\loadtocmacros
\def\xytxt#1{%Function: place text #1 at x, y
   \xy{\vbox to0pt{\vss
   \hbox to0pt{\strut#1\hss}\kern0pt}}}
\tolerance500\hbadness=499\hfuzz=8pt
%\parindent0pt %=1pc
\everyverbatim{\emc}

\bluetitle Paradigms: The winds and halfwinds

\bluesubtitle Details matter

\blueissue \maps{96}1

%\blueauthor Kees van der Laan

\bluepictures\pythtreepic\spiralpic\windpic\trimodelpic\tritreepic
   \bintreepic\rotatedbintreepic\chartpic

\beginscript
\everyverbatim{\unmc}
\bluehead BLUe's Design V

Hi folks. 
How to draw lines at {\oldstyle45}$^\circ$ in \TeX{} is exercised.
This simple-looking and innocent problem touches on fundamental issues, 
such as should we adhere to the Cartesian picture environment 
approach,\ftn{The \LaTeX{} picture environment for example.}
or do we need something else now and then?

This work emerged from studying Gurari's approach to graphics
incented by a suggestion in Jos Winnink's review, \maps{94}2.

The discussion below explains what has been used in BLUe's format system 
in the turtle graphics\ftn
{Knuth already used the `Turtle' idea in his dragon figures.
 For those interested in turtle graphics consult for example 
 S. Papert: Mindstorms.}
macros, especially in the coding of
\cs{N}, \cs{E}, \cs{S}, \cs{W},  
\cs{NE}, \cs{SE}, \cs{SW}, \cs{NW}, next to 
\cs{ESE}, and \cs{WSW}.
Examples are included which show what can be attained by these
basic functionalities.
It is also shown how the obtained pictures can be stored 
in the picture database |pic.dat| for reuse
with  different scaling or positioning.

In the Appendix some tree diversions have been given.

\bluehead What is the problem?

\TeX's \cs{hrule} and \cs{vrule} primitives are a gem and very powerful.
It would be nice to have similar primitives for any direction.
In absence of these we can use line pieces provided in fonts.
However, the latter approach suffers from the following drawbacks
\bitem for a few discrete directions only
\bitem line lengths are discrete too
\bitem line thickness is inflexible.
\smallbreak

\bluehead Why?

The need for general and flexible line elements arose when I faced the problem how
to draw classical fractals.\ftn{Inspired by Gurari's work on \TeX{} and graphics.}
The very least is the possibility to draw lines at {\oldstyle45}$^\circ$\Dash the halfwinds.

\blueexample Pythagorean tree

$$\pythtreepic$$
How to do this in \TeX\ftn
{For the coding of \cs{pythtree} see later. Or
 Macro writing\Dash with confidence.}?

Through the picture environment? 
Too clumsy, and cumbersome when changing the order, for example.

Through \PS?
This is possible, especially it provides for lines at all 
orientations.\ftn{J V Romanovsky has provided a concise \PS{} program.}

Through \MF? Definitely, see my \MF{} anthology.

However, why not go for how far we can get just by \TeX?

And what about the relevancy? I'm very pleased by the spin-off  how to
typeset binary trees or charts, even rotated without the use of \PS.
See the Appendix or the Publishing with \TeX{} user's guide.

What we need is not the Cartesian picture environment approach, 
but the good old penplotter \TeX niques, better known
in the pedagogical world as `Turtle graphics.'

\bluehead Turtle graphics

The basic idea is that the position of the turtle is maintained in 
the dimen variables \cs{x} and \cs{y},
with the reference point left invariant. 
The accompanying figure shows the effect of \cs{N1}: draw the line 
(\cs{x}, \cs{y})\dash(\cs{x}, \cs{y}+1), i.e.\ the turtle moves up.
After completion \cs{y} has been increased by \cs{unitlength}.

%Perhaps I better put it in pic.dat
\vskip2.5\bigskipamount
$$\unitlength.5ex
  \y=0pt\x-10\unitlength
  {\W{4}\E{40}}\S{4}%
  {\advance\y-2\unitlength\xytxt{ Ref.\ point}}%
  \N{20}\whiteE{20}\S4\whiteS4\xytxt{ (x,y)}$$
\vskip1.5\bigskipamount
The movements\Dash our first steps in the turtle graphics world\Dash 
can be achieved by the control sequences
\bitem \cs{N}, \cs{E}, \cs{S}, \cs{W} mean draw north, east, south and west, 
       similar for \cs{NE}, \cs{SE}, \cs{SW}, and \cs{NW}
\bitem \cs{whiteN}, \cs{whiteE}, \cs{whiteS}, \cs{whiteW} mean
      {\em  white}-draw north, east, south and west, i.e., the turtle just moves.\ftn{The
         halfwinds can be composed from the winds in this case.}
\smallbreak

\blueexample Spiral

To get the flavour another classical picture, which shows
that we don't have to worry about coordinates.
$$\spiralpic$$
The spiral is marked up essentially as follows\ftn{For the 
   placement within context details 
   consult \cs{spiralpic} in pic.dat.} 
\beginverbatim
\unitlength.5ex \k30 
\loop\E{\the\k}\advance\k-1
     \S{\the\k}\advance\k-1
     \W{\the\k}\advance\k-1
     \N{\the\k}\advance\k-1
\ifnum\k>4 \repeat
!endverbatim
\vskip-\medskipamount
\bluehead Basics

Essential for the understanding is familiarity with \TeX's
{\em boxes of size zero}, to know the effect of \cs{kern}-s and
\cs{h/vss}-s inside, and of combinations of these boxes.
Before reading on peruse the following.

\bluesubhead Kerns and stretchorshrink-s

within boxes of size zero.

\blueexample With and without boxes of size zero

\beginverbatim
\newdimen\x \x=4ex \newdimen\y \y=2ex
.\hbox to 0pt{\kern\x a\hss}. 
\kern10ex and \kern10ex
.\kern\x a.

and

.\hbox to0pt{\kern\x\vbox to0pt
   {\vss\hbox{a}\kern\y}\hss}.
\kern10ex and \kern10ex
.\kern\x\raise\y\hbox{a}.
!endverbatim
with result
%\newdimen\x \newdimen\y
\bgroup
\x4ex \y2ex
$$.\hbox to0pt{\kern\x a\hss}. 
\kern10ex and \kern10ex
.\kern\x a.$$
and
$$.\hbox to0pt{\kern\x\vbox to0pt
   {\vss\hbox{a}\kern\y}\hss}.
\kern10ex and \kern10ex
.\kern\x\raise\y\hbox{a}.$$
\egroup
By this mechanism we can move to
any point on the page and put there what we wish.
The essential issue of the box of zero width is that
the {\em reference point is left invariant.} 
It is the same before and after.

\bluesubhead Putting it together

In vertical mode the \cs{hbox}-es are aligned on the reference point, and 
when the heights and depths are zero the \cs{hbox}-es overprint,
and the order of specification is immaterial.

In (restricted) horizontal mode \cs{hbox}-es of width zero overprint
and can be given in any order, \TB{} {\oldstyle389}.

In math mode the zero size boxes overprint. 
In display math the invariant reference point is centered horizontally.

Coding in \TeX{} simple? Forget it!
So unusual, but \dots con\-sequent, utmost consequent, sigh. 

\bluesubhead Coding flashbacks

The codes which follow are the fifth or so version.
The zeroeth version was there to please me, excited me.
Recursive programming worked as I expected.
Then I had a version which served to try out as many examples as I could think of.
During the process of collecting examples I strove after consistency of the codes.
Why did I use integer arithmetic anyway? 
I had no good reason and I decided to
use dimensions and do the arithmetic through the dimensions, 
and widened en-passant the allowed arguments of the winds and
halfwinds to expand to `factor'-s.

And what about the context?

It seemed necessary to abstract from the multitude of boxes and to come up with
an enveloping hbox of width zero.

Finally, details were taken care of, such as how do the macros behave in the various
contexts.
Do the winds and halfwinds  behave the same?
It turned out that they did not. So I had to go back from where I started.
I considered the early versions as prototypes  and started 
anew guided by specs, 
with simplicity and robustness as yardsticks, 
stating precisely how the elements should behave.
By all means no sinecure, but IMHO with all respect,
a must in software engineering.\ftn{In fact I had this article nearly finished
   when I realized that the vertical rules induce a vbox of the size of the
   rules, while other directions when boxed yielded a box of size zero.
   Not nice and confusing, although for the article and in my hands it was ok.
   Nevertheless, I decided to go for a uniform approach. When boxed the dimensions
   of the box should be zero.}
Indeed, a superficially, simple problem.

Is that all? Essentially yes, but \dots details matter.
 
\bluehead The winds and halfwinds

The intuitive idea is to compose lines out of elements, from what I call atoms. 
I used  squares, casu quo rectangles, as atoms, and 
stacked these as follows.\ftn{In order to make it visible
  \cs{linethickness} has been set to 1ex. Experiments with bullets and \LaTeX's line fonts
   did not yield the pleasing exact results.}  

Essential  is how lines leave a mathematical point. 
The accompanying model picture  is obtained through the following macros.
\beginverbatim
\let\0\N \let\1\NE \let\2\E \let\3\SE 
\let\4\S \let\5\SW \let\6\W \let\7\NW 
\linethickness1ex
\setbox\hlfwndelm=\hbox{\vrule
   width\the\linethickness 
   height\the\linethickness depth0pt}
\unitlength10ex
\def\draw{\csname\the\dir\endcsname1}
$$\loop\ifnum\dir<8{\draw}\advance\dir1\repeat$$
!endverbatim

\thispicture{\linethickness1ex}
$$\windpic$$
Remarks. \cs{N} etc.\ draw in the implied directions with length of the argument
and \cs{unitlength} as scaling.



 
\bluehead Pondering aloud

Can we attain compatibility with \TeX's rules primitives?
I don't think so, alas. On the other hand we have to 
reconsider the leaving of the rules from a point. 

\bluesubhead Thickness

What is meant by thickness if we stack instead of tile?
What is the perceived blackness?

I presumed that stacking  with square elements
of size \cs{linethickness}${\times}$\cs{linethickness}\Dash 
   like in the example figure\Dash 
yields the same blackness as a rule of thickness \cs{linethickness}.\ftn{I also
   supplied macros\Dash tiled variants\Dash for  \cs{NW} and \cs{NE}.}

\bluesubhead Size

Usually the size along the x-axis must be provided.
I prefer to have the real size specified independently from the orientation
of the line.
However, the resulting size is not necessarily \#1${\times}$\cs{unitlength}.\ftn{To put 
   it in another way: the required length must be a multiple of the atom size.} 
In general the result differs at most by half the atom size, 
because it is composed of a multiple of the atomic element. 
We have to correct by $\sqrt2$ to compensate for the direction, when we
pace along one of the axes.
In the example the required length is {\oldstyle10}ex, 
with as result the  stacking of {\oldstyle7} atoms of size {\oldstyle1}ex.

For large lines one could think of combining \LaTeX's line{\oldstyle10}
line elements with the smaller elements. 
I refrained from that for two reasons.
Firstly, the \LaTeX's NW line element\Dash the |\char'145|\Dash 
did not fit exactly in the box, and 
secondly, the inflexibility of the thickness of the font elements.

\bluehead Design specs

With awareness of the above I specified the following for the
microscopic level\Dash the wind and halfwind commands proper\Dash
and for the macroscopic level\Dash the placement within context.

\bluesubhead Microscopics

The functionality is
to draw a line of the specified length in the direction as implied by the
control sequence name.
The general specifications read as follows.
\bitem as argument a `factor' is expected, to yield the required length
       \#1${\times}$\cs{unitlength}\ftn{The idea is that not only integer values
         can be specified but also decimal fractions.}
\bitem parameterization is by \cs{linethickness}
\bitem after drawing, the position of the turtle is at the end of each line,
       the reference point has been left invariant, and all
       the boxes have zero width, height and depth. 
\smallbreak
Extra for the four halfwinds the following.
\bitem parameterization is by \cs{hlfwndelm} and  \cs{linethickness}
       in there
\bitem draw a line of $\approx$ the specified size
\bitem the atoms are stacked diagonally, at the corners.
\smallbreak

\bluesubhead Macroscopics

The placement within context is the concern of the user.
Because of the zero dimensions of the boxes it is a nuisance
to skip or kern when using a picture to create the open space,
the niche for the picture.
Moreover, when the picture does not take dimensions we are in trouble
at page breaks. Therefore assistance is badly needed. 
The picture environment idea  combined with 
databases come to rescue. 
The {\it use\/} of prefab pictures has been simplified in this way, 
while there is flexibility via \cs{thispicture} to override the defaults.

Pictures can be stored in BLUe's format pic.dat database. 
Within each database element the default placement within context can be povided for.
Through the use of \cs{everypicture} and/or \cs{thispicture} the defaults can be 
overriden. 
This approach complies with the general principles adopted in BLUe's format system. 

\bluehead Coding the winds and halfwinds

In the fourth version, where emphasis was put on that all boxes have zero dimensions,
I also decided to separate to get at the (x, y)  position from what is put there.
This is much in the spirit of the second \cs{point} macro of \TB{} {\oldstyle389}, and
adheres to the {\it separation of concerns\/} adage.\ftn{IMHO it makes the code more
   trustworthy and circumvents pitfalls. 
   Especially, the mixing up of the kerns needed to get at (x, y) 
   with the kerns to position what has to be put at (x, y).}

The dimension variables \cs{x} and \cs{y} have after completion the values
of the coordinates of the end of the line.
\beginverbatim
\newbox\hlfwndelm
\newdimen\linethickness \linethickness1ex%.2pt
\newdimen\auxdim %linesize
%
\def\xy#1{%Function: place #1 at x, y
   \vbox to0pt{\kern-\y
   \hbox to0pt{\kern\x#1\hss}\vss}}
%
\def\xytxt#1{%Function: place text #1 at x, y
   \xy{\vbox to0pt{\vss
   \hbox to0pt{\strut#1\hss}\kern0pt}}}
%
\def\N#1{\xy{\kern-.5\linethickness
  \vbox to0pt{\vss
  \hrule height#1\unitlength
   width\linethickness}}%
\advance\y#1\unitlength}
%
\def\S#1{\advance\y-#1\unitlength{\N{#1}}}
%
\def\E#1{\xy{\vbox to0pt{\vss
   \hrule width#1\unitlength
          height\linethickness 
          depth0pt\vss
}}\advance\x#1\unitlength}
%
\def\W#1{\advance\x-#1\unitlength{\E{#1}}}
%
\def\NE#1{\auxdim#1\unitlength\correction
\loop\advance\auxdim-\wd\hlfwndelm
\ifdim\auxdim>-.5\wd\hlfwndelm
   \xy{\vbox to0pt{\vss\copy\hlfwndelm}}%
   \advance\x\wd\hlfwndelm
   \advance\y\ht\hlfwndelm 
\repeat}
%
\def\NW#1{\auxdim#1\unitlength\correction
\loop\advance\auxdim-\wd\hlfwndelm
\ifdim\auxdim>-.5\wd\hlfwndelm 
   \advance\x-\wd\hlfwndelm
   \xy{\vbox to0pt{\vss\copy\hlfwndelm}}%
   \advance\y\ht\hlfwndelm
\repeat}
%
\def\SW#1{\auxdim#1\unitlength\correction
\loop\advance\auxdim-\wd\hlfwndelm
\ifdim\auxdim>-.5\wd\hlfwndelm 
   \advance\x-\wd\hlfwndelm
   \advance\y-\ht\hlfwndelm
   \xy{\vbox to0pt{\vss\copy\hlfwndelm}}%
\repeat}
%
\def\SE#1{\auxdim#1\unitlength\correction
\loop\advance\auxdim-\wd\hlfwndelm
\ifdim\auxdim>-.5\wd\hlfwndelm 
   \advance\y-\ht\hlfwndelm
   \xy{\vbox to0pt{\vss\copy\hlfwndelm}}%
   \advance\x\wd\hlfwndelm
\repeat}
%For \NE and \NW the titled variants read
\def\NE#1{\auxdim#1\unitlength\correction
\loop\advance\auxdim-.5\wd\hlfwndelm
\ifdim\auxdim>-.25\wd\hlfwndelm
   \xy{\vbox to0pt{\vss\copy\hlfwndelm}}%
   \advance\x.5\wd\hlfwndelm
   \advance\y.5\ht\hlfwndelm 
\repeat}
%
\def\NW#1{\auxdim#1\unitlength\correction
\loop\advance\auxdim-.5\wd\hlfwndelm
\ifdim\auxdim>-.25\wd\hlfwndelm 
   \xy{\vbox to0pt{\vss
       \llap{\copy\hlfwndelm}}}%
   \advance\x-.5\wd\hlfwndelm
   \advance\y.5\ht\hlfwndelm
\repeat}
!endverbatim

\bluehead Coding a database element

As promised in the Macroscopics section the visibility of the picture\Dash
   that is the size\Dash
has to be added when the picture is stored in the database for (re)use.
In order to do so I added two extra layers. 
The structure of a pic.dat database element, and
a picture environment on top of for example
gkp's environment to allow user flexibility.

If we assume that the picture
proper has been created within gkp's
\beginverbatim
\def\gkpbeginpicture(#1,#2)(#3,#4)%
%#1, #2 xsize, ysize (dimensionless)
%#3, #4 xshift, yshift (dimensionless)
{...}  
\def\gkpendpicture{...} 
!endverbatim
then the flexibility layer reads
\thispicture{\emc}
\beginverbatim
\def\beginpicture{\bgroup
   \the\everypicture\the\thispicture
   \gkpbeginpicture(\the\xdim,\the\ydim)%
   (\the\xoffset,\the\yoffset)%
   <pictureproper>}  
\def\endpicture{...} 
!endverbatim
A pic.dat database entry consists of a quadruple:
\cs{lst} list element tag,
\cs{<name>pic} the name,
a group with defaults,\ftn{Demarcated by explicit braces.} and
the picture proper enclosed by
\cs{beginpicture} and \cs{endpicture}.
\beginverbatim
\lst\<name>pic{<defaults>}
\beginpicture
<pictureproper>
\endpicture
!endverbatim
 
\blueexample Coding the database element bintreepic

The \cs{bintreepic} element of the pic.dat database reads as follows.\ftn{Note
   that there is much flexibilty here. Also the \cs{bintree} macros can be 
   reused as such. \cs{bintreepic} comes down to an invoke of this macro
   with some flexibilty added.}
\beginverbatim
\lst\bintreepic{\bgroup
   \unitlength.5ex\kk32 
   \xoffset{-32} \yoffset{-2}%
   \xdim{66}\ydim{5}%
   \def\eertnib##1\bintree{\fi}
\beginpicture\bintree\endpicture\egroup}
%with in the kernel blue.tex
\def\bintree{\S1\ifnum\kk=2 \eertnib\fi
   \divide\kk2 {\W{\the\kk}\bintree}%
   \E{\the\kk}\bintree}
%and accounting for the leaves
\def\eertnib#1\bintree{\fi\global\advance\k1
   \whiteS1\xytxt{ \csname\the\k\endcsname}}
!endverbatim

\bluehead Coding recursion

Long I believed that tail recursion\Dash as used for example in the 
\cs{loop} \dots \cs{repeat}\Dash  is not sufficient. We also have
to cope with `Ackermann-like splittings' of the recursion. 
For the case of the Pythagorean tree for example, this means that at each recursion
level we have to take care of the left branch and the right branch, i.e.\ two invocations
must be done. 
This interferes with how to handle the termination of the recursion.
A problem? \TeX{} too difficult?
Hang on there are at least two elegant and general solutions.

\bluesubhead Recursion termination

\blueexample $n$!

As pedagogical example the calculation of $n$!
\beginverbatim
\n=...  %counter var
\nfac=1 %default
\def\fac{\ifnum\n=1 \caf\fi
   \multiply\nfac\n \advance\n-1 \fac}
\def\caf#1\fac{\fi}
!endverbatim
The termination is obtained because \cs{fac} is used as end terminator
in the definition of \cs{caf}. \cs{fac} is implicitly gobbled, and 
the process backtracks, resulting finally in termination.

\blueexample Pythagorean tree

Without explanation the Pythagorean tree recursive macro
is given below.\ftn
{Hopefully, it is self-explanatory, at least 
 with respect to the main flow. By the way in what order
 is the tree drawn?}
At each level we have two invocations\Dash the branching\Dash 
to take care of the left and right branch.
\beginverbatim
\def\pythtree{\ifnum\level=1 \eerthtyp\fi
    \advance\level-1 
    \multiply\kk23\divide\kk32%\sqrt2 
    {\leftbranch\draw\pythtree}%
     \rightbranch\draw\pythtree}
\def\eerthtyp#1\pythtree{\fi}
!endverbatim
No build up of \cs{fi}-s, no use of \cs{expandafter} nor \cs{let}. 
The \cs{let} mechanism has been used throughout in \TB.

\bluesubhead A la Knuth

In the coding of \cs{squine}\Dash a quadratic spline\Dash
Knuth showed how to terminate (tail) recursions in \TeX. 
For \cs{fac} this results in the following.
\beginverbatim
\def\fac{\ifnum\n>1 \expandafter\dofac\fi}
\def\dofac{\multiply\nfac\n 
   \advance\n-1 \fac}
!endverbatim

For the Pythagorean tree the result reads as follows.
\beginverbatim
\def\pythtree{\ifnum\level>1 
   \expandafter\dopyth\fi}
\def\dopyth{\advance\level-1 
    \multiply\kk23\divide\kk32
    {\leftbranch\draw\pythtree}%
     \rightbranch\draw\pythtree}
!endverbatim
Earlier I noticed the elegance of introducing an extra level, especially
to circumvent too many \cs{expandafter}-s in a row.

As an aside the use reads
\beginverbatim
\let\0\N \let\1\NE \let\2\E \let\3\SE 
\let\4\S \let\5\SW \let\6\W \let\7\NW
\def\leftbranch{\advance\dir7
 \ifnum\dir>7 \advance\dir-8 \fi}%mod 8
\def\rightbranch{\advance\dir1 
 \ifnum\dir>7 \advance\dir-8 \fi}%mod 8
\def\draw{\csname\the\dir\endcsname{\the\kk}}
\def\pythtree{\ifnum\level>1 
   \expandafter\dopyth\fi}
\def\dopyth{\advance\level-1 
    \multiply\kk23\divide\kk32
    {\leftbranch\draw\pythtree}%
     \rightbranch\draw\pythtree}
$$\unitlength0.1pt\kk128 %Size
                  \level5%Order
  \N{\the\kk}            %Trunk
  \pythtree$$
\tracingstats1
\bye
!endverbatim

\bluehead Trinaries

For {\oldstyle45}$^\circ$ lines I used square elements.
Why not use a rectangular element for {\oldstyle30}$^\circ$ lines
in conformance to the direction?

{\catcode`\^=7 \blueexample Lines at {\oldstyle30}$^\circ$

}
$$\trimodelpic$$
This model is obtained by
\beginverbatim
$$\x0pt\y0pt
  {\N{10}}{\ESE{10}}{\WSW{10}}$$
%with initializations
\linethickness1ex
\setbox\trielm=\hbox{\vrule 
   width1.74\linethickness 
   height\linethickness\relax}
%To account for element in 30 degrees direction
\unitlengthy\ht\trielm %default.2pt
\unitlengthx\wd\trielm %default.3482pt
\unitlength\unitlengthy%default.2pt
%and the macros
\def\WSW#1{\auxdim#1\unitlength\divide\auxdim2 
   \loop\advance\auxdim-\unitlengthy 
   \ifdim\auxdim>-.5\unitlengthy
      \advance\x-\unitlengthx
      \advance\y-\unitlengthy
      \xy{\vbox to0pt{\vss\copy\trielm}}%
   \repeat}
%
\def\ESE#1{\auxdim#1\unitlength\divide\auxdim2 
   \loop\advance\auxdim-\unitlengthy 
   \ifdim\auxdim>-.5\unitlengthy
      \advance\y-\unitlengthy
      \xy{\vbox to0pt{\vss\copy\trielm}}%
      \advance\x\unitlengthx
   \repeat}     
!endverbatim

\blueexample Trinary tree

$$\N{128}\tritreepic$$
\beginverbatim
$$\x0pt\y0pt\level6 \kk128\N{128}\tritree$$
%with trinary tree macro
\def\tritree{\ifnum1=\level \eertirt\fi
    \advance\level-1 \divide\kk2
    {\N{\the\kk}\tritree}%
    {\ESE{\the\kk}\tritree}%
     \WSW{\the\kk}\tritree}
\def\eertirt#1\tritree{\fi}
!endverbatim
Remark. The \cs{unitlength}-s are default 
        equal to the sides of the elementary rectangular block.
        The size of the tree can be controlled by \cs{kk}.

\bluehead Epilogue

The lines at {\oldstyle45}$^\circ$ have little compatibility
with \TeX's rules, alas, especially with non-neglible thickness. 
I was surprised to realize that \TeX's defaults for rules are 
not symmetric around their axes in relation to the reference point. 
\medskip\noindent
Have fun, and all the best.

\makesignature\let\makesignature\relax

\bluehead Appendix: Binary tree and chart

\blueexample Binary tree

\beginverbatim
\bluepictures\bintreepic\par
$$\bintreepic$$
!endverbatim
with result
$$\bintreepic$$

How can we add leaves\ftn{See the PWT user guide for the answer.}?

\bluesubhead Rotated tree

Once we understand turtle graphics, rotating a tree can be done easily 
by shifting the meaning of the directions, and adjusting the
positioning of the leaves.\ftn{A white lie. The tree is actually mirrored
   because I like the leaves to be numbered from the top. 
   In general we can rotate via \PS.}

\blueexample Rotated tree

\begindemo
\thispicture{\def\1{cgl}
  \def\2{PWT}\def\3{July}
  \def\4{1995}\def\5{\dots}
  \yoffset{-16}\ydim{28}}
$$\rotatedbintreepic$$
!yields
\thispicture{\def\1{cgl}\def\2{PWT}
  \def\3{July}\def\4{1995}
  \def\5{\dots}\def\6{}\def\7{}
  \yoffset{-16}\ydim{28}}
$$\rotatedbintreepic$$
\enddemo
\cs{bintree} and \cs{eertnib} come with blue.tex, and
\cs{rotatedtreepic} is included in pic.dat.
The \cs{rotatedtreepic} entry reads as follows.
\beginverbatim
\lst\rotatedbintreepic{%July 1995, cgl
\bgroup\unitlength1ex%
  \let\W\N \let\exchange\E 
  \let\E\S \let\S\exchange
  \def\1{x}\def\2{y}\def\3{a}\def\4{b}%
  \def\5{piet}\def\6{hans}\def\7{etc.}%
  \k0\kk16\xdim{10}\ydim{30}%
\beginpicture\bintree\endpicture\egroup
\thispicture{}}
!endverbatim 

\bluesubhead Chart

Through the \cs{bintree} macro we can also
obtain charts elegantly.

\blueexample Chart, \TB{} ex{\oldstyle22}.{\oldstyle14} {\oldstyle248}

$$\chartpic$$
obtained via
\beginverbatim
%labels in preorder (default in \chartpic)
\def\1{LMB, 1912}
\def\2{MJHB, 1882}\def\5{PAME, 1884}
\def\3{JHB, 1838} \def\4{MDB, 1840}
\def\6{EFE, 1845} \def\7{CLW, 1850}
\ekk8
\k0\unitlength2ex\x0pt\y0pt\kk8
\hbox{\bintree}
%with auxiliaries
\let\Eold\E
\def\E{\global\advance\k1
  \xytxt{ \csname\the\k\endcsname}\Eold}
!endverbatim
Remark. An aid in finding the numbers of the branches is
to delete \cs{csname} and \cs{endcsname} in \cs{E} .
The way of traversal at hand is called preorder.

When using \cs{chartpic} from |pic.dat| the texts along the branches
\Dash |\def\1{...} etc.|\Dash
have to be supplied within a \cs{thispicture},
to override the defaults.
\medbreak
\makesignature
\pasteuptoc
\endscript