libraryextensions/scene/demos/Voxels.xtl
Voxels.xtl -- voxel chunks as arrays, shared by the voxels-* demos (docs/voxels.md). A chunk is a 16 by 16 by 16 array of block numbers, indexed x (east), y (up), z (south); 0 is air. Import: "vx:" u_se< "Voxels" (Not voxels.xtl: on a case-insensitive file system a demo of that name would be this file -- ask E8.)
Chunks
ˡnames : Char
the blocks' names, in their order
ᵛˣ⁼u̲se< "Voxels"
ᵛˣnames air stone dirt grass sand water wood leaves
ˡnames ← "air stone dirt grass sand water wood leaves"
ˡglyphs : Char
a character for each block when a chunk is printed, air first: stone #, dirt %, grass ", sand :, water ~, wood |, leaves *
ˡglyphs ← " #%\":~|*"
ˡxs : Int
every cell's x (east), as a vector in the chunk's order (x slowest)
ᵛˣ⁼u̲se< "Voxels"
18 t̲ake ᵛˣxs 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ˡxs ← i d̲iv 256
ˡzs : Int
every cell's z (south), in the chunk's order (z fastest)
ᵛˣ⁼u̲se< "Voxels"
18 t̲ake ᵛˣzs 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1
ˡzs ← i m̲od 16
ˡh̲ills : Float -> Int
vx:h_ills phase: a 16 by 16 height field (x by z), rolling hills of heights 3 to 12; the phase shifts them
ˡh̲ills ← { p → x ← f̲loat (r̲ange 16) − 1 a ← 2.5 × s̲in p + x ÷ 2.5 b ← 2.0 × c̲os p + x ÷ 3.0 f̲loor 7.5 + a '+ t̲able b }
ˡc̲hunk : (Num a, Truthy a) => Int -> a
vx:c_hunk h: the chunk on a height field h (x by z): grass on top, three of dirt, stone below; water fills air below 7, and sand replaces grass at or below it; one tree on the hill at (4, 4) when it stands above the water
ˡc̲hunk ← { h → top ← (1 + ˡzs + 16 × ˡxs) s̲elect r̲avel h d ← top − ˡys b ← (d = 1) × 3 b ← b + (d > 1) × (d < 5) × 2 b ← b + (d ≥ 5) × 1 b ← b + (b = 3) × (ˡys ≤ 7) × 1 b ← b + (b = 0) × (ˡys < 7) × 5 ⍝ the tree: a trunk of 3 at (4, 4), leaves around its top t ← (1 + 4 + 16 × 4) s̲elect r̲avel h up ← t > 7 ax ← a̲bs ˡxs − 4 az ← a̲bs ˡzs − 4 trunk ← up × (ax = 0) × (az = 0) × (ˡys ≥ t) × ˡys < t + 3 crown ← up × (ax ≤ 1) × (az ≤ 1) × (ˡys ≥ t + 2) × (ˡys ≤ t + 3) × 1 − trunk b ← b + trunk × 6 − b b ← b + crown × (b = 0) × 7 16 16 16 r̲eshape b }
ˡc̲ounts : (Num a, Truthy a) => Int -> a
vx:c_ounts b: how many of each block, air first
ˡc̲ounts ← { b → '+ r̲/₂ ((r̲ange 8) − 1) '= t̲able r̲avel b }
ˡs̲ide : Int -> Int -> Char
x vx:s_ide b: the slice at x, as characters, up at the top
ˡs̲ide ← { x b → r̲ev (1 + (x + 1) s̲elect b) s̲elect ˡglyphs }
ˡc̲olumn : a -> a
a column value (x by z) at every cell of its column
ˡc̲olumn ← { m → 16 16 16 r̲eshape (1 + ˡzs + 16 × ˡxs) s̲elect r̲avel m }
ˡt̲op : (Num a, Truthy a) => a -> a
vx:t_op b: what is seen from above: the highest non-air block of each column (x by z) -- the top's height by a max-reduction down each column, then the block there picked by comparing heights
ˡt̲op ← { b → y1 ← 16 16 16 r̲eshape ˡys + 1 hi ← 'm̲ax r̲/₂ y1 × b > 0 '+ r̲/₂ b × y1 = ˡc̲olumn hi }
Faces
X : Int
the cells' coordinates as 16 by 16 by 16 arrays
X ← 16 16 16 r̲eshape ˡxs
ˡs̲olid : (Num a, Num b, Truthy b) => a -> b
a solid block is any but air and water
ˡs̲olid ← { b → (b > 0) × b ≠ 5 }
ˡe̲xposed : (Num a, Truthy b) => a -> b
the exposed faces in the six directions -- west, east, down, up, north, south: numbered 0 to 5 -- as a 6 by 4096 Boolean array: a solid cell whose neighbor that way is not solid. The neighbor is a rotation along the axis (the six rotations of the Life idiom) with the plane that wrapped around made air: beyond the border is air.
ˡe̲xposed ← { b → s ← ˡs̲olid b w ← s > (-1 o̲-₁ s) × X > 0 e ← s > (1 o̲-₁ s) × X < 15 d ← s > (-1 o̲-₂ s) × Y > 0 u ← s > (1 o̲-₂ s) × Y < 15 n ← s > (-1 o̲-₃ s) × Z > 0 so ← s > (1 o̲-₃ s) × Z < 15 6 4096 r̲eshape (r̲avel w) c̲at (r̲avel e) c̲at (r̲avel d) c̲at (r̲avel u) c̲at (r̲avel n) c̲at r̲avel so }
ˡs̲urface : (Num a, Truthy b) => a -> b
water's surface: water with air above it, facing up
ˡs̲urface ← { b → (b = 5) > (1 o̲-₂ b > 0) × Y < 15 }
ʰr̲ows : Int -> Int -> Int
d r_ows mb: the faces of one direction as 5 rows -- x, y, z of the cell, the direction, the block -- from mb, the mask times 1 + the block (so one array carries both)
ʰr̲ows ← { d mb → k ← w̲here mb > 0 (5 c̲at t̲ally k) r̲eshape (k s̲elect ˡxs) c̲at (k s̲elect ˡys) c̲at (k s̲elect ˡzs) c̲at ((t̲ally k) r̲eshape d) c̲at (k s̲elect mb) − 1 }
ˡf̲aces : Int -> Int
vx:f_aces b: every face to draw, one row each -- x y z direction block -- the six directions' exposed faces, then water's surface
ˡf̲aces ← { b → m ← ˡe̲xposed b bb ← 1 + r̲avel b r ← (0 ʰr̲ows bb × 1 s̲elect m) c̲at₂ (1 ʰr̲ows bb × 2 s̲elect m) c̲at₂ (2 ʰr̲ows bb × 3 s̲elect m) r ← r c̲at₂ (3 ʰr̲ows bb × 4 s̲elect m) c̲at₂ (4 ʰr̲ows bb × 5 s̲elect m) c̲at₂ (5 ʰr̲ows bb × 6 s̲elect m) 2 1 t̲ranspose r c̲at₂ 3 ʰr̲ows bb × r̲avel ˡs̲urface b }
ˡc̲ount : (Num a, Truthy a) => Int -> a
vx:c_ount f: how many faces in each direction (west east down up north south); a single block shows one face each way:
ᵛˣ⁼u̲se< "Voxels"
one ← 16 16 16 r̲eshape (ᵛˣxs = 8) × (ᵛˣys = 8) × ᵛˣzs = 8
ᵛˣc̲ount ᵛˣf̲aces one 1 1 1 1 1 1
ˡc̲ount ← { f → '+ r̲/₂ (r̲ange 6) '= t̲able 1 + 4 s̲elect₂ f }
Drawing
ox : Int
the corners of each direction's face, from its cell's corner, taken in pairs round the square (1 2, 2 3, 3 4, 4 1): x, y, z, 6 by 8 each
ox ← 6 8 r̲eshape (8 r̲eshape 0) c̲at (8 r̲eshape 1) c̲at (0 1 1 1 1 0 0 0) c̲at (0 1 1 1 1 0 0 0) c̲at (0 1 1 1 1 0 0 0) c̲at 0 1 1 1 1 0 0 0
oy : Int
oy ← 6 8 r̲eshape (0 1 1 1 1 0 0 0) c̲at (0 1 1 1 1 0 0 0) c̲at (8 r̲eshape 0) c̲at (8 r̲eshape 1) c̲at (0 0 0 1 1 1 1 0) c̲at 0 0 0 1 1 1 1 0
oz : Int
oz ← 6 8 r̲eshape (0 0 0 1 1 1 1 0) c̲at (0 0 0 1 1 1 1 0) c̲at (0 0 0 1 1 1 1 0) c̲at (0 0 0 1 1 1 1 0) c̲at (8 r̲eshape 0) c̲at 8 r̲eshape 1
ˡe̲dges : Int -> Float
vx:e_dges f: the faces' outlines as segments for scene: 8 points a face (4 edges, 2 points each), n*8 by 3, the chunk centered on the origin and scaled to -1..1
ˡe̲dges ← { f → d ← 1 + 4 s̲elect₂ f z8 ← 8 r̲eshape 0 px ← (d s̲elect ox) + (1 s̲elect₂ f) '+ t̲able z8 py ← (d s̲elect oy) + (2 s̲elect₂ f) '+ t̲able z8 pz ← (d s̲elect oz) + (3 s̲elect₂ f) '+ t̲able z8 p ← 2 1 t̲ranspose (3 c̲at 8 × t̲ally f) r̲eshape (r̲avel px) c̲at (r̲avel py) c̲at r̲avel pz ((f̲loat p) − 8.0) ÷ 8.0 }
ˡcolors : Float
each block's color, red green blue (air first)
ˡcolors ← 8 3 r̲eshape 0 0 0 0.55 0.55 0.58 0.55 0.38 0.22 0.35 0.7 0.25 0.9 0.82 0.55 0.25 0.45 0.9 0.45 0.3 0.15 0.2 0.5 0.2
ˡc̲orners : Int -> Float
vx:c_orners f: each face's four corners in order round it, n*4 by 3, in blocks -- the quads scene draws for the faces
ˡc̲orners ← { f → d ← 1 + 4 s̲elect₂ f z4 ← 4 r̲eshape 0 px ← (d s̲elect cx) + (1 s̲elect₂ f) '+ t̲able z4 py ← (d s̲elect cy) + (2 s̲elect₂ f) '+ t̲able z4 pz ← (d s̲elect cz) + (3 s̲elect₂ f) '+ t̲able z4 f̲loat 2 1 t̲ranspose (3 c̲at 4 × t̲ally f) r̲eshape (r̲avel px) c̲at (r̲avel py) c̲at r̲avel pz }
ˡq̲uads : Int -> Float
vx:q_uads f: the faces as filled quads for scene, a chunk centered on the origin and scaled to -1..1, like vx:e_dges
ˡq̲uads ← { f → ((ˡc̲orners f) − 8.0) ÷ 8.0 }
Worlds: many chunks
ʰw̲eights : Int -> Int -> Float
value noise, made by linear algebra: random heights on a grid every s blocks, interpolated to n by n -- M G M', M the n by k hat-function weights of each grid line
ʰw̲eights ← { s n → k ← 1 + n d̲iv s t ← (f̲loat (r̲ange n) − 1) ÷ f̲loat s 0.0 m̲ax 1.0 − a̲bs t '− t̲able f̲loat (r̲ange k) − 1 }
ʰn̲oise : Int -> Int -> Float
ʰn̲oise ← { s n → m ← s ʰw̲eights n k ← 1 + n d̲iv s g ← (f̲loat r̲oll! (k × k) r̲eshape 1000) ÷ 1000.0 m '+ '× i̲nner ((k c̲at k) r̲eshape g) '+ '× i̲nner 2 1 t̲ranspose m }
ˡh̲eights : Int -> Int
vx:h_eights n: an n by n height field (x by z), three octaves of value noise -- every 16, 8 and 4 blocks -- from 4 to 29 (seeded)
ˡh̲eights ← { n → v ← (16.0 × 16 ʰn̲oise n) + (7.0 × 8 ʰn̲oise n) + 3.0 × 4 ʰn̲oise n 4 m̲ax 29 m̲in f̲loor 4.0 + v }
ʰc̲oords : Int -> Int
a world's cells' coordinates, for a shape nx ny nz (x slowest)
ʰc̲oords ← { sh → j ← (r̲ange '× r̲/ sh) − 1 yz ← (2 s̲elect sh) × 3 s̲elect sh (3 c̲at t̲ally j) r̲eshape (j d̲iv yz) c̲at ((j d̲iv 3 s̲elect sh) m̲od 2 s̲elect sh) c̲at j m̲od 3 s̲elect sh }
ˡt̲errain : (Num a, Truthy a) => Int -> a
vx:t_errain h: the world on a height field h (nx by nz), 32 tall: grass, dirt, stone, water filling air below 14, sand at the shore -- the chunk's rules, over the whole world
ˡt̲errain ← { h → nx ← 1 s̲elect s̲hape h nz ← 2 s̲elect s̲hape h c ← ʰc̲oords nx c̲at 32 c̲at nz xs ← 1 s̲elect c ys ← 2 s̲elect c zs ← 3 s̲elect c d ← ((1 + zs + nz × xs) s̲elect r̲avel h) − ys b ← (d = 1) × 3 b ← b + (d > 1) × (d < 5) × 2 b ← b + (d ≥ 5) × 1 b ← b + (b = 3) × (ys ≤ 14) × 1 b ← b + (b = 0) × (ys < 14) × 5 (nx c̲at 32 c̲at nz) r̲eshape b }
ˡt̲ree : (Num a, Truthy a) => Int -> a -> a
t vx:t_ree b: a tree at column t (x z) when it stands on grass: a trunk of 4 and a crown of leaves, placed into b -- only the tree's own cells are worked out (their indexes into b), then set by a membership mask, so a tree costs little in a big block
ˡt̲ree ← { t b → sh ← s̲hape b ny ← 2 s̲elect sh nz ← 3 s̲elect sh tx ← 1 s̲elect t tz ← 2 s̲elect t v ← r̲avel b col ← (1 + tz + nz × ((r̲ange ny) − 1) + ny × tx) s̲elect v 0 = '+ r̲/ col = 3 ? b y0 ← 1 + '+ r̲/ (col = 3) × (r̲ange ny) − 1 ty ← y0 + (r̲ange 4) − 1 ty ← (ty < ny) r̲eplicate ty trunk ← 1 + tz + nz × ty + ny × tx d5 ← (r̲ange 5) − 3 dx ← r̲avel d5 '{ ⍺ + 0 × ⍵ } t̲able d5 dz ← r̲avel d5 '{ ⍵ + 0 × ⍺ } t̲able d5 wide ← ((a̲bs dx) + a̲bs dz) < 4 small ← ((a̲bs dx) ≤ 1) × (a̲bs dz) ≤ 1 u̲p ← { y m → y ≥ ny ? 0 r̲eshape 0 1 + (tz + m r̲eplicate dz) + nz × y + ny × tx + m r̲eplicate dx } crown ← ((y0 + 3) u̲p wide) c̲at ((y0 + 4) u̲p wide) c̲at (y0 + 5) u̲p small n ← t̲ally v v ← v + ((r̲ange n) m̲ember? trunk) × 6 − v v ← v + ((r̲ange n) m̲ember? crown) × (v = 0) × 7 sh r̲eshape v }
ˡw̲orldFaces : Int -> Int
vx:w_orldFaces b: every face of a world, one row each -- x y z direction block -- as vx:f_aces does for a chunk, the borders of the world air
ˡw̲orldFaces ← { b → sh ← s̲hape b c ← ʰc̲oords sh s ← ˡs̲olid b xs ← sh r̲eshape 1 s̲elect c ys ← sh r̲eshape 2 s̲elect c zs ← sh r̲eshape 3 s̲elect c mx ← (1 s̲elect sh) − 1 my ← (2 s̲elect sh) − 1 mz ← (3 s̲elect sh) − 1 w ← s > (-1 o̲-₁ s) × xs > 0 e ← s > (1 o̲-₁ s) × xs < mx d ← s > (-1 o̲-₂ s) × ys > 0 u ← s > (1 o̲-₂ s) × ys < my n ← s > (-1 o̲-₃ s) × zs > 0 so ← s > (1 o̲-₃ s) × zs < mz top ← (b = 5) > (1 o̲-₂ b > 0) × ys < my bb ← 1 + r̲avel b r̲w ← { d m → k ← w̲here m > 0 (5 c̲at t̲ally k) r̲eshape (k s̲elect 1 s̲elect c) c̲at (k s̲elect 2 s̲elect c) c̲at (k s̲elect 3 s̲elect c) c̲at ((t̲ally k) r̲eshape d) c̲at (k s̲elect m) − 1 } r ← (0 r̲w bb × r̲avel w) c̲at₂ (1 r̲w bb × r̲avel e) c̲at₂ (2 r̲w bb × r̲avel d) c̲at₂ (3 r̲w bb × r̲avel u) r ← r c̲at₂ (4 r̲w bb × r̲avel n) c̲at₂ (5 r̲w bb × r̲avel so) c̲at₂ 3 r̲w bb × r̲avel top 2 1 t̲ranspose r }
ˡc̲hunkOf : Int -> Int
vx:c_hunkOf f: the chunk of each face (1 up): x, z and y in 16s
ˡc̲hunkOf ← { f → 1 + ((1 s̲elect₂ f) d̲iv 16) + (4 × (3 s̲elect₂ f) d̲iv 16) + 16 × (2 s̲elect₂ f) d̲iv 16 }
ˡf̲orest : Int -> Int -> Int
ts vx:f_orest b: trees at the columns ts (n by 2: x z), each where it stands on grass -- vx:t_ree folded over them
ˡf̲orest ← { ts b → boxes ← ('{ ⍵ s̲elect ts } m̲ap r̲ange t̲ally ts) c̲at e̲nclose b d̲isclose '{ e̲nclose (d̲isclose ⍺) ˡt̲ree d̲isclose ⍵ } r̲/ boxes }
Endless worlds
ˡh̲ash : (Num a, Num b) => a -> b -> Float
a grid point's random value, 0 to 1, from its coordinates alone (i by j, any integers): the same point always gets the same value, so any part of an endless world can be made by itself and fits its neighbors
ᵛˣ⁼u̲se< "Voxels"
(3 ᵛˣh̲ash 4) = 3 ᵛˣh̲ash 4 1
ˡh̲ash ← { i j → v ← 43758.5453 × s̲in (12.9898 × f̲loat i) '+ t̲able 78.233 × f̲loat j v − f̲loat f̲loor v }
ʰw̲eight : Num a => Float -> a -> Float
ʰw̲eight ← { t k → d ← 0.0 m̲ax 1.0 − a̲bs t '− t̲able f̲loat k d × d × 3.0 − 2.0 × d }
ʰn̲oiseOf : Num a => a -> Int -> Float
ʰn̲oiseOf ← { s c → x0 ← 1 s̲elect c z0 ← 2 s̲elect c n ← 3 s̲elect c tx ← (f̲loat x0 + (r̲ange n) − 1) ÷ f̲loat s tz ← (f̲loat z0 + (r̲ange n) − 1) ÷ f̲loat s gx ← (f̲loor 'm̲in r̲/ tx) + (r̲ange 2 + (f̲loor 'm̲ax r̲/ tx) − f̲loor 'm̲in r̲/ tx) − 1 gz ← (f̲loor 'm̲in r̲/ tz) + (r̲ange 2 + (f̲loor 'm̲ax r̲/ tz) − f̲loor 'm̲in r̲/ tz) − 1 (tx ʰw̲eight gx) '+ '× i̲nner (gx ˡh̲ash gz) '+ '× i̲nner 2 1 t̲ranspose tz ʰw̲eight gz }
ˡh̲eightsAt : Int -> Int
vx:h_eightsAt x0 z0 n: the heights of the n by n columns from block (x0, z0), x by z, of the endless world: three octaves of value noise (every 32, 16 and 8 blocks), 3 to 29, the sea at 14 -- any square anywhere, always the same
ˡh̲eightsAt ← { c → v ← (18.0 × 32 ʰn̲oiseOf c) + (8.0 × 16 ʰn̲oiseOf c) + 3.0 × 8 ʰn̲oiseOf c 3 m̲ax 29 m̲in f̲loor 2.0 + v }
inner : Int
inner ← 1 + (1 + cell m̲od 16) + 18 × ((cell d̲iv 16) m̲od 32) + 32 × 1 + cell d̲iv 512
ˡp̲atch : Int -> Box Int
vx:p_atch c: column c (cx cz) of the endless world, 16 by 32 by 16 blocks: made with a border of one block from its neighbors' heights, so its faces at the border hide where a neighbor is solid; trees (two places hashed from the column, kept inside it). A box of its faces (world coordinates, one row each: x y z direction block) and a box of its solid mask (16 by 32 by 16, flat, x slowest)
ˡp̲atch ← { c → x0 ← (16 × 1 s̲elect c) − 1 z0 ← (16 × 2 s̲elect c) − 1 h ← ˡh̲eightsAt x0 c̲at z0 c̲at 18 b ← ˡt̲errain h r ← (1 s̲elect c) ˡh̲ash 2 s̲elect c q ← (2 s̲elect c) ˡh̲ash 1 s̲elect c t ← 4 + f̲loor 10.0 × (r̲avel r) c̲at (r̲avel q) c̲at (r̲avel r × q) c̲at r̲avel 1.0 − r × q b ← (2 2 r̲eshape t) ˡf̲orest b f ← ˡw̲orldFaces b keep ← ((1 s̲elect₂ f) ≥ 1) × ((1 s̲elect₂ f) ≤ 16) × ((3 s̲elect₂ f) ≥ 1) × (3 s̲elect₂ f) ≤ 16 f ← keep r̲eplicate f f ← f + ((t̲ally f) c̲at 5) r̲eshape x0 c̲at 0 c̲at z0 c̲at 0 0 (e̲nclose f) c̲at e̲nclose inner s̲elect r̲avel ˡs̲olid b }
Columns, quickly
ˡc̲olumnBlocks : Int -> Int
vx:c_olumnBlocks c: the blocks of column c (cx cz) of the endless world with a border of one from its neighbors, 18 by 32 by 18: the heights, the terrain's rules, two trees placed by hash -- the first of the three parts of making a column (about 12 ms)
ˡc̲olumnBlocks ← { c → x0 ← (16 × 1 s̲elect c) − 1 z0 ← (16 × 2 s̲elect c) − 1 h ← ˡh̲eightsAt x0 c̲at z0 c̲at 18 d ← ((1 + cz18 + 18 × cx18) s̲elect r̲avel h) − cy18 b ← (d = 1) × 3 b ← b + (d > 1) × (d < 5) × 2 b ← b + (d ≥ 5) × 1 b ← b + (b = 3) × (cy18 ≤ 14) × 1 b ← b + (b = 0) × (cy18 < 14) × 5 b ← 18 32 18 r̲eshape b r ← (1 s̲elect c) ˡh̲ash 2 s̲elect c q ← (2 s̲elect c) ˡh̲ash 1 s̲elect c t ← 4 + f̲loor 10.0 × (r̲avel r) c̲at (r̲avel q) c̲at (r̲avel r × q) c̲at r̲avel 1.0 − r × q (2 2 r̲eshape t) ˡf̲orest b }
ˡc̲olumnMask : (Num a, Num b, Truthy b) => a -> b
vx:c_olumnMask b: the solid mask of a column's own cells (16 by 32 by 16, flat, x slowest), from its blocks
ˡc̲olumnMask ← { b → inner s̲elect r̲avel ˡs̲olid b }
ˡc̲olumnFaces : Int -> Int -> Int
c vx:c_olumnFaces b: the faces of column c's own cells, in world coordinates, one row each (x y z direction block) -- found over the block with its border, so faces against a solid neighbor hide; the second part of making a column
ˡc̲olumnFaces ← { c b → s ← ˡs̲olid b w ← s > (-1 o̲-₁ s) × X18 > 0 e ← s > (1 o̲-₁ s) × X18 < 17 d ← s > (-1 o̲-₂ s) × Y18 > 0 u ← s > (1 o̲-₂ s) × Y18 < 31 n ← s > (-1 o̲-₃ s) × Z18 > 0 so ← s > (1 o̲-₃ s) × Z18 < 17 top ← (b = 5) > (1 o̲-₂ b > 0) × Y18 < 31 bb ← own × 1 + r̲avel b x0 ← (16 × 1 s̲elect c) − 1 z0 ← (16 × 2 s̲elect c) − 1 r̲w ← { d m → k ← w̲here m > 0 (5 c̲at t̲ally k) r̲eshape (x0 + k s̲elect cx18) c̲at (k s̲elect cy18) c̲at (z0 + k s̲elect cz18) c̲at ((t̲ally k) r̲eshape d) c̲at (k s̲elect m) − 1 } r ← (0 r̲w bb × r̲avel w) c̲at₂ (1 r̲w bb × r̲avel e) c̲at₂ (2 r̲w bb × r̲avel d) c̲at₂ (3 r̲w bb × r̲avel u) r ← r c̲at₂ (4 r̲w bb × r̲avel n) c̲at₂ (5 r̲w bb × r̲avel so) c̲at₂ 3 r̲w bb × r̲avel top 2 1 t̲ranspose r }