⍝ Turtle graphics:
⍝
⍝ NB: testing this script with option upper case 'V' displays the images:
⍝
⍝ 'V'test'turtle' ⍝ view images: Esc to quit.
:ReturnIf 1 0≡83 ⎕dr 256 ⍝ big-endian:
tt←{⍺←⊢ ⍝ try turtle
pts←('V'∊Alpha)↓'⌸' ⍝ ~'V'∊⍺: points only, no image
chksum⌊0.5+⍺ turtle pts,⍵ ⍝ checksum of points
}
⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 2D turtle examples:
⍝ Escape (Esc) to close the graphics window.
hilbert ←, ⊂'A' '-BF+AFA+FB-' ⍝ Hilbert productions
hilbert ,← ⊂'B' '+AF-BFB-FA+' ⍝ (turtle ignores A and B)
tt hilbert lsys⍣4 ⊢'A' ⍝ order-4 Hilbert curve
585648
A60 ← 'A=↑1 B=↑1 +=⌽¯60 -=⌽60' ⍝ A and B fwd; 60 degree turns
koch ← 'A' 'A-A++A-A' ⍝ Koch curve production
A60 tt koch lsys⍣3⊢'A++A++A' ⍝ order-3 Koch curve
169411
⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝
:ReturnIf ~1∊'Vv'∊Alpha ⍝ not watching: save time
peano ←, ⊂'A' 'AFBFA-F-BFAFB+F+AFBFA' ⍝ Peano curve productions
peano ,← ⊂'B' 'BFAFB+F+AFBFA-F-BFAFB' ⍝ (turtle ignores A and B)
tt peano lsys⍣3 ⊢'A' ⍝ order-3 Peano curve
529580
dragon ←, ⊂'A' 'A+BF+' ⍝ Dragon curve productions
dragon ,← ⊂'B' '-FA-B' ⍝ (turtle ignores A and B)
tt dragon lsys⍣10 ⊢'FA' ⍝ order-10 Dragon curve
767677
tt'⎕',('X' 'XFY+')('Y' 'FY')lsys⍣12⊢'X' ⍝ traced squiral
873548
gosper ←, ⊂'A' 'A-B--B+A++AA+B-' ⍝ Gosper curve productions
gosper ,← ⊂'B' '+A-BB--B-A++A+B' ⍝ (A and B are fwd 1)
A60 tt gosper lsys⍣3 ⊢'A' ⍝ order-3 Gosper curve
958083
sierpinski ←, ⊂'A' '+B-A-B+' ⍝ Sierpinski triangle productions
sierpinski ,← ⊂'B' '-A+B+A-' ⍝ (A and B are fwd 1)
A60 tt sierpinski lsys⍣6 ⊢'A' ⍝ order-6 Sierpinski curve
702288
A30 ← 'A=↑1 B=↑1 +=⌽¯30 -=⌽30' ⍝ A and B are fwd 1; 30° turns
fern ←, ⊂'X' 'B-[[X]+X]+B[+BX]-X' ⍝ Fractal plant
fern ,← ⊂'B' 'BB' ⍝ (X is ignored)
A30 tt fern lsys⍣3 ⊢'X' ⍝ order-3 fern
484820
star←{ ⍝ ⍵-pointed star
⍺←⌊(⍵-1)÷2 ⍝ winding number
M←'F=↑1 T=⌽360÷',⍕⍵÷⍺ ⍝ macros
P←'X' 'FTX' ⍝ production
M tt P lsys⍣⍵⊢'X' ⍝ star drawing
}
stars←{(⍳⌊⍵÷2)star¨⍵} ⍝ all ⍵-stars
stars 11 ⍝ all 11-pointed stars
462785 471875 431132 433193 426821
⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 3D turtle examples:
⍝ Cursor keys ↑ ↓ ← → and keys z x to rotate.
⍝ Keys b and f to move image backwards and forwards.
⍝ Escape (Esc) to close the graphics window.
hilb3 ← 'A' '∨×AF∨×AFA-F∨÷÷AFA∧F+÷÷AFA-F÷A-÷'
tt¨ '' '⌹',¨⊂ hilb3 lsys⍣2 ⊢'A' ⍝ order-2 3D Hilbert curve
464589 464589
⍝ Polyhedron Schläfli dihedral angle approx
⍝ --------- -------- -------------- ------
⍝ Tetrahedron {3,3} ¯2○÷3 70.53°
⍝ Cube {4,3} ○÷2 90.00°
⍝ Octahedron {3,4} (○1)−¯2○÷3 109.47°
⍝ Dodecahedron {5,3} (○1)-¯3○2 116.56°
⍝ Icosahedron {3,5} (○1)-¯2○(5*0.5)÷3 138.19°
⍝
⍝ https://en.wikipedia.org/wiki/Table_of_polyhedron_dihedral_angles
platonic←{⍺←'' ⍝ Platonic solids
tetrahedron←{ ⍝ Tetrahedron
T←turn○÷6 ⍝ 30° turn
P←pitch ¯2○÷3*0.5 ⍝ pitch
S←'X' 'F++++[+∨F]X' ⍝ production
(F,T,P)turtle ⍺,S lsys⍣3⊢'X' ⍝ 3 turtle paths
}
cube←{ ⍝ Cube
T←turn○÷2 ⍝ 90° turn
R←roll○÷2 ⍝ roll
S←'X' '[+FX×+F+F]' ⍝ production
(F,T,R)turtle ⍺,S lsys⍣4⊢'X' ⍝ 4 turtle paths
}
octahedron←{ ⍝ Octahedron
T←turn○÷4 ⍝ 45° turn
P←pitch○÷4 ⍝ pitch
S←'X' 'F++[+∧F][+∨F]X' ⍝ production
(F,T,P)turtle ⍺,S lsys⍣4⊢'X' ⍝ 4 turtle paths
}
dodecahedron←{ ⍝ Dodecahedron
T←turn○2÷5 ⍝ 72° turn
R←roll(○1)-¯3○2 ⍝ roll
S←'X' 'F[×+F+F[÷+F+F]+F]+X' ⍝ production
(F,T,R)turtle ⍺,S lsys⍣5⊢'X' ⍝ 5 turtle paths
}
icosahedron←{ ⍝ Icosahedron
T←turn○÷3 ⍝ 60° turn
R←roll ¯2○(5*0.5)÷3 ⍝ roll
S←'X' '[F++F[---×+F-[-×+F×++F]-F]]+×X' ⍝ production
(F,T,R)turtle ⍺,S lsys⍣5⊢'X' ⍝ 5 turtle paths
}
F←'F=↑1 ' ⍝ forward 1 unit
attd←{⍕(⍺⍺,¨⊂'=',⍵⍵),∘⍕¨⍵÷○÷180 ¯180} ⍝ attitude change
turn←'+-'attd'⌽' ⍝ left/right turn (radians)
roll←'×÷'attd'⊖' ⍝ anti/clock roll
pitch←'∧∨'attd'⍋' ⍝ up/down pitch
turtle←⍺⍺ ⍝ (uses tt for test script)
⍵∊'Tt',33:⍺ tetrahedron ⍵ ⍝ Schläfli: {3,3}
⍵∊'Cc',43:⍺ cube ⍵ ⍝ .. {4,3}
⍵∊'Oo',34:⍺ octahedron ⍵ ⍝ .. {3,4}
⍵∊'Dd',53:⍺ dodecahedron ⍵ ⍝ .. {5,3}
⍵∊'Ii',35:⍺ icosahedron ⍵ ⍝ .. {3,5}
}
'' '⌹' ∘.(tt platonic)'TCODI' ⍝ wire and anaglyph
121116 768030 504036 487883 894311
121116 768030 504036 487883 894311
⍝ The following function takes a vector of edge matrices and returns a vector of
⍝ face matrices. Using graph-searching techniques, it identifies and collects
⍝ the edges that constitute each face of the polyhedron:
faces←{ ⍝ face polygons from edges
faces←{ ⍝ look for polygon faces
pgns←⍺ holes ⍵ ⍝ ⍺-holes in graph ⍵
~⍬≡(∊graph)~∊pgns:(⍺+1)∇ ⍵ ⍝ no luck: increase polygon size
{↑(1+≢⍵)⍴↑⍵}¨pgns⌷¨¨⊂⊂verts ⍝ polygon faces
}
holes←{ ⍝ chordless (≤⍺)-cycles in graph ⍵
spin←{(+/∧\⍵≠⌊/⍵)⌽⍵} ⍝ rotation of lowest vertex to front
flip←{{¯1⌽⌽⍵}⍣(</1 0 1/3↑¯1⌽⍵)⊢⍵} ⍝ & ordering of adjacent vertices
norm←flip∘spin ⍝ canonical orientation
⍺←≢⍵ ⋄ max←⍺ ⍝ max cycle length
∪↑,/(⍳⍴⍵){ ⍝ unique collected cycles
max<≢⍺:⍬ ⍝ path too long: quit
nx←(⊃⌽⍺)⊃⍵ ⍝ next vertices
(⊃⍺)∊nx:⊂norm ⍺ ⍝ cycle: normalised orientation
px←⍺∘,¨nx~⍺ ⍝ extended paths
gx←px{ ⍝ reduced graphs
f t←¯2↑⍺ ⍝ latest from-to vertices
fm tm←f t≠⊂⍳⍴⍵ ⍝ from and to masks
(fm∧tm∨f≠⍵)/¨⍵ ⍝ graphs with removed edges
}¨⊂⍵ ⍝ unreduced graph
∪↑,/px ∇¨gx ⍝ unique cycles
}¨⊂⍵ ⍝ starting graph
}
rnd←{(10*-⍺)×⌊0.5+⍵×10*⍺} ⍝ rounding to ⍺ decimal places
edges←↓¨4 rnd ⍵ ⍝ edges are vertex pairs
verts←∪↑,/edges ⍝ vertices
links←verts∘⍳¨edges ⍝ vertices per edge
vids←⍳⍴verts ⍝ vertex ids
masks←↓vids∘.∊links ⍝ edges per vertex
graph←,∘↑¨(masks/¨⊂links)~¨¨vids ⍝ graph of vertices
3 faces graph ⍝ polyhedron faces
}
⌊0.5+ '⌸' turtle platonic 'T' ⍝ 6 edge lines of tetrahedron
┌─────────┬─────────┬─────────┬─────────┬──────────┬──────────┐
│22 ¯39 16│22 39 16│ 22 39 16│¯45 0 16│¯45 0 16│22 ¯39 16│
│22 39 16│ 0 0 ¯47│¯45 0 16│ 0 0 ¯47│ 22 ¯39 16│ 0 0 ¯47│
└─────────┴─────────┴─────────┴─────────┴──────────┴──────────┘
⌊0.5+ faces '⌸' turtle platonic 'T' ⍝ 4 face triangles of tetrahedron
┌──────────┬──────────┬───────────┬──────────┐
│22 ¯39 16│ 22 ¯39 16│ 22 ¯39 16│ 22 39 16│
│22 39 16│ 22 39 16│ 0 0 ¯47│ 0 0 ¯47│
│ 0 0 ¯47│¯45 0 16│¯45 0 16│¯45 0 16│
│22 ¯39 16│ 22 ¯39 16│ 22 ¯39 16│ 22 39 16│
└──────────┴──────────┴───────────┴──────────┘
⍝ We can display the faces with solid fill colours drawn in far-to-near order
⍝ so that the ones in front hide those behind. The following little edits of
⍝ test's local copy of [turtle] do the trick. Notice the call to the above
⍝ function [faces]:
edit←{⎕fx ⍵ subs ⎕cr ⍺} ⍝ function editor
'turtle' edit 'image lines' 'image faces lines' ⍝ using face polygons
'turtle' edit 'FCol' 'FillCol' ⍝ ¯¯¯¯¯ ⍝ Fill colours
'turtle' edit 'lwidth' 'fstyle' ⍝ property rename
'turtle' edit '''Lwidth'' 4' '''FStyle'' 0' ⍝ solid fill ...
'turtle' edit '⍵×192' '240-⍵×80' ⍝ ... with light greys
'turtle' edit 'greys depth' 'greys depth 1↓¨' ⍝ without duplicated ...
'turtle' edit '+/¨⊢/¨' '+/¨⊢/¨1↓¨' ⍝ ¯¯¯ ⍝ ... vertices
⍝ ¯¯¯
tt platonic¨ 'TCODI' ⍝ solid polyhedra
121116 768030 504036 487883 894311
⍝∇ turtle lsys subs chksum
Back to: code
Back to: Workspaces