Assignment 8: SNEKAD

For this assignment, I decided to replicate a simple loop-based algorithm from Computer Graphics & Art, the SNEKAD:

Obviously, the original consists of discrete cells with blocks of horizontal or vertical lines. I made that an integral part of my design with a double for-loop – one for each row, and one for each cell in a row.

The probability that a block has horizontal lines increases as the column of the cell increases – the more we go to the left, the more horizontal lines we get. I made that a part of the design, as well:

The number of blocks in a row (26) and in a column (36) corresponds to the original graphic. In order to fit this many blocks onto my screen, I had to make the blocks relatively small – 24 pixels to the side. (This also explains the weird dimensions of the window – 624 = 24*26 and 864 = 24*36.)

Unfortunately, that meant that I was not able to approximate the wood texture that seems to be a feature of the original graphic (although it is also possible that it was just an artifact of scanning). It is impossible to assign non-integer line thicknesses via strokeWeight in Processing – and the jump from 1 to 2 is too noticeable to produce a nice pattern.

I had a small issue when trying to match the probability distribution of the original image – while the first column never had any horizontal blocks, the last column always had a few vertical ones. This imbalance was due to the fact that the probability of a block being horizontal depends on the leftmost x value of the block. Thus, while the leftmost column always had a probability of 0 for horizontal blocks, the rightmost column always had a probability other than 100. Changing the multiplier to 110 instead of 100 fixes the issue.

I like the fake 3D feeling of the blocks, caused by the blocks’ trailing white space. I considered removing it by tweaking the block size or the spacing, but I realized that its presence makes the experience more interesting; in the end, I decided to keep it.

The code is presented below. Each block is generated with the elem function. The window regenerates on mouse press. Additionally, the program is adjustable, with all important variables presented as constants. This allows the user to tweak the look of the output as they want; I particularly like a version with large spaces between lines:

It has a very different feel from the original graphic – it looks like some sort of a taxonomic hierarchy, a flowchart with a lot of branches. It is amazing how a small change in two variables completely overhauls our perception.

Overall, a cute little easy project!

int STAGE_WIDTH = 624;
int STAGE_HEIGHT = 864;

int ELEM_WIDTH = 24;
int ELEM_HEIGHT = 24;

int HORIZONTAL_SPACING = 4;
int VERTICAL_SPACING = 4;

void settings() {
  size(STAGE_WIDTH, STAGE_HEIGHT);
}

void setup() {
  generate();
}

void draw() {
  if (mousePressed) {
    generate();
  }
}

void generate() {
  background(255);
 
  for (int hCounter = 0; hCounter < STAGE_HEIGHT/ELEM_HEIGHT; hCounter += 1) {
    for (int wCounter = 0; wCounter < STAGE_WIDTH/ELEM_WIDTH; wCounter += 1) {
      int randomInt = int(random(100));
      if (randomInt < (105*wCounter)/(STAGE_WIDTH/ELEM_WIDTH)) {
        elem(wCounter*ELEM_WIDTH, hCounter*ELEM_HEIGHT, ELEM_WIDTH, ELEM_HEIGHT, HORIZONTAL_SPACING, true);
      }
      else {
        elem(wCounter*ELEM_WIDTH, hCounter*ELEM_HEIGHT, ELEM_WIDTH, ELEM_HEIGHT, VERTICAL_SPACING, false);
      }
    }
  }
}

void elem(int xStart, int yStart, int w, int h, int spacing, boolean isHorizontal) { 
  stroke(0);
  
  if (isHorizontal) {
    int counter = 0;
    while (spacing*counter < h) {
      line(xStart, yStart+spacing*counter, xStart+w, yStart+spacing*counter);
      counter += 1;
    }
  }
  else {
    int counter = 0;
    while (spacing*counter < w) {
      line(xStart+spacing*counter, yStart, xStart+spacing*counter, yStart+h);
      counter += 1;
    }
  }
}