sourcedemos/rosetta/cube.xtl

1⍝!/usr/bin/env xetal 2⍝ A cube turning in space, drawn by the Geometry3D and Svg libraries: 3⍝ twelve frames as a wireframe, then twelve shaded, each shown with 4⍝ []S_HOW (the browser's pane shows them in turn; the command line 5⍝ writes cube-1.svg, cube-2.svg, ... under --draw). Every number here 6⍝ is computed by arrays: the eight corners are one matrix, a turn is 7⍝ one inner product, the faces are ordered far to near by their mean 8⍝ depth, and a face's shade is the angle between its normal and the 9⍝ light. The Rosetta stone's rehearsal (docs/rosetta.md). 10ᵍ⁼u̲se< "Geometry3D" 11ᵛ⁼u̲se< "Svg" 12 13size ← 300.0 ⍝ the picture is size by size 14eye ← 6.0 ⍝ the viewer's distance along z 15zoom ← 70.0 ⍝ pixels per unit 16light ← 0.3 0.5 0.8 ⍝ from the viewer's side, upper right 17 18cube ← ᵍc̲ube 2 19faces ← ᵍc̲ubeFaces @ 20 21⍝ The screen points of a face: projected, zoomed, centered, y up. 22ᵘs̲creen ← { f → 23 p ← eye ᵍp̲roject f 24 xs ← (size ÷ 2) + zoom × 1 s̲elect p 25 ys ← (size ÷ 2) − zoom × 2 s̲elect p 26 (2 c̲at t̲ally xs) r̲eshape xs c̲at ys 27} 28 29⍝ The normal of a face: the cross product of two of its edges. 30ᵘn̲ormal ← { f → 31 u ← (2 s̲elect₂ f) − 1 s̲elect₂ f 32 w ← (4 s̲elect₂ f) − 1 s̲elect₂ f 33 ((1 o̲- u) × 2 o̲- w) − (2 o̲- u) × 1 o̲- w 34} 35 36⍝ How lit a face is, 0 to 1: the cosine of the angle between its 37⍝ outward normal and the light, and 0 when it faces away. The normal 38⍝ is turned outward by the side of the cube's center it is on. 39ᵘl̲it ← { f → 40 n ← ᵘn̲ormal f 41 center ← ('+ r̲/ o̲\ f) ÷ 4.0 42 outward ← n × (2.0 × f̲loat 0 < '+ r̲/ n × center) − 1.0 43 0 m̲ax ('+ r̲/ outward × light) ÷ ('+ r̲/ n × n) ^ 0.5 44} 45 46⍝ A face as a polygon, shaded (or, with fill "none", as a wireframe). 47ᵘp̲olygon ← { shaded f → 48 fill ← ᵛf̲ill "shaded" i̲f< "v:r_gb 3 r_eshape 40 + 200 * u:l_it f; \"none\""
i̲f< expands to
({ @ → (shaded) ? ᵛr̲gb 3 r̲eshape 40 + 200 × ᵘl̲it f◆ "none" } @)
49 (fill c̲at "#222" ᵛs̲troke 1.5) ᵛp̲olygon f̲loor 0.5 + ᵘs̲creen f 50} 51 52⍝ The cube turned by a degrees about x and 1.3 a about y, as a picture: 53⍝ its faces drawn far to near, so nearer faces cover farther ones. 54ᵘs̲cene ← { shaded a → 55 turned ← ((ᵍr̲otY 1.3 × a) ᵍt̲urn ᵍr̲otX a) ᵍt̲urn cube 56 solid ← faces ᵍs̲olid turned 57 polygons ← '{ i → shaded ᵘp̲olygon i s̲elect solid } m̲ap ᵍo̲rder solid 58 (size c̲at size) ᵛp̲icture d̲isclose '{ x y → e̲nclose (d̲isclose x) c̲at d̲isclose y } r̲/ polygons 59} 60 61ᵘf̲rame ← { shaded a → ⎕S̲HOW shaded ᵘs̲cene a◆ ⎕D̲L 0.04◆ @ } 62 63angles ← 30.0 × f̲loat o̲ffsets 12 64shown ← '{ a → 0 ᵘf̲rame a } e̲ach angles 65shown ← '{ a → 1 ᵘf̲rame a } e̲ach angles 66"24 frames shown"