1 | <!DOCTYPE html>
|
---|
2 | <html>
|
---|
3 | <head>
|
---|
4 | <meta charset="UTF-8">
|
---|
5 | <title>Voronoi</title>
|
---|
6 | <link rel="stylesheet" href="../css/style.css">
|
---|
7 | <script type="text/javascript" src="../../dist/paper.js"></script>
|
---|
8 | <script type="text/javascript" src="http://jonathanpuckey.com/static/rhill-voronoi-core.js"></script>
|
---|
9 | <script type="text/paperscript" canvas="canvas">
|
---|
10 | var voronoi = new Voronoi();
|
---|
11 | var sites = generateBeeHivePoints(view.size / 200, true);
|
---|
12 | var bbox, diagram;
|
---|
13 | var oldSize = view.size;
|
---|
14 | var spotColor = new Color('red');
|
---|
15 | var mousePos = view.center;
|
---|
16 | var selected = false;
|
---|
17 |
|
---|
18 | onResize();
|
---|
19 |
|
---|
20 | function onMouseDown(event) {
|
---|
21 | sites.push(event.point);
|
---|
22 | renderDiagram();
|
---|
23 | }
|
---|
24 |
|
---|
25 | function onMouseMove(event) {
|
---|
26 | mousePos = event.point;
|
---|
27 | if (event.count == 0)
|
---|
28 | sites.push(event.point);
|
---|
29 | sites[sites.length - 1] = event.point;
|
---|
30 | renderDiagram();
|
---|
31 | }
|
---|
32 |
|
---|
33 | function renderDiagram() {
|
---|
34 | project.activeLayer.children = [];
|
---|
35 | var diagram = voronoi.compute(sites, bbox);
|
---|
36 | if (diagram) {
|
---|
37 | for (var i = 0, l = sites.length; i < l; i++) {
|
---|
38 | var cell = diagram.cells[sites[i].voronoiId];
|
---|
39 | if (cell) {
|
---|
40 | var halfedges = cell.halfedges,
|
---|
41 | length = halfedges.length;
|
---|
42 | if (length > 2) {
|
---|
43 | var points = [];
|
---|
44 | for (var j = 0; j < length; j++) {
|
---|
45 | v = halfedges[j].getEndpoint();
|
---|
46 | points.push(new Point(v));
|
---|
47 | }
|
---|
48 | createPath(points, sites[i]);
|
---|
49 | }
|
---|
50 | }
|
---|
51 | }
|
---|
52 | }
|
---|
53 | }
|
---|
54 |
|
---|
55 | function removeSmallBits(path) {
|
---|
56 | var averageLength = path.length / path.segments.length;
|
---|
57 | var min = path.length / 50;
|
---|
58 | for(var i = path.segments.length - 1; i >= 0; i--) {
|
---|
59 | var segment = path.segments[i];
|
---|
60 | var cur = segment.point;
|
---|
61 | var nextSegment = segment.next;
|
---|
62 | var next = nextSegment.point + nextSegment.handleIn;
|
---|
63 | if (cur.getDistance(next) < min) {
|
---|
64 | segment.remove();
|
---|
65 | }
|
---|
66 | }
|
---|
67 | }
|
---|
68 |
|
---|
69 | function generateBeeHivePoints(size, loose) {
|
---|
70 | var points = [];
|
---|
71 | var col = view.size / size;
|
---|
72 | for(var i = -1; i < size.width + 1; i++) {
|
---|
73 | for(var j = -1; j < size.height + 1; j++) {
|
---|
74 | var point = new Point(i, j) / new Point(size) * view.size + col / 2;
|
---|
75 | if(j % 2)
|
---|
76 | point += new Point(col.width / 2, 0);
|
---|
77 | if(loose)
|
---|
78 | point += (col / 4) * Point.random() - col / 4;
|
---|
79 | points.push(point);
|
---|
80 | }
|
---|
81 | }
|
---|
82 | return points;
|
---|
83 | }
|
---|
84 | function createPath(points, center) {
|
---|
85 | var path = new Path();
|
---|
86 | if (!selected) {
|
---|
87 | path.fillColor = spotColor;
|
---|
88 | } else {
|
---|
89 | path.fullySelected = selected;
|
---|
90 | }
|
---|
91 | path.closed = true;
|
---|
92 |
|
---|
93 | for (var i = 0, l = points.length; i < l; i++) {
|
---|
94 | var point = points[i];
|
---|
95 | var next = points[(i + 1) == points.length ? 0 : i + 1];
|
---|
96 | var vector = (next - point) / 2;
|
---|
97 | path.add({
|
---|
98 | point: point + vector,
|
---|
99 | handleIn: -vector,
|
---|
100 | handleOut: vector
|
---|
101 | });
|
---|
102 | }
|
---|
103 | path.scale(0.95);
|
---|
104 | removeSmallBits(path);
|
---|
105 | return path;
|
---|
106 | }
|
---|
107 |
|
---|
108 | function onResize() {
|
---|
109 | var margin = 20;
|
---|
110 | bbox = {
|
---|
111 | xl: margin,
|
---|
112 | xr: view.bounds.width - margin,
|
---|
113 | yt: margin,
|
---|
114 | yb: view.bounds.height - margin
|
---|
115 | };
|
---|
116 | for (var i = 0, l = sites.length; i < l; i++) {
|
---|
117 | sites[i] = sites[i] * view.size / oldSize;
|
---|
118 | }
|
---|
119 | oldSize = view.size;
|
---|
120 | renderDiagram();
|
---|
121 | }
|
---|
122 |
|
---|
123 | function onKeyDown(event) {
|
---|
124 | if (event.key == 'space') {
|
---|
125 | selected = !selected;
|
---|
126 | renderDiagram();
|
---|
127 | }
|
---|
128 | }
|
---|
129 | </script>
|
---|
130 | </head>
|
---|
131 | <body>
|
---|
132 | <canvas id="canvas" resize></canvas>
|
---|
133 | </body>
|
---|
134 | </html> |
---|