From a44e609b27642afc77495293d975f2ea0bbf6f3e Mon Sep 17 00:00:00 2001 From: Fbenas Date: Tue, 13 Oct 2020 21:58:58 +0100 Subject: Add maths function to detect two intersection circles --- resources/js/boid.js | 138 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 108 insertions(+), 30 deletions(-) (limited to 'resources/js/boid.js') diff --git a/resources/js/boid.js b/resources/js/boid.js index 2ae692d..85793ff 100644 --- a/resources/js/boid.js +++ b/resources/js/boid.js @@ -36,11 +36,23 @@ class Boid { let rayInteval = 2; let noOfSteps = this.fieldOfView / rayInteval; + let is_clockwise = Math.random() >= 0.5; + for (let i = 0; i < noOfSteps / 2; i++) { - if (i != 0) { + if (i == 0) { + rays.push(rayInteval * i); + continue; + } + + if (is_clockwise) { rays.push(rayInteval * -i); } + rays.push(rayInteval * i); + + if (!is_clockwise) { + rays.push(rayInteval * -i); + } } return rays; @@ -57,10 +69,12 @@ class Boid { let rayAngle = tweakAngle + this.direction + rays[i]; - if (i == 0 && this.detectBoid(rayAngle, boids)) { + // Check against all other boids + if (i == 0 && this.detectBoids(rayAngle, boids)) { continue; } + // Check against scene boundaries if (this.detectBox(this.scene_width, this.scene_height, rayAngle)) { continue; } @@ -71,34 +85,9 @@ class Boid { console.log('cannot find suitable ray'); } - detectBoid(direction, boids) { + detectBoids(direction, boids) { for (let i = 0; i < boids.length; i++) { - // rule out ourselves - if (this.id == boids[i].id) { - continue; - } - - let thisFututrePosition = this.findPoint(this.x, this.y, this.boidBuffer, direction); - let thisPath = { - x1: this.x, - y1: this.y, - x2: thisFututrePosition.x, - y2: thisFututrePosition.y - }; - - let boidFuturePosition = this.findPoint(boids[i].x, boids[i].y, boids[i].boidBuffer, boids[i].direction); - let boidPath = { - x1: boids[i].x, - y1: boids[i].y, - x2: boidFuturePosition.x, - y2: boidFuturePosition.y - }; - - let thisIntersectsBoid = this.pathsIntersect( - thisPath.x1, thisPath.y1, thisPath.x2, thisPath.y2, boidPath.x1, boidPath.y1, boidPath.x2, boidPath.y2 - ); - - if (thisIntersectsBoid) { + if (this.detectBoid(direction, boids[i])) { return true; } } @@ -106,6 +95,95 @@ class Boid { return false; } + detectBoid(direction, boid) { + // rule out ourselves + if (this.id == boid.id) { + return false; + } + + // let cross = this.doPathsCross(direction, boid); + // + // if (cross) { + // console.log('paths cross detected'); + // } + + let intersect = this.boidsIntersect(boid); + + if (intersect) { + console.log('boids intersect detected'); + } + } + + boidsIntersect(boid) { + this.twoCirclesIntersect(this.radius, boid.radius, this.x, boid.x, this.y, boid.y); + } + + twoCirclesIntersect(r1, r2, x1, x2, y1, y2) { + // from https://planetcalc.com/8098/ (bottom of page) + // https://mathworld.wolfram.com/Circle-CircleIntersection.html + // d is the abs distance between the two circles center + let d = this.distanceBetweenPoints(x1, x2, y1, y2); + + // a is distance to our x3 point ( I think ) + let a = (Math.pow(r1, 2) - Math.pow(r2, 2) + Math.pow(d, 2)) / (2 * d); + + // h is some other segment of some other circle ( I dont really know ) + let h = Math.sqrt(Math.pow(r1, 2) - Math.pow(a, 2)); + + // x3 and y3 represent the point between the two circle midpoints, perpindicular to which will be our intersects + // ( maybe ) + let x3 = x1 + ((a / d) * (x2 - x1)); + let y3 = y1 + ((a / d) * (y2 - y1)); + + // x4 and y4 are one of the intersect points + let x4 = x3 + ((h / d) * (y2 - y1)); + let y4 = y3 - ((h / d) * (x2 - x1)); + + if (!x4 || !y4) { + return false; + } + console.log('intersecting circles'); + return { + x: x4, + y: y4 + }; + } + + distanceBetweenPoints(x1, x2, y1, y2) { + let dx = Math.abs(x1 - x2); + let dy = Math.abs(y1 - y2); + + return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + } + + doPathsCross(direction, boid) { + let thisFututrePosition = this.findPoint(this.x, this.y, this.boidBuffer, direction); + let thisPath = { + x1: this.x, + y1: this.y, + x2: thisFututrePosition.x, + y2: thisFututrePosition.y + }; + + let boidFuturePosition = this.findPoint(boid.x, boid.y, boid.boidBuffer, boid.direction); + let boidPath = { + x1: boid.x, + y1: boid.y, + x2: boidFuturePosition.x, + y2: boidFuturePosition.y + }; + + let thisIntersectsBoid = this.pathsIntersect( + thisPath.x1, thisPath.y1, thisPath.x2, thisPath.y2, boidPath.x1, boidPath.y1, boidPath.x2, boidPath.y2 + ); + + if (thisIntersectsBoid) { + return true; + } + + return false; + } + pathsIntersect(x1, y1, x2, y2, x3, y3, x4, y4) { // Check if none of the lines are of length 0 if ((x1 === x2 && y1 === y2) || (x3 === x4 && y3 === y4)) { @@ -165,7 +243,7 @@ class Boid { 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) { -- cgit v1.2.3