Day 24 - Art 1

Geometric art and only use one geometric shape

Dynamic Triangular Grid Wave

This generative art piece creates a dynamic grid of layered, rotating triangles. The artwork features multiple background and foreground layers, with each layer consisting of progressively smaller triangles that rotate smoothly over time. The shapes are arranged in a grid pattern, with their rotation and size influenced by their position, creating an ever-changing visual effect. The interplay of layers and rotation speeds adds depth and movement to the composition, offering a mesmerizing, evolving display.

    // Define constants
    let gridSize = 8; // Number of shapes per row and column (reduced for smaller canvas)
    let shapeSize = 40; // Size of each shape (reduced for smaller canvas)
    let rotationSpeed = 0.5; // Speed of rotation, determines how fast the shapes rotate
    let layerCount = 5; // Number of layers of triangles in each shape
    let backgroundLayerCount = 5; // Number of background layers of triangles
    let smoothRotation = 0; // Variable to store smooth rotation, which is incremented over time for a continuous rotation effect
    let canvas;
    
    function setup() {
      // Create the canvas and set it to the parent HTML element with id 'canvas-container'
      canvas = createCanvas(400, 400);
      canvas.parent('canvas-container');
      
      // Set the angle mode to DEGREES for easier angle manipulation
      angleMode(DEGREES);
      
      // Disable stroke for shapes to make them clean and solid
      noStroke();
    }
    
    function draw() {
      // Set the background color to dark gray
      background(30);
      
      // Move the origin of the canvas to the center
      translate(width / 2, height / 2);
    
      // Calculate half the grid size for centering shapes
      let halfGrid = gridSize / 2;
    
      // Update smooth rotation using a consistent increment
      smoothRotation += rotationSpeed;
    
      // Draw background layers of triangles
      for (let bg = backgroundLayerCount; bg >= 1; bg--) {
        // Calculate the scale factor for each background layer (larger layers further in the background)
        let scaleFactor = 1 + bg * 0.2;
        
        // Map the background layer index to a gradient color from white to dark gray
        let layerShade = map(bg, 1, backgroundLayerCount, 255, 50);
        
        // Loop through grid positions to place background triangles
        for (let x = -halfGrid * scaleFactor; x < halfGrid * scaleFactor; x++) {
          for (let y = -halfGrid * scaleFactor; y < halfGrid * scaleFactor; y++) {
            push(); // Save the current drawing state
            
            // Calculate position based on grid and scale factor
            let posX = x * shapeSize * 0.9 / scaleFactor;
            let posY = y * shapeSize * 0.9 / scaleFactor;
            
            // Translate to the new position
            translate(posX, posY);
            
            // Rotate the triangles based on smooth rotation and grid position for dynamic movement
            rotate(smoothRotation + (x + y) * 10);
            
            // Draw the layered triangles for the current background layer
            drawLayeredTriangles(0, 0, (shapeSize / 2) * scaleFactor, bg, layerShade);
            
            pop(); // Restore the previous drawing state
          }
        }
      }
    
      // Draw foreground grid of triangles
      for (let x = -halfGrid; x < halfGrid; x++) {
        for (let y = -halfGrid; y < halfGrid; y++) {
          push(); // Save the current drawing state
          
          // Calculate position for each foreground triangle
          let posX = x * shapeSize * 0.9;
          let posY = y * shapeSize * 0.9;
          
          // Translate to the new position
          translate(posX, posY);
          
          // Rotate the triangles based on smooth rotation and grid position for dynamic movement
          rotate(smoothRotation + (x + y) * 10);
          
          // Set the layer shade for the foreground triangles (white color)
          let layerShade = 255;
          
          // Draw the layered triangles for the foreground grid
          drawLayeredTriangles(0, 0, shapeSize / 2, 0, layerShade);
          
          pop(); // Restore the previous drawing state
        }
      }
    }
    
    // Function to draw layered triangles with a specified size, offset, and color shade
    function drawLayeredTriangles(x, y, size, layerOffset, shade) {
      for (let i = 0; i < layerCount; i++) {
        // Calculate the size of each triangle layer, progressively smaller
        let layerSize = size * (1 - i * 0.15);
        
        // Calculate the phase (angle) for each layer's rotation, creating a smooth animation effect
        let phase = (smoothRotation + (i + layerOffset) * 30) % 360;
        
        // Calculate a value based on the sine of the phase to create dynamic changes in the shape
        let t = abs(sin(radians(phase)));
    
        // Set the fill color for the triangle layers
        fill(shade);
    
        // Begin drawing the triangle
        beginShape();
        
        // Define the three vertices of the triangle, adjusting based on the layer size and dynamic 't' value
        vertex(x, y - layerSize * (1 + t)); // Top vertex
        vertex(x - layerSize * (1 - t), y + layerSize * t); // Bottom-left vertex
        vertex(x + layerSize * (1 - t), y + layerSize * t); // Bottom-right vertex
        
        // Complete the triangle shape
        endShape(CLOSE);
      }
    }