Help thinking out an attraction behavior

@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.

live in p5.editor

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


1 Like