Buernortey – Assignment 11

Concept

I grew up in a fishing community in Ghana. Every morning, fishermen would cast their nets into the water. The net would fan out in a wide circle, hang in the air for a moment, then hit the surface and sink. That image stayed with me.

This sketch simulates that moment using cellular automata. Clicking the canvas casts a net from that point. The net expands outward as a glowing ring. Cells are born at the edge of the ring, age as it passes through them, and fade back into dark water. Multiple nets can be cast at once. Their rings spread, overlap, and dissolve.

The water is dark. The threads glow warm white, then cool to teal, then disappear. It is meant to feel like watching from the shore at dawn.

Code Highlight

This is the castNet() function. It is the part I am most proud of.

function castNet(mx, my) {
  let ci     = floor(mx / CELL_SIZE);
  let cj     = floor(my / CELL_SIZE);
  let radius = 2;

  for (let di = -radius - 1; di <= radius + 1; di++) {
    for (let dj = -radius - 1; dj <= radius + 1; dj++) {
      let dist = sqrt(di * di + dj * dj);
      if (dist >= radius - 0.5 && dist <= radius + 0.5) {
        let ni = (ci + di + cols) % cols;
        let nj = (cj + dj + rows) % rows;
        grid[ni][nj] = 1;
      }
    }
  }
}

When a user clicks, a small ring of cells is planted. The ring shape is important. A single dot would expand as a filled blob. A ring seed gives the CA the right structure to start expanding as a hollow circle. The dist check selects only cells that fall on the boundary of that radius. This is what makes it look like a cast net rather than a spreading stain.

The rules in stepGrid() do the rest:

if (cur === 0) {
  if (youngNeighbors === 2 || youngNeighbors === 3) next = 1;

} else if (cur === 1) {
  if (youngNeighbors === 1 || youngNeighbors === 2) next = 1;
  else next = 2;

} else {
  next = cur + 1;
  if (next >= NUM_STATES) next = 0;
}

Cells on the outer edge of the ring always have enough young neighbors to birth new cells one step further out. Cells on the inside do not. This is what causes the ring to expand rather than fill.

Embedded Sketch

Controls:

  • CLICK to cast a net
  • SPACE to play or pause
  • C to clear the water
  • UP / DOWN to change thread length
  • [ and ] to change speed

Milestones and Challenges

Starting with the ring seed. The first version planted a single cell on click. It expanded as a diamond-shaped blob. It looked nothing like a net. Switching to a ring seed of radius 2 changed the behavior immediately. The CA had enough structure to expand in a circle.

 

Getting the birth rule right. Using exactly 3 young neighbors caused the ring to break apart into fragments. Changing to 2 or 3 young neighbors kept the ring solid as it expanded. That one number made the difference between scattered dots and a clean circle.

The color palette. The colors needed to feel like water. I started with bright saturated colors and they felt wrong. I moved to warm white for fresh threads, cooling through teal, then fading back to dark water. The result feels like something glowing underwater.

Multiple overlapping nets. Casting two nets close together causes their rings to collide. Where they overlap, the birth rules create unexpected new patterns. This was not planned. It came from the rules themselves.

Challenges. The biggest issue was performance on a large canvas. Switching from a regular JavaScript array to Uint8Array improved frame rates noticeably. The toroidal wrapping also caused edge bugs early on. The modulo trick (x + di + cols) % cols handles cells at the canvas boundary cleanly.

Reflection

The moment the ring seed worked was when the project finally felt like something. Before that it was just another cellular automata sketch. Once the net started expanding from a click, it became connected to something real.

The overlap behavior surprised me. Two rings colliding was not designed. It came from the rules. The CA did something I did not ask it to do, and it looked right. That is what makes cellular automata interesting.

The sketch is quiet. Dark water, glowing threads, and a click. That is enough.

Ideas for Future Work

Add sound. The moment of casting could trigger a soft water sound. The expanding ring could carry a faint ambient tone that fades with the threads.

Add wind. A directional force could skew the ring as it expands so the net drifts the way a real net does in current.

Add retraction. After the ring reaches a certain size, it could collapse back toward the origin. This would complete the full cast and pull motion.

Add drag. Holding and dragging before releasing could control the direction and force of the cast.

References and Inspiration

Conway’s Game of Life — birth and survival logic.

Nature of Code, Chapter 7 — grid structure and neighbor counting.

Zach Lieberman — finding personal meaning in computational work.

Growing up in a fishing community in Ghana — the real inspiration.

3 thoughts on “Buernortey – Assignment 11”

  1. I love that you were inspired by your local community in Ghana! very beautiful and the colors are well coordinated.

  2. It is nice to see that so many of us translate our culture in our sketches! well done! It is very satisfying to see how the different shapes melt into each other, it feels very therapeutic and interesting to see.

    I do agree with your comment on how adding sound would make it more immersive, something like a water ambiance would further make the interaction more enjoyable.

  3. This is such a beautiful project Buernortey. The story behind it makes the whole sketch feel so much more meaningful and human centered. Using cellular automata to simulate the nets expanding instead of just drawing them was a brilliant idea and figuring out that ring seed logic must have been so satisfying. I really appreciate how minimal and quiet the visual aesthetic is with just the dark water and glowing threads. It is really inspiring how you turned a personal memory into such an elegant piece of code. Amazing work on this.

Leave a Reply to yr2263 Cancel reply

Your email address will not be published. Required fields are marked *