{lines} ← {defs←default} ##.turtle cmds ⍝ Flying-turtle graphics. [turtle] displays fractal curves in a temporary window. Hit Escape to close. Right argument [cmds] is a vector of single-character macro calls as produced by →lsys←. Left argument [defs] are macro definitions, which expand to primitive turtle commands: ↑⍵ move forward ⍵ units (⍵<0: move backward) ⌽⍵ turn left ⍵ degrees (⍵<0: turn right) ⊖⍵ roll anti-clockwise ⍵ degress (⍵<0: roll clockwise) ⍋⍵ pitch upwards ⍵ degrees (⍵<0: pitch downwards) [ stack turtle's current position and attitude, and continue ] pop turtle's position and attitude to start a new path Default [defs] vector: 'F=↑1 +=⌽¯90 -=⌽90 ×=⊖¯90 ÷=⊖90 ∧=⍋90 ∨=⍋¯90' defines: F=↑1 F → forward move of 1 unit +=⌽¯90 + → right turn of 90° -=⌽90 - → left turn of 90° ×=⊖¯90 × → clockwise roll of 90° ÷=⊖90 ÷ → anti-clockwise roll of 90° ∧=⍋¯90 ∧ → upwards pitch of 90° ∨=⍋90 ∨ → downwards pitch of 90° Commands without a corresponding macro definition are ignored except that: '⎕' signals line segments to be drawn one at a time to trace progress. '⌹' causes 3D images to be rendered in red/cyan Anaglyph mode (see below). '⌸' returns the [lines] result (without displaying its image) for further processing, such as hidden line removal or polygon colouring. 2D example ---------- turtle'⎕ FF+F-F' ⍝ [trace progress] fwd fwd right fwd left fwd produces a window containing an image like this: ┌─────────┐ forward 1; forward 1; right turn │ │ │ forward 1; left turn │ ┌──┘ │ forward 1 │ │ │ │ │ ← turtle starts here heading north; Esc to quit. └─────────┘ 3D example ---------- turtle'F+F-F∧F∨F' ⍝ fwd right fwd left fwd up fwd down fwd produces a 3D zigzag. 3D images can be rotated and zoomed for better viewing: ↑ ↓ cursor-keys rotate the image around the x-axis. ← → .. .. .. .. .. y-azis. z x keys .. .. .. z-axis. b f keys zoom the image backwards and forwards ¯ ¯ 3D images are given a hint of perspective by scaling the points' x and y values, and by greying lines with respect to their z positions. Anaglyph 3D Images ------------------ If the [cmds] vector for a 3D image contains a '⌹' character, slightly offset cyan and red images are presented, suitable for viewing through red and cyan 3D- spectacles. These can be constructed using cardboard and coloured toffee-wrapp- ing paper, thus: ┌─────────────────────────────────┐ ┌─────────────────────┘ ┌──────────┐ ┌─┐ ┌──────────┐ └─────────────────────┐ │ ┌───────────────────┐ │//////////│ ┌┘ └┐ │\\\\\\\\\\│ ┌───────────────────┐ │ │ │ │ │///red////│ │ │ │\\\cyan\\\│ │ │ │ │ │ │ │////L/////│ │ │ │\\\\R\\\\\│ │ │ │ │ │ │ │//////////│ │ │ │\\\\\\\\\\│ │ │ │ └─┘ │ └──────────┘ │ │ └──────────┘ │ └─┘ └──────────────┘ └──────────────┘ Your toffee paper may vary. Having chosen filters, adjust the image colours by changing the RGB values in inner function [colours], so that the left and right images disappear when viewed through each of the right and left filters in turn. clrs←(0 255 255)(255 0 0) ⍝ left and right colours Ref: https://en.wikipedia.org/wiki/3D_film#Anaglyph NB: to avoid eyestrain, please don't stare through these filters for too long. See below for an example. Branching Fractals ------------------ Stacking-commands [ and ] allow the production of branching fractals; see the "fractal plant" examples below. On encountering a [ command, the turtle's curr- ent position and attitude are stacked, and processing continued. When the corr- esponding ] is reached, the stacked state of the turtle is restored and a new branch started from that point. Ref: https://en.wikipedia.org/wiki/Turtle_graphics Ref: https://en.wikipedia.org/wiki/L-system Technical notes: The turtle's state is defined by the triple: (position heading banking): position: (i j k) coordinates in 3-space heading: (i j k) unit vector: direction of movement banking: (i j k) unit vector normal to heading The turtle's position is changed by inner function [move] and its attitude by functions [turn] [roll] and [pitch]. Inner function [cmds] takes the right argument vector of single-character macro calls and expands each into a primitive turtle command and numeric argument, using the left argument vector of macro definitions [defs]. [draw] processes the vector of turtle commands, left to right, and accumulates a list of paths, where each path is a list of (x y) coordinate pairs. Each ']' in the command stream starts a new path, which means that non-branching fractals produce only a single-item paths list. [rotn] returns an ⍺-rotation of points array ⍵. ⍺ is a 4-vector: the join of the rotation angle in radians with the unit 3-vector of the axis of rotation. If the rotation is around one of the i, j or k axes, the calculation is achieved with the slightly quicker complex arithmetic function [rot2]. Otherwise, if the rotation is around an axis other than i, j or k, the more general [rot3], which uses quaternion arithmetic, is used. See →H←. [points] returns a vector of polygon Points matrices from a list of path lists. For 2D images, the Points are adjusted to fill 95% of the display window, leav- ing a 2.5% border. 3D images are reduced so that they may be rotated without their edges straying outside the window. Inner function [centred] centres the Points values within the window. For 3D images, the centre of rotation is chosen as the position with a minimum least-squares distance from all points, using over-specified matrix division (⌹): ⍵-⍤1¨⊂pts⌹(≢pts)⍴1 ⍝ 3D: mid point centred [image] takes a vector of polygon Points matrices and displays them in a square window in the upper right corner of the screen. [trace] renders images one line at a time if right argument [cmds] contains '⎕'. [put] places coloured lines in the Poly object. With tracing, the Points and FCol property vectors are extended incrementally. This presents a problem in that the vectors must always be of the same length, which means that neither can be extended before the other without incurring a LENGTH ERROR. To avoid this: the FCol property is first set to an empty scalar value; then the Points vector extended; and finally, FCol set to the new vector. This sequence may be achieved with a single left-to-right vector assignment: put←{pp.(FCol Points FCol)←(⊂⊂⍬),⍵} ⍝ rendering of polygon points Examples: ⍝ NB: After each example, hit Escape to close the graphics window. ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 2D turtle examples: turtle'⎕',('X' 'XFY+')('Y' 'FY')lsys⍣21⊢'X' ⍝ square spiral ("squiral"?) hilbert ←, ⊂'A' '-BF+AFA+FB-' ⍝ Hilbert curve productions →lsys← hilbert ,← ⊂'B' '+AF-BFB-FA+' ⍝ (turtle ignores A and B) turtle hilbert lsys⍣4 ⊢'A' ⍝ order-4 Hilbert curve turtle '⎕',hilbert lsys⍣4 ⊢'A' ⍝ traced Hilbert curve peano ←, ⊂'A' 'AFBFA-F-BFAFB+F+AFBFA' ⍝ Peano curve productions peano ,← ⊂'B' 'BFAFB+F+AFBFA-F-BFAFB' ⍝ (turtle ignores A and B) turtle peano lsys⍣3 ⊢'A' ⍝ order-3 Peano curve dragon ←, ⊂'A' 'A+BF+' ⍝ Dragon curve productions dragon ,← ⊂'B' '-FA-B' ⍝ (turtle ignores A and B) turtle dragon lsys⍣10 ⊢'FA' ⍝ order-10 Dragon curve A60 ← 'A=↑1 B=↑1 +=⌽¯60 -=⌽60' ⍝ A and B are fwd 1; 60° turns koch ← 'A' 'A-A++A-A' ⍝ Koch curve production A60 turtle koch lsys⍣3 ⊢'A++A++A' ⍝ order-3 Koch curve (snowflake) 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 turtle gosper lsys⍣3 ⊢'A' ⍝ order-3 Gosper curve sierpinski ←, ⊂'A' '+B-A-B+' ⍝ Sierpinski triangle productions sierpinski ,← ⊂'B' '-A+B+A-' ⍝ (A and B are fwd 1) A60 turtle sierpinski lsys⍣6 ⊢'A' ⍝ order-6 Sierpinski curve A30 ← 'A=↑1 B=↑1 +=⌽¯30 -=⌽30' ⍝ A and B are fwd 1; 30° turns sprig ←, ⊂'A' 'B[+A][-A]BA' ⍝ Symmetrical fractal plant sprig ,← ⊂'B' 'BB' ⍝ (A and B are fwd 1) A30 turtle sprig lsys⍣4 ⊢'A' ⍝ order-4 sprig fern ←, ⊂'X' 'B-[[X]+X]+B[+BX]-X' ⍝ Asymmetrical fractal plant fern ,← ⊂'B' 'BB' ⍝ (X is ignored) A30 turtle fern lsys⍣4 ⊢'X' ⍝ order-4 fern A30 turtle '⎕',fern lsys⍣4 ⊢'X' ⍝ tracing growth bush ← 'A' 'AA-[-A+A+A]+[+A-A-A]' ⍝ Asymmetrical windswept bush A30 turtle bush lsys⍣3 ⊢'A' ⍝ order-3 bush star←{ ⍝ ⍵-pointed star ⍺←⌊(⍵-1)÷2 ⍝ winding number M←'F=↑1 T=⌽360÷',⍕⍵÷⍺ ⍝ macros P←'X' 'FTX' ⍝ production M turtle P lsys⍣⍵⊢'X' ⍝ star drawing } star 5 ⍝ 5-pointed star 2 3 star¨ 7 ⍝ two 7-pointed stars stars←{(⍳⌊⍵÷2)star¨⍵} ⍝ all ⍵-stars stars 17 ⍝ all 17-pointed stars ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 3D turtle examples: ⍝ Cursor keys ↑ ↓ ← → and keys z x rotate the image. ⍝ Escape (Esc) closes the graphics window. hilb3 ← 'A' '∨×AF∨×AFA-F∨÷÷AFA∧F+÷÷AFA-F÷A-÷' ⍝ order-2 3D Hilbert curve turtle hilb3 lsys⍣2 ⊢'A' ⍝ The following function generates one of the 5 platonic solids: 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 ⍵∊'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} } platonic¨ 'TCODI' ⍝ wire frame views '⌹'platonic¨ 'TCODI' ⍝ anaglyph 3D ⍝ Testing [turtle] with an upper case 'V' left argument displays the images. ⍝ The tests include a modification of the [turtle] function, which produces ⍝ solid-looking images, with hidden edges removed: 'V'test'turtle' ⍝ verbose test shows images. See also: lsys H Back to: contents Back to: Workspaces