@scudly Thanks a lot. The particles of life nailed it totally.
I’m goint to integrate this in the rest of my code.
I’ll leave here an example of what I cooked so far. It’s a fun stuff to play with, xhanging forces and limits cool stuff… I made a very controlled one.
it’s a little oppressesd in the half a page of the editor though…
also the code is not very clean yet.
let bodies = []
let cnv;
let force;
const K = 0.5;
const friction = 0.5;
let bodiesNumber = 200;
let pressedX, pressedY;
let c;
let forces = [
[0, 0],
[5, -9]
]
let minDist = [
[-1, -1],
[100, 10]
]
let maxDist = [
[-1, 0],
[2000, 100]
]
function setup() {
cnv = createCanvas(900, 900);
C = color(100, 40, 60);
for (var i = 0; i < bodiesNumber; i++) {
// bodies.push(new Body(random(180,220), random(180,220), 30, c));
bodies.push(new Body(random(200, 700), random(100, 700), 30, c));
}
bodies[0].mass = 80;
bodies[0].type = 0;
}
function draw() {
background(185, 175, 185);
// translate(width/2 , height/2 );
// scale(scrollOff/200);
for (const b of bodies) {
b.display();
b.update();
}
}
function mouseDragged() {
bodies[0].pos.x = mouseX;
bodies[0].pos.y = mouseY;
}
class Body {
constructor(x, y, m, c) {
this.pos = createVector(x, y, 1);
this.mass = m;
this.vel = createVector(0, 0);
this.strength = 0.2;
this.minDist = this.mass * 1.5; // <=== experiences
this.maxDist = 100;
this.type = 1;
this.color1 = color(110, 50, 60, 50)
this.color2 = color(210, 150, 160, 50)
this.color3 = color(11, 5, 6, 50)
this.dispColor = this.color1;
}
update() {
let dir = createVector(0, 0);
let totalForce = createVector(0, 0);
let acc = createVector(0, 0);
let dist = 0;
for (const body of bodies) {
if (body !== this) {
this.maxDist = maxDist[this.type][body.type];
this.minDist = minDist[this.type][body.type]
// console.log(body)
//clear for this particle
dir.mult(0);
//copy to keep from messing origina value
dir = body.pos.copy();
// get dir to other
dir.sub(this.pos);
//store distance before normalizing
dist = dir.mag();
//normalize
dir.normalize();
//repel based on dist
if (dist < minDist[this.type][body.type]) {
this.dispColor = this.color2
// don't mess with dir
const force = dir.copy();
// an arbitrary value - in the example we had a table with a unique
// value for each combination. Let's see what i'll need...
force.mult(forces[this.type][body.type] * -10); // negative => repel
//map dist to positive 0~1 and multiply
const mappedD = abs(map(dist, 0, this.minDist, 1, 0)); // <== note 1 e 0 not 0 e 1
force.mult(mappedD);
// a constant to scale down the forces 0.5 in the example
force.mult(K)
//accumulate all the forces of all other particles interacting with this one
totalForce.add(force);
}
if (dist < maxDist[this.type][body.type]) {
this.dispColor = this.color3;
// don't mess with dir
const force = dir.copy();
// an arbitrary value - in the example we had a table with a unique
// value for each combination. Let's see what i'll need...
force.mult(forces[this.type][body.type]);
//map dist to positive 0~1 and multiply
const mappedD = abs(map(dist, 0, maxDist[this.type][body.type], 1, 0)); // <== note 1 e 0 not 0 e 1
force.mult(mappedD);
// a constant to scale down the forces 0.5 in the example
force.mult(K)
//accumulate all the forces of all other particles interacting with this one
totalForce.add(force);
}
}
}
acc.add(totalForce); // if mass totalForce/this.mass
this.vel.add(acc);
this.pos.add(this.vel);
this.vel.mult(friction);
}
display() {
push();
noStroke()
fill(255, 30);
circle(this.pos.x, this.pos.y, this.maxDist)
stroke(255, 0, 0, 50);
fill(255, 250, 250, 20);
circle(this.pos.x, this.pos.y, this.minDist)
fill(this.dispColor);
fill(this.dispColor);
circle(this.pos.x, this.pos.y, this.mass);
// if (this.type === 1) {
// image(img, this.pos.x, this.pos.y);
// textSize(7)
// text('Nome Filhadaputa', this.pos.x -25, this.pos.y +30);
// } else {
// fill(this.dispColor);
// noStroke()
// circle(this.pos.x, this.pos.y, this.mass);
// }
pop();
}
} //<== eof attractor