Skip to content
Browse files

Generate Delaunay from Voronoi.

  • Loading branch information...
1 parent 841f354 commit bcf37e4a66c55d53eeb9263097c6120633baf6aa @mbostock committed
Showing with 109 additions and 186 deletions.
  1. +6 −5 examples/delaunay/delaunay.html
  2. +0 −120 examples/delaunay/delaunay.js
  3. +3 −0 examples/index.html
  4. +87 −53 lib/jit/voronoi.js
  5. +9 −8 lib/jit/voronoi.min.js
  6. +4 −0 src/externs.js
View
11 examples/delaunay/delaunay.html
@@ -4,7 +4,7 @@
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Delaunay Triangulation</title>
<script type="text/javascript" src="../../d3.js"></script>
- <script type="text/javascript" src="delaunay.js"></script>
+ <script type="text/javascript" src="../../lib/jit/voronoi.min.js"></script>
<style type="text/css">
@import url("../../lib/colorbrewer/colorbrewer.css");
@@ -22,8 +22,8 @@
var w = 960,
h = 500;
-var vertices = d3.range(500).map(function() {
- return [~~(w * Math.random()), ~~(h * Math.random())];
+var vertices = d3.range(500).map(function(d) {
+ return [Math.random() * w, Math.random() * h];
});
var svg = d3.select("body")
@@ -32,11 +32,12 @@
.attr("height", h)
.attr("class", "PiYG");
-svg.selectAll("path")
+svg.append("svg:g")
+ .selectAll("path")
.data(delaunay(vertices))
.enter("svg:path")
.attr("class", function(d, i) { return "q" + (i % 9) + "-9"; })
- .attr("d", function(d) { return "M" + d[0] + "L" + d[1] + "L" + d[2] + "Z"; });
+ .attr("d", function(d) { return "M" + d.join("L") + "Z"; });
</script>
</body>
View
120 examples/delaunay/delaunay.js
@@ -1,120 +0,0 @@
-// Based on work by:
-// Mike Migurski - mike.teczno.com/notes/canvas-warp.html
-// Joshua Bell - travellermap.com/tmp/delaunay.htm
-// Sjaak Priester - codeguru.com/cpp/data/mfc_database/misc/article.php/c8901
-// Joseph O'Rourke - exaflop.org/docs/cgafaq/cga1.html
-
-function delaunay(vertices) {
- var bounds = delaunay_bounds(vertices),
- boundsMap = {},
- circumcircles = [delaunay_circumcircle(bounds)],
- triangles = [bounds];
- boundsMap[bounds[0]] = 1;
- boundsMap[bounds[1]] = 1;
- boundsMap[bounds[2]] = 1;
-
- // For each vertex…
- vertices.forEach(function(vertex) {
- var edgesMap = {},
- edges = [];
-
- // Remove triangles whose circumcircle contains the vertex.
- for (var i in triangles) {
- if (circumcircles[i](vertex)) {
- var triangle = triangles[i];
- addEdge(triangle[0], triangle[1]);
- addEdge(triangle[1], triangle[2]);
- addEdge(triangle[2], triangle[0]);
- delete circumcircles[i];
- delete triangles[i];
- }
- }
-
- // Add the specified edge. If it's already present, delete it!
- function addEdge(v0, v1) {
- var edge = (v0[0] > v1[0]) || (v0[0] == v1[0] && v0[1] > v1[1])
- ? [v1, v0]
- : [v0, v1];
- if (edge in edgesMap) delete edges[edgesMap[edge]];
- else edgesMap[edge] = edges.push(edge) - 1;
- }
-
- // Add triangles for each remaining edge and the new vertex.
- for (var i in edges) {
- var edge = edges[i],
- triangle = [edge[0], edge[1], vertex];
- circumcircles.push(delaunay_circumcircle(triangle));
- triangles.push(triangle);
- }
- });
-
- // Remove triangles that share a vertex with the bounds.
- // The filter also removes any triangles we deleted previously.
- return triangles.filter(function(triangle) {
- return !triangle.some(function(vertex) {
- return vertex in boundsMap;
- });
- });
-}
-
-function delaunay_bounds(vertices) {
- var minX = Infinity,
- minY = Infinity,
- maxX = -Infinity,
- maxY = -Infinity,
- dx,
- dy;
- for (var i = 0, n = vertices.length; i < n; i++) {
- var vertex = vertices[i];
- if (vertex[0] < minX) minX = vertex[0];
- if (vertex[0] > maxX) maxX = vertex[0];
- if (vertex[1] < minY) minY = vertex[1];
- if (vertex[1] > maxY) maxY = vertex[1];
- }
- dx = (maxX - minX) * 10;
- dy = (maxY - minX) * 10;
- return [
- [minX - dx, minY - dy * 3],
- [minX - dx, maxY + dy],
- [maxX + dx * 3, maxY + dy]
- ];
-}
-
-function delaunay_circumcircle(triangle) {
- var v0 = triangle[0],
- v1 = triangle[1],
- v2 = triangle[2],
- A = v1[0] - v0[0],
- B = v1[1] - v0[1],
- C = v2[0] - v0[0],
- D = v2[1] - v0[1],
- E = A * (v0[0] + v1[0]) + B * (v0[1] + v1[1]),
- F = C * (v0[0] + v2[0]) + D * (v0[1] + v2[1]),
- G = 2 * (A * (v2[1] - v1[1]) - B * (v2[0] - v1[0])),
- cx,
- cy,
- dx,
- dy,
- r2;
-
- // If collinear, find extremes and use the midpoint.
- if (Math.abs(G) < 1e-6) {
- var minX = Math.min(v0[0], v1[0], v2[0]),
- minY = Math.min(v0[1], v1[1], v2[1]),
- maxX = Math.max(v0[0], v1[0], v2[0]),
- maxY = Math.max(v0[1], v1[1], v2[1]);
- dx = (cx = (minX + maxX) / 2) - minX;
- dy = (cy = (minY + maxY) / 2) - minY;
- } else {
- dx = (cx = (D * E - B * F) / G) - v0[0];
- dy = (cy = (A * F - C * E) / G) - v0[1];
- }
- r2 = dx * dx + dy * dy;
-
- return function(vertex) {
- var dx = cx - vertex[0],
- dy = cy - vertex[1],
- d2 = dx * dx + dy * dy;
- return d2 <= r2;
- };
-}
View
3 examples/index.html
@@ -12,6 +12,7 @@
<li><a href="calendar/dji.html">calendar-dji</a></li>
<li><a href="calendar/vix.html">calendar-vix</a></li>
<li><a href="choropleth/choropleth.html">choropleth</a></li>
+ <li><a href="delaunay/delaunay.html">delaunay</a></li>
<li><a href="donut/donut.html">donut</a></li>
<li><a href="dot/dot.html">dot</a></li>
<li><a href="force/force.html">force</a></li>
@@ -19,9 +20,11 @@
<li><a href="line/line.html">line</a></li>
<li><a href="pie/pie.html">pie</a></li>
<li><a href="pie/pie-transition.html">pie-transition</a></li>
+ <li><a href="splom/splom.html">splom</a></li>
<li><a href="stream/stream.html">stream</a></li>
<li><a href="stream/stack.html">stack</a></li>
<li><a href="symbol-map/symbol-map.html">symbol-map</a></li>
+ <li><a href="voronoi/voronoi.html">voronoi</a></li>
<li><a href="zoom/zoom.html">zoom</a></li>
</ul>
</body>
View
140 lib/jit/voronoi.js
@@ -7,42 +7,90 @@
* @returns polygons [[[x1, y1], [x2, y2], …], …]
*/
voronoi = function(vertices) {
- var polygons = vertices.map(function() { return []; }),
- opposite = {"l": "r", "r": "l"};
+ var polygons = vertices.map(function() { return []; });
// Note: we expect the caller to clip the polygons, if needed.
- var Canvas = {
- plotEdge: function(e) {
- var s1,
- s2,
- x1,
- x2,
- y1,
- y2;
- if (e.a == 1 && e.b >= 0) {
- s1 = e.ep["r"];
- s2 = e.ep["l"];
- } else {
- s1 = e.ep["l"];
- s2 = e.ep["r"];
- }
- if (e.a == 1) {
- y1 = s1 ? s1.y : -1e6;
- x1 = e.c - e.b * y1;
- y2 = s2 ? s2.y : 1e6;
- x2 = e.c - e.b * y2;
- } else {
- x1 = s1 ? s1.x : -1e6;
- y1 = e.c - e.a * x1;
- x2 = s2 ? s2.x : 1e6;
- y2 = e.c - e.a * x2;
- }
- var v1 = [x1, y1],
- v2 = [x2, y2];
- polygons[e.region["l"].index].push(v1, v2);
- polygons[e.region["r"].index].push(v1, v2);
+ voronoi_tessellate(vertices, function(e) {
+ var s1,
+ s2,
+ x1,
+ x2,
+ y1,
+ y2;
+ if (e.a == 1 && e.b >= 0) {
+ s1 = e.ep["r"];
+ s2 = e.ep["l"];
+ } else {
+ s1 = e.ep["l"];
+ s2 = e.ep["r"];
}
- };
+ if (e.a == 1) {
+ y1 = s1 ? s1.y : -1e6;
+ x1 = e.c - e.b * y1;
+ y2 = s2 ? s2.y : 1e6;
+ x2 = e.c - e.b * y2;
+ } else {
+ x1 = s1 ? s1.x : -1e6;
+ y1 = e.c - e.a * x1;
+ x2 = s2 ? s2.x : 1e6;
+ y2 = e.c - e.a * x2;
+ }
+ var v1 = [x1, y1],
+ v2 = [x2, y2];
+ polygons[e.region["l"].index].push(v1, v2);
+ polygons[e.region["r"].index].push(v1, v2);
+ });
+
+ // Reconnect the polygon segments into counterclockwise loops.
+ return polygons.map(function(polygon, i) {
+ var cx = vertices[i][0],
+ cy = vertices[i][1];
+ polygon.forEach(function(v) {
+ v.angle = Math.atan2(v[0] - cx, v[1] - cy);
+ });
+ return polygon.sort(function(a, b) {
+ return a.angle - b.angle;
+ }).filter(function(d, i) {
+ return !i || (d.angle - polygon[i - 1].angle > 1e-10);
+ });
+ });
+};
+
+/**
+* @param vertices [[x1, y1], [x2, y2], …]
+* @returns triangles [[[x1, y1], [x2, y2], [x3, y3]], …]
+ */
+delaunay = function(vertices) {
+ var edges = vertices.map(function() { return []; }),
+ triangles = [];
+
+ // Use the Voronoi tessellation to determine Delaunay edges.
+ voronoi_tessellate(vertices, function(e) {
+ edges[e.region["l"].index].push(vertices[e.region["r"].index]);
+ });
+
+ // Reconnect the edges into counterclockwise triangles.
+ edges.forEach(function(edge, i) {
+ var v = vertices[i],
+ cx = v[0],
+ cy = v[1];
+ edge.forEach(function(v) {
+ v.angle = Math.atan2(v[0] - cx, v[1] - cy);
+ });
+ edge.sort(function(a, b) {
+ return a.angle - b.angle;
+ });
+ for (var j = 0, m = edge.length - 1; j < m; j++) {
+ triangles.push([v, edge[j], edge[j + 1]]);
+ }
+ });
+
+ return triangles;
+};
+
+var voronoi_opposite = {"l": "r", "r": "l"};
+
+function voronoi_tessellate(vertices, callback) {
var Sites = {
list: vertices
@@ -125,7 +173,7 @@ voronoi = function(vertices) {
rightRegion: function(he) {
return he.edge == null
? Sites.bottomSite
- : he.edge.region[opposite[he.side]];
+ : he.edge.region[voronoi_opposite[he.side]];
}
};
@@ -244,8 +292,8 @@ voronoi = function(vertices) {
endPoint: function(edge, side, site) {
edge.ep[side] = site;
- if (!edge.ep[opposite[side]]) return;
- Canvas.plotEdge(edge);
+ if (!edge.ep[voronoi_opposite[side]]) return;
+ callback(edge);
},
distance: function(s, t) {
@@ -359,7 +407,7 @@ voronoi = function(vertices) {
e = Geom.bisect(bot, top);
bisector = EdgeList.createHalfEdge(e, pm);
EdgeList.insert(llbnd, bisector);
- Geom.endPoint(e, opposite[pm], v);
+ Geom.endPoint(e, voronoi_opposite[pm], v);
p = Geom.intersect(llbnd, bisector);
if (p) {
EventQueue.del(llbnd);
@@ -377,20 +425,6 @@ voronoi = function(vertices) {
for (lbnd = EdgeList.right(EdgeList.leftEnd);
lbnd != EdgeList.rightEnd;
lbnd = EdgeList.right(lbnd)) {
- Canvas.plotEdge(lbnd.edge);
+ callback(lbnd.edge);
}
-
- // Reconnect the polygon segments into counterclockwise loops.
- return polygons.map(function(polygon, i) {
- var cx = vertices[i][0],
- cy = vertices[i][1];
- polygon.forEach(function(v) {
- v.angle = Math.atan2(v[0] - cx, v[1] - cy);
- });
- return polygon.sort(function(a, b) {
- return a.angle - b.angle;
- }).filter(function(d, i) {
- return !i || (d.angle - polygon[i - 1].angle > 1e-10);
- });
- });
-};
+}
View
17 lib/jit/voronoi.min.js
@@ -1,8 +1,9 @@
-(function(){var k=null;
-voronoi=function(w){var y=w.map(function(){return[]}),z={l:"r",r:"l"},A={A:function(a){var c,b,d,e;if(a.d==1&&a.a>=0){c=a.k.r;b=a.k.l}else{c=a.k.l;b=a.k.r}if(a.d==1){d=c?c.y:-1E6;c=a.b-a.a*d;e=b?b.y:1E6;b=a.b-a.a*e}else{c=c?c.x:-1E6;d=a.b-a.d*c;b=b?b.x:1E6;e=a.b-a.d*b}c=[c,d];b=[b,e];y[a.region.l.index].push(c,b);y[a.region.r.index].push(c,b)}},t={c:w.map(function(a,c){return{index:c,x:a[0],y:a[1]}}).sort(function(a,c){return a.y<c.y?-1:a.y>c.y?1:a.x<c.x?-1:a.x>c.x?1:0}),v:k},f={c:[],m:k,n:k,D:function(){f.m=
-f.o(k,"l");f.n=f.o(k,"l");f.m.r=f.n;f.n.l=f.m;f.c.unshift(f.m,f.n)},o:function(a,c){return{g:a,h:c,u:k,l:k,r:k}},i:function(a,c){c.l=a;c.r=a.r;a.r.l=c;a.r=c},F:function(a){var c=f.m;do c=c.r;while(c!=f.n&&n.H(c,a));return c=c.l},j:function(a){a.l.r=a.r;a.r.l=a.l;a.g=k},right:function(a){return a.r},left:function(a){return a.l},G:function(a){return a.g==k?t.v:a.g.region[a.h]},B:function(a){return a.g==k?t.v:a.g.region[z[a.h]]}},n={z:function(a,c){var b={region:{l:a,r:c},k:{l:k,r:k}},d=c.x-a.x,e=c.y-
-a.y,h=d>0?d:-d,l=e>0?e:-e;b.b=a.x*d+a.y*e+(d*d+e*e)*0.5;if(h>l){b.d=1;b.a=e/d;b.b/=d}else{b.a=1;b.d=d/e;b.b/=e}return b},t:function(a,c){var b=a.g,d=c.g;if(!b||!d||b.region.r==d.region.r)return k;var e=b.d*d.a-b.a*d.d;if(Math.abs(e)<1.0E-10)return k;var h=(b.b*d.a-d.b*b.a)/e;e=(d.b*b.d-b.b*d.d)/e;var l=b.region.r,s=d.region.r;if(l.y<s.y||l.y==s.y&&l.x<s.x){l=a;b=b}else{l=c;b=d}if((b=h>=b.region.r.x)&&l.h=="l"||!b&&l.h=="r")return k;return{x:h,y:e}},H:function(a,c){var b=a.g,d=b.region.r,e=c.x>d.x;
-if(e&&a.h=="l")return 1;if(!e&&a.h=="r")return 0;if(b.d==1){var h=c.y-d.y,l=c.x-d.x,s=0,o=0;if(!e&&b.a<0||e&&b.a>=0)o=s=h>=b.a*l;else{o=c.x+c.y*b.a>b.b;if(b.a<0)o=!o;o||(s=1)}if(!s){d=d.x-b.region.l.x;o=b.a*(l*l-h*h)<d*h*(1+2*l/d+b.a*b.a);if(b.a<0)o=!o}}else{l=b.b-b.d*c.x;b=c.y-l;h=c.x-d.x;d=l-d.y;o=b*b>h*h+d*d}return a.h=="l"?o:!o},w:function(a,c,b){a.k[c]=b;a.k[z[c]]&&A.A(a)},s:function(a,c){var b=a.x-c.x,d=a.y-c.y;return Math.sqrt(b*b+d*d)}},i={c:[],i:function(a,c,b){a.u=c;a.p=c.y+b;b=0;for(var d=
-i.c,e=d.length;b<e;b++){var h=d[b];if(!(a.p>h.p||a.p==h.p&&c.x>h.u.x))break}d.splice(b,0,a)},j:function(a){for(var c=0,b=i.c,d=b.length;c<d&&b[c]!=a;++c);b.splice(c,1)},empty:function(){return i.c.length==0},I:function(a){for(var c=0,b=i.c,d=b.length;c<d;++c)if(b[c]==a)return b[c+1];return k},min:function(){var a=i.c[0];return{x:a.u.x,y:a.p}},C:function(){return i.c.shift()}};f.D();t.v=t.c.shift();for(var p=t.c.shift(),x,g,q,v,B,j,r,m,u;;){i.empty()||(x=i.min());if(p&&(i.empty()||p.y<x.y||p.y==x.y&&
-p.x<x.x)){g=f.F(p);q=f.right(g);r=f.B(g);u=n.z(r,p);j=f.o(u,"l");f.i(g,j);if(m=n.t(g,j)){i.j(g);i.i(g,m,n.s(m,p))}g=j;j=f.o(u,"r");f.i(g,j);(m=n.t(j,q))&&i.i(j,m,n.s(m,p));p=t.c.shift()}else if(i.empty())break;else{g=i.C();v=f.left(g);q=f.right(g);B=f.right(q);r=f.G(g);j=f.B(q);m=g.u;n.w(g.g,g.h,m);n.w(q.g,q.h,m);f.j(g);i.j(q);f.j(q);g="l";if(r.y>j.y){g=r;r=j;j=g;g="r"}u=n.z(r,j);j=f.o(u,g);f.i(v,j);n.w(u,z[g],m);if(m=n.t(v,j)){i.j(v);i.i(v,m,n.s(m,r))}(m=n.t(j,B))&&i.i(j,m,n.s(m,r))}}for(g=f.right(f.m);g!=
-f.n;g=f.right(g))A.A(g.g);return y.map(function(a,c){var b=w[c][0],d=w[c][1];a.forEach(function(e){e.q=Math.atan2(e[0]-b,e[1]-d)});return a.sort(function(e,h){return e.q-h.q}).filter(function(e,h){return!h||e.q-a[h-1].q>1.0E-10})})};})()
+(function(){var m=null;
+voronoi=function(q){var v=q.map(function(){return[]});A(q,function(h){var c,g,i,j;if(h.d==1&&h.a>=0){c=h.m.r;g=h.m.l}else{c=h.m.l;g=h.m.r}if(h.d==1){i=c?c.y:-1E6;c=h.b-h.a*i;j=g?g.y:1E6;g=h.b-h.a*j}else{c=c?c.x:-1E6;i=h.b-h.d*c;g=g?g.x:1E6;j=h.b-h.d*g}c=[c,i];g=[g,j];v[h.region.l.index].push(c,g);v[h.region.r.index].push(c,g)});return v.map(function(h,c){var g=q[c][0],i=q[c][1];h.forEach(function(j){j.j=Math.atan2(j[0]-g,j[1]-i)});return h.sort(function(j,r){return j.j-r.j}).filter(function(j,r){return!r||
+j.j-h[r-1].j>1.0E-10})})};delaunay=function(q){var v=q.map(function(){return[]}),h=[];A(q,function(c){v[c.region.l.index].push(q[c.region.r.index])});v.forEach(function(c,g){var i=q[g],j=i[0],r=i[1];c.forEach(function(s){s.j=Math.atan2(s[0]-j,s[1]-r)});c.sort(function(s,z){return s.j-z.j});for(var f=0,t=c.length-1;f<t;f++)h.push([i,c[f],c[f+1]])});return h};var B={l:"r",r:"l"};
+function A(q,v){var h={c:q.map(function(a,d){return{index:d,x:a[0],y:a[1]}}).sort(function(a,d){return a.y<d.y?-1:a.y>d.y?1:a.x<d.x?-1:a.x>d.x?1:0}),v:m},c={c:[],n:m,o:m,C:function(){c.n=c.p(m,"l");c.o=c.p(m,"l");c.n.r=c.o;c.o.l=c.n;c.c.unshift(c.n,c.o)},p:function(a,d){return{g:a,h:d,u:m,l:m,r:m}},i:function(a,d){d.l=a;d.r=a.r;a.r.l=d;a.r=d},D:function(a){var d=c.n;do d=d.r;while(d!=c.o&&g.G(d,a));return d=d.l},k:function(a){a.l.r=a.r;a.r.l=a.l;a.g=m},right:function(a){return a.r},left:function(a){return a.l},
+F:function(a){return a.g==m?h.v:a.g.region[a.h]},A:function(a){return a.g==m?h.v:a.g.region[B[a.h]]}},g={z:function(a,d){var b={region:{l:a,r:d},m:{l:m,r:m}},e=d.x-a.x,k=d.y-a.y,o=e>0?e:-e,n=k>0?k:-k;b.b=a.x*e+a.y*k+(e*e+k*k)*0.5;if(o>n){b.d=1;b.a=k/e;b.b/=e}else{b.a=1;b.d=e/k;b.b/=k}return b},t:function(a,d){var b=a.g,e=d.g;if(!b||!e||b.region.r==e.region.r)return m;var k=b.d*e.a-b.a*e.d;if(Math.abs(k)<1.0E-10)return m;var o=(b.b*e.a-e.b*b.a)/k;k=(e.b*b.d-b.b*e.d)/k;var n=b.region.r,x=e.region.r;
+if(n.y<x.y||n.y==x.y&&n.x<x.x){n=a;b=b}else{n=d;b=e}if((b=o>=b.region.r.x)&&n.h=="l"||!b&&n.h=="r")return m;return{x:o,y:k}},G:function(a,d){var b=a.g,e=b.region.r,k=d.x>e.x;if(k&&a.h=="l")return 1;if(!k&&a.h=="r")return 0;if(b.d==1){var o=d.y-e.y,n=d.x-e.x,x=0,u=0;if(!k&&b.a<0||k&&b.a>=0)u=x=o>=b.a*n;else{u=d.x+d.y*b.a>b.b;if(b.a<0)u=!u;u||(x=1)}if(!x){e=e.x-b.region.l.x;u=b.a*(n*n-o*o)<e*o*(1+2*n/e+b.a*b.a);if(b.a<0)u=!u}}else{n=b.b-b.d*d.x;b=d.y-n;o=d.x-e.x;e=n-e.y;u=b*b>o*o+e*e}return a.h=="l"?
+u:!u},w:function(a,d,b){a.m[d]=b;a.m[B[d]]&&v(a)},s:function(a,d){var b=a.x-d.x,e=a.y-d.y;return Math.sqrt(b*b+e*e)}},i={c:[],i:function(a,d,b){a.u=d;a.q=d.y+b;b=0;for(var e=i.c,k=e.length;b<k;b++){var o=e[b];if(!(a.q>o.q||a.q==o.q&&d.x>o.u.x))break}e.splice(b,0,a)},k:function(a){for(var d=0,b=i.c,e=b.length;d<e&&b[d]!=a;++d);b.splice(d,1)},empty:function(){return i.c.length==0},H:function(a){for(var d=0,b=i.c,e=b.length;d<e;++d)if(b[d]==a)return b[d+1];return m},min:function(){var a=i.c[0];return{x:a.u.x,
+y:a.q}},B:function(){return i.c.shift()}};c.C();h.v=h.c.shift();for(var j=h.c.shift(),r,f,t,s,z,l,w,p,y;;){i.empty()||(r=i.min());if(j&&(i.empty()||j.y<r.y||j.y==r.y&&j.x<r.x)){f=c.D(j);t=c.right(f);w=c.A(f);y=g.z(w,j);l=c.p(y,"l");c.i(f,l);if(p=g.t(f,l)){i.k(f);i.i(f,p,g.s(p,j))}f=l;l=c.p(y,"r");c.i(f,l);(p=g.t(l,t))&&i.i(l,p,g.s(p,j));j=h.c.shift()}else if(i.empty())break;else{f=i.B();s=c.left(f);t=c.right(f);z=c.right(t);w=c.F(f);l=c.A(t);p=f.u;g.w(f.g,f.h,p);g.w(t.g,t.h,p);c.k(f);i.k(t);c.k(t);
+f="l";if(w.y>l.y){f=w;w=l;l=f;f="r"}y=g.z(w,l);l=c.p(y,f);c.i(s,l);g.w(y,B[f],p);if(p=g.t(s,l)){i.k(s);i.i(s,p,g.s(p,w))}(p=g.t(l,z))&&i.i(l,p,g.s(p,w))}}for(f=c.right(c.n);f!=c.o;f=c.right(f))v(f.g)};})()
View
4 src/externs.js
@@ -168,3 +168,7 @@ d3.time = {
format: 1,
parse: 1
};
+
+// jit
+var voronoi,
+ delaunay;

0 comments on commit bcf37e4

Please sign in to comment.
Something went wrong with that request. Please try again.