librarydemos/rosetta/Stone.xtl

Stone: the Rosetta stone's geometry and faces (docs/rosetta.md), a library beside the demo ("st:" u_se< "Stone"). The stone is three carousels sharing one place: the whole stone rolling about the x axis through the idioms (roll it up or down for the previous or next idiom), and its two halves, closed boxes, each turning about the y axis through the languages, one for the top half of the facing idiom, one for the bottom. Each is a square prism, so the geometry never changes: the facing side shows the current item and the sides at right angles show its neighbors, found by index; the lid of the top half and the floor of the bottom name the idioms before and after. The halves turn independently, which is the impossible part: no solid turns like this, and none needs to. Points are Geometry3D's (3 rows), pictures Svg's.

source · imports g: lib/Geometry3D.xtl; v: lib/Svg.xtl

ˡwidth : Float

value · line 20

The stone's size: width, height (the halves are each half of it) and depth, in scene units; the viewer's distance; the picture's size in pixels and its scale.

ˡwidth ← 2.4
Used in: ˡr̲ing

ˡheight : Float

value · line 21
ˡheight ← 2.0
Used in: ˡr̲ing

ˡdepth : Float

value · line 22
ˡdepth ← 2.0
Used in: ˡr̲ing

ˡeye : Float

value · line 23
ˡeye ← 7.0
Used in: ˡs̲creen

ˡsize : Float

value · line 24
ˡsize ← 420.0

zoom : Float

value (private) · line 25
zoom ← 112.0
Used in: ˡs̲creen

ˡb̲ox : Float -> Float

function · line 30

The corners of a box centered on the origin: w h d in a 3-vector, 3 x 8 (near face then far face, each from the top left anticlockwise, as g:c_ube orders them).

ˡb̲ox ← { whd → (3 8 r̲eshape 8 r̲eplicate 0.5 × whd) × ᵍc̲ube 2 }
Used in: ˡr̲ing

ˡv̲iew : Float -> Float

function · line 34

The view: the stone turned a little about x and y so three sides show; every solid below is given in the view's frame.

ˡv̲iew ← { points → ((ᵍr̲otX 22.0) ᵍt̲urn ᵍr̲otY -28.0) ᵍt̲urn points }
Used in: ˡr̲ing

ˡs̲creen : Float -> Float

function · line 38

Points in the view's frame projected and placed in the picture, y up: a 3 x n matrix of points to a 2 x n matrix of pixels.

ˡs̲creen ← { points →
  p ← ˡeye ᵍp̲roject points
  xs ← (ˡsize ÷ 2) + zoom × 1 s̲elect p
  ys ← (ˡsize ÷ 2) − zoom × 2 s̲elect p
  (2 c̲at t̲ally xs) r̲eshape xs c̲at ys
}
Used in: ˡp̲anel

ˡb̲ase : Float -> Int

function · line 52

How the prisms turn: an axis advanced by a degrees (90 per item) is drawn turned by only the part of a quarter turn under way, a m̲od 90, and its sides show the items counted from the one the turn started at, f̲loor a ÷ 90 steps from the first. So a turn ends with the same picture it would have begun from, the sides relabel only at that instant, and the halves always stand upright where they can turn.

ˡb̲ase ← { a → f̲loor a ÷ 90.0 }

ˡp̲art : Float -> Float

function · line 53
ˡp̲art ← { a → a − 90.0 × f̲loat ˡb̲ase a }
Used in: ˡr̲ing

ˡr̲ing : Float -> Float -> Float

function · line 75

The six sides of a language half advanced by a degrees: the closed box of one half (1 the top half, -1 the bottom), its front, right, back and left sides, then its lid and its floor, as a 6 x 3 x 4 array, rolled with the whole stone by d degrees about x. The next language comes round from the right, so the half turns by -a about y. ˢᵗringOffsets says which language each side shows, counted from st:b_ase: 0, 1, 2, -1. The lid and the floor are ordered so that text reads upright as they roll round to the front: the next idiom comes up from below, so the stone rolls by -d about x; ˢᵗcapOffsets says which idiom each shows, counted from st:b_ase: -1 on the lid, 1 on the floor (so the top half's lid and the bottom half's floor name the stone's neighbors; the two caps between the halves are hidden until a half turns). A half is a closed box so that nothing shows through it while it turns. half (a d) ˢᵗr̲ing @.

      ˢᵗ⁼u̲se< "Stone"
      s̲hape 1 ˢᵗr̲ing 0.0 0.0
6 3 4
      s̲hape -1 ˢᵗr̲ing 45.0 30.0
6 3 4
ˡr̲ing ← { half ad →
  box ← ˡb̲ox ˡwidth c̲at (ˡheight ÷ 2) c̲at ˡdepth
  lifted ← box + 3 8 r̲eshape 8 r̲eplicate 0.0 c̲at (half × ˡheight ÷ 4) c̲at 0.0
  sides ← 6 4 r̲eshape 1 2 3 4 2 6 7 3 6 5 8 7 5 1 4 8 5 6 2 1 4 3 7 8
  turned ← (ᵍr̲otY n̲eg ˡp̲art 1 s̲elect ad) ᵍt̲urn lifted
  sides ᵍs̲olid ˡv̲iew (ᵍr̲otX n̲eg ˡp̲art 2 s̲elect ad) ᵍt̲urn turned
}
Used in: ᵘs̲tone

ˡringOffsets : Int

value · line 82
ˡringOffsets ← 0 1 2 -1
Used in: ᵘs̲tone

ˡcapOffsets : Int

value · line 83
ˡcapOffsets ← -1 1
Used in: ᵘs̲tone

ˡp̲anel : Box Char -> Float -> Char

function · line 93

A face as a panel in the picture: its corners (top left, top right, bottom right, bottom left; 3 x 4) turned by the view, filled, with the given lines drawn on it in face coordinates (0 to 1 across and down), each line a boxed text of markup (runs from v:s_pan, or text through v:e_scape), the first line small (a title), the rest in the code size. A face turned away from the viewer gets its fill only: nearer faces cover it, but text laid on a face seen nearly edge-on could poke out past it. (fill c̲at lines) ˢᵗp̲anel face.

ˡp̲anel ← { style f →
  s ← ˡs̲creen f
  fill ← d̲isclose 1 s̲elect style
  lines ← 1 d̲rop style
  shape ← ((ᵛf̲ill fill) c̲at "#30363d" ᵛs̲troke 1.2) ᵛp̲olygon f̲loor 0.5 + s
  n̲ot ˡf̲acing s ? shape
  on ← ˡa̲ffine 1 2 4 s̲elect₂ s
  texts ← ʰj̲oin '{ k → k ˡl̲ine d̲isclose k s̲elect lines } m̲ap r̲ange t̲ally lines
  shape c̲at on ᵛg̲roup texts
}
Used in: ᵘs̲tone

ˡr̲ounded : Float -> Float

function · line 110

Picture coordinates to a thousandth of a pixel: the last digits of a projected coordinate differ between machines (their sine and cosine differ in the last place), and the pictures are pinned as text.

      ˢᵗ⁼u̲se< "Stone"
      ˢᵗr̲ounded 1.23456789 100.0004
1.235 100.0
ˡr̲ounded ← { xs → (f̲loat f̲loor 0.5 + 1000.0 × xs) ÷ 1000.0 }
Used in: ˡa̲ffine

ˡa̲ffine : Float -> Char

function · line 119

The transform attribute mapping the unit square onto a face from its top left, top right and bottom left corners (2 x 3, picture coordinates), as v:m_atrix does, the six numbers rounded after the differences are taken (rounding before them leaves float noise).

      ˢᵗ⁼u̲se< "Stone"
      ˢᵗa̲ffine 2 3 r̲eshape 10.0 30.0 10.0 20.0 20.0 40.0
 transform="matrix(20.0 0.0 0.0 20.0 10.0 20.0)"
ˡa̲ffine ← { c →
  tl ← 1 s̲elect₂ c
  tr ← (2 s̲elect₂ c) − tl
  bl ← (3 s̲elect₂ c) − tl
  "transform" ᵛa̲ttr "matrix(" c̲at (f̲ormat ˡr̲ounded tr) c̲at " " c̲at (f̲ormat ˡr̲ounded bl) c̲at " " c̲at (f̲ormat ˡr̲ounded tl) c̲at ")"
}
Used in: ˡp̲anel

ˡf̲acing : Truthy a => Float -> a

function · line 135

Whether a face's corners (2 x 4 in the picture, y down) go round clockwise on the screen, which is how a face toward the viewer reads (its signed area is positive); a face turned away goes round the other way.

      ˢᵗ⁼u̲se< "Stone"
      ˢᵗf̲acing 2 4 r̲eshape 0 1 1 0 0 0 1 1
1
      ˢᵗf̲acing 2 4 r̲eshape 0 0 1 1 0 1 1 0
0
ˡf̲acing ← { s →
  xs ← 1 s̲elect s
  ys ← 2 s̲elect s
  0 < '+ r̲/ (xs × 1 o̲- ys) − ys × 1 o̲- xs
}
Used in: ˡp̲anel

ˡl̲ine : Int -> Char -> Char

function · line 145

One line of markup on a face: line k from the top; the first line is the title, small and gray, the others code, bold and black in a monospace face a tenth of the face high (the faces are small on a phone, so the code is the boldest thing on them).

ˡl̲ine ← { k t →
  size ← "k = 1" i̲f< "\"0.06\"; \"0.1\""
  y ← "k = 1" i̲f< "0.13; 0.14 + 0.16 * f_loat k"
  color ← "k = 1" i̲f< "\"#4b5563\"; \"#000000\""
  weight ← "k = 1" i̲f< "\"500\"; \"700\""
  ((ᵛa̲t 0.06 c̲at y) c̲at ("font-size" ᵛa̲ttr size) c̲at ("font-weight" ᵛa̲ttr weight) c̲at (ᵛf̲ill color) c̲at "font-family" ᵛa̲ttr "ui-monospace, monospace") ᵛm̲arkup t
}
i̲f< expands to
({ @ → (k = 1) ? "0.06"◆ "0.1" } @)
i̲f< expands to
({ @ → (k = 1) ? 0.13◆ 0.14 + 0.16 × f̲loat k } @)
i̲f< expands to
({ @ → (k = 1) ? "#4b5563"◆ "#000000" } @)
i̲f< expands to
({ @ → (k = 1) ? "500"◆ "700" } @)
Used in: ˡp̲anel

ˡp̲ainting : Num a => a -> Int

function · line 155

The faces of a solid (F x 3 x 4, in the view's frame) in the order to paint them: far to near, so nearer faces cover farther ones.

ˡp̲ainting ← { solid → ᵍo̲rder solid }
Used in: ᵘs̲tone

ʰj̲oin : Box Char -> Char

function (private) · line 158
ʰj̲oin ← { b →
  0 = t̲ally b ? ""
  d̲isclose '{ x y → e̲nclose (d̲isclose x) c̲at d̲isclose y } r̲/ b
}
Used in: ˡp̲anel