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)

Week 2 Sketch

Concept:

I recently took on the challenge of simulating the motion of a falling feather in nature using p5.js. The goal was to go beyond a simple straight-down fall and imbue the feather with a sense of personality through its movement, all while controlling it solely through acceleration. I envisioned a feather that gently drifts and rocks side to side as it descends, mimicking the playful dance of a real feather caught in a gentle breeze.

Code Highlight:

One of the aspects I’m particularly proud of is how I implemented the rocking motion coupled with a horizontal boost:

// Apply wind force (horizontal acceleration) with Perlin noise and angle influence
let windDirection = noise(noiseOffset) * 2 - 1; // -1 to 1
featherAx = windForce * windDirection + abs(sin(featherAngle)) * 0.5 * windDirection;

This snippet shows how the feather’s horizontal acceleration (featherAx) is influenced not just by random wind (using Perlin noise) but also by its current angle (featherAngle). The abs(sin(featherAngle)) term provides a boost in the direction of the rotation, making the feather sway more pronouncedly as it rocks. This simple addition significantly enhances the visual appeal and realism of the motion.

Embedded Sketch:

Reflection and Future Work:

I’m quite pleased with how this simulation turned out. The feather’s motion feels natural and captures the essence of its lightness and susceptibility to air currents. However, there’s always room for improvement! Here are some ideas for future exploration:

  • More Realistic Feather Shape: The current U-shape is a simplification. Implementing a more detailed feather shape, perhaps with multiple segments, could add visual interest.

  • Interaction with Wind: It would be interesting to allow the user to interact with the wind, perhaps by blowing on the feather through a microphone or using the mouse to create gusts.

  • 3D Simulation: Extending the simulation to 3D space could open up new possibilities for exploring the feather’s movement in a more immersive environment.

  • Multiple Feathers: Simulating multiple feathers interacting with each other and the wind could create a mesmerizing visual experience.

Week 1 Sketch

Concept

The concept behind this code revolves around generating a dynamic and visually engaging animation using Bézier curves. Bézier curves, often used in computer graphics to model smooth curves, provide an ideal foundation for creating a path that an animated object can follow. In this program, a “walker” moves along a Bézier curve defined by a set of fluctuating control points. The movement along the curve is complemented by changing colors, creating a lively and evolving visual pattern. This approach allows for the exploration of procedural animation techniques, where randomness and mathematical functions are used to produce aesthetically pleasing, unpredictable outcomes.

Reflections for the Future

Looking forward, there are several enhancements and extensions that could be made to this project. One possible improvement is to introduce user interactivity, allowing viewers to influence the motion, control points, or colors in real-time. Another idea is to experiment with more complex curve types, such as cubic or quadratic Bézier curves, to see how they impact the animation’s aesthetics. Furthermore, adding sound that reacts to the movement or colors could create a multisensory experience, deepening the engagement with the artwork.

Response 1

Flake’s introduction to “The Computational Beauty of Nature” really got me thinking about how we approach understanding the world around us. I’ve always been drawn to the reductionist approach, dissecting things down to their smallest parts to see how they work. But Flake’s argument for considering interactions and the emergent properties of complex systems is really compelling. The ant colony example is a perfect illustration – a single ant is pretty simple, but a whole colony exhibits incredibly sophisticated behaviors you wouldn’t predict just by studying individual ants.

I’m left with a lot of questions though. Flake mentions the “frugal” nature of the rules governing interactions – is there a way to quantify this frugality? And how exactly do we go about describing these interactions in a computational way? The idea of “nature’s program” is intriguing, but I wonder how far that metaphor can be stretched. What I found most interesting was the connection between computation and natural phenomena like fractals and chaos. It’s mind-blowing to think that simple iterative processes can generate such intricate and seemingly unpredictable patterns. I’m definitely looking forward to diving deeper into these topics in the following chapters.