Attractors

Concept and Inspiration:

Clifford attractors are fascinating mathematical objects that produce intricate patterns when iteratively calculated. I was inspired by the work of Paul Bourke who uses similar concepts to create mesmerizing visuals.

Code Breakdown:

class Attractor {
  constructor() {
    // Generate random parameters for the attractor equation
    this.a = random(-2, 2);
    this.b = random(-2, 2);
    this.c = random(0.5, 2);
    this.d = random(0.5, 2);
    this.pos = createVector(0, 0); // Initial position

    // Assign two random colors for interpolation
    this.color1 = color(random(255), random(255), random(255));
    this.color2 = color(random(255), random(255), random(255));
  }

  update() {
    // Calculate the next position based on the attractor equation
    let xNext = sin(this.a * this.pos.y) + this.c * cos(this.a * this.pos.x);
    let yNext = sin(this.b * this.pos.x) + this.d * cos(this.b * this.pos.y);
    this.pos.set(xNext, yNext);
  }

  show() {
    // Map the attractor's position to screen coordinates
    let xScreen = map(this.pos.x, -3, 3, 0, width);
    let yScreen = map(this.pos.y, -3, 3, 0, height);

    // Interpolate between the two colors based on position magnitude
    let lerpAmount = map(this.pos.mag(), 0, 5, 0, 1);
    let lerpedColor = lerpColor(this.color1, this.color2, lerpAmount);

    stroke(lerpedColor); // Set the stroke color
    point(xScreen, yScreen); // Draw a point at the calculated position
  }
}

let attractors = [];

function setup() {
  createCanvas(400, 400);
  background(220);

  // Create an array of attractors
  for (let i = 0; i < 5; i++) {
    attractors.push(new Attractor());
  }
}

function draw() {
  background(220, 10); // Fade the background slightly

  for (let attractor of attractors) {
    for (let i = 0; i < 100; i++) {
      attractor.update();
      attractor.show();
    }
  }
}

function mousePressed() {
  if (mouseButton === LEFT) {
    attractors = []; // Clear existing attractors
    for (let i = 0; i < 5; i++) {
      attractors.push(new Attractor());
    }
  }
}

Highlight:

I’m particularly proud of the show() function, which handles the color interpolation based on the attractor’s position. This creates a smooth transition between two randomly generated colors, adding depth and visual interest to the patterns.

Embedded Sketch: (click screen to render new art)

Reflection and Future Work:

This project was a fun exploration of generative art and p5.js.

Future improvements:

  • User Interaction: Allow users to interact with the sketch by changing parameters or adding new attractors.

  • Animation: Introduce animation to the attractors, making them move or change over time.

Problems Encountered:

  • Visual Fidelity: Finding a good balance of colors was challenging. As well, when rendering, the images come out very grainy. I must experiment further to see if that can be improved

  • Performance: With a large number of attractors, the sketch can become slow. I might explore optimization techniques to improve performance.

Overall, this project was a rewarding experience that allowed me to learn more about generative art and p5.js.

Works cited:

Clifford Attractors : r/p5js (reddit.com)

Clifford Attractors (paulbourke.net)

Leave a Reply

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