Day 12 - Art 1

Subdivision

Recursive Spiral Growth

This generative art piece creates a dynamic, expanding spiral pattern based on a logarithmic equation. The spiral grows over time, with each point connected by lines that recursively subdivide, adding complexity to the design. The recursion process creates intricate subdivisions between points, with lines drawn from the center to midpoints, and larger sections formed by connecting every other point. The result is a mesmerizing, evolving pattern that combines mathematical beauty with recursive geometry.

    // Constants for the spiral
    let a = 1;  // Constant for the spiral (controls the initial size)
    let b = 0.2;  // Growth factor for the spiral (controls the rate of expansion)
    let numPoints = 100;  // Number of points to generate along the spiral
    let goldenRatio = 1.618;  // Golden ratio for potential future growth adjustments
    let maxRadius;  // Maximum radius of the spiral (based on canvas size)
    let angle = 0;  // Initial angle for the spiral's growth
    let subdivisions = 3;  // Number of recursive subdivisions to add complexity
    let canvas;  // Canvas variable to store the created canvas
    
    // Setup function: Runs once when the sketch starts
    function setup() {
      // Create a 400x400 canvas and attach it to the HTML element with the id 'canvas-container'
      canvas = createCanvas(400, 400);
      canvas.parent('canvas-container');
    
      // Set the maximum radius based on half the width of the canvas
      maxRadius = width / 2;
    
      // Set the frame rate to control the speed of the animation
      frameRate(30);  
    }
    
    // Draw function: Runs continuously to render the animation
    function draw() {
      // Set the background color to black
      background(0);
    
      // Calculate the center of the canvas
      let centerX = width / 2;
      let centerY = height / 2;
    
      // Array to store the points along the spiral
      let points = [];
    
      // Loop through the number of points to generate the spiral
      for (let i = 0; i < numPoints; i++) {
        // Calculate the angle for each point along the spiral (spread out the angles)
        let theta = angle + i * (PI / 20);  // Use a fixed increment of PI/20 to spread the points
    
        // Calculate the radius using the logarithmic spiral equation
        let radius = a * exp(b * theta);  // Exponential growth of the spiral
    
        // Ensure the radius doesn't exceed the maximum radius of the canvas
        radius = constrain(radius, 0, maxRadius);
    
        // Calculate the x and y coordinates for the current point on the spiral
        let x = centerX + radius * cos(theta);
        let y = centerY + radius * sin(theta);
    
        // Store the point's coordinates in the points array
        points.push({ x, y });
      }
    
      // Call the function to recursively draw subdivisions based on the generated points
      drawSubdivisions(centerX, centerY, points, subdivisions);
    
      // Update the angle to animate the spiral's growth
      angle += 0.02;
    }
    
    // Recursive function to draw subdivisions and add complexity to the spiral
    function drawSubdivisions(centerX, centerY, points, depth) {
      // Base case: Stop recursion if depth is zero (no more subdivisions)
      if (depth <= 0) return;
    
      // Loop through each pair of adjacent points
      for (let i = 0; i < points.length - 1; i++) {
        let p1 = points[i];
        let p2 = points[i + 1];
    
        // Draw a line between the two points to create subdivisions
        stroke(255, 100);  // Set stroke color with some transparency
        line(p1.x, p1.y, p2.x, p2.y);
    
        // Calculate the midpoint between the two points
        let midX = (p1.x + p2.x) / 2;
        let midY = (p1.y + p2.y) / 2;
    
        // Draw a line from the center to the midpoint to emphasize the subdivisions
        stroke(255, 150);  // Change stroke color for center-to-midpoint lines
        line(centerX, centerY, midX, midY);
    
        // Recursively create more subdivisions for the current segment by adding the midpoint
        drawSubdivisions(centerX, centerY, [p1, { x: midX, y: midY }, p2], depth - 1);
      }
    
      // Optionally, create larger subdivisions by connecting every other point
      for (let i = 0; i < points.length - 2; i++) {
        let p1 = points[i];
        let p2 = points[i + 2];  // Skip one point to create larger sections
    
        // Draw lines between points to further subdivide the spiral
        stroke(255, 50);  // Set stroke color with lower transparency for these lines
        line(p1.x, p1.y, p2.x, p2.y);
      }
    }