Built with blockbuilder.org
Last active
August 25, 2017 09:22
-
-
Save ddramone/5db5cf87f906beb9a01e924dabffecf7 to your computer and use it in GitHub Desktop.
voronoi knn
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
license: mit |
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
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
.links { | |
stroke: #000; | |
stroke-opacity: 0.2; | |
} | |
.polygons { | |
fill: none; | |
stroke: #000; | |
} | |
</style> | |
<svg width="960" height="500"></svg> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
console.clear(); | |
var svg = d3.select("svg"), | |
width = +svg.attr("width"), | |
height = +svg.attr("height"); | |
/** DUMB DATA **/ | |
var sites = d3.range(200) | |
.map(function(d) { | |
var x = Math.random() * (width - 80) + 40; | |
var y = Math.random() * (height-80) + 40; | |
return { | |
x: x, | |
y: y, | |
id: 'luminiare'+Math.random() | |
}; | |
}).filter((point)=>{ | |
var x = point.x; | |
var y = point.y; | |
xInRange = x>200 && x<600; | |
yInRange = y<400; | |
return !(xInRange && yInRange); | |
}); | |
var voronoi = d3.voronoi() | |
.x((d)=>d.x) | |
.y((d)=>d.y) | |
.extent([[0, 0], [width, height]]); | |
var diagram = voronoi(sites); | |
var links = diagram.links(); | |
var averageDistance = getAverageDistance(); | |
var radius = svg.append("g") | |
.attr("class", "spread"); | |
var polygon = svg.append("g") | |
.attr("class", "polygons") | |
.selectAll("path") | |
.data(voronoi.polygons(sites)) | |
.enter().append("path") | |
.attr('stroke','cyan') | |
.call(redrawPolygon); | |
var circles = svg.append("g") | |
.attr("class", "circles") | |
.selectAll('circle') | |
.data(sites) | |
.enter().append('circle') | |
.attr('r', 10) | |
.attr('fill',function(d){ | |
return 'red'; | |
}) | |
.attr("cy", (d)=> d.y) | |
.attr("cx", (d)=> d.x) | |
.on("click", findNeighbours) | |
.on("mouseenter", showRadius) | |
function showRadius(){ | |
var cell = findCell(d3.mouse(this)); | |
radius.selectAll('circle').remove(); | |
radius | |
.append('circle') | |
.attr('r', averageDistance) | |
.attr("cy", cell.data.y) | |
.attr("cx", cell.data.x) | |
.attr('stroke','blue') | |
.attr('fill','#fffbea'); | |
} | |
var highlighted = []; | |
function findCell(m) { | |
return diagram.find(m[0],m[1]) | |
} | |
function findNeighbours() { | |
var cell = findCell(d3.mouse(this)); | |
var cellData = diagram.cells[cell.index]; | |
cell.data.status = 'localized'; | |
for(var edgeIndex of cellData.halfedges) | |
{ | |
var edge = diagram.edges[edgeIndex]; | |
var neighbour = edge.left == cell ? edge.right : edge.left; | |
if(!neighbour) continue; | |
if(neighbour.data.status == 'localized') continue; | |
var tP = neighbour.data; // target Point | |
var sP = cell.data; // source Point | |
var distance = Math.sqrt( | |
(Math.pow(tP.x-sP.x,2))+ | |
(Math.pow(tP.y-sP.y,2))) | |
if(distance < averageDistance){ | |
neighbour.data.status = 'highlighted'; | |
} | |
// break; | |
} | |
redraw(); | |
} | |
function redraw() { | |
circles.data(sites) | |
.attr('fill',function(d){ | |
return { | |
localized: 'blue', | |
highlighted: 'green' | |
}[d.status] || 'red' | |
}) | |
} | |
function redrawPolygon(polygon) { | |
polygon | |
.attr("d", function(d) { return d ? "M" + d.join("L") + "Z" : null; }); | |
} | |
function getAverageDistance() { | |
var distances = links.map(function(d) { | |
return Math.sqrt( | |
Math.pow(d.target.x - d.source.x,2) + | |
Math.pow(d.target.y - d.source.y,2) | |
); | |
}); | |
var max = d3.max(distances); | |
var min = d3.min(distances); | |
var mean = d3.mean(distances); | |
return max-(max-mean)/2; | |
return (max+mean)/2; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment