xxxxxxxxxx
96
let boids = [];
let speed = 50;
let view_distance = 150;
function setup() {
createCanvas(400, 400);
let rangle;
for (i = 0; i < 40; i++) {
rangle = random(0, 2 * Math.PI);
boids.push(new Boid(
random(0, width),
random(0, height),
speed * Math.cos(rangle),
speed * Math.sin(rangle)
));
}
}
function draw() {
background(220);
boids.forEach(boid => boid.update());
boids.forEach(boid => boid.draw());
let lineStart = [boids[0].pos.x, boids[0].pos.y];
let lineEnd = [boids[0].pos.x + boids[0].vel.x,
boids[0].pos.y + boids[0].vel.y];
line(lineStart[0], lineStart[1], lineEnd[0], lineEnd[1]);
noFill();
circle(lineStart[0], lineStart[1], 150);
}
class Boid {
constructor(initX, initY, initVX, initVY) {
this.pos = createVector(initX, initY);
this.vel = createVector(initVX, initVY);
}
update() {
this.pos.add(this.new_pos(deltaTime / 1000));
this.edge_check();
this.stray_from_others();
}
draw() {
push()
translate(this.pos.x, this.pos.y);
rotate(this.vel.heading());
noStroke();
fill("#b00");
triangle(-5, -5, -5, 5, 10, 0);
pop()
}
edge_check() {
let offset = 10
if (this.pos.x < - offset) {
this.pos.x += width + offset*2;
}
else if (this.pos.x > width + offset) {
this.pos.x -= width + offset*2;
}
if (this.pos.y < -offset) {
this.pos.y += height + offset*2;
}
else if (this.pos.y > height + offset) {
this.pos.y -= height + offset*2;
}
}
stray_from_others() {
let dist_sq;
for (var boid of boids) {
let sep_vec = p5.Vector.sub(boid.pos, this.pos);
dist_sq = sep_vec.magSq();
if (dist_sq == 0) {
continue
}
else if (dist_sq > view_distance**2) {
continue
}
let dist_sq_inv = 1 / dist_sq**(0.7);
let cross = p5.Vector.cross(this.vel, sep_vec);
let direc = (cross.z < 0) ? 1: -1;
this.vel.rotate(direc * dist_sq_inv * Math.PI / 2);
}
}
new_pos(dt) {
return p5.Vector.mult(this.vel, dt);
}
}