diff options
Diffstat (limited to 'resources/js/boid.js')
-rw-r--r-- | resources/js/boid.js | 81 |
1 files changed, 62 insertions, 19 deletions
diff --git a/resources/js/boid.js b/resources/js/boid.js index a15022a..a3aefea 100644 --- a/resources/js/boid.js +++ b/resources/js/boid.js @@ -14,27 +14,34 @@ class Boid { this.scene_height = scene_height; // Boid "dynamic" properties - this.rayLength = 40; + this.rayLength = 60; + this.wallBuffer = 40; this.turnStepAmount = 20; - this.stepAmount = 4; - this.fieldOfView = 270; + this.stepAmount = 2; + this.fieldOfView = 180; this.boidBuffer = 20; } move(boids) { // this.direction += Math.random() * (2 * this.turnStepAmount) - this.turnStepAmount + let direction = this.findNextRay(boids); - this.direction = this.findNextRay(boids); + if (!direction) { + return false; + } + this.direction = direction; var vector = this.findPoint(this.x, this.y, this.stepAmount, this.direction); this.x = vector.x; this.y = vector.y; + + return true; } buildRays() { let rays = new Array(); - let rayInteval = 2; + let rayInteval = 5; let noOfSteps = this.fieldOfView / rayInteval; let is_clockwise = Math.random() >= 0.5; @@ -61,27 +68,33 @@ class Boid { findNextRay(boids) { let rays = this.buildRays(); + let collision = false; for (let i = 0; i < rays.length; i++) { - let tweakAngle = 0; - // if (Math.random() > 0.95) { - // tweakAngle = this.turnStepAmount * Math.random() - (this.turnStepAmount / 2); - // } - - let rayAngle = tweakAngle + this.direction + rays[i]; + let rayAngle = this.direction + rays[i]; // Check against all other boids if (this.detectBoids(rayAngle, boids)) { + if (i == 0) { + collision = true; + } continue; } // Check against scene boundaries if (this.detectBox(this.scene_width, this.scene_height, rayAngle)) { + if (i == 0) { + collision = true; + } continue; } return rayAngle; } + if (!collision) { + return this.direction; + } + console.log('cannot find suitable ray'); return false; } @@ -112,9 +125,16 @@ class Boid { if (intersect) { console.log('boids intersect detected'); + return true; } - return intersect; + return this.willBoidsIntersect(boid, direction); + } + + willBoidsIntersect(boid, direction) { + let future_position = this.findPoint(this.x, this.y, this.rayLength, direction); + + return this.lineIntersectsCircle(this.x, future_position.x, this.y, future_position.y, boid.radius * 2, boid.x, boid.y); } boidsIntersect(boid) { @@ -145,13 +165,36 @@ class Boid { if (!x4 || !y4) { return false; } - console.log('intersecting circles'); + return { x: x4, y: y4 }; } + lineIntersectsCircle(x1, x2, y1, y2, r, rx, ry) { + // first r is at 0,0 so we must first move the line the same distance + // Normalize points + x1 -= rx; + y1 -= ry; + x2 -= rx; + y2 -= ry; + + let dx = x2 - x1; + let dy = y2 - y1; + + let dr = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + let dd = (x1 * y2) - (x2 * y1); + + let di = (Math.pow(r, 2) * Math.pow(dr, 2)) - Math.pow(dd, 2); + + if (di < 0) { + return false; + } else { + return true; + } + } + distanceBetweenPoints(x1, x2, y1, y2) { let dx = Math.abs(x1 - x2); let dy = Math.abs(y1 - y2); @@ -219,7 +262,7 @@ class Boid { } detectBox(width, height, direction) { - let point = this.findPoint(this.x, this.y, this.rayLength, direction); + let point = this.findPoint(this.x, this.y, this.wallBuffer, direction); if (point.x - this.radius < 0 || point.y - this.radius < 0 || @@ -235,18 +278,18 @@ class Boid { findPoint(x1, y1, length, angle) { angle *= Math.PI / 180; - var x2 = x1 + length * Math.cos(angle), - y2 = y1 + length * Math.sin(angle); + let x2 = x1 + length * Math.cos(angle); // must be rad + let y2 = y1 + length * Math.sin(angle); // must be radrayLength return { - x: x2, - y: y2 + x: parseFloat((Number(x2).toFixed(2))), + y: parseFloat(Number(y2).toFixed(2)) }; } draw(context) { this.drawBoid(context); - // this.drawRay(context, this.x, this.y, this.rayLength, this.direction); + this.drawRay(context, this.x, this.y, this.rayLength, this.direction); } drawBoid(context) { |