Skip to content

Instantly share code, notes, and snippets.

@enjalot
Last active August 29, 2015 14:25
Show Gist options
  • Save enjalot/247ea24faa3e69de6fe0 to your computer and use it in GitHub Desktop.
Save enjalot/247ea24faa3e69de6fe0 to your computer and use it in GitHub Desktop.
voronoi delaunay drawing
{"description":"voronoi delaunay drawing","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"points.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"state.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"ui.js":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/zc3ezCl.png","ajax-caching":true}
/*
Double click to add a point
Drag a point to move it around
Double click a point to remove it
*/
var geomPoints, voronoi, delaunay;
var svg = d3.select("svg").append("g")
var n = tributary.points.length;
var drag = d3.behavior.drag()
.on("drag", function(d,i) {
d.x += d3.event.dx;
d.y += d3.event.dy;
update();
})
.on("dragend", function() {
//save();
});
d3.select("svg").on("dblclick", function() {
var mouse = d3.mouse(this);
tributary.points.push({x: mouse[0], y: mouse[1], value: 10});
svg.selectAll("circle").remove()
svg.selectAll("path").remove();
update();
//save();
})
var path = d3.svg.line()
function update() {
process();
//draw voronoi
var vpaths = svg.selectAll("path.voronoi")
.data(voronoi)
vpaths.enter()
.append("path").classed("voronoi", true);
vpaths.exit().remove();
if(tributary.state.useV) {
vpaths.attr("d", path);
} else {
vpaths.remove();
//vpaths.attr("d", null);
}
//draw delaunay
var dpaths = svg.selectAll("path.delaunay")
.data(delaunay)
dpaths.enter()
.append("path").classed("delaunay", true)
dpaths.exit().remove();
if(tributary.state.useD) {
dpaths.attr("d", path);
} else {
dpaths.remove()
//dpaths.attr("d", null);
}
var circles = svg.selectAll("circle.point")
.data(tributary.points)
circles.enter()
.append("circle").classed("point", true)
.call(drag)
.on("dblclick", function(d) {
d3.event.cancelBubble = true;
var ind = tributary.points.indexOf(d);
tributary.points.splice(ind, 1);
n = tributary.points.length;
update();
//save();
})
circles.exit().remove();
circles
.attr({
cx: function(d) { return d.x },
cy: function(d) { return d.y },
r: 10
})
.each(function() {
this.parentNode.appendChild(this);
})
if(tributary.state.useP) {
circles.attr("opacity", 1);
} else {
circles.attr("opacity", 0);
}
}
update();
//progressively build out the voronoi/delaunay
//progressively draw the voronoi paths/delaunay
function process() {
geomPoints = tributary.points.map(function(d) {
return [d.x, d.y];
})
voronoi = d3.geom.voronoi(geomPoints);
delaunay = d3.geom.delaunay(geomPoints);
}
function save() {
var cm = tributary.getCodeEditor("points.json");
cm.setValue(JSON.stringify(tributary.points, null, 2));
cm = tributary.getCodeEditor("state.json");
cm.setValue(JSON.stringify(tributary.state, null, 2));
}
tributary.drawUI();
tributary.update = update;
tributary.save = save;
[
{
"x": 400,
"y": 616,
"value": 10
},
{
"x": 223,
"y": 443.8125,
"value": 10
},
{
"x": 511,
"y": 587.8125,
"value": 10
},
{
"x": 295,
"y": 171.8125,
"value": 10
},
{
"x": 564,
"y": 152.8125,
"value": 10
},
{
"x": 651,
"y": 225.8125,
"value": 10
},
{
"x": 437,
"y": 137.8125,
"value": 10
},
{
"x": 667,
"y": 450.8125,
"value": 10
},
{
"x": 692,
"y": 336.8125,
"value": 10
},
{
"x": 215,
"y": 296.8125,
"value": 10
},
{
"x": 395,
"y": 389.8125,
"value": 10
},
{
"x": 600,
"y": 532.8125,
"value": 10
},
{
"x": 294,
"y": 565.8125,
"value": 10
},
{
"x": 480,
"y": 342,
"value": 10
},
{
"x": 416,
"y": 324,
"value": 10
},
{
"x": 462,
"y": 403,
"value": 10
},
{
"x": 439,
"y": 361,
"value": 10
},
{
"x": 376,
"y": 192,
"value": 10
},
{
"x": 277,
"y": 258,
"value": 10
},
{
"x": 253,
"y": 376,
"value": 10
},
{
"x": 277,
"y": 482,
"value": 10
},
{
"x": 360,
"y": 575,
"value": 10
},
{
"x": 451,
"y": 581,
"value": 10
},
{
"x": 544,
"y": 546,
"value": 10
},
{
"x": 621,
"y": 485,
"value": 10
},
{
"x": 656,
"y": 386,
"value": 10
},
{
"x": 653,
"y": 290,
"value": 10
},
{
"x": 592,
"y": 205,
"value": 10
},
{
"x": 490,
"y": 176,
"value": 10
},
{
"x": 604,
"y": 423,
"value": 10
},
{
"x": 614,
"y": 343,
"value": 10
},
{
"x": 605,
"y": 258,
"value": 10
},
{
"x": 535,
"y": 208,
"value": 10
},
{
"x": 439,
"y": 203,
"value": 10
},
{
"x": 341,
"y": 233,
"value": 10
},
{
"x": 283,
"y": 325,
"value": 10
},
{
"x": 289,
"y": 425,
"value": 10
},
{
"x": 327,
"y": 491,
"value": 10
},
{
"x": 404,
"y": 531,
"value": 10
},
{
"x": 478,
"y": 522,
"value": 10
},
{
"x": 551,
"y": 475,
"value": 10
},
{
"x": 429,
"y": 408,
"value": 10
},
{
"x": 482,
"y": 375,
"value": 10
},
{
"x": 456,
"y": 318,
"value": 10
},
{
"x": 391,
"y": 352,
"value": 10
},
{
"x": 351,
"y": 440,
"value": 10
},
{
"x": 330,
"y": 373,
"value": 10
},
{
"x": 347,
"y": 303,
"value": 10
},
{
"x": 401,
"y": 260,
"value": 10
},
{
"x": 487,
"y": 253,
"value": 10
},
{
"x": 536,
"y": 289,
"value": 10
},
{
"x": 545,
"y": 359,
"value": 10
},
{
"x": 524,
"y": 422,
"value": 10
},
{
"x": 477,
"y": 461,
"value": 10
},
{
"x": 415,
"y": 472,
"value": 10
}
]
{
"useD": true,
"useV": true,
"useP": true
}
#display {
background-color: #000000
}
.voronoi {
fill: none;
pointer-events: none;
}
.voronoi, .voronoiButton {
stroke: #ffffff;
stroke-width: 3;
}
.delaunay {
fill: none;
pointer-events: none;
}
.delaunay, .delaunayButton {
stroke: #ffffff;
stroke-width: 3;
}
.point {
fill: #7183DD;
}
.point, .pointButton {
stroke: #7183DD;
stroke-width: 3;
}
.saveButton {
stroke: #ffffff;
stroke-width: 3;
}
text {
font-size: 14px;
fill: #ffffff;
pointer-events: none;
}
.selected {
stroke: #ffffff;
stroke-width: 1;
}
tributary.drawUI = function() {
var svg = d3.select("svg");
var bw = 114;
var bh = 20;
svg.append("rect")
.classed("voronoiButton", true)
.attr({
x: tributary.sw - bw - 10,
y: tributary.sh - 3*bh - 20,
width: bw,
height: bh
}).on("click", function(d,i) {
tributary.state.useV = !tributary.state.useV;
d3.select(".voronoiText").classed("selected", tributary.state.useV);
d3.event.cancelBubble = true;
tributary.update();
})
svg.append("text")
.text("show voronoi").classed("voronoiText", true)
.attr({
x: tributary.sw - bw + 2,
y: tributary.sh - 3*bh -5
});
svg.append("rect")
.classed("delaunayButton", true)
.attr({
x: tributary.sw - bw - 10,
y: tributary.sh - 2*bh - 15,
width: bw,
height: bh
}).on("click", function(d,i) {
tributary.state.useD = !tributary.state.useD;
d3.select(".delaunayText").classed("selected", tributary.state.useD)
d3.event.cancelBubble = true;
tributary.update();
})
svg.append("text")
.text("show delaunay").classed("delaunayText", true)
.attr({
x: tributary.sw - bw - 1,
y: tributary.sh - 2*bh -1
});
svg.append("rect")
.classed("pointButton", true)
.attr({
x: tributary.sw - bw - 10,
y: tributary.sh - bh - 10,
width: bw,
height: bh
}).on("click", function(d,i) {
tributary.state.useP = !tributary.state.useP;
d3.select(".pointsText").classed("selected", tributary.state.useP)
d3.event.cancelBubble = true;
tributary.update();
})
svg.append("text")
.text("show points").classed("pointsText", true)
.attr({
x: tributary.sw - bw + 9,
y: tributary.sh - bh + 4
});
svg.append("rect")
.classed("saveButton", true)
.attr({
x: 10,
y: tributary.sh - bh - 10,
width: bw,
height: bh
}).on("click", function(d,i) {
d3.event.cancelBubble = true;
tributary.save();
})
svg.append("text")
.classed("write", true)
.text("write to json")
.attr({
x: 27,
y: tributary.sh - bh + 4
});
d3.select(".pointsText").classed("selected", tributary.state.useP)
d3.select(".voronoiText").classed("selected", tributary.state.useV)
d3.select(".delaunayText").classed("selected", tributary.state.useD)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment