Created
September 16, 2017 00:57
-
-
Save timetocode/0750ed05b524d5fe0106f32947afb42e to your computer and use it in GitHub Desktop.
spatial rid w/ raycast as a search option (can fill the grid with objects or arrays instead of a specific value)
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
function length(x,y) { | |
return Math.sqrt((x * x) + (y * y)) | |
} | |
function norm(x ,y) { | |
var len = length(x, y) | |
if (len > 0) { | |
return { x: x/len, y: y/len } | |
} else { | |
return { x: 0, y: 0 } | |
} | |
} | |
class Grid { | |
constructor(width, height, defaultValue) { | |
// console.log('defaultValue', defaultValue) | |
var value = 0 | |
if (typeof defaultValue !== 'undefined') { | |
value = defaultValue | |
} | |
this.width = width | |
this.height = height | |
this.cells = [] | |
for (var i = 0; i < this.width * this.height; i++) { | |
if (value !== 0) { | |
this.cells.push(value) | |
} else { | |
this.cells.push(0) | |
} | |
} | |
} | |
static fromData(width, height, arrayOfValues) { | |
} | |
// converts 2D coords to 1D index | |
getIndex(x, y) { | |
return x + this.width * y | |
} | |
// converts 1D index to 2D coords | |
getXY(index) { | |
return { | |
x: index % this.width, | |
y: Math.floor(index / this.width) | |
} | |
} | |
boundsCheck(x, y) { | |
// probably off by 1, untested | |
return (x >= 0 && x <= this.width && y >= 0 && y <= this.height) | |
} | |
set(x, y, value) { | |
if (!this.boundsCheck(x,y)) { | |
return // perhaps warn rather than silently fail? | |
} | |
//console.log('new value', value) | |
this.cells[this.getIndex(x, y)] = value | |
} | |
get(x, y) { | |
if (!this.boundsCheck(x,y)) { | |
return // perhaps warn rather than silently fail? | |
} | |
return this.cells[this.getIndex(x, y)] | |
} | |
toKeyArray() { | |
var arr = [] | |
for (var i = 0; i < this.cells.length; i++) { | |
if (this.cells[i] === 0) { | |
arr.push(0) | |
} else { | |
arr.push(this.cells[i].key) | |
} | |
} | |
return arr | |
} | |
// searchFunc is passed the value of the grid at each tile visited along the ray | |
// searchFunc must return true if the ray should continue or false if the ray should terminate | |
searchRay(x1, y1, x2, y2, maxLength, searchFunc) { | |
// grid width | |
var dim = 1 | |
var lengthSoFar = 0 | |
//maxLength = length(x2 - x1, y2 - y1) | |
// direction and magnitude | |
var dx = x2 - x1 | |
var dy = y2 - y1 | |
// direction, normalized | |
var rayDir = norm(dx, dy) | |
// grid coordinates for start of the ray | |
var gx = Math.floor(x1 / dim) | |
var gy = Math.floor(y1 / dim) | |
// directionality | |
var stepX = (dx > 0) ? 1 : -1 | |
var stepY = (dy > 0) ? 1 : -1 | |
// distance to next cell | |
var tMaxX = 99999 | |
var tMaxY = 99999 | |
var tDeltaX = 0 | |
var tDeltaY = 0 | |
if (rayDir.x < 0) { | |
tMaxX = (gx * dim - x1) / rayDir.x | |
tDeltaX = dim / -rayDir.x | |
} else if (rayDir.x > 0) { | |
tMaxX = ((gx+1) * dim - x1) / rayDir.x | |
tDeltaX = dim / rayDir.x | |
} | |
if (rayDir.y < 0) { | |
tMaxY = (gy * dim - y1) / rayDir.y | |
tDeltaY = dim / -rayDir.y | |
} else if (rayDir.y > 0) { | |
tMaxY = ((gy+1) * dim - y1) / rayDir.y | |
tDeltaY = dim / rayDir.y | |
} | |
var i = 0 | |
var cache = {} | |
var objectsNearRay = [] | |
while (i < 9999) { | |
var cell = this.get(gx, gy) | |
//console.log('lengthSoFar', lengthSoFar) | |
var continueSearching = searchFunc(cell, gx, gy) | |
if (!continueSearching) { | |
return | |
} | |
if (tMaxX < tMaxY) { | |
tMaxX += tDeltaX | |
gx += stepX | |
} else { | |
tMaxY += tDeltaY | |
gy += stepY | |
} | |
i++ | |
} | |
} | |
} | |
module.exports = Grid |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment