Gesture Sigils

Gesture Sigils

some examples of gesture sigils

1. Overview

A sigil or gesture sigil refers to a combination of symbols that come together to describe the state of a Gesture at a particular point in time. A sigil will convey the three main components of a Gesture: value, duration, and behavior.

This document aims to specify a core set of sigils to work with that can be used to unambiguously notate gesture. Notation is generated using Janet, the built-in scripting language for the wiki engine used here (weewiki). The drawing library used is btprnt, a drawing library for 1-bit graphics.

2. Tangled File

<<sigils.janet>>=
<<sigil-writer>>
<<components>>
<<sigil>>
<<sigils-demo>>

3. Loading and Initializing a Sigil Writer

A Sigil Writer is a construct that contains all the data needed to produce sigils. This includes tilemaps for both radicals and runes.

A Sigil Writer, once initialized, can then be passed to drawing funcitons to draw components of a sigil.

A Sigil Writer can be created with sigil-writer-create.

<<sigil-writer>>=
(defn sigil-writer-create []
  (def loadtiles-file (dofile "loadtiles/loadtiles.janet"))
  (def gen-tilemap ((loadtiles-file 'gen-tilemap) :value))
  (def runes-file (dofile "runes/runes.janet"))
  (def radicals-file (dofile "radicals/radicals.janet"))
  (var sw @{})
  (put sw :runes-tmap
       (gen-tilemap "runes/runes.txt" 7 7 8 8))
  (put sw :runes-names ((runes-file 'runes) :value))
  (put sw :radicals-tmap
       (gen-tilemap "radicals/radicals.txt" 4 4 6 6))
  (put sw :radicals-names ((radicals-file 'radicals) :value))
  sw)

(defn sigil-writer-clean [sw]
  (btprnt/del (sw :runes-tmap))
  (btprnt/del (sw :radicals-tmap)))

4. Drawing a Sigil

The funciton sigil will draw a sigil. bp is the instance of btprnt. glyph is the region containing the bounding box for a glyph. sw is an instance of the sigil writer.

The val, num, den, and behavior are all the components that make up a single sigil. num and den are the numerator/denominator fractional pair that make up rate multiplier. value refers to a name of a rune. Behavior forms the behavior.

<<sigil>>=
(defn sigil [bp glyph sw value num den behavior]
  (rune bp glyph sw value)
  (lglyphs bp glyph sw num den)
  (diacritic bp glyph sw behavior))

5. Components

5.1. Drawing L Glyphs For Duration and Rate Scaling

A Sigil has two special glyphs that sit on the bottom left and right corners of the Sigil, known as L-Glyphs. These convey the rate scaling value as a fractional value: left is numerator, right is denominator.

Rate scaling refers to manipulating the speed of the underlying phasor controlling the Gesture signal. The phasor is resynthesized from an input phasor signal (this algorithm is known as a rephasor), so the the phasor's speed is always relative to that of the input phasor. A rate scaling factor of 2 doubles the speed of phasor, making it twice as fast. A value of 0.5 (or 1/2) makes the phasor twice as slow.

Inverting the fraction, rate scaling turns into duration. A rate of 1/2 becomes a duration of 2 periods, or "beats". Using duration can sometimes be a more intuitive way to think about Gesture.

5.1.1. Generic Left L-Glyph

To draw a generic left L-glpyh, use left-glyph.

<<generic-lglyphs>>=
(defn left-glyph [bp reg sw a b c d]
  (def rad-a ((sw :radicals-names) a))
  (def rad-b ((sw :radicals-names) b))
  (def rad-c ((sw :radicals-names) c))
  (def rad-d ((sw :radicals-names) d))

  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    1 13
    (rad-a 0) (rad-a 1)
    4 4
    1 1)
  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    1 17
    (rad-b 0) (rad-b 1)
    4 4
    1 1)
  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    1 21
    (rad-c 0) (rad-c 1)
    4 4
    1 1)
  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    5 21
    (rad-d 0) (rad-d 1)
    4 4
    1 1))

5.1.2. Generic Right L Glyph

right-glyph works similarly to left-glyph, just in the opposite direction.

<<generic-lglyphs>>=
(defn right-glyph [bp reg sw a b c d]
  (def rad-a ((sw :radicals-names) a))
  (def rad-b ((sw :radicals-names) b))
  (def rad-c ((sw :radicals-names) c))
  (def rad-d ((sw :radicals-names) d))

  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    21 13
    (rad-a 0) (rad-a 1)
    4 4
    1 1)
  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    21 17
    (rad-b 0) (rad-b 1)
    4 4
    1 1)
  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    21 21
    (rad-c 0) (rad-c 1)
    4 4
    1 1)
  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    17 21
    (rad-d 0) (rad-d 1)
    4 4
    1 1))

5.1.3. Using a Number Set for L Glyphs

Groups of 4 radicals form to make a single L glyph. The table below curates a set of L glyphs to be used to represent numerical values. Each entry is an array of 4 radicals, or an array of 2 arrays which each consist of 4 radicals. The latter is required when left and right L glyphs need different radicals.

<<numbers>>=
(def numbers @{
  0 @[:empty :empty :empty :empty]
  1 @[@[:empty :tstub :blknee :rstub]
      @[:empty :tstub :brknee :lstub]]
  2 @[:empty :dot :dot :empty]
  3 @[:empty :dot :dot :dot]
  4 @[:empty :empty :box :empty]
  5 @[:empty :dot :box :empty]
  6 @[:empty :dot :box :dot]
  7 @[@[:empty :tstub :blknee :rtee]
      @[:empty :tstub :brknee :ltee]]
  8 @[@[:empty :ttee :blknee :rtee]
      @[:empty :ttee :brknee :ltee]]
  9 @[@[:empty :ttee :dot :rtee]
      @[:empty :ttee :dot :ltee]]
  10 @[@[:empty :dot :box :rtee]
       @[:empty :dot :box :ltee]]
  11 @[:empty :box :dot :dot]
  12 @[:empty :box :dot :box]
  13 @[@[:empty :box :dot :rstub]
       @[:empty :box :dot :lstub]]
  14 @[@[:empty :box :box :rstub]
       @[:empty :box :box :lstub]]
  15 @[@[:empty :tstub :box :rstub]
       @[:empty :tstub :box :lstub]]
  16 @[:tbrack :tstub :box :empty]
  })

5.1.4. Drawing L Glyphs

<<components>>=
<<generic-lglyphs>>
<<numbers>>

(defn get-glyph [num val pos]
  (def a (num val))
  (if (= (length a) 4) a (a pos)))

(defn lglyphs [bp reg sw num den]
  (def l (get-glyph numbers num 0))
  (def r (get-glyph numbers den 1))
  (left-glyph bp reg sw (l 0) (l 1) (l 2) (l 3))
  (right-glyph bp reg sw (r 0) (r 1) (r 2) (r 3))

  )

5.2. Drawing Diacritics For Behavior

Diacritics, or the markings that go above the main rune, denote the behavior of that particular sigil, which inidicates the interpolation method for which the current value goes to the next value.

5.2.1. Generic Diacritic

Like L-Glyphs, these are built of radicals. There can be either 5 or 6 radicals. When there are 5 radicals, there is a single middle radical.

<<generic-diacritic>>=
(defn draw-radical [bp reg sw rad pos &opt centerpad]
  (default centerpad 2)
  (def r ((sw :radicals-names) rad))
  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    (+ (* pos 4) centerpad 1) 1
    (r 0) (r 1)
    4 4
    1 1))

(defn draw-side-radical [bp reg sw rad pos]
  (def r ((sw :radicals-names) rad))
  (btprnt/tile
    bp (sw :radicals-tmap)
    reg
    (+ (* (pos 0) 20) 1)
    (+ (* (+ (pos 1) 1) 4) 1)
    (r 0) (r 1)
    4 4
    1 1))

(defn draw-diacritic [bp glyph sw rads &opt side-rads]
  (default side-rads nil)
  (def centerpad (if (= (length rads) 5) 2 0))
  (for i 0 (length rads)
    (draw-radical bp glyph sw (rads i) i centerpad))

  (if-not (nil? side-rads)
          (do
            (if-not (nil? (side-rads 0))
                    (draw-side-radical
                      bp glyph sw (side-rads 0) @[0 0]))
            (if-not (nil? (side-rads 1))
                    (draw-side-radical
                      bp glyph sw (side-rads 1) @[0 1]))
            (if-not (nil? (side-rads 2))
                    (draw-side-radical
                      bp glyph sw (side-rads 2) @[1 0]))
            (if-not (nil? (side-rads 3))
                    (draw-side-radical
                      bp glyph sw (side-rads 3) @[1 1])))))

5.2.2. Diacritic look-up table for Behaviors

<<behaviors>>=
(def behaviors @{
  :empty
    @[@[:empty :empty :empty :empty :empty] nil]
  :step
    @[@[:empty :empty :dot :empty :empty] nil]
  :linear
    @[@[:lstub :hstripe :hstripe :hstripe :hstripe :rstub]
      nil]
  :expon
    @[@[:lstub :hstripe :hstripe :hstripe :hstripe :rtee]
      nil]
  :gliss
    @[@[:empty :blknee :hstripe :brknee :empty]
      nil]
  :gliss-small
    @[@[:dot :blknee :hstripe :brknee :dot]
      @[:empty :empty :empty :empty]]
  :gliss-medium
    @[@[:lbrack :blknee :hstripe :brknee :rbrack]
      @[:empty :empty :empty :empty]]
  :gliss-large
    @[@[:box :blknee :hstripe :brknee :box]
      @[:empty :empty :empty :empty]]
})

5.2.3. Drawing Specific Diacritics

These will look up values from the behaviorstable.

<<components>>=
<<generic-diacritic>>
<<behaviors>>
(defn diacritic [bp reg sw name]
  (def dia (behaviors name))
  (draw-diacritic bp reg sw (dia 0) (dia 1)))

5.3. Drawing Runes for Values

Runes are symbols used to represent the value component of a gesture node inside a sigil.

The rune is placed at the center of the sigil and scaled 2x to be 14px in size. A 16px square is allocated for the rune, leaving a 1px border around it.

The surrounding border of the rune area is 4px thick, this plus the 1px offset makes a total offset of 5px. There is an additional 1px border around the entire sigil which adds an additional 1px.

<<components>>=
(defn rune [bp reg sw name]
  (def glyph ((sw :runes-names) name))
  (btprnt/tile
    bp (sw :runes-tmap)
    reg
    6 6
    (glyph 0) (glyph 1)
    7 7
    2 1))

6. Some sample sigils

A small demo showcasing the kinds of sigils that can be made with this interface.

<<sigils-demo>>=
(defn sigils-bp []
  (def sw (sigil-writer-create))
  (def bp (btprnt/new 256 256))
  (def canvas @[0 0 256 256])
  (def sig
    (array
      (array
        @[:yi 1 2 :gliss-small]
        @[:er 3 4 :gliss-medium]
        @[:san 5 6 :gliss-large]
        @[:si 7 8 :step]
        @[:wu 9 10 :linear]
        @[:liu 11 12 :expon]
        @[:qi 13 14 :empty]
        @[:ba 15 16 :gliss-small])
      (array
        @[:diamond 1 1 :linear]
        @[:asym 3 1 :step]
        @[:ttile 2 3 :step]
        @[:boxinbox 8 4 :gliss-small]
        @[:ryshar 1 1 :gliss-small]
        @[:haerabeek 2 2 :gliss-small]
        @[:che 1 1 :gliss-small]
        @[:kat 2 1 :expon])
      (array
        @[:lubigis 1 1 :step]
        @[:nahaisheed 4 1 :step]
        @[:med 4 1 :step]
        @[:nip 4 1 :gliss-small]
        @[:shaichorip 4 1 :gliss-medium]
        @[:hetachae 2 1 :gliss-small]
        @[:jofaep 2 1 :expon]
        @[:fyshee 2 1 :gliss-large])
      (array
        @[:jupyshaet 1 12 :gliss-large]
        @[:bechak 1 12 :gliss-medium]
        @[:baechived 1 13 :gliss-medium]
        @[:wypen 10 2 :gliss-large]
        @[:kaekaek 9 1 :gliss-medium]
        @[:suchai 7 4 :gliss-medium]
        @[:paipuchev 2 1 :gliss-small]
        @[:zaimep 1 3 :step])
      (array
        @[:shaishik 15 13 :step]
        @[:wozhish 14 1 :expon]
        @[:ser 3 3 :linear]
        @[:ciweet 5 5 :linear]
        @[:gaecaijag 4 5 :gliss-small]
        @[:neteevib 3 7 :step]
        @[:raetaeteb 8 2 :step]
        @[:ba 2 5 :step])
      (array
        @[:qi 6 4 :step]
        @[:liu 9 2 :gliss-small]
        @[:wu 9 1 :expon]
        @[:si 6 5 :expon]
        @[:san 9 4 :linear]
        @[:er 3 7 :linear]
        @[:yi 4 2 :linear]
        @[:med 4 8 :gliss-large])
      (array
        @[:jupyshaet 1 1 :linear]
        @[:nip 1 2 :step]
        @[:nahaisheed 1 3 :linear]
        @[:shaichorip 1 4 :step]
        @[:fyshee 4 1 :expon]
        @[:boxinbox 3 1 :expon]
        @[:jofaep 2 1 :gliss-small]
        @[:lubigis 1 1 :gliss-medium])
      (array
        @[:suchai 8 7 :linear]
        @[:bechak 7 6 :step]
        @[:asym 6 5 :linear]
        @[:wypen 5 4 :step]
        @[:hetachae 4 3 :expon]
        @[:ryshar 3 2 :expon]
        @[:paipuchev 1 2 :gliss-small]
        @[:zaimep 3 4 :gliss-medium])
      ))

  (def nrows 8)
  (def ncols 8)
  (for row 0 nrows
    (for col 0 ncols
      (def gridlet (btprnt/grid bp canvas 8 8 col row))
      (def center (btprnt/centerbox bp gridlet 26 26))
      (def s ((sig row) col))
      (btprnt/outline bp center 1)
      (sigil bp center sw (s 0) (s 1) (s 2) (s 3))))
  (sigil-writer-clean sw)
  bp)