Published
Edited
Aug 23, 2019
1 fork
7 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
class Boid {
constructor([x, y, z], scene) {
this.position = new THREE.Vector3(x, y, z);
this.acceleration = new THREE.Vector3(0, 0, 0);

const angle = randomAngle();
this.velocity = new THREE.Vector3(
Math.cos(angle),
Math.sin(angle),
Math.sin(angle)
);

this.init(scene);
}

init(scene) {
const { position } = this;

const r = boidValues[0][1];
const geometry = new THREE.BoxBufferGeometry(r, r, r);
const material = new THREE.MeshPhongMaterial({
color: `rgba(150,150,150, 1)`
});
const cube = new THREE.Mesh(geometry, material);
cube.position.set(...position.toArray());

scene.add(cube);
this.mesh = cube;
}

run(boids, scene, counter) {
this.flock(boids);
this.update(counter);
this.borders();
}

applyForce(force) {
const mass = boidValues[0][4];
this.acceleration.add(force.divideScalar(mass));
}

flock(boids, scene) {
const sep = this.separate(boids);
const ali = this.align(boids, scene);
const coh = this.cohesion(boids);

sep.multiplyScalar(behaviorValues[0][0]);
ali.multiplyScalar(behaviorValues[0][1]);
coh.multiplyScalar(behaviorValues[0][2]);

this.applyForce(sep);
this.applyForce(ali);
this.applyForce(coh);
}

separate(boids) {
const { position, velocity } = this;
const steer = new THREE.Vector3(0, 0, 0);
let count = 0;

for (let boid of boids) {
const d = position.distanceTo(boid.position);

const neighborDistSeperate = behaviorValues[0][3];
if (d > 0 && d < neighborDistSeperate) {
const diff = new THREE.Vector3().subVectors(position, boid.position);
diff.normalize();
diff.divideScalar(d);
steer.add(diff);
count += 1;
}
}

if (count > 0) {
steer.divideScalar(count);
}

if (steer.length() > 0) {
const maxSpeed = boidValues[0][2];
const maxForce = boidValues[0][3];
steer.setLength(maxSpeed);
steer.sub(velocity);
steer.clampLength(0, maxForce);
}

return steer;
}

align(boids) {
const { position, velocity } = this;
const sum = new THREE.Vector3(0, 0, 0);
let count = 0;

for (let boid of boids) {
const d = position.distanceTo(boid.position);

const neighborDistAlign = behaviorValues[0][4];
if (d > 0 && d < neighborDistAlign) {
sum.add(boid.velocity);
count += 1;
}
}

if (count > 0) {
const maxSpeed = boidValues[0][2];
const maxForce = boidValues[0][3];
sum.divideScalar(count);
sum.setLength(maxSpeed);
const steer = new THREE.Vector3().subVectors(sum, velocity);
steer.clampLength(0, maxForce);
return steer;
}
return new THREE.Vector3(0, 0, 0);
}

cohesion(boids) {
const { position } = this;
const sum = new THREE.Vector3(0, 0, 0);
let count = 0;

for (let boid of boids) {
const d = position.distanceTo(boid.position);

const neighborDistCohesion = behaviorValues[0][5];
if (d > 0 && d < neighborDistCohesion) {
sum.add(boid.position);
count += 1;
}
}

if (count > 0) {
sum.divideScalar(count);
return this.seek(sum);
}

return new THREE.Vector3(0, 0, 0);
}

seek(target) {
const { position, velocity } = this;
const maxSpeed = boidValues[0][2];
const maxForce = boidValues[0][3];

const desired = new THREE.Vector3().subVectors(target, position);
desired.setLength(maxSpeed);

const steer = new THREE.Vector3().subVectors(desired, velocity);
steer.clampLength(0, maxForce);

return steer;
}

borders() {
const { position } = this;
const area = areaValues[0][0];
const r = boidValues[0][1];

if (position.x < -r) position.x = area + r;
if (position.y < -r) position.y = area + r;
if (position.z < -r) position.z = area + r;
if (position.x > area + r) position.x = -r;
if (position.y > area + r) position.y = -r;
if (position.z > area + r) position.z = -r;
}

update(counter) {
const { position, velocity, acceleration, mesh, color } = this;

const maxSpeed = boidValues[0][2];
velocity.add(acceleration);
velocity.clampLength(0, maxSpeed);
position.add(velocity);
acceleration.multiplyScalar(0);
mesh.position.set(...position.toArray());
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more