Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

delaunator

Package Overview
Dependencies
Maintainers
15
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

delaunator - npm Package Compare versions

Comparing version 3.0.2 to 4.0.0

288

delaunator.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.Delaunator = factory());
}(this, (function () { 'use strict';
(global = global || self, global.Delaunator = factory());
}(this, function () { 'use strict';
var EPSILON = Math.pow(2, -52);
var EDGE_STACK = new Uint32Array(512);
var Delaunator = function Delaunator(coords) {
var this$1 = this;
var n = coords.length >> 1;

@@ -18,15 +17,46 @@ if (n > 0 && typeof coords[0] !== 'number') { throw new Error('Expected coords to contain numbers.'); }

// arrays that will store the triangulation graph
var maxTriangles = 2 * n - 5;
var triangles = this.triangles = new Uint32Array(maxTriangles * 3);
var halfedges = this.halfedges = new Int32Array(maxTriangles * 3);
var maxTriangles = Math.max(2 * n - 5, 0);
this._triangles = new Uint32Array(maxTriangles * 3);
this._halfedges = new Int32Array(maxTriangles * 3);
// temporary arrays for tracking the edges of the advancing convex hull
this._hashSize = Math.ceil(Math.sqrt(n));
var hullPrev = this.hullPrev = new Uint32Array(n); // edge to prev edge
var hullNext = this.hullNext = new Uint32Array(n); // edge to next edge
var hullTri = this.hullTri = new Uint32Array(n); // edge to adjacent triangle
var hullHash = new Int32Array(this._hashSize).fill(-1); // angular edge hash
this._hullPrev = new Uint32Array(n); // edge to prev edge
this._hullNext = new Uint32Array(n); // edge to next edge
this._hullTri = new Uint32Array(n); // edge to adjacent triangle
this._hullHash = new Int32Array(this._hashSize).fill(-1); // angular edge hash
// temporary arrays for sorting points
this._ids = new Uint32Array(n);
this._dists = new Float64Array(n);
this.update();
};
Delaunator.from = function from (points, getX, getY) {
if ( getX === void 0 ) getX = defaultGetX;
if ( getY === void 0 ) getY = defaultGetY;
var n = points.length;
var coords = new Float64Array(n * 2);
for (var i = 0; i < n; i++) {
var p = points[i];
coords[2 * i] = getX(p);
coords[2 * i + 1] = getY(p);
}
return new Delaunator(coords);
};
Delaunator.prototype.update = function update () {
var ref = this;
var coords = ref.coords;
var hullPrev = ref._hullPrev;
var hullNext = ref._hullNext;
var hullTri = ref._hullTri;
var hullHash = ref._hullHash;
var n = coords.length >> 1;
// populate an array of point indices; calculate input data bbox
var ids = new Uint32Array(n);
var minX = Infinity;

@@ -44,3 +74,3 @@ var minY = Infinity;

if (y > maxY) { maxY = y; }
ids[i] = i;
this._ids[i] = i;
}

@@ -93,3 +123,21 @@ var cx = (minX + maxX) / 2;

if (minRadius === Infinity) {
throw new Error('No Delaunay triangulation exists for this input.');
// order collinear points by dx (or dy if all x are identical)
// and return the list as a hull
for (var i$4 = 0; i$4 < n; i$4++) {
this._dists[i$4] = (coords[2 * i$4] - coords[0]) || (coords[2 * i$4 + 1] - coords[1]);
}
quicksort(this._ids, this._dists, 0, n - 1);
var hull = new Uint32Array(n);
var j = 0;
for (var i$5 = 0, d0 = -Infinity; i$5 < n; i$5++) {
var id = this._ids[i$5];
if (this._dists[id] > d0) {
hull[j++] = id;
d0 = this._dists[id];
}
}
this.hull = hull.subarray(0, j);
this.triangles = new Uint32Array(0);
this.halfedges = new Uint32Array(0);
return;
}

@@ -99,3 +147,3 @@

if (orient(i0x, i0y, i1x, i1y, i2x, i2y)) {
var i$4 = i1;
var i$6 = i1;
var x$1 = i1x;

@@ -106,3 +154,3 @@ var y$1 = i1y;

i1y = i2y;
i2 = i$4;
i2 = i$6;
i2x = x$1;

@@ -116,12 +164,11 @@ i2y = y$1;

var dists = new Float64Array(n);
for (var i$5 = 0; i$5 < n; i$5++) {
dists[i$5] = dist(coords[2 * i$5], coords[2 * i$5 + 1], center.x, center.y);
for (var i$7 = 0; i$7 < n; i$7++) {
this._dists[i$7] = dist(coords[2 * i$7], coords[2 * i$7 + 1], center.x, center.y);
}
// sort the points by distance from the seed triangle circumcenter
quicksort(ids, dists, 0, n - 1);
quicksort(this._ids, this._dists, 0, n - 1);
// set up the seed triangle as the starting hull
this.hullStart = i0;
this._hullStart = i0;
var hullSize = 3;

@@ -137,2 +184,3 @@

hullHash.fill(-1);
hullHash[this._hashKey(i0x, i0y)] = i0;

@@ -145,6 +193,6 @@ hullHash[this._hashKey(i1x, i1y)] = i1;

for (var k = 0, xp = (void 0), yp = (void 0); k < ids.length; k++) {
var i$6 = ids[k];
var x$2 = coords[2 * i$6];
var y$2 = coords[2 * i$6 + 1];
for (var k = 0, xp = (void 0), yp = (void 0); k < this._ids.length; k++) {
var i$8 = this._ids[k];
var x$2 = coords[2 * i$8];
var y$2 = coords[2 * i$8 + 1];

@@ -157,8 +205,8 @@ // skip near-duplicate points

// skip seed triangle points
if (i$6 === i0 || i$6 === i1 || i$6 === i2) { continue; }
if (i$8 === i0 || i$8 === i1 || i$8 === i2) { continue; }
// find a visible edge on the convex hull using edge hash
var start = 0;
for (var j = 0, key = this._hashKey(x$2, y$2); j < this._hashSize; j++) {
start = hullHash[(key + j) % this$1._hashSize];
for (var j$1 = 0, key = this._hashKey(x$2, y$2); j$1 < this._hashSize; j$1++) {
start = hullHash[(key + j$1) % this._hashSize];
if (start !== -1 && start !== hullNext[start]) { break; }

@@ -179,6 +227,6 @@ }

// add the first triangle from the point
var t = this$1._addTriangle(e, i$6, hullNext[e], -1, -1, hullTri[e]);
var t = this._addTriangle(e, i$8, hullNext[e], -1, -1, hullTri[e]);
// recursively flip triangles from the point until they satisfy the Delaunay condition
hullTri[i$6] = this$1._legalize(t + 2);
hullTri[i$8] = this._legalize(t + 2);
hullTri[e] = t; // keep track of boundary triangles on the hull

@@ -190,4 +238,4 @@ hullSize++;

while (q = hullNext[n$1], orient(x$2, y$2, coords[2 * n$1], coords[2 * n$1 + 1], coords[2 * q], coords[2 * q + 1])) {
t = this$1._addTriangle(n$1, i$6, q, hullTri[i$6], -1, hullTri[n$1]);
hullTri[i$6] = this$1._legalize(t + 2);
t = this._addTriangle(n$1, i$8, q, hullTri[i$8], -1, hullTri[n$1]);
hullTri[i$8] = this._legalize(t + 2);
hullNext[n$1] = n$1; // mark as removed

@@ -201,4 +249,4 @@ hullSize--;

while (q = hullPrev[e], orient(x$2, y$2, coords[2 * q], coords[2 * q + 1], coords[2 * e], coords[2 * e + 1])) {
t = this$1._addTriangle(q, i$6, e, -1, hullTri[e], hullTri[q]);
this$1._legalize(t + 2);
t = this._addTriangle(q, i$8, e, -1, hullTri[e], hullTri[q]);
this._legalize(t + 2);
hullTri[q] = t;

@@ -212,39 +260,22 @@ hullNext[e] = e; // mark as removed

// update the hull indices
this$1.hullStart = hullPrev[i$6] = e;
hullNext[e] = hullPrev[n$1] = i$6;
hullNext[i$6] = n$1;
this._hullStart = hullPrev[i$8] = e;
hullNext[e] = hullPrev[n$1] = i$8;
hullNext[i$8] = n$1;
// save the two new edges in the hash table
hullHash[this$1._hashKey(x$2, y$2)] = i$6;
hullHash[this$1._hashKey(coords[2 * e], coords[2 * e + 1])] = e;
hullHash[this._hashKey(x$2, y$2)] = i$8;
hullHash[this._hashKey(coords[2 * e], coords[2 * e + 1])] = e;
}
this.hull = new Uint32Array(hullSize);
for (var i$7 = 0, e$1 = this.hullStart; i$7 < hullSize; i$7++) {
this$1.hull[i$7] = e$1;
for (var i$9 = 0, e$1 = this._hullStart; i$9 < hullSize; i$9++) {
this.hull[i$9] = e$1;
e$1 = hullNext[e$1];
}
this.hullPrev = this.hullNext = this.hullTri = null; // get rid of temporary arrays
// trim typed triangle mesh arrays
this.triangles = triangles.subarray(0, this.trianglesLen);
this.halfedges = halfedges.subarray(0, this.trianglesLen);
this.triangles = this._triangles.subarray(0, this.trianglesLen);
this.halfedges = this._halfedges.subarray(0, this.trianglesLen);
};
Delaunator.from = function from (points, getX, getY) {
if ( getX === void 0 ) getX = defaultGetX;
if ( getY === void 0 ) getY = defaultGetY;
var n = points.length;
var coords = new Float64Array(n * 2);
for (var i = 0; i < n; i++) {
var p = points[i];
coords[2 * i] = getX(p);
coords[2 * i + 1] = getY(p);
}
return new Delaunator(coords);
};
Delaunator.prototype._hashKey = function _hashKey (x, y) {

@@ -255,71 +286,84 @@ return Math.floor(pseudoAngle(x - this._cx, y - this._cy) * this._hashSize) % this._hashSize;

Delaunator.prototype._legalize = function _legalize (a) {
var this$1 = this;
var ref = this;
var triangles = ref.triangles;
var triangles = ref._triangles;
var halfedges = ref._halfedges;
var coords = ref.coords;
var halfedges = ref.halfedges;
var b = halfedges[a];
var i = 0;
var ar = 0;
/* if the pair of triangles doesn't satisfy the Delaunay condition
* (p1 is inside the circumcircle of [p0, pl, pr]), flip them,
* then do the same check/flip recursively for the new pair of triangles
*
* pl pl
* /||\ / \
* al/ || \bl al/\a
* / || \ / \
* / a||b \flip/___ar___\
* p0\ || /p1 => p0\---bl---/p1
* \ || / \ /
* ar\ || /br b\/br
* \||/ \ /
* pr pr
*/
var a0 = a - a % 3;
var b0 = b - b % 3;
// recursion eliminated with a fixed-size stack
while (true) {
var b = halfedges[a];
var al = a0 + (a + 1) % 3;
var ar = a0 + (a + 2) % 3;
var bl = b0 + (b + 2) % 3;
/* if the pair of triangles doesn't satisfy the Delaunay condition
* (p1 is inside the circumcircle of [p0, pl, pr]), flip them,
* then do the same check/flip recursively for the new pair of triangles
*
* pl pl
* /||\ / \
* al/ || \bl al/\a
* / || \ / \
* / a||b \flip/___ar___\
* p0\ || /p1 => p0\---bl---/p1
* \ || / \ /
* ar\ || /br b\/br
* \||/ \ /
* pr pr
*/
var a0 = a - a % 3;
ar = a0 + (a + 2) % 3;
if (b === -1) { return ar; }
if (b === -1) { // convex hull edge
if (i === 0) { break; }
a = EDGE_STACK[--i];
continue;
}
var p0 = triangles[ar];
var pr = triangles[a];
var pl = triangles[al];
var p1 = triangles[bl];
var b0 = b - b % 3;
var al = a0 + (a + 1) % 3;
var bl = b0 + (b + 2) % 3;
var illegal = inCircle(
coords[2 * p0], coords[2 * p0 + 1],
coords[2 * pr], coords[2 * pr + 1],
coords[2 * pl], coords[2 * pl + 1],
coords[2 * p1], coords[2 * p1 + 1]);
var p0 = triangles[ar];
var pr = triangles[a];
var pl = triangles[al];
var p1 = triangles[bl];
if (illegal) {
triangles[a] = p1;
triangles[b] = p0;
var illegal = inCircle(
coords[2 * p0], coords[2 * p0 + 1],
coords[2 * pr], coords[2 * pr + 1],
coords[2 * pl], coords[2 * pl + 1],
coords[2 * p1], coords[2 * p1 + 1]);
var hbl = halfedges[bl];
if (illegal) {
triangles[a] = p1;
triangles[b] = p0;
// edge swapped on the other side of the hull (rare); fix the halfedge reference
if (hbl === -1) {
var e = this.hullStart;
do {
if (this$1.hullTri[e] === bl) {
this$1.hullTri[e] = a;
break;
}
e = this$1.hullNext[e];
} while (e !== this.hullStart);
}
this._link(a, hbl);
this._link(b, halfedges[ar]);
this._link(ar, bl);
var hbl = halfedges[bl];
var br = b0 + (b + 1) % 3;
// edge swapped on the other side of the hull (rare); fix the halfedge reference
if (hbl === -1) {
var e = this._hullStart;
do {
if (this._hullTri[e] === bl) {
this._hullTri[e] = a;
break;
}
e = this._hullPrev[e];
} while (e !== this._hullStart);
}
this._link(a, hbl);
this._link(b, halfedges[ar]);
this._link(ar, bl);
this._legalize(a);
return this._legalize(br);
var br = b0 + (b + 1) % 3;
// don't worry about hitting the cap: it can only happen on extremely degenerate input
if (i < EDGE_STACK.length) {
EDGE_STACK[i++] = br;
}
} else {
if (i === 0) { break; }
a = EDGE_STACK[--i];
}
}

@@ -331,4 +375,4 @@

Delaunator.prototype._link = function _link (a, b) {
this.halfedges[a] = b;
if (b !== -1) { this.halfedges[b] = a; }
this._halfedges[a] = b;
if (b !== -1) { this._halfedges[b] = a; }
};

@@ -340,5 +384,5 @@

this.triangles[t] = i0;
this.triangles[t + 1] = i1;
this.triangles[t + 2] = i2;
this._triangles[t] = i0;
this._triangles[t + 1] = i1;
this._triangles[t + 2] = i2;

@@ -473,2 +517,2 @@ this._link(t, a);

})));
}));

@@ -1,1 +0,1 @@

!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):t.Delaunator=i()}(this,function(){"use strict";var t=Math.pow(2,-52),i=function(i){var n=i.length>>1;if(n>0&&"number"!=typeof i[0])throw new Error("Expected coords to contain numbers.");this.coords=i;var s=2*n-5,l=this.triangles=new Uint32Array(3*s),o=this.halfedges=new Int32Array(3*s);this._hashSize=Math.ceil(Math.sqrt(n));for(var f=this.hullPrev=new Uint32Array(n),u=this.hullNext=new Uint32Array(n),v=this.hullTri=new Uint32Array(n),d=new Int32Array(this._hashSize).fill(-1),_=new Uint32Array(n),y=1/0,g=1/0,c=-1/0,w=-1/0,p=0;p<n;p++){var b=i[2*p],x=i[2*p+1];b<y&&(y=b),x<g&&(g=x),b>c&&(c=b),x>w&&(w=x),_[p]=p}for(var z,S,k,A=(y+c)/2,T=(g+w)/2,M=1/0,K=0;K<n;K++){var m=r(A,T,i[2*K],i[2*K+1]);m<M&&(z=K,M=m)}var U=i[2*z],L=i[2*z+1];M=1/0;for(var N=0;N<n;N++)if(N!==z){var E=r(U,L,i[2*N],i[2*N+1]);E<M&&E>0&&(S=N,M=E)}for(var D=i[2*S],F=i[2*S+1],I=1/0,P=0;P<n;P++)if(P!==z&&P!==S){var j=h(U,L,D,F,i[2*P],i[2*P+1]);j<I&&(k=P,I=j)}var q=i[2*k],B=i[2*k+1];if(I===1/0)throw new Error("No Delaunay triangulation exists for this input.");if(a(U,L,D,F,q,B)){var C=S,G=D,H=F;S=k,D=q,F=B,k=C,q=G,B=H}var J=function(t,i,r,a,h,e){var n=r-t,s=a-i,l=h-t,o=e-i,f=n*n+s*s,u=l*l+o*o,v=.5/(n*o-s*l);return{x:t+(o*f-s*u)*v,y:i+(n*u-l*f)*v}}(U,L,D,F,q,B);this._cx=J.x,this._cy=J.y;for(var O=new Float64Array(n),Q=0;Q<n;Q++)O[Q]=r(i[2*Q],i[2*Q+1],J.x,J.y);!function t(i,r,a,h){if(h-a<=20)for(var n=a+1;n<=h;n++){for(var s=i[n],l=r[s],o=n-1;o>=a&&r[i[o]]>l;)i[o+1]=i[o--];i[o+1]=s}else{var f=a+h>>1,u=a+1,v=h;e(i,f,u),r[i[a]]>r[i[h]]&&e(i,a,h),r[i[u]]>r[i[h]]&&e(i,u,h),r[i[a]]>r[i[u]]&&e(i,a,u);for(var d=i[u],_=r[d];;){do{u++}while(r[i[u]]<_);do{v--}while(r[i[v]]>_);if(v<u)break;e(i,u,v)}i[a+1]=i[v],i[v]=d,h-u+1>=v-a?(t(i,r,u,h),t(i,r,a,v-1)):(t(i,r,a,v-1),t(i,r,u,h))}}(_,O,0,n-1),this.hullStart=z;var R=3;u[z]=f[k]=S,u[S]=f[z]=k,u[k]=f[S]=z,v[z]=0,v[S]=1,v[k]=2,d[this._hashKey(U,L)]=z,d[this._hashKey(D,F)]=S,d[this._hashKey(q,B)]=k,this.trianglesLen=0,this._addTriangle(z,S,k,-1,-1,-1);for(var V=0,W=void 0,X=void 0;V<_.length;V++){var Y=_[V],Z=i[2*Y],$=i[2*Y+1];if(!(V>0&&Math.abs(Z-W)<=t&&Math.abs($-X)<=t)&&(W=Z,X=$,Y!==z&&Y!==S&&Y!==k)){for(var tt=0,it=0,rt=this._hashKey(Z,$);it<this._hashSize&&(-1===(tt=d[(rt+it)%this._hashSize])||tt===u[tt]);it++);for(var at=tt=f[tt],ht=void 0;ht=u[at],!a(Z,$,i[2*at],i[2*at+1],i[2*ht],i[2*ht+1]);)if((at=ht)===tt){at=-1;break}if(-1!==at){var et=this._addTriangle(at,Y,u[at],-1,-1,v[at]);v[Y]=this._legalize(et+2),v[at]=et,R++;for(var nt=u[at];ht=u[nt],a(Z,$,i[2*nt],i[2*nt+1],i[2*ht],i[2*ht+1]);)et=this._addTriangle(nt,Y,ht,v[Y],-1,v[nt]),v[Y]=this._legalize(et+2),u[nt]=nt,R--,nt=ht;if(at===tt)for(;a(Z,$,i[2*(ht=f[at])],i[2*ht+1],i[2*at],i[2*at+1]);)et=this._addTriangle(ht,Y,at,-1,v[at],v[ht]),this._legalize(et+2),v[ht]=et,u[at]=at,R--,at=ht;this.hullStart=f[Y]=at,u[at]=f[nt]=Y,u[Y]=nt,d[this._hashKey(Z,$)]=Y,d[this._hashKey(i[2*at],i[2*at+1])]=at}}}this.hull=new Uint32Array(R);for(var st=0,lt=this.hullStart;st<R;st++)this.hull[st]=lt,lt=u[lt];this.hullPrev=this.hullNext=this.hullTri=null,this.triangles=l.subarray(0,this.trianglesLen),this.halfedges=o.subarray(0,this.trianglesLen)};function r(t,i,r,a){var h=t-r,e=i-a;return h*h+e*e}function a(t,i,r,a,h,e){return(a-i)*(h-r)-(r-t)*(e-a)<0}function h(t,i,r,a,h,e){var n=r-t,s=a-i,l=h-t,o=e-i,f=n*n+s*s,u=l*l+o*o,v=.5/(n*o-s*l),d=(o*f-s*u)*v,_=(n*u-l*f)*v;return d*d+_*_}function e(t,i,r){var a=t[i];t[i]=t[r],t[r]=a}function n(t){return t[0]}function s(t){return t[1]}return i.from=function(t,r,a){void 0===r&&(r=n),void 0===a&&(a=s);for(var h=t.length,e=new Float64Array(2*h),l=0;l<h;l++){var o=t[l];e[2*l]=r(o),e[2*l+1]=a(o)}return new i(e)},i.prototype._hashKey=function(t,i){return Math.floor((r=t-this._cx,a=i-this._cy,h=r/(Math.abs(r)+Math.abs(a)),(a>0?3-h:1+h)/4*this._hashSize))%this._hashSize;var r,a,h},i.prototype._legalize=function(t){var i=this.triangles,r=this.coords,a=this.halfedges,h=a[t],e=t-t%3,n=h-h%3,s=e+(t+1)%3,l=e+(t+2)%3,o=n+(h+2)%3;if(-1===h)return l;var f,u,v,d,_,y,g,c,w,p,b,x,z,S,k,A,T=i[l],M=i[t],K=i[s],m=i[o];if(f=r[2*T],u=r[2*T+1],v=r[2*M],d=r[2*M+1],_=r[2*K],y=r[2*K+1],g=r[2*m],c=r[2*m+1],(w=f-g)*((x=d-c)*(A=(z=_-g)*z+(S=y-c)*S)-(k=(b=v-g)*b+x*x)*S)-(p=u-c)*(b*A-k*z)+(w*w+p*p)*(b*S-x*z)<0){i[t]=m,i[h]=T;var U=a[o];if(-1===U){var L=this.hullStart;do{if(this.hullTri[L]===o){this.hullTri[L]=t;break}L=this.hullNext[L]}while(L!==this.hullStart)}this._link(t,U),this._link(h,a[l]),this._link(l,o);var N=n+(h+1)%3;return this._legalize(t),this._legalize(N)}return l},i.prototype._link=function(t,i){this.halfedges[t]=i,-1!==i&&(this.halfedges[i]=t)},i.prototype._addTriangle=function(t,i,r,a,h,e){var n=this.trianglesLen;return this.triangles[n]=t,this.triangles[n+1]=i,this.triangles[n+2]=r,this._link(n,a),this._link(n+1,h),this._link(n+2,e),this.trianglesLen+=3,n},i});
!function(i,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(i=i||self).Delaunator=t()}(this,function(){"use strict";var i=Math.pow(2,-52),t=new Uint32Array(512),r=function(i){var t=i.length>>1;if(t>0&&"number"!=typeof i[0])throw new Error("Expected coords to contain numbers.");this.coords=i;var r=Math.max(2*t-5,0);this._triangles=new Uint32Array(3*r),this._halfedges=new Int32Array(3*r),this._hashSize=Math.ceil(Math.sqrt(t)),this._hullPrev=new Uint32Array(t),this._hullNext=new Uint32Array(t),this._hullTri=new Uint32Array(t),this._hullHash=new Int32Array(this._hashSize).fill(-1),this._ids=new Uint32Array(t),this._dists=new Float64Array(t),this.update()};function s(i,t,r,s){var h=i-r,a=t-s;return h*h+a*a}function h(i,t,r,s,h,a){return(s-t)*(h-r)-(r-i)*(a-s)<0}function a(i,t,r,s,h,a){var e=r-i,n=s-t,l=h-i,o=a-t,_=e*e+n*n,f=l*l+o*o,d=.5/(e*o-n*l),v=(o*_-n*f)*d,u=(e*f-l*_)*d;return v*v+u*u}function e(i,t,r,s){if(s-r<=20)for(var h=r+1;h<=s;h++){for(var a=i[h],l=t[a],o=h-1;o>=r&&t[i[o]]>l;)i[o+1]=i[o--];i[o+1]=a}else{var _=r+1,f=s;n(i,r+s>>1,_),t[i[r]]>t[i[s]]&&n(i,r,s),t[i[_]]>t[i[s]]&&n(i,_,s),t[i[r]]>t[i[_]]&&n(i,r,_);for(var d=i[_],v=t[d];;){do{_++}while(t[i[_]]<v);do{f--}while(t[i[f]]>v);if(f<_)break;n(i,_,f)}i[r+1]=i[f],i[f]=d,s-_+1>=f-r?(e(i,t,_,s),e(i,t,r,f-1)):(e(i,t,r,f-1),e(i,t,_,s))}}function n(i,t,r){var s=i[t];i[t]=i[r],i[r]=s}function l(i){return i[0]}function o(i){return i[1]}return r.from=function(i,t,s){void 0===t&&(t=l),void 0===s&&(s=o);for(var h=i.length,a=new Float64Array(2*h),e=0;e<h;e++){var n=i[e];a[2*e]=t(n),a[2*e+1]=s(n)}return new r(a)},r.prototype.update=function(){for(var t=this.coords,r=this._hullPrev,n=this._hullNext,l=this._hullTri,o=this._hullHash,_=t.length>>1,f=1/0,d=1/0,v=-1/0,u=-1/0,y=0;y<_;y++){var g=t[2*y],c=t[2*y+1];g<f&&(f=g),c<d&&(d=c),g>v&&(v=g),c>u&&(u=c),this._ids[y]=y}for(var w,p,b,A=(f+v)/2,k=(d+u)/2,x=1/0,S=0;S<_;S++){var z=s(A,k,t[2*S],t[2*S+1]);z<x&&(w=S,x=z)}var U=t[2*w],M=t[2*w+1];x=1/0;for(var T=0;T<_;T++)if(T!==w){var m=s(U,M,t[2*T],t[2*T+1]);m<x&&m>0&&(p=T,x=m)}for(var K=t[2*p],L=t[2*p+1],P=1/0,E=0;E<_;E++)if(E!==w&&E!==p){var F=a(U,M,K,L,t[2*E],t[2*E+1]);F<P&&(b=E,P=F)}var H=t[2*b],I=t[2*b+1];if(P===1/0){for(var N=0;N<_;N++)this._dists[N]=t[2*N]-t[0]||t[2*N+1]-t[1];e(this._ids,this._dists,0,_-1);for(var j=new Uint32Array(_),q=0,D=0,B=-1/0;D<_;D++){var C=this._ids[D];this._dists[C]>B&&(j[q++]=C,B=this._dists[C])}return this.hull=j.subarray(0,q),this.triangles=new Uint32Array(0),void(this.halfedges=new Uint32Array(0))}if(h(U,M,K,L,H,I)){var G=p,J=K,O=L;p=b,K=H,L=I,b=G,H=J,I=O}var Q=function(i,t,r,s,h,a){var e=r-i,n=s-t,l=h-i,o=a-t,_=e*e+n*n,f=l*l+o*o,d=.5/(e*o-n*l);return{x:i+(o*_-n*f)*d,y:t+(e*f-l*_)*d}}(U,M,K,L,H,I);this._cx=Q.x,this._cy=Q.y;for(var R=0;R<_;R++)this._dists[R]=s(t[2*R],t[2*R+1],Q.x,Q.y);e(this._ids,this._dists,0,_-1),this._hullStart=w;var V=3;n[w]=r[b]=p,n[p]=r[w]=b,n[b]=r[p]=w,l[w]=0,l[p]=1,l[b]=2,o.fill(-1),o[this._hashKey(U,M)]=w,o[this._hashKey(K,L)]=p,o[this._hashKey(H,I)]=b,this.trianglesLen=0,this._addTriangle(w,p,b,-1,-1,-1);for(var W=0,X=void 0,Y=void 0;W<this._ids.length;W++){var Z=this._ids[W],$=t[2*Z],ii=t[2*Z+1];if(!(W>0&&Math.abs($-X)<=i&&Math.abs(ii-Y)<=i)&&(X=$,Y=ii,Z!==w&&Z!==p&&Z!==b)){for(var ti=0,ri=0,si=this._hashKey($,ii);ri<this._hashSize&&(-1===(ti=o[(si+ri)%this._hashSize])||ti===n[ti]);ri++);for(var hi=ti=r[ti],ai=void 0;ai=n[hi],!h($,ii,t[2*hi],t[2*hi+1],t[2*ai],t[2*ai+1]);)if((hi=ai)===ti){hi=-1;break}if(-1!==hi){var ei=this._addTriangle(hi,Z,n[hi],-1,-1,l[hi]);l[Z]=this._legalize(ei+2),l[hi]=ei,V++;for(var ni=n[hi];ai=n[ni],h($,ii,t[2*ni],t[2*ni+1],t[2*ai],t[2*ai+1]);)ei=this._addTriangle(ni,Z,ai,l[Z],-1,l[ni]),l[Z]=this._legalize(ei+2),n[ni]=ni,V--,ni=ai;if(hi===ti)for(;h($,ii,t[2*(ai=r[hi])],t[2*ai+1],t[2*hi],t[2*hi+1]);)ei=this._addTriangle(ai,Z,hi,-1,l[hi],l[ai]),this._legalize(ei+2),l[ai]=ei,n[hi]=hi,V--,hi=ai;this._hullStart=r[Z]=hi,n[hi]=r[ni]=Z,n[Z]=ni,o[this._hashKey($,ii)]=Z,o[this._hashKey(t[2*hi],t[2*hi+1])]=hi}}}this.hull=new Uint32Array(V);for(var li=0,oi=this._hullStart;li<V;li++)this.hull[li]=oi,oi=n[oi];this.triangles=this._triangles.subarray(0,this.trianglesLen),this.halfedges=this._halfedges.subarray(0,this.trianglesLen)},r.prototype._hashKey=function(i,t){return Math.floor((r=i-this._cx,s=t-this._cy,h=r/(Math.abs(r)+Math.abs(s)),(s>0?3-h:1+h)/4*this._hashSize))%this._hashSize;var r,s,h},r.prototype._legalize=function(i){for(var r,s,h,a,e,n,l,o,_,f,d,v,u,y,g,c,w=this._triangles,p=this._halfedges,b=this.coords,A=0,k=0;;){var x=p[i],S=i-i%3;if(k=S+(i+2)%3,-1!==x){var z=x-x%3,U=S+(i+1)%3,M=z+(x+2)%3,T=w[k],m=w[i],K=w[U],L=w[M];if(r=b[2*T],s=b[2*T+1],h=b[2*m],a=b[2*m+1],e=b[2*K],n=b[2*K+1],l=b[2*L],o=b[2*L+1],_=void 0,f=void 0,d=void 0,v=void 0,u=void 0,y=void 0,void 0,g=void 0,c=void 0,(_=r-l)*((v=a-o)*(c=(u=e-l)*u+(y=n-o)*y)-(g=(d=h-l)*d+v*v)*y)-(f=s-o)*(d*c-g*u)+(_*_+f*f)*(d*y-v*u)<0){w[i]=L,w[x]=T;var P=p[M];if(-1===P){var E=this._hullStart;do{if(this._hullTri[E]===M){this._hullTri[E]=i;break}E=this._hullPrev[E]}while(E!==this._hullStart)}this._link(i,P),this._link(x,p[k]),this._link(k,M);var F=z+(x+1)%3;A<t.length&&(t[A++]=F)}else{if(0===A)break;i=t[--A]}}else{if(0===A)break;i=t[--A]}}return k},r.prototype._link=function(i,t){this._halfedges[i]=t,-1!==t&&(this._halfedges[t]=i)},r.prototype._addTriangle=function(i,t,r,s,h,a){var e=this.trianglesLen;return this._triangles[e]=i,this._triangles[e+1]=t,this._triangles[e+2]=r,this._link(e,s),this._link(e+1,h),this._link(e+2,a),this.trianglesLen+=3,e},r});
const EPSILON = Math.pow(2, -52);
const EDGE_STACK = new Uint32Array(512);

@@ -26,15 +27,25 @@ export default class Delaunator {

// arrays that will store the triangulation graph
const maxTriangles = 2 * n - 5;
const triangles = this.triangles = new Uint32Array(maxTriangles * 3);
const halfedges = this.halfedges = new Int32Array(maxTriangles * 3);
const maxTriangles = Math.max(2 * n - 5, 0);
this._triangles = new Uint32Array(maxTriangles * 3);
this._halfedges = new Int32Array(maxTriangles * 3);
// temporary arrays for tracking the edges of the advancing convex hull
this._hashSize = Math.ceil(Math.sqrt(n));
const hullPrev = this.hullPrev = new Uint32Array(n); // edge to prev edge
const hullNext = this.hullNext = new Uint32Array(n); // edge to next edge
const hullTri = this.hullTri = new Uint32Array(n); // edge to adjacent triangle
const hullHash = new Int32Array(this._hashSize).fill(-1); // angular edge hash
this._hullPrev = new Uint32Array(n); // edge to prev edge
this._hullNext = new Uint32Array(n); // edge to next edge
this._hullTri = new Uint32Array(n); // edge to adjacent triangle
this._hullHash = new Int32Array(this._hashSize).fill(-1); // angular edge hash
// temporary arrays for sorting points
this._ids = new Uint32Array(n);
this._dists = new Float64Array(n);
this.update();
}
update() {
const {coords, _hullPrev: hullPrev, _hullNext: hullNext, _hullTri: hullTri, _hullHash: hullHash} = this;
const n = coords.length >> 1;
// populate an array of point indices; calculate input data bbox
const ids = new Uint32Array(n);
let minX = Infinity;

@@ -52,3 +63,3 @@ let minY = Infinity;

if (y > maxY) maxY = y;
ids[i] = i;
this._ids[i] = i;
}

@@ -101,3 +112,21 @@ const cx = (minX + maxX) / 2;

if (minRadius === Infinity) {
throw new Error('No Delaunay triangulation exists for this input.');
// order collinear points by dx (or dy if all x are identical)
// and return the list as a hull
for (let i = 0; i < n; i++) {
this._dists[i] = (coords[2 * i] - coords[0]) || (coords[2 * i + 1] - coords[1]);
}
quicksort(this._ids, this._dists, 0, n - 1);
const hull = new Uint32Array(n);
let j = 0;
for (let i = 0, d0 = -Infinity; i < n; i++) {
const id = this._ids[i];
if (this._dists[id] > d0) {
hull[j++] = id;
d0 = this._dists[id];
}
}
this.hull = hull.subarray(0, j);
this.triangles = new Uint32Array(0);
this.halfedges = new Uint32Array(0);
return;
}

@@ -122,12 +151,11 @@

const dists = new Float64Array(n);
for (let i = 0; i < n; i++) {
dists[i] = dist(coords[2 * i], coords[2 * i + 1], center.x, center.y);
this._dists[i] = dist(coords[2 * i], coords[2 * i + 1], center.x, center.y);
}
// sort the points by distance from the seed triangle circumcenter
quicksort(ids, dists, 0, n - 1);
quicksort(this._ids, this._dists, 0, n - 1);
// set up the seed triangle as the starting hull
this.hullStart = i0;
this._hullStart = i0;
let hullSize = 3;

@@ -143,2 +171,3 @@

hullHash.fill(-1);
hullHash[this._hashKey(i0x, i0y)] = i0;

@@ -151,4 +180,4 @@ hullHash[this._hashKey(i1x, i1y)] = i1;

for (let k = 0, xp, yp; k < ids.length; k++) {
const i = ids[k];
for (let k = 0, xp, yp; k < this._ids.length; k++) {
const i = this._ids[k];
const x = coords[2 * i];

@@ -214,3 +243,3 @@ const y = coords[2 * i + 1];

// update the hull indices
this.hullStart = hullPrev[i] = e;
this._hullStart = hullPrev[i] = e;
hullNext[e] = hullPrev[n] = i;

@@ -225,11 +254,10 @@ hullNext[i] = n;

this.hull = new Uint32Array(hullSize);
for (let i = 0, e = this.hullStart; i < hullSize; i++) {
for (let i = 0, e = this._hullStart; i < hullSize; i++) {
this.hull[i] = e;
e = hullNext[e];
}
this.hullPrev = this.hullNext = this.hullTri = null; // get rid of temporary arrays
// trim typed triangle mesh arrays
this.triangles = triangles.subarray(0, this.trianglesLen);
this.halfedges = halfedges.subarray(0, this.trianglesLen);
this.triangles = this._triangles.subarray(0, this.trianglesLen);
this.halfedges = this._halfedges.subarray(0, this.trianglesLen);
}

@@ -242,66 +270,81 @@

_legalize(a) {
const {triangles, coords, halfedges} = this;
const {_triangles: triangles, _halfedges: halfedges, coords} = this;
const b = halfedges[a];
let i = 0;
let ar = 0;
/* if the pair of triangles doesn't satisfy the Delaunay condition
* (p1 is inside the circumcircle of [p0, pl, pr]), flip them,
* then do the same check/flip recursively for the new pair of triangles
*
* pl pl
* /||\ / \
* al/ || \bl al/ \a
* / || \ / \
* / a||b \ flip /___ar___\
* p0\ || /p1 => p0\---bl---/p1
* \ || / \ /
* ar\ || /br b\ /br
* \||/ \ /
* pr pr
*/
const a0 = a - a % 3;
const b0 = b - b % 3;
// recursion eliminated with a fixed-size stack
while (true) {
const b = halfedges[a];
const al = a0 + (a + 1) % 3;
const ar = a0 + (a + 2) % 3;
const bl = b0 + (b + 2) % 3;
/* if the pair of triangles doesn't satisfy the Delaunay condition
* (p1 is inside the circumcircle of [p0, pl, pr]), flip them,
* then do the same check/flip recursively for the new pair of triangles
*
* pl pl
* /||\ / \
* al/ || \bl al/ \a
* / || \ / \
* / a||b \ flip /___ar___\
* p0\ || /p1 => p0\---bl---/p1
* \ || / \ /
* ar\ || /br b\ /br
* \||/ \ /
* pr pr
*/
const a0 = a - a % 3;
ar = a0 + (a + 2) % 3;
if (b === -1) return ar;
if (b === -1) { // convex hull edge
if (i === 0) break;
a = EDGE_STACK[--i];
continue;
}
const p0 = triangles[ar];
const pr = triangles[a];
const pl = triangles[al];
const p1 = triangles[bl];
const b0 = b - b % 3;
const al = a0 + (a + 1) % 3;
const bl = b0 + (b + 2) % 3;
const illegal = inCircle(
coords[2 * p0], coords[2 * p0 + 1],
coords[2 * pr], coords[2 * pr + 1],
coords[2 * pl], coords[2 * pl + 1],
coords[2 * p1], coords[2 * p1 + 1]);
const p0 = triangles[ar];
const pr = triangles[a];
const pl = triangles[al];
const p1 = triangles[bl];
if (illegal) {
triangles[a] = p1;
triangles[b] = p0;
const illegal = inCircle(
coords[2 * p0], coords[2 * p0 + 1],
coords[2 * pr], coords[2 * pr + 1],
coords[2 * pl], coords[2 * pl + 1],
coords[2 * p1], coords[2 * p1 + 1]);
const hbl = halfedges[bl];
if (illegal) {
triangles[a] = p1;
triangles[b] = p0;
// edge swapped on the other side of the hull (rare); fix the halfedge reference
if (hbl === -1) {
let e = this.hullStart;
do {
if (this.hullTri[e] === bl) {
this.hullTri[e] = a;
break;
}
e = this.hullNext[e];
} while (e !== this.hullStart);
}
this._link(a, hbl);
this._link(b, halfedges[ar]);
this._link(ar, bl);
const hbl = halfedges[bl];
const br = b0 + (b + 1) % 3;
// edge swapped on the other side of the hull (rare); fix the halfedge reference
if (hbl === -1) {
let e = this._hullStart;
do {
if (this._hullTri[e] === bl) {
this._hullTri[e] = a;
break;
}
e = this._hullPrev[e];
} while (e !== this._hullStart);
}
this._link(a, hbl);
this._link(b, halfedges[ar]);
this._link(ar, bl);
this._legalize(a);
return this._legalize(br);
const br = b0 + (b + 1) % 3;
// don't worry about hitting the cap: it can only happen on extremely degenerate input
if (i < EDGE_STACK.length) {
EDGE_STACK[i++] = br;
}
} else {
if (i === 0) break;
a = EDGE_STACK[--i];
}
}

@@ -313,4 +356,4 @@

_link(a, b) {
this.halfedges[a] = b;
if (b !== -1) this.halfedges[b] = a;
this._halfedges[a] = b;
if (b !== -1) this._halfedges[b] = a;
}

@@ -322,5 +365,5 @@

this.triangles[t] = i0;
this.triangles[t + 1] = i1;
this.triangles[t + 2] = i2;
this._triangles[t] = i0;
this._triangles[t + 1] = i1;
this._triangles[t + 2] = i2;

@@ -327,0 +370,0 @@ this._link(t, a);

{
"name": "delaunator",
"version": "3.0.2",
"version": "4.0.0",
"description": "An incredibly fast JavaScript library for Delaunay triangulation of 2D points",

@@ -11,10 +11,10 @@ "main": "delaunator.js",

"devDependencies": {
"c8": "^3.2.0",
"eslint": "^5.6.0",
"c8": "^5.0.1",
"eslint": "^5.16.0",
"eslint-config-mourner": "^3.0.0",
"esm": "^3.0.84",
"rollup": "^0.66.2",
"rollup-plugin-buble": "^0.19.2",
"rollup-plugin-terser": "^3.0.0",
"tape": "^4.9.1"
"esm": "^3.2.25",
"rollup": "^1.15.6",
"rollup-plugin-buble": "^0.19.6",
"rollup-plugin-terser": "^5.0.0",
"tape": "^4.10.2"
},

@@ -26,6 +26,6 @@ "repository": {

"scripts": {
"lint": "eslint index.js test.js bench.js rollup.config.js docs/diagrams.js",
"lint": "eslint index.js test/test.js bench.js rollup.config.js docs/diagrams.js",
"pretest": "npm run lint",
"test": "node -r esm test.js",
"cov": "c8 node -r esm test.js && c8 report -r html",
"test": "node -r esm test/test.js",
"cov": "c8 node -r esm test/test.js && c8 report -r html",
"bench": "node -r esm bench.js",

@@ -32,0 +32,0 @@ "build": "rollup -c",

@@ -9,3 +9,3 @@ # Delaunator [![Build Status](https://travis-ci.org/mapbox/delaunator.svg?branch=master)](https://travis-ci.org/mapbox/delaunator) [![](https://img.shields.io/badge/simply-awesome-brightgreen.svg)](https://github.com/mourner/projects)

Projects based on Delaunator:
### Projects based on Delaunator

@@ -15,7 +15,7 @@ - [d3-delaunay](https://github.com/d3/d3-delaunay) for Voronoi diagrams, search, traversal and rendering.

Ports to other languages:
### Ports to other languages
- [delaunator-rs](https://github.com/mourner/delaunator-rs) (Rust)
- [fogleman/delaunay](https://github.com/fogleman/delaunay) (Go)
- [delaunator-rs](https://github.com/mourner/delaunator-rs) (Rust, a work in progress)
- [delaunator-cpp](https://github.com/delfrrr/delaunator-cpp) (C++, a work in progress)
- [delaunator-cpp](https://github.com/delfrrr/delaunator-cpp) (C++)

@@ -49,4 +49,4 @@ <img src="delaunator.png" alt="Delaunay triangulation example" width="600" />

```html
<script src="https://unpkg.com/delaunator@3.0.1/delaunator.min.js"></script> <!-- minified build -->
<script src="https://unpkg.com/delaunator@3.0.1/delaunator.js"></script> <!-- dev build -->
<script src="https://unpkg.com/delaunator@3.0.2/delaunator.min.js"></script> <!-- minified build -->
<script src="https://unpkg.com/delaunator@3.0.2/delaunator.js"></script> <!-- dev build -->
```

@@ -103,2 +103,7 @@

#### delaunay.update()
Updates the triangulation if you modified `delaunay.coords` values in place, avoiding expensive memory allocations.
Useful for iterative relaxation algorithms such as [Lloyd's](https://en.wikipedia.org/wiki/Lloyd%27s_algorithm).
## Performance

@@ -111,3 +116,3 @@

:-- | --: | --: | --: | --: | --: | --: | --: | --:
**delaunator** | 95ms | 75ms | 68ms | 31ms | 1.15s | 1.11s | 979ms | 314ms
**delaunator** | 82ms | 61ms | 66ms | 25ms | 1.07s | 950ms | 830ms | 278ms
[faster&#8209;delaunay](https://github.com/Bathlamos/delaunay-triangulation) | 473ms | 411ms | 272ms | 68ms | 4.27s | 4.62s | 4.3s | 810ms

@@ -114,0 +119,0 @@ [incremental&#8209;delaunay](https://github.com/mikolalysenko/incremental-delaunay) | 547ms | 505ms | 172ms | 528ms | 5.9s | 6.08s | 2.11s | 6.09s

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc