Art
Oct 26, 2024
Random Subway Map
A piece based on the topic of patterns.

Demo

Here's a link to my sketch: https://editor.p5js.org/interfinity/sketches/P4X9zRvWJ

Overview

Speaking of patterns, one of the first ideas that came to my mind is the NYC subway lines, as I ofter view on Google maps when navigating around. So I decided to base my piece on the subway line patterns.

Process

To draw random subway lines in a similar way to those subway line diagrams, I need to set up how each line can move. Before that, I decided to create a dot matrix pattern on my canvas. This can be done by using two for loops, one inside the other. Here's the code I wrote:

points = [];
step = 20;

background(245);

for (i = step; i < height; i += step) {
  for (j = step; j < width; j += step) {
    points.push([j, i]);
  }
}

strokeCap(ROUND);
strokeJoin(ROUND);
noFill();
stroke(210);
strokeWeight(myPointWidth);

for (i = 0; i < points.length; i++) {
  point(points[i][0], points[i][1]);
}

Then, I could draw the subway lines based on the dot matrix pattern: for vertical lines, it must start at the first row, the go either strait down 1 unit or go diagonally to the bottom right or bottom left. Each move is randomly selected so every time the line is drawn, it will probably be different from the line prior. I added some restrictions to the random selection to avoid the lines to look too zig-zag, which is unrealistic. Here's the code for my drawVerticalLine() function, which takes in a variable color for the color of the line:

function drawVerticalLine(color) {
  strokeWeight(myStrokeWeight);
  stroke(color);
  let myIndex = Math.floor(random(widthCount));
  let myX = points[myIndex][0];
  let myY = points[myIndex][1];
  let myLine = [];

  myLine.push([myX, myY]);

  beginShape();
  let randomWay = 1;
  let lastWay = 1;
  let lastTwoWays = 1;
  let lastThreeWays = 1;

  while (true) {
    lastThreeWays = lastTwoWays;
    lastTwoWays = lastWay;
    lastWay = randomWay;
    if (lastWay == 0) {
      if ((myIndex + 1) % widthCount == 0) {
        randomWay = 1;
      } else {
        if (lastWay != lastTwoWays || lastWay != lastThreeWays) {
          randomWay = lastWay;
        } else {
          randomWay = Math.floor(random(2));
        }
      }
    } else if (lastWay == 2) {
      if ((myIndex + 1) % widthCount == 1) {
        randomWay = 1;
      } else {
        if (lastWay != lastTwoWays || lastWay != lastThreeWays) {
          randomWay = lastWay;
        } else {
          randomWay = Math.floor(random(2)) + 1;
        }
      }
    } else {
      if ((myIndex + 1) % widthCount == 0) {
        randomWay = Math.floor(random(2)) + 1;
      } else if ((myIndex + 1) % widthCount == 1) {
        randomWay = Math.floor(random(2));
      } else {
        if (lastWay != lastTwoWays || lastWay != lastThreeWays) {
          randomWay = lastWay;
        } else {
          randomWay = Math.floor(random(3));
        }
      }
    }

    if (randomWay == 0) {
      myIndex += widthCount + 1;
    } else if (randomWay == 1) {
      myIndex += widthCount;
    } else if (randomWay == 2) {
      myIndex += widthCount - 1;
    }

    if (myIndex < points.length) {
      myX = points[myIndex][0];
      myY = points[myIndex][1];
    } else {
      break;
    }
    myLine.push([myX, myY]);
  }

  for (i = 0; i < myLine.length; i++) {
    vertex(myLine[i][0], myLine[i][1]);
  }

  endShape();
}

Drawing the horizontal lines only require a few tweaks to the drawVerticalLine() function, such as instead of moving straight down, the line could move strait from left to right, and instead of moving diagonally to the bottom left, the line could move diagonally to the top right.

Then I need to give each line a different color. Interestingly, I found this MTA website which listed the colors they use for the NYC subway lines: http://web.mta.info/developers/resources/line_colors.htm, so I created two arrays with these colors: one for the vertical lines and one for the horizontal lines (by the way, the colors for the horizontal lines are exactly the 3 lines that goes in the east-west direction across Manhattan):

let verticalLineColors = [
  "#0039A6", //Blue
  "#FF6319", //Orange
  "#6CBE45", //Light Green
  "#996633", //Brown
  "#FCCC0A", //Yellow
  "#EE352E", //Red
  "#00933C", //Dark Green
];

let horizontalLineColors = [
  "#A7A9AC", //Light Gray
  "#B933AD", //Purple
  "#808183", //Dark Gray
];

Finally, I used the mousePressed() function so that when the user clicks the canvas, a new random subway map will be generated.

function mousePressed() {
  drawLines();
}

Conclusion

Instead of precisely drawing a subway map of NYC or other cities, I wanted this piece to be more abstract: there are no indicator of stations, or any emphasis on the intersection of two or more lines. This abstraction and the randomness of my piece make it more of an art expression than a useful tool like an ordinary subway map. We use the subway map every day and it is always the same (when is the last time MTA built a new subway line?) so why not experience something random, something that changes on every click?