xxxxxxxxxx
235
class Boid {
constructor() {
// Initialize boid's position with a random depth (z-axis)
this.pos = createVector(random(-width/4,width/4), random(-height/4,height/4), random(-300,300));
this.vel = p5.Vector.random3D();
this.vel.setMag(random(0.5, 1.5));
// Initialize acceleration and other parameters
this.acc = createVector(0, 0, 0);
this.maxForce = 0.095; // Maximum steering force
this.maxVel = 2; // Maximum velocity
this.fov = 30; // Field of view (how far the boid can see, however I use different values for different behaviors);
this.halfWidth = width / 2;
this.halfHeight = height / 2;
// this.maxDist = 1000;
this.col = randomGaussian(0, 20);// Random color for pigeons
this.initDir = createVector(0,0,1)
// this.OGdirection = createVector(0,0,1);
// this.direction = createVector(0,0,0);
this.bodyLength = 30;
this.bodyWidth = 3;
this.bodyHeight = 10
this.z = 0;
}
// Function to handle canvas edges
checkEdges() {
if (this.pos.x > width) {
// this.pos.x = -width/2;
this.vel.x *= -1;
} else if (this.pos.x < -width) {
// this.pos.x = width/2;
this.vel.x *= -1;
}
if (this.pos.y > height) {
// this.pos.y = -height/2;
this.vel.y *= -1;
} else if (this.pos.y < -height) {
// this.pos.y = height/2;
this.vel.y *= -1;
}
if (this.pos.z > 2000) {
// this.pos.z = -1000;
this.vel.z *= -1;
} else if (this.pos.z < -2000) {
// this.pos.z = 1000;
this.vel.z *= -1;
}
}
// Function to update the boid's position and behavior
update(boids, d) {
this.checkEdges();
this.flock(boids);
this.vel.add(this.acc);
this.pos.add(this.vel);
this.acc.set(0, 0, 0);
this.vel.limit(this.maxVel);
}
// Function for alignment behavior
align(boids, d) {
let fov = this.fov*2;
let steering = createVector();
// Boids In View
let biv = 0;
for (let other of boids) {
let d = dist(
this.pos.x,
this.pos.y,
this.pos.z,
other.pos.x,
other.pos.y,
other.pos.z
);
if (other != this && d > 10 && d < fov) {
steering.add(other.vel);
biv++;
}
}
if (biv > 0) {
steering.div(biv);
steering.setMag(this.maxVel);
steering.sub(this.vel);
steering.limit(this.maxForce);
}
// this.direction = steering;
// this.direction.normalize();;
return steering;
}
// Function for separation behavior
seperate(boids, d) {
let fov = this.fov/2;
let steering = createVector();
let biv = 0;
for (let other of boids) {
let d = dist(
this.pos.x,
this.pos.y,
this.pos.z,
other.pos.x,
other.pos.y,
other.pos.z
);
if (other != this && d < fov) {
let diff = p5.Vector.sub(this.pos, other.pos);
diff.div(d);
steering.add(diff);
biv++;
// print("hi");
}
if (biv > 0) {
steering.div(biv);
steering.setMag(this.maxVel);
steering.sub(this.vel);
steering.limit(this.maxForce);
// steering.mult(-10);
steering.setMag(-1);
}
}
// if (biv > 0) {
// steering.div(biv);
// steering.setMag(this.maxVel);
// steering.sub(this.vel);
// steering.limit(this.maxForce);
// }
return steering;
}
// Function for cohesion behavior
cohesion(boids, d) {
let fov = this.fov;
let steering = createVector();
let biv = 0;
for (let other of boids) {
let d = dist(
this.pos.x,
this.pos.y,
this.pos.z,
other.pos.x,
other.pos.y,
other.pos.z
);
if (other != this && d < fov) {
steering.add(other.pos);
biv++;
}
}
if (biv > 0) {
steering.div(biv);
steering.setMag(this.maxVel);
steering.sub(this.pos);
steering.sub(this.vel);
steering.limit(this.maxForce);
}
return steering;
}
// Function to apply flocking behaviors (gets steering values form all 3 functions and adds them to the acceleration)
flock(boids) {
let alignment = this.align(boids);
let cohesion = this.cohesion(boids);
let seperation = this.seperate(boids);
this.acc.add(alignment);
this.acc.add(cohesion);
this.acc.add(seperation);
this.acc.limit(this.maxForce);
}
move(boids){
push();
scale(0.2);
translate(this.pos.x,this.pos.y,this.pos.z);
this.render(boids);
pop();
}
render(boids) {
this.update(boids);
strokeWeight(0.2);
// Make boids less opaque the further away they are on the Z-axis
// stroke(this.col, 255 * ((this.pos.z + 500) / 1000));
// point(this.pos.x, this.pos.y, this.pos.z);
for (let i = -10; i < 10; i++){
let x = map(i,-10,10,0,PI);
let y = map(i,-10,10,0,TWO_PI);
this.z += 0.01;
this.changeInDir = p5.Vector.sub(this.initDir,this.vel);
this.changeInDir.normalize();
push();
this.changeInDir.mult(45);
angleMode(DEGREES);
rotateX(this.changeInDir.y);
rotateY(-this.changeInDir.x*2);
rotateZ(this.changeInDir.z);
angleMode(RADIANS);
translate(2*cos(y+this.z*3),5*cos(x+this.z/5),i*3);
strokeWeight(0.2);
fill(130);
specularMaterial(250);
box(10*sin(x),20*sin(x),3);
pop();
}
}
}
let flockList = [];
class Flock {
constructor() {
// Create a flock of 200 boids
for (let i = 0; i < 100; i++) {
flockList.push(new Boid());
}
}
render() {
for (let boid of flockList) {
// boid.flock(flockList);
boid.move(flockList);
}
}
}