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