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: