Skip to content

Instantly share code, notes, and snippets.

@shimizu
Last active July 27, 2016 03:06
Show Gist options
  • Save shimizu/e88fbc94cb43acddebdaaebed8931fc7 to your computer and use it in GitHub Desktop.
Save shimizu/e88fbc94cb43acddebdaaebed8931fc7 to your computer and use it in GitHub Desktop.
重み付けボロノイ図
<!DOCTYPE html>
<meta charset="utf-8">
<title>加重ボロノイ分割テスト</title>
<style>
svg {
width: 449px;
height: 500px;
}
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
</style>
<body>
<svg id="normal"></svg>
<svg id="power"></svg>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
(function(){
var w = 449;
var h = 500;
var padding = 30;
var pointLength = 25;
var dataset = [];
var normalLayer = d3.select("#normal").append("g")
.attr("width", w)
.attr("height", h)
var powerLayer = d3.select("#power").append("g")
.attr("width", w)
.attr("height", h)
for(var x = 0; x < pointLength/2; x++){
for(var y = 0; y < pointLength/2; y++){
var newNumber1 = x * 10 + 5;
var newNumber2 = y * 10 + 5;
var r = Math.floor(Math.random() * 100)
dataset.push({x:newNumber1, y:newNumber2, r:r})
}
}
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d.x; })])
.range([padding, w - padding * 2]);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d.y; })])
.range([h - padding, padding]);
var rScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d.r; })])
.range([2, 10]);
dataset.forEach(function(d) { d.cx = d.x; d.cy = d.y; d.r = rScale(d.r) });
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(5);
var voronoi = d3.geom.voronoi()
.x(function(d){ return xScale(d.x) })
.y(function(d){ return yScale(d.y) })
.clipExtent([[padding,padding/2],[w - (padding + (padding/2)),h - padding]])
drawCharts(normalLayer, false)
drawCharts(powerLayer, true)
function drawCharts(layer, flag) {
var cell = layer.selectAll("g")
.data(dataset)
.enter()
.append('g');
cell.append("circle")
.attr("cx", function(d) {
return xScale(d.x);
})
.attr("cy", function(d) {
return yScale(d.y);
})
.attr("r", function(d) {
return d.r;
})
if(flag) dataset.forEach(weight(.2, dataset))
var pathArray = voronoi(dataset);
cell.append("svg:path")
.attr("class", "cell")
.attr({
"class":"cell",
"d":function(d, i) { return "M" + pathArray[i].join("L") + "Z"},
stroke:"#FF1493",
fill:"white",
"fill-opacity": 0.4
})
layer.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
layer.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
}
})();
// reference:http://bl.ocks.org/nitaku/616c4ef99f71d3dab203
function weight(value, nodes) {
var maxRadius = 30
var padding = 2
var quadtree = d3.geom.quadtree(nodes);
return function(d) {
var r = d.r + maxRadius + padding
var nx1 = d.x - r
var nx2 = d.x + r
var ny1 = d.y - r
var ny2 = d.y + r
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x
var y = d.y - quad.point.y
var l = Math.sqrt(x * x + y * y)
var r = d.r + quad.point.r + padding
if (l < r) {
l = (l - r) / l * value
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x
quad.point.y += y
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1
})
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment