week3 – attractors and movers

Concept:

The concept for this project was to be able to create a recognizable pattern while also using movers and attractors. I was inspired by the flower-dotted patterns as well as Dan Gries’s work. In this project, I try to integrate what we learned in class to recreate such a pattern. However, I decided to add more forces that can disturb the pattern as if it’s almost a shadow.

Highlight of some code:

For this project, I decided to build upon the practice we had in class. I initially wrote a code similar to what we did in class and then watched the nature of the code video and added elements to that. I played around with the names to see what patterns I got. After that, I decided to create some turbulence by creating a bouncing effect when the balls reached the borders of the canvas and by creating gravity between some of the particles. I had so many issues with debugging the code because I was experimenting with it mostly to create a pattern I liked. I think the most challenging part was making the different bodies work relatively in response to one another while also creating interesting shapes as they moved around the canvas. 

These images are different iterations at different stages of my code until I reach the desired result.

class Mover {
  constructor(x, y, m) {
    this.pos = createVector(x, y);
    this.vel = p5.Vector.random2D();
     // this.vel.mult(5);
    //     the acceleration will change when forces act on it
    this.acc = createVector(0, 0);
    this.mass = m;//this store mass m of mover []
    this.r = sqrt(this.mass) * 0.15; //r=sqr m * a constant this is for the radious 
  }

  applyForce(force) {
    let f = p5.Vector.div(force, this.mass);
    this.acc.add(f); //add the forces to acceleration 
  }
//   attract to one another gravity btw diff objects
  TwoAttract(mover) {
    //this.pos-mover=vector(from mover to another mover)
    let force = p5.Vector.sub(this.pos, mover.pos); // 
    let distanceSq = constrain(force.magSq(), 1000, 10000); //limit btwn 1000 and 10000
    let G = 0.2; //gravatational constant 
    let strength = (G * (this.mass * mover.mass)) / distanceSq; //f=G*(m1m2)/d'2 law of gravity 
    force.setMag(strength); //set the force and mag as calculated 
    mover.applyForce(force); //apply calculated to mover 
  }

  update() {
    this.vel.add(this.acc);
    this.pos.add(this.vel);
    this.acc.set(0, 0);
    
        // Boundary checks 
    if (this.pos.x > width) {
      this.pos.x = width;
      this.vel.x *= -1; // Reverse horizontal velocity when hitting right edge
    } else if (this.pos.x < 0) {
      this.pos.x = 0;
      this.vel.x *= -0.1; // Reverse horizontal velocity when hitting left edge
    }
    
    if (this.pos.y > height) {
      this.pos.y = height;
      this.vel.y *= -0.2; // Reverse vertical velocity when hitting bottom edge
    } else if (this.pos.y < 0) {
      this.pos.y = 0;
      this.vel.y *= -0.2; // Reverse vertical velocity when hitting top edge
    }
    // Reset acceleration to 0 after each frame
    this.acc.mult(0);
    
    
  }
  RandomColors(){
  //     colors function
   
   let R = random(90, 100); // r is a random number between 0 - 255
   let G = random(100, 120); // g is a random number betwen 100 - 200
   let B = random(150, 200); // b is a random number between 0 - 100
  return color(R,G,B);
}

  show() {
     strokeWeight(0);
    fill(this.RandomColors());
    ellipse(this.pos.x, this.pos.y, this.r * 2);
  }
}
//class to attract objects to the attractor to show how gravity is btwn 2 objects the attractor and the objects 
class Attractor {
  constructor(x, y, m) {
    this.pos = createVector(x, y);
    this.mass = m;
    this.r = sqrt(this.mass) *115;
  }

  attract(mover) {
    let force = p5.Vector.sub(this.pos, mover.pos);
    let distanceSq = constrain(force.magSq(), 1000, 1500);
    let G = 4;
    let strength = (G * (this.mass * mover.mass)) / distanceSq;
    force.setMag(strength);
    mover.applyForce(force);
  }

  show() {
  
  }
}
let movers = [];
let twoattract;
let attractor;

function setup() {
  createCanvas(600, 600);
  //movers attracted to attracor
  for (let i = 0; i < 6; i++) {
    let x = random(width / 2);
    let y = random(height / 2);
    let m = random(50, 100);
    movers[i] = new Mover(x, y, m);
  }
  attractor = new Attractor(width / 2.5, height / 2, 100);

  background(0);
}

function draw() {
  //3 movers attracted to each other
  for (let t = 0; t < 4; t++) {
    movers[t].update();
    movers[t].show();
    //attractor applies force to each other
    attractor.attract(movers[t]);

    for (let u = 0; u < 6; u++) {
      for (let other of movers) {
        if (t !== u) {
          movers[t].TwoAttract(movers[u]);
        }
      }
    }
  }

  attractor.show();
}

 

Embedded sketch:

Reflection and Future Work:

I am happy with the result of this project; however, I think there is room for improvement.  I think the forces acting on the objects and the attraction more coherent with one another to make them feel a little more pattern would create even more pleasing results. Further, I want to experiment with other shapes rather than circles maybe lines or triangles that would potential;;y create other patterns as they move.

Resources:

https://www.researchgate.net/publication/258499541_Classification_of_symmetry_groups_for_planar_n-body_choreographies

https://dangries.com/rectangleworld/demos/nBody/

https://github.com/nature-of-code/noc-book-2/tree/main/content/examples/01_vectors/example_1_9_motion_101_velocity_and_random_acceleration

https://thecodingtrain.com/tracks/the-nature-of-code-2/noc/2-forces/6-mutual-attraction

Leave a Reply

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