From 9ef76536ca78b47beaed4b5bedd9d99df4d6a1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Sat, 9 May 2020 14:29:54 +0200 Subject: [PATCH] Integrate obstacles in repel force --- boids.mjs | 34 ++++++++++++++++------------------ geometry.mjs | 20 +++++++++----------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/boids.mjs b/boids.mjs index 9aed1a8..e9a2ebc 100644 --- a/boids.mjs +++ b/boids.mjs @@ -79,11 +79,9 @@ class Boids // List of active simulated boids this.boids = []; - this.boidsLength = 0; // List of obstacles this.obstacles = obstacles; - this.obstaclesLength = this.obstacles.length; // Vector registers used for holding temporary values this.registers = [ @@ -122,7 +120,6 @@ class Boids add(center) { this.boids.push(new Boid(this.params, center)); - this.boidsLength += 1; } /** Start the simulation. */ @@ -174,7 +171,8 @@ class Boids */ _update(delta) { - const boidsLength = this.boidsLength; + const boidsLength = this.boids.length; + const obstaclesLength = this.obstacles.length; for (let i = 0; i < boidsLength; ++i) { @@ -187,7 +185,7 @@ class Boids let visibles = 0; // Compute mean flock position and velocity and compute - // the repel force + // the repel force from other boids for (let j = 0; j < boidsLength; ++j) { if (i != j) @@ -211,6 +209,17 @@ class Boids } } + // Compute the repel force from obstacles + for (let j = 0; j < obstaclesLength; ++j) + { + const obstacle = this.obstacles[j]; + + if (obstacle.distance(me.pos) < this.params.closeDist) + { + me.vel.add(me.pos).sub(obstacle.center); + } + } + // Attract towards center of visible flock if (visibles >= 1) { @@ -239,17 +248,6 @@ class Boids .mul(this.params.matchAccel)); } - // Avoid obstacles - for (let j = 0; j < this.obstaclesLength; ++j) - { - const obstacle = this.obstacles[j]; - - if (obstacle.intersect(me.pos, this.params.radius)) - { - me.vel.sub(obstacle.center).add(me.pos); - } - } - // Do not surpass maximum speed const speed = me.vel.normSquared(); @@ -269,8 +267,8 @@ class Boids */ _draw() { - const boidsLength = this.boidsLength; - const obstaclesLength = this.obstaclesLength; + const boidsLength = this.boids.length; + const obstaclesLength = this.obstacles.length; this.ctx.clearRect( -this.width / 2, -this.height / 2, diff --git a/geometry.mjs b/geometry.mjs index d1dcda5..fa8bf57 100644 --- a/geometry.mjs +++ b/geometry.mjs @@ -93,13 +93,11 @@ export class Rectangle this.center = new Vector(x + w / 2, y + h / 2); } - intersect(point, radius) + distance(point) { - return ( - point.x >= this.x - radius - && point.x < this.x + this.w + radius - && point.y >= this.y - radius - && point.y < this.y + this.h + radius + return Math.hypot( + Math.max(point.x - this.x - this.w, 0, this.x - point.x), + Math.max(point.y - this.y - this.h, 0, this.y - point.y), ); } @@ -117,12 +115,12 @@ export class Circle this.center = new Vector(x, y); } - intersect(point, radius) + distance(point) { - return ( - Vector.distSquared(this.center, point) - <= (this.r + radius) * (this.r + radius) - ); + return Math.hypot( + this.center.x - point.x, + this.center.y - point.y, + ) - this.r; } draw(ctx)