Where ideas percolate and thoughts brew

Geometric Tessellation

About This Sketch

A grid of diamonds rotates in synchronized waves, creating mesmerizing geometric patterns. The position-based rotation offset makes the pattern flow across the canvas like a visual wave.

Tessellation is fundamental to art and mathematicsโ€”from Islamic geometric patterns to Escher's impossible tilings. This sketch combines classic tessellation with modern animation to create an ever-evolving kaleidoscope.

Algorithm

A tessellating pattern of rotating diamonds that creates a hypnotic kaleidoscope effect. Each cell rotates at a slightly different rate based on its position in the grid. **Key Concepts:** - **Tessellation**: Repeating pattern that tiles a plane without gaps - **Transformation Matrix**: Translate to cell center, then rotate - **Position-Based Variation**: Rotation offset depends on grid coordinates - **Nested Shapes**: Concentric diamonds create depth - **Spatial Color Mapping**: Color determined by position in grid **How it works:** 1. Divide canvas into regular grid of cells 2. For each cell, translate to its center point 3. Calculate rotation based on base angle + position offset 4. This creates wave-like rotation propagation across grid 5. Draw outer diamond shape 6. Draw inner diamond for visual richness 7. Choose color based on cell's position in grid 8. Increment base rotation each frame

Pseudocode

SETUP:
  rotation = 0
  gridSize = 40

DRAW (every frame):
  CLEAR background

  FOR x = 0 to canvas_width STEP gridSize:
    FOR y = 0 to canvas_height STEP gridSize:
      SAVE transformation

      MOVE to (x + gridSize/2, y + gridSize/2)

      cell_rotation = rotation + (x + y) ร— 0.01
      ROTATE by cell_rotation

      position_sum = x + y
      color = gradient based on position_sum

      DRAW outer diamond shape
      DRAW inner diamond shape

      RESTORE transformation

  rotation = rotation + 0.01

Source Code

let sketch = function(p) {
    let rotation = 0;

    p.setup = function() {
        p.createCanvas(400, 300);
        p.colorMode(p.RGB);
    };

    p.draw = function() {
        const colors = getThemeColors();
        p.background(...colors.bg);

        let gridSize = 40;

        for (let x = 0; x < p.width; x += gridSize) {
            for (let y = 0; y < p.height; y += gridSize) {
                p.push();
                p.translate(x + gridSize/2, y + gridSize/2);

                // Different rotation based on position
                let cellRotation = rotation + (x + y) * 0.01;
                p.rotate(cellRotation);

                // Color based on position
                let t = p.map(x + y, 0, p.width + p.height, 0, 1);
                let col = t < 0.33 ? colors.accent1 :
                         t < 0.66 ? colors.accent2 : colors.accent3;

                p.noFill();
                p.stroke(...col);
                p.strokeWeight(2);

                // Draw diamond
                p.beginShape();
                p.vertex(0, -gridSize/2.5);
                p.vertex(gridSize/2.5, 0);
                p.vertex(0, gridSize/2.5);
                p.vertex(-gridSize/2.5, 0);
                p.endShape(p.CLOSE);

                // Inner diamond
                p.beginShape();
                p.vertex(0, -gridSize/5);
                p.vertex(gridSize/5, 0);
                p.vertex(0, gridSize/5);
                p.vertex(-gridSize/5, 0);
                p.endShape(p.CLOSE);

                p.pop();
            }
        }

        rotation += 0.003;
    };
};