Finding immediate neighbors of a point (within k
distance/size), in a n x n
grid.
Last active
May 14, 2016 23:38
-
-
Save saifuddin778/447ce023b561e09d075807cbec476f56 to your computer and use it in GitHub Desktop.
Grid Neighborhood
This file contains 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
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
text-align: center; | |
font-family: monospace !important; | |
} | |
#n_picker { | |
display: inline-block; | |
vertical-align: top; | |
text-align: left; | |
} | |
#neighborhood { | |
width: 200px; | |
height: 100px; | |
text-align: left; | |
margin-top: 20px; | |
} | |
</style> | |
<body> | |
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<script> | |
var ntypes = { | |
square: square, | |
up_triangle: up_triangle, | |
down_triangle: down_triangle, | |
diamond: diamond, | |
butterfly_left: butterfly_left, | |
butterfly_right: butterfly_right, | |
chess: chess, | |
}; | |
function static_(obj) { | |
var statik = d3.selectAll("rect") | |
.filter(function(d) { | |
return d.x >= obj.min_x - 1 && d.x <= obj.max_x + 1 //to cover those decimals | |
}) | |
.filter(function(d) { | |
return d.y >= obj.min_y - 1 && d.y <= obj.max_y + 1 //to cover those decimals | |
}) | |
.filter(function(d) { | |
return d.p != obj.p_i; | |
}); | |
return statik; | |
} | |
function chess(obj) { | |
//picks chess neighborhood associated with a point | |
var neighbors = static_(obj).filter(function(d, i) { | |
return (i % 2 == 1) | |
}); | |
return neighbors; | |
} | |
function square(obj) { | |
//picks square neighborhood associated with a point | |
var neighbors = static_(obj); | |
return neighbors; | |
} | |
function butterfly_right(obj) { | |
//picks the right-butterfly neighborhood associated with a point | |
var r = {}; | |
d3.range(nn + 1).map(function(d, i) { | |
var yu = obj.p_y - (nh * (nn - i)); | |
var yd = obj.p_y + (nh * (nn - i)); | |
for (var k = 0; k < i + 1; k++) { | |
var xl = obj.p_x - (k * pad); | |
var xr = obj.p_x + (k * pad); | |
r[xl + "-" + yu] = true; | |
r[xr + "-" + yd] = true; | |
} | |
}); | |
var neighbors = static_(obj).filter(function(d) { | |
return (d.x + '-' + d.y in r); | |
}); | |
return neighbors; | |
} | |
function butterfly_left(obj) { | |
//picks the left-butterfly neighborhood associated with a point | |
var r = {}; | |
d3.range(nn + 1).map(function(d, i) { | |
var yu = obj.p_y - (nh * (nn - i)); | |
var yd = obj.p_y + (nh * (nn - i)); | |
for (var k = 0; k < i + 1; k++) { | |
var xl = obj.p_x - (k * pad); | |
var xr = obj.p_x + (k * pad); | |
r[xr + "-" + yu] = true; | |
r[xl + "-" + yd] = true; | |
} | |
}); | |
var neighbors = static_(obj).filter(function(d) { | |
return (d.x + '-' + d.y in r); | |
}); | |
return neighbors; | |
} | |
function diamond(obj) { | |
//picks diamond neighborhood associated with a point | |
var r = {}; | |
d3.range(nn + 1).map(function(d, i) { | |
var yu = obj.p_y - (nh * (nn - i)); | |
var yd = obj.p_y + (nh * (nn - i)); | |
for (var k = 0; k < i + 1; k++) { | |
var xl = obj.p_x - (k * pad); | |
var xr = obj.p_x + (k * pad); | |
r[xl + "-" + yu] = true; | |
r[xr + "-" + yu] = true; | |
r[xl + "-" + yd] = true; | |
r[xr + "-" + yd] = true; | |
} | |
}); | |
var neighbors = static_(obj).filter(function(d) { | |
return (d.x + '-' + d.y in r); | |
}); | |
return neighbors; | |
} | |
function down_triangle(obj) { | |
//picks down triangular neighborhood associated with a point | |
var r = {}; | |
d3.range(nn + 1).map(function(d, i) { | |
var y = obj.p_y + (nh * (nn - i)); | |
for (var k = 0; k < i + 1; k++) { | |
var xl = obj.p_x - (k * pad); | |
var xr = obj.p_x + (k * pad); | |
r[xl + "-" + y] = true; | |
r[xr + "-" + y] = true; | |
} | |
}); | |
var neighbors = static_(obj).filter(function(d) { | |
return (d.x + '-' + d.y in r); | |
}); | |
return neighbors; | |
} | |
function up_triangle(obj) { | |
//picks upper triangular neighborhood associated with a point | |
var r = {}; | |
d3.range(nn + 1).map(function(d, i) { | |
var y = obj.p_y - (nh * (nn - i)); | |
for (var k = 0; k < i + 1; k++) { | |
var xl = obj.p_x - (k * pad); | |
var xr = obj.p_x + (k * pad); | |
r[xl + "-" + y] = true; | |
r[xr + "-" + y] = true; | |
} | |
}); | |
var neighbors = static_(obj).filter(function(d) { | |
return (d.x + '-' + d.y in r); | |
}); | |
return neighbors; | |
} | |
var width = 500; | |
var height = 500; | |
//number of boxes per row | |
var row = 50; | |
//size of the grid | |
var n = row * row; | |
//width and height of each box | |
var nw = width / row, | |
nh = height / row; | |
//padding between each box | |
var pad = (width / row); | |
//begin y from negative so that the first box is 0, 0 | |
var x = 0; | |
var y = 0 - pad; | |
var nn = 1; | |
var colors_ = d3.scale | |
.linear() | |
.interpolate(d3.interpolateHcl) | |
.domain([0, n]) | |
.range(["lightblue", "green"]); | |
var nodes = d3.range(n).map(function(d, i) { | |
//grid creation | |
x = pad * (i % row); | |
if (i % row == 0) { | |
y += pad; | |
} | |
return { | |
x: x, | |
y: y, | |
p: i + 1, | |
r_i: i % row, | |
color: "#1E8BC3" //colors_(i) | |
}; | |
}); | |
var svg = d3.select('body') | |
.append('svg') | |
.attr('width', width) | |
.attr('height', height); | |
var g = svg.append("g") | |
.attr('id', 'scope') | |
.attr("transform", "translate(0,0)"); | |
var points = g.selectAll('.nodes') | |
.data(nodes) | |
.enter() | |
.append("rect") | |
.attr("x", function(d) { | |
return d.x | |
}) | |
.attr("y", function(d) { | |
return d.y | |
}) | |
.attr("width", nw) | |
.attr("height", nh) | |
.style("stroke", "white") | |
.style("fill", function(d) { | |
return d.color | |
}); | |
points.on('mouseover', function(d) { | |
d3.selectAll('rect').style("fill", function(d) { | |
return d.color | |
}); | |
d3.select(this).style("fill", "red"); | |
var obj = { | |
p_i: d.p, | |
p_x: d.x, | |
p_y: d.y, | |
min_x: d.x, | |
min_y: d.y, | |
max_x: d.x, | |
max_y: d.y, | |
}; | |
var n_items = d3.range(1, nn + 1); | |
for (var i = 0; i < n_items.length; i++) { | |
var k = n_items[i]; | |
var nxmin = Math.floor(obj.p_x - (pad * k)); | |
var nxmax = Math.ceil(obj.p_x + (pad * k)); | |
var nymin = Math.floor(obj.p_y - (pad * k)); | |
var nymax = Math.ceil(obj.p_y + (pad * k)); | |
if (nxmin < obj.min_x) { | |
obj.min_x = nxmin; | |
} | |
if (nxmax > obj.max_x) { | |
obj.max_x = nxmax; | |
} | |
if (nymin < obj.min_y) { | |
obj.min_y = nymin; | |
} | |
if (nymax > obj.max_y) { | |
obj.max_y = nymax; | |
} | |
} | |
var ntype = $('input[name="ntype"]:checked').val(); | |
var neighbors = ntypes[ntype](obj); | |
neighbors.style("fill", "#87D37C"); | |
d3.event.stopPropagation(); | |
return false; | |
}); | |
</script> | |
<div id='n_picker'> | |
<b>Size</b> | |
<select id="n_neighbors"></select> | |
<div id="neighborhood"> | |
<b>Neighborhood</b> | |
</br> | |
<p><input name="ntype" type="radio" value="square" checked>square</input> | |
</p> | |
<p><input name="ntype" type="radio" value="chess">chess</input> | |
</p> | |
<p><input name="ntype" type="radio" value="up_triangle">triangle (up)</input> | |
</p> | |
<p><input name="ntype" type="radio" value="down_triangle">triange (down)</input> | |
</p> | |
<p><input name="ntype" type="radio" value="diamond">diamond</input> | |
</p> | |
<p><input name="ntype" type="radio" value="butterfly_left">butterfly (left)</input> | |
</p> | |
<p><input name="ntype" type="radio" value="butterfly_right">butterfly (right)</input> | |
</p> | |
</div> | |
</div> | |
<script> | |
var limit = row / 3; | |
for (var i = 0; i <= limit; i++) { | |
if (i == nn) { | |
var opt = "<option value=" + i + " selected>" + i + "</option>"; | |
} else { | |
var opt = "<option value=" + i + ">" + i + "</option>"; | |
} | |
$("#n_neighbors").append(opt); | |
} | |
$("#n_neighbors").change(function(e) { | |
nn = +this.value; | |
}); | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment