String models

Again consider the table of strings over \lbrace0, 1\rbrace:

    000
    001
    010
    011
    100
    101
    110
    111

This table is laid out in two dimensions: The text of each string extends horizontally and the list of strings descends vertically. The ‘keyboard’ rendering of strings by the previous page’s program follows the same two-dimensional layout. Each string’s text extends along the x-axis, and the list of strings extends along the z-axis. We read a string by fixing a value in z, and then reading the colors (corresponding to symbols) by increasing x.

Of course, 3D graphics provides more options than the printed page. There are three dimensions, and also such attributes as color, shape, position, size, orientation, and transparency. To define other models for sets of string, we’ll color-code symbols as before, but combine other graphical attributes in various ways. The following program renders strings using several different models.

Some string models

Consider program design. A model is defined by two elements:

  1. A scene graph to represent the symbols of the alphabet. For example, under the keyboard model this is a sequence of colored blocks and, under the disk model, a set of colored disks encircling the circumference of a larger circle.
  2. An operator to transform the scene graph representing the set of strings of length one less. The operator takes account of the preceding symbol a, just as the vertical position of strings in a list depends on the string’s first symbol. For example, under the keyboard model, the operator shrinks a string set, and translates it along the z-axis to the position of the preceding symbol and along the x-axis past that symbol. And under the disk model, the operator rotates a scaled-down string set to the position of the preceding symbol a, and translates to the circumference of a‘s disk.

How is a model applied to produce a scene graph? If string length n = 1, return the scene graph r which represents the set of length 1 strings. If n > 1, combine r with the scene graphs obtained as follows: Apply the model to n-1 to obtain a scene graph rp and then, for each symbol a, apply operator op to rp and a. The function gets called with string length n, a scene graph r for the alphabet, the operator op for combining scene graphs, and the size of the alphabet base:

function applyModel(n, r, op, base) {
  root = new THREE.Object3D(); // empty scene graph
  root.add(r.clone());
  if (n > 1) {
    rp = applyModel(n-1, r, op, base);
    for (i = 0; i < base; i++) {
      // apply op to rp and the i'th symbol
      root.add(op(rp.clone(), i, base));
    }
  }
  return root;
}