2013-03-02 14:58:09 -05:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
2014-08-16 13:24:54 -04:00
|
|
|
<meta charset="UTF-8">
|
|
|
|
<title>Voronoi</title>
|
|
|
|
<link rel="stylesheet" href="../css/style.css">
|
|
|
|
<script type="text/javascript" src="../../dist/paper-full.js"></script>
|
2016-01-27 05:56:26 -05:00
|
|
|
<script type="text/javascript" src="http://paperjs.org/assets/js/rhill-voronoi-core.js"></script>
|
2014-08-16 13:24:54 -04:00
|
|
|
<script type="text/paperscript" canvas="canvas">
|
2016-02-10 10:15:35 -05:00
|
|
|
var voronoi = new Voronoi();
|
2014-08-16 13:24:54 -04:00
|
|
|
var sites = generateBeeHivePoints(view.size / 200, true);
|
|
|
|
var bbox, diagram;
|
|
|
|
var oldSize = view.size;
|
|
|
|
var spotColor = new Color('red');
|
|
|
|
var mousePos = view.center;
|
|
|
|
var selected = false;
|
2013-03-02 14:58:09 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
onResize();
|
2013-03-02 14:58:09 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
function onMouseDown(event) {
|
|
|
|
sites.push(event.point);
|
|
|
|
renderDiagram();
|
|
|
|
}
|
2013-03-02 14:58:09 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
function onMouseMove(event) {
|
|
|
|
mousePos = event.point;
|
|
|
|
if (event.count == 0)
|
|
|
|
sites.push(event.point);
|
|
|
|
sites[sites.length - 1] = event.point;
|
|
|
|
renderDiagram();
|
|
|
|
}
|
2013-03-02 14:58:09 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
function renderDiagram() {
|
2016-02-23 05:59:59 -05:00
|
|
|
project.activeLayer.removeChildren();
|
2014-08-16 13:24:54 -04:00
|
|
|
var diagram = voronoi.compute(sites, bbox);
|
|
|
|
if (diagram) {
|
|
|
|
for (var i = 0, l = sites.length; i < l; i++) {
|
|
|
|
var cell = diagram.cells[sites[i].voronoiId];
|
|
|
|
if (cell) {
|
|
|
|
var halfedges = cell.halfedges,
|
|
|
|
length = halfedges.length;
|
|
|
|
if (length > 2) {
|
|
|
|
var points = [];
|
|
|
|
for (var j = 0; j < length; j++) {
|
|
|
|
v = halfedges[j].getEndpoint();
|
|
|
|
points.push(new Point(v));
|
|
|
|
}
|
|
|
|
createPath(points, sites[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-03-02 14:58:09 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
function removeSmallBits(path) {
|
|
|
|
var averageLength = path.length / path.segments.length;
|
|
|
|
var min = path.length / 50;
|
2017-04-22 12:50:53 -04:00
|
|
|
for (var i = path.segments.length - 1; i >= 0; i--) {
|
2014-08-16 13:24:54 -04:00
|
|
|
var segment = path.segments[i];
|
|
|
|
var cur = segment.point;
|
|
|
|
var nextSegment = segment.next;
|
|
|
|
var next = nextSegment.point + nextSegment.handleIn;
|
|
|
|
if (cur.getDistance(next) < min) {
|
|
|
|
segment.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-03-02 14:58:09 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
function generateBeeHivePoints(size, loose) {
|
|
|
|
var points = [];
|
|
|
|
var col = view.size / size;
|
2017-04-22 12:50:53 -04:00
|
|
|
for (var i = -1; i < size.width + 1; i++) {
|
|
|
|
for (var j = -1; j < size.height + 1; j++) {
|
2014-08-16 13:24:54 -04:00
|
|
|
var point = new Point(i, j) / new Point(size) * view.size + col / 2;
|
|
|
|
if (j % 2)
|
|
|
|
point += new Point(col.width / 2, 0);
|
|
|
|
if (loose)
|
|
|
|
point += (col / 4) * Point.random() - col / 4;
|
|
|
|
points.push(point);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return points;
|
|
|
|
}
|
|
|
|
function createPath(points, center) {
|
|
|
|
var path = new Path();
|
|
|
|
if (!selected) {
|
|
|
|
path.fillColor = spotColor;
|
|
|
|
} else {
|
|
|
|
path.fullySelected = selected;
|
|
|
|
}
|
|
|
|
path.closed = true;
|
2013-03-02 14:58:09 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
for (var i = 0, l = points.length; i < l; i++) {
|
|
|
|
var point = points[i];
|
|
|
|
var next = points[(i + 1) == points.length ? 0 : i + 1];
|
|
|
|
var vector = (next - point) / 2;
|
|
|
|
path.add({
|
|
|
|
point: point + vector,
|
|
|
|
handleIn: -vector,
|
|
|
|
handleOut: vector
|
|
|
|
});
|
|
|
|
}
|
|
|
|
path.scale(0.95);
|
|
|
|
removeSmallBits(path);
|
|
|
|
return path;
|
|
|
|
}
|
2013-03-02 14:58:09 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
function onResize() {
|
|
|
|
var margin = 20;
|
|
|
|
bbox = {
|
|
|
|
xl: margin,
|
|
|
|
xr: view.bounds.width - margin,
|
|
|
|
yt: margin,
|
|
|
|
yb: view.bounds.height - margin
|
|
|
|
};
|
|
|
|
for (var i = 0, l = sites.length; i < l; i++) {
|
|
|
|
sites[i] = sites[i] * view.size / oldSize;
|
|
|
|
}
|
|
|
|
oldSize = view.size;
|
|
|
|
renderDiagram();
|
|
|
|
}
|
2013-03-02 14:58:09 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
function onKeyDown(event) {
|
|
|
|
if (event.key == 'space') {
|
|
|
|
selected = !selected;
|
|
|
|
renderDiagram();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
2013-03-02 14:58:09 -05:00
|
|
|
</head>
|
|
|
|
<body>
|
2014-08-16 13:24:54 -04:00
|
|
|
<canvas id="canvas" resize></canvas>
|
2013-03-02 14:58:09 -05:00
|
|
|
</body>
|
2014-04-06 07:44:19 -04:00
|
|
|
</html>
|