import Vector from './vector.mjs'; const meanPos = new Vector(0, 0); const meanVel = new Vector(0, 0); const repelForce = new Vector(0, 0); export const update = (boids, params, width, height, time) => { const boidsSize = boids.length; for (let i = 0; i < boidsSize; ++i) { const me = boids[i]; meanPos.reset(); meanVel.reset(); repelForce.reset(); let visibleSize = 0; for (let j = 0; j < boidsSize; ++j) { if (i != j) { const you = boids[j]; const dist = Vector.distSquared(me.pos, you.pos); if (dist < params.visibleDist * params.visibleDist) { meanPos.add(you.pos); meanVel.add(you.vel); visibleSize += 1; if (dist < params.closeDist * params.closeDist) { repelForce.add(me.pos).sub(you.pos); } } } } // Attract towards center of visible flock if (visibleSize >= 1) { me.vel.add(meanPos.div(visibleSize) .sub(me.pos) .mul(params.centerAccel)); } // Attract toward center of screen if out of bounds if (me.pos.x < width * -.4 || me.pos.x > width * .4 || me.pos.y < height * -.4 || me.pos.y > height * .4) { me.vel.addMul(me.pos, -params.boundsAccel); } // Repel away from close boids me.vel.add(repelForce.mul(params.repelAccel)); // Match other boids’ velocity if (visibleSize >= 1) { me.vel.add(meanVel.div(visibleSize) .sub(me.vel) .mul(params.matchAccel)); } // Do not surpass maximum speed const speed = me.vel.normSquared(); if (speed > params.maxSpeed * params.maxSpeed) { me.vel.div(Math.sqrt(speed)).mul(params.maxSpeed); } // Integrate speed me.pos.addMul(me.vel, time); } };