A Pen by Martijn Kunstman on CodePen.
Created
December 20, 2021 08:07
-
-
Save martijnkunstman/95a75ffce163da900bd9413ca2505c26 to your computer and use it in GitHub Desktop.
spacial hash
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let canvasWidth = 600; | |
| let canvasHeight = 500; | |
| let spacialHash; | |
| let boids = []; | |
| let diameter = 10; | |
| let boidsCount = 2000; | |
| let useSpacialHash = true; | |
| let grid = diameter; | |
| let counter = 0; | |
| let log = true; | |
| function neighbors(arr, m, n) { | |
| // define what a neighbor is | |
| let v = [ | |
| [-1, -1], | |
| [-1, 0], | |
| [-1, 1], | |
| [0, -1], | |
| [0, 0], | |
| [0, 1], | |
| [1, -1], | |
| [1, 0], | |
| [1, 1] | |
| ]; | |
| // filter edges & map | |
| return v | |
| .filter( | |
| ([h, j]) => | |
| h + m >= 0 && h + m < arr.length && j + n >= 0 && j + n < arr[0].length | |
| ) | |
| .map(([h, j]) => arr[h + m][j + n]); | |
| } | |
| function setup() { | |
| createCanvas(canvasWidth, canvasHeight); | |
| spacialHash = new SpatialHash({ w: canvasWidth, h: canvasHeight }, grid); | |
| for (let a = 0; a < boidsCount; a++) { | |
| let boid = new Boid(random(0, canvasWidth), random(0, canvasHeight)); | |
| boids.push(boid); | |
| spacialHash.insert(boid); | |
| } | |
| } | |
| function draw() { | |
| counter = 0; | |
| spacialHash.clear(); | |
| for (let a = 0; a < boids.length; a++) { | |
| boids[a].update(); | |
| spacialHash.insert(boids[a]); | |
| } | |
| background(150); | |
| let xx = Math.floor(mouseX / grid); | |
| let yy = Math.floor(mouseY / grid); | |
| fill(255); | |
| rect(xx * grid, yy * grid, grid, grid); | |
| //get all 8 border cells in grid... | |
| fill(200); | |
| rect((xx - 1) * grid, (yy - 1) * grid, grid, grid); | |
| rect((xx - 1) * grid, yy * grid, grid, grid); | |
| rect((xx - 1) * grid, (yy + 1) * grid, grid, grid); | |
| rect((xx + 1) * grid, (yy - 1) * grid, grid, grid); | |
| rect((xx + 1) * grid, yy * grid, grid, grid); | |
| rect((xx + 1) * grid, (yy + 1) * grid, grid, grid); | |
| rect(xx * grid, (yy - 1) * grid, grid, grid); | |
| rect(xx * grid, (yy + 1) * grid, grid, grid); | |
| for (a = 0; a < spacialHash.hashTable.length; a++) { | |
| for (let b = 0; b < spacialHash.hashTable[a].length; b++) { | |
| for (let c = 0; c < spacialHash.hashTable[a][b].length; c++) { | |
| fill(255); | |
| //check overlay | |
| if (useSpacialHash) { | |
| spacialHash.hashTable[a][b][c].checkOverlay( | |
| neighbors(spacialHash.hashTable, a, b) | |
| ); | |
| } else { | |
| spacialHash.hashTable[a][b][c].checkOverlay(boids); | |
| } | |
| // | |
| if (a >= yy - 1 && a <= yy + 1 && b >= xx - 1 && b <= xx + 1) { | |
| fill(51); | |
| } | |
| circle( | |
| spacialHash.hashTable[a][b][c].x, | |
| spacialHash.hashTable[a][b][c].y, | |
| diameter | |
| ); | |
| } | |
| } | |
| } | |
| fill(0, 0, 255); | |
| textSize(32); | |
| text(Math.round(frameRate())+"-"+counter, 10, 30); | |
| } | |
| class Boid { | |
| constructor(x, y) { | |
| this.x = x; | |
| this.y = y; | |
| this.direction = { x: Math.random() - 0.5, y: Math.random() - 0.5 }; | |
| this.w = canvasWidth; | |
| this.h = canvasHeight; | |
| } | |
| checkOverlay(parents) { | |
| parents = [].concat(...parents); | |
| for (let a = 0; a < parents.length; a++) { | |
| counter++; | |
| let disx = parents[a].x - this.x; | |
| let disy = parents[a].y - this.y; | |
| if (disx != 0 && disy != 0) { | |
| if (Math.hypot(disx, disy) < diameter) { | |
| fill(255, 0, 0); | |
| } | |
| } | |
| } | |
| } | |
| update() { | |
| this.x = this.x + this.direction.x; | |
| this.y = this.y + this.direction.y; | |
| if (this.x < diameter) { | |
| this.direction.x = -this.direction.x; | |
| this.x = diameter; | |
| } | |
| if (this.y < diameter) { | |
| this.direction.y = -this.direction.y; | |
| this.y = diameter; | |
| } | |
| if (this.x > this.w - diameter) { | |
| this.direction.x = -this.direction.x; | |
| this.x = this.w - diameter; | |
| } | |
| if (this.y > this.h - diameter) { | |
| this.direction.y = -this.direction.y; | |
| this.y = this.h - diameter; | |
| } | |
| } | |
| } | |
| class SpatialHash { | |
| constructor(bounds, gridSize) { | |
| this.gridSize = gridSize; | |
| this.hashTable = []; | |
| this.horizontal = Math.ceil(bounds.w / gridSize); | |
| this.vertical = Math.ceil(bounds.h / gridSize); | |
| for (let a = 0; a < this.vertical; a++) { | |
| this.hashTable.push([]); | |
| for (let b = 0; b < this.horizontal; b++) { | |
| this.hashTable[a].push([]); | |
| } | |
| } | |
| } | |
| clear() { | |
| for (let a = 0; a < this.vertical; a++) { | |
| for (let b = 0; b < this.horizontal; b++) { | |
| this.hashTable[a][b] = []; | |
| } | |
| } | |
| } | |
| insert(object) { | |
| this.hashTable[Math.floor(object.y / this.gridSize)][ | |
| Math.floor(object.x / this.gridSize) | |
| ].push(object); | |
| } | |
| find(point) { | |
| return this.hashTable; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| html, body { | |
| margin:0 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment