d3-geo-voronoi
Advanced tools
Comparing version 2.0.1 to 2.1.0
@@ -1,2 +0,2 @@ | ||
// https://github.com/Fil/d3-geo-voronoi v2.0.1 Copyright 2021 Philippe Rivière | ||
// https://github.com/Fil/d3-geo-voronoi v2.1.0 Copyright 2024 Philippe Rivière | ||
(function (global, factory) { | ||
@@ -6,3 +6,3 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-delaunay'), require('d3-geo'), require('d3-array'), require('d3-tricontour')) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3, global.d3, global.d3, global.d3)); | ||
}(this, (function (exports, d3Delaunay, d3Geo, d3Array, d3Tricontour) { 'use strict'; | ||
})(this, (function (exports, d3Delaunay, d3Geo, d3Array, d3Tricontour) { 'use strict'; | ||
@@ -21,3 +21,3 @@ const pi = Math.PI; | ||
Math.sign || | ||
function(x) { | ||
function (x) { | ||
return x > 0 ? 1 : x < 0 ? -1 : 0; | ||
@@ -39,3 +39,3 @@ }; | ||
a[2] * b[0] - a[0] * b[2], | ||
a[0] * b[1] - a[1] * b[0] | ||
a[0] * b[1] - a[1] * b[0], | ||
]; | ||
@@ -57,3 +57,3 @@ } | ||
atan2(cartesian[1], cartesian[0]) * degrees, | ||
asin(max(-1, min(1, cartesian[2]))) * degrees | ||
asin(max(-1, min(1, cartesian[2]))) * degrees, | ||
]; | ||
@@ -72,3 +72,3 @@ } | ||
function excess(triangle) { | ||
triangle = triangle.map(p => cartesian(p)); | ||
triangle = triangle.map((p) => cartesian(p)); | ||
return cartesianDot(triangle[0], cartesianCross(triangle[2], triangle[1])); | ||
@@ -100,3 +100,3 @@ } | ||
urquhart, | ||
find | ||
find, | ||
}; | ||
@@ -106,6 +106,6 @@ } | ||
function geo_find(neighbors, points) { | ||
function distance2(a,b) { | ||
function distance2(a, b) { | ||
let x = a[0] - b[0], | ||
y = a[1] - b[1], | ||
z = a[2] - b[2]; | ||
y = a[1] - b[1], | ||
z = a[2] - b[2]; | ||
return x * x + y * y + z * z; | ||
@@ -124,3 +124,3 @@ } | ||
dist = distance2(xyz, cartesian(points[cell])); | ||
neighbors[cell].forEach(i => { | ||
neighbors[cell].forEach((i) => { | ||
let ndist = distance2(xyz, cartesian(points[i])); | ||
@@ -145,3 +145,3 @@ if (ndist < dist) { | ||
let pivot = 0; | ||
while (isNaN(points[pivot][0]+points[pivot][1]) && pivot++ < points.length); | ||
while (isNaN(points[pivot][0] + points[pivot][1]) && pivot++ < points.length); | ||
@@ -165,8 +165,8 @@ const r = d3Geo.geoRotation(points[pivot]), | ||
zeros.forEach(i => (points[i] = [FAR, 0])); | ||
zeros.forEach((i) => (points[i] = [FAR, 0])); | ||
// Add infinite horizon points | ||
points.push([0,FAR]); | ||
points.push([-FAR,0]); | ||
points.push([0,-FAR]); | ||
points.push([0, FAR]); | ||
points.push([-FAR, 0]); | ||
points.push([0, -FAR]); | ||
@@ -178,3 +178,3 @@ const delaunay = d3Delaunay.Delaunay.from(points); | ||
// clean up the triangulation | ||
const {triangles, halfedges, inedges} = delaunay; | ||
const { triangles, halfedges, inedges } = delaunay; | ||
for (let i = 0, l = halfedges.length; i < l; i++) { | ||
@@ -192,3 +192,3 @@ if (halfedges[i] < 0) { | ||
inedges[triangles[b]] = b % 3 == 0 ? b + 2 : b - 1; | ||
i += 2 - i % 3; | ||
i += 2 - (i % 3); | ||
} else if (triangles[i] > points.length - 3 - 1) { | ||
@@ -198,3 +198,3 @@ triangles[i] = pivot; | ||
} | ||
// there should always be 4 degenerate triangles | ||
@@ -206,7 +206,7 @@ // console.warn(degenerate); | ||
function geo_edges(triangles, points) { | ||
const _index = new Set; | ||
const _index = new Set(); | ||
if (points.length === 2) return [[0, 1]]; | ||
triangles.forEach(tri => { | ||
triangles.forEach((tri) => { | ||
if (tri[0] === tri[1]) return; | ||
if (excess(tri.map(i => points[i])) < 0) return; | ||
if (excess(tri.map((i) => points[i])) < 0) return; | ||
for (let i = 0, j; i < 3; i++) { | ||
@@ -217,7 +217,7 @@ j = (i + 1) % 3; | ||
}); | ||
return Array.from(_index, d => d.split("-").map(Number)); | ||
return Array.from(_index, (d) => d.split("-").map(Number)); | ||
} | ||
function geo_triangles(delaunay) { | ||
const {triangles} = delaunay; | ||
const { triangles } = delaunay; | ||
if (!triangles) return []; | ||
@@ -239,4 +239,4 @@ | ||
// if (!use_centroids) { | ||
return triangles.map(tri => { | ||
const c = tri.map(i => points[i]).map(cartesian), | ||
return triangles.map((tri) => { | ||
const c = tri.map((i) => points[i]).map(cartesian), | ||
V = cartesianAdd( | ||
@@ -260,3 +260,3 @@ cartesianAdd(cartesianCross(c[1], c[0]), cartesianCross(c[2], c[1])), | ||
const neighbors = []; | ||
triangles.forEach(tri => { | ||
triangles.forEach((tri) => { | ||
for (let j = 0; j < 3; j++) { | ||
@@ -297,3 +297,3 @@ const a = tri[j], | ||
cartesianCross(cartesianCross(m, c), c), | ||
cartesianCross(cartesianCross(cartesianCross(m, c), c), c) | ||
cartesianCross(cartesianCross(cartesianCross(m, c), c), c), | ||
] | ||
@@ -321,3 +321,3 @@ .map(spherical) | ||
// reorder each polygon | ||
const reordered = polygons.map(poly => { | ||
const reordered = polygons.map((poly) => { | ||
const p = [poly[0][2]]; // t | ||
@@ -372,3 +372,3 @@ let k = poly[0][1]; // k = c | ||
const s = sign(cartesianDot(cartesianCross(b, a), c)); | ||
return spherical(cartesianNormalize(cartesianAdd(a, b)).map(d => s * d)); | ||
return spherical(cartesianNormalize(cartesianAdd(a, b)).map((d) => s * d)); | ||
} | ||
@@ -378,3 +378,3 @@ | ||
const mesh = []; | ||
polygons.forEach(poly => { | ||
polygons.forEach((poly) => { | ||
if (!poly) return; | ||
@@ -391,3 +391,3 @@ let p = poly[poly.length - 1]; | ||
function geo_urquhart(edges, triangles) { | ||
return function(distances) { | ||
return function (distances) { | ||
const _lengths = new Map(), | ||
@@ -401,3 +401,3 @@ _urquhart = new Map(); | ||
triangles.forEach(tri => { | ||
triangles.forEach((tri) => { | ||
let l = 0, | ||
@@ -412,6 +412,6 @@ remove = -1; | ||
} | ||
_urquhart.set(remove, false); | ||
_urquhart.set(remove, false); | ||
}); | ||
return edges.map(edge => _urquhart.get(edge.join("-"))); | ||
return edges.map((edge) => _urquhart.get(edge.join("-"))); | ||
}; | ||
@@ -423,4 +423,5 @@ } | ||
hull = []; | ||
triangles.map(tri => { | ||
if (excess(tri.map(i => points[i > points.length ? 0 : i])) > 1e-12) return; | ||
triangles.map((tri) => { | ||
if (excess(tri.map((i) => points[i > points.length ? 0 : i])) > 1e-12) | ||
return; | ||
for (let i = 0; i < 3; i++) { | ||
@@ -434,7 +435,7 @@ let e = [tri[i], tri[(i + 1) % 3]], | ||
const _index = new Map; | ||
const _index = new Map(); | ||
let start; | ||
_hull.forEach(e => { | ||
_hull.forEach((e) => { | ||
e = e.split("-").map(Number); | ||
_index.set(e[0],e[1]); | ||
_index.set(e[0], e[1]); | ||
start = e[0]; | ||
@@ -457,3 +458,3 @@ }); | ||
function geoVoronoi(data) { | ||
const v = function(data) { | ||
const v = function (data) { | ||
v.delaunay = null; | ||
@@ -467,6 +468,6 @@ v._data = data; | ||
const temp = v._data | ||
.map(d => [v._vx(d), v._vy(d), d]) | ||
.filter(d => isFinite(d[0] + d[1])); | ||
v.points = temp.map(d => [d[0], d[1]]); | ||
v.valid = temp.map(d => d[2]); | ||
.map((d) => [v._vx(d), v._vy(d), d]) | ||
.filter((d) => isFinite(d[0] + d[1])); | ||
v.points = temp.map((d) => [d[0], d[1]]); | ||
v.valid = temp.map((d) => d[2]); | ||
v.delaunay = geoDelaunay(v.points); | ||
@@ -477,3 +478,3 @@ } | ||
v._vx = function(d) { | ||
v._vx = function (d) { | ||
if (typeof d == "object" && "type" in d) { | ||
@@ -484,3 +485,3 @@ return d3Geo.geoCentroid(d)[0]; | ||
}; | ||
v._vy = function(d) { | ||
v._vy = function (d) { | ||
if (typeof d == "object" && "type" in d) { | ||
@@ -492,3 +493,3 @@ return d3Geo.geoCentroid(d)[1]; | ||
v.x = function(f) { | ||
v.x = function (f) { | ||
if (!f) return v._vx; | ||
@@ -498,3 +499,3 @@ v._vx = f; | ||
}; | ||
v.y = function(f) { | ||
v.y = function (f) { | ||
if (!f) return v._vy; | ||
@@ -505,3 +506,3 @@ v._vy = f; | ||
v.polygons = function(data) { | ||
v.polygons = function (data) { | ||
if (data !== undefined) { | ||
@@ -514,3 +515,3 @@ v(data); | ||
type: "FeatureCollection", | ||
features: [] | ||
features: [], | ||
}; | ||
@@ -525,3 +526,5 @@ if (v.valid.length === 0) return coll; | ||
type: "Polygon", | ||
coordinates: [[...poly, poly[0]].map(i => v.delaunay.centers[i])] | ||
coordinates: [ | ||
[...poly, poly[0]].map((i) => v.delaunay.centers[i]), | ||
], | ||
}, | ||
@@ -531,4 +534,4 @@ properties: { | ||
sitecoordinates: v.points[i], | ||
neighbours: v.delaunay.neighbors[i] // not part of the public API | ||
} | ||
neighbours: v.delaunay.neighbors[i], // not part of the public API | ||
}, | ||
}) | ||
@@ -543,4 +546,4 @@ ); | ||
sitecoordinates: v.points[0], | ||
neighbours: [] | ||
} | ||
neighbours: [], | ||
}, | ||
}); | ||
@@ -550,3 +553,3 @@ return coll; | ||
v.triangles = function(data) { | ||
v.triangles = function (data) { | ||
if (data !== undefined) { | ||
@@ -561,21 +564,21 @@ v(data); | ||
.map((tri, index) => { | ||
tri = tri.map(i => v.points[i]); | ||
tri = tri.map((i) => v.points[i]); | ||
tri.center = v.delaunay.centers[index]; | ||
return tri; | ||
}) | ||
.filter(tri => excess(tri) > 0) | ||
.map(tri => ({ | ||
.filter((tri) => excess(tri) > 0) | ||
.map((tri) => ({ | ||
type: "Feature", | ||
properties: { | ||
circumcenter: tri.center | ||
circumcenter: tri.center, | ||
}, | ||
geometry: { | ||
type: "Polygon", | ||
coordinates: [[...tri, tri[0]]] | ||
} | ||
})) | ||
coordinates: [[...tri, tri[0]]], | ||
}, | ||
})), | ||
}; | ||
}; | ||
v.links = function(data) { | ||
v.links = function (data) { | ||
if (data !== undefined) { | ||
@@ -585,3 +588,3 @@ v(data); | ||
if (!v.delaunay) return false; | ||
const _distances = v.delaunay.edges.map(e => | ||
const _distances = v.delaunay.edges.map((e) => | ||
d3Geo.geoDistance(v.points[e[0]], v.points[e[1]]) | ||
@@ -598,13 +601,13 @@ ), | ||
length: _distances[i], | ||
urquhart: !!_urquart[i] | ||
urquhart: !!_urquart[i], | ||
}, | ||
geometry: { | ||
type: "LineString", | ||
coordinates: [v.points[e[0]], v.points[e[1]]] | ||
} | ||
})) | ||
coordinates: [v.points[e[0]], v.points[e[1]]], | ||
}, | ||
})), | ||
}; | ||
}; | ||
v.mesh = function(data) { | ||
v.mesh = function (data) { | ||
if (data !== undefined) { | ||
@@ -616,7 +619,10 @@ v(data); | ||
type: "MultiLineString", | ||
coordinates: v.delaunay.edges.map(e => [v.points[e[0]], v.points[e[1]]]) | ||
coordinates: v.delaunay.edges.map((e) => [ | ||
v.points[e[0]], | ||
v.points[e[1]], | ||
]), | ||
}; | ||
}; | ||
v.cellMesh = function(data) { | ||
v.cellMesh = function (data) { | ||
if (data !== undefined) { | ||
@@ -642,3 +648,3 @@ v(data); | ||
type: "MultiLineString", | ||
coordinates | ||
coordinates, | ||
}; | ||
@@ -648,3 +654,3 @@ }; | ||
v._found = undefined; | ||
v.find = function(x, y, radius) { | ||
v.find = function (x, y, radius) { | ||
v._found = v.delaunay.find(x, y, v._found); | ||
@@ -655,3 +661,3 @@ if (!radius || d3Geo.geoDistance([x, y], v.points[v._found]) < radius) | ||
v.hull = function(data) { | ||
v.hull = function (data) { | ||
if (data !== undefined) { | ||
@@ -666,3 +672,3 @@ v(data); | ||
type: "Polygon", | ||
coordinates: [[...hull.map(i => points[i]), points[hull[0]]]] | ||
coordinates: [[...hull.map((i) => points[i]), points[hull[0]]]], | ||
}; | ||
@@ -678,3 +684,3 @@ }; | ||
.triangulate((data, x, y) => { | ||
v = geoDelaunay(data.map(d => [x(d), y(d)])); | ||
v = geoDelaunay(data.map((d, i) => [x(d, i), y(d, i)])); | ||
return v.delaunay; | ||
@@ -685,6 +691,6 @@ }) | ||
const A = projection.invert([points[2 * i], points[2 * i + 1]]), | ||
B = projection.invert([points[2 * j], points[2 * j + 1]]); | ||
B = projection.invert([points[2 * j], points[2 * j + 1]]); | ||
return d3Geo.geoInterpolate(A, B)(a); | ||
}) | ||
.ringsort(rings => { | ||
.ringsort((rings) => { | ||
// tricky thing: in isobands this function is called twice, | ||
@@ -694,3 +700,3 @@ // we want to reverse the polygons’s winding order only in tricontour() | ||
if (rings.length && !rings[0].reversed) { | ||
rings.forEach(ring => ring.reverse()); | ||
rings.forEach((ring) => ring.reverse()); | ||
rings[0].reversed = true; | ||
@@ -710,2 +716,2 @@ } | ||
}))); | ||
})); |
@@ -1,2 +0,2 @@ | ||
// https://github.com/Fil/d3-geo-voronoi v2.0.1 Copyright 2021 Philippe Rivière | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-delaunay"),require("d3-geo"),require("d3-array"),require("d3-tricontour")):"function"==typeof define&&define.amd?define(["exports","d3-delaunay","d3-geo","d3-array","d3-tricontour"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).d3=e.d3||{},e.d3,e.d3,e.d3,e.d3)}(this,(function(e,t,n,o,r){"use strict";const i=Math.PI,u=i/2,a=180/i,s=i/180,l=Math.atan2,c=Math.cos,f=Math.max,p=Math.min,d=Math.sin,h=Math.sign||function(e){return e>0?1:e<0?-1:0},g=Math.sqrt;function y(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function m(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function v(e,t){return[e[0]+t[0],e[1]+t[1],e[2]+t[2]]}function _(e){var t=g(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);return[e[0]/t,e[1]/t,e[2]/t]}function M(e){return[l(e[1],e[0])*a,(t=f(-1,p(1,e[2])),(t>1?u:t<-1?-u:Math.asin(t))*a)];var t}function b(e){const t=e[0]*s,n=e[1]*s,o=c(n);return[o*c(t),o*d(t),d(n)]}function j(e){return y((e=e.map((e=>b(e))))[0],m(e[2],e[1]))}function E(e){const r=function(e){if(e.length<2)return{};let o=0;for(;isNaN(e[o][0]+e[o][1])&&o++<e.length;);const r=n.geoRotation(e[o]),i=n.geoStereographic().translate([0,0]).scale(1).rotate(r.invert([180,0]));e=e.map(i);const u=[];let a=1;for(let t=0,n=e.length;t<n;t++){let n=e[t][0]**2+e[t][1]**2;!isFinite(n)||n>1e32?u.push(t):n>a&&(a=n)}const s=1e6*g(a);u.forEach((t=>e[t]=[s,0])),e.push([0,s]),e.push([-s,0]),e.push([0,-s]);const l=t.Delaunay.from(e);l.projection=i;const{triangles:c,halfedges:f,inedges:p}=l;for(let t=0,n=f.length;t<n;t++)if(f[t]<0){const e=t%3==2?t-2:t+1,n=t%3==0?t+2:t-1,r=f[e],i=f[n];f[r]=i,f[i]=r,f[e]=f[n]=-1,c[t]=c[e]=c[n]=o,p[c[r]]=r%3==0?r+2:r-1,p[c[i]]=i%3==0?i+2:i-1,t+=2-t%3}else c[t]>e.length-3-1&&(c[t]=o);return l}(e),i=function(e){const{triangles:t}=e;if(!t)return[];const n=[];for(let e=0,o=t.length/3;e<o;e++){const o=t[3*e],r=t[3*e+1],i=t[3*e+2];o!==r&&r!==i&&n.push([o,i,r])}return n}(r),u=function(e,t){const n=new Set;return 2===t.length?[[0,1]]:(e.forEach((e=>{if(e[0]!==e[1]&&!(j(e.map((e=>t[e])))<0))for(let t,r=0;r<3;r++)t=(r+1)%3,n.add(o.extent([e[r],e[t]]).join("-"))})),Array.from(n,(e=>e.split("-").map(Number))))}(i,e),a=function(e,t){const n=[];e.forEach((e=>{for(let t=0;t<3;t++){const o=e[t],r=e[(t+1)%3];n[o]=n[o]||[],n[o].push(r)}})),0===e.length&&(2===t?(n[0]=[1],n[1]=[0]):1===t&&(n[0]=[]));return n}(i,e.length),s=function(e,t){function n(e,t){let n=e[0]-t[0],o=e[1]-t[1],r=e[2]-t[2];return n*n+o*o+r*r}return function(o,r,i){void 0===i&&(i=0);let u,a,s=i;const l=b([o,r]);do{u=i,i=null,a=n(l,b(t[u])),e[u].forEach((e=>{let o=n(l,b(t[e]));if(o<a)return a=o,i=e,void(s=e)}))}while(null!==i);return s}}(a,e),l=function(e,t){return e.map((e=>{const n=e.map((e=>t[e])).map(b);return M(_(v(v(m(n[1],n[0]),m(n[2],n[1])),m(n[0],n[2]))))}))}(i,e),{polygons:c,centers:f}=function(e,t,n){const o=[],r=e.slice();if(0===t.length){if(n.length<2)return{polygons:o,centers:r};if(2===n.length){const e=b(n[0]),t=b(n[1]),u=_(v(e,t)),a=_(m(e,t)),s=m(u,a),l=[u,m(u,s),m(m(u,s),s),m(m(m(u,s),s),s)].map(M).map(i);return o.push(l),o.push(l.slice().reverse()),{polygons:o,centers:r}}}t.forEach(((e,t)=>{for(let n=0;n<3;n++){const r=e[n],i=e[(n+1)%3],u=e[(n+2)%3];o[r]=o[r]||[],o[r].push([i,u,t,[r,i,u]])}}));function i(e){let n=-1;return r.slice(t.length,1/0).forEach(((o,r)=>{o[0]===e[0]&&o[1]===e[1]&&(n=r+t.length)})),n<0&&(n=r.length,r.push(e)),n}return{polygons:o.map((e=>{const t=[e[0][2]];let o=e[0][1];for(let n=1;n<e.length;n++)for(let n=0;n<e.length;n++)if(e[n][0]==o){o=e[n][1],t.push(e[n][2]);break}if(t.length>2)return t;if(2==t.length){const o=x(n[e[0][3][0]],n[e[0][3][1]],r[t[0]]),u=x(n[e[0][3][2]],n[e[0][3][0]],r[t[0]]),a=i(o),s=i(u);return[t[0],s,t[1],a]}})),centers:r}}(l,i,e),p=function(e){const t=[];return e.forEach((e=>{if(!e)return;let n=e[e.length-1];for(let o of e)o>n&&t.push([n,o]),n=o})),t}(c),d=function(e,t){const n=new Set,o=[];e.map((e=>{if(!(j(e.map((e=>t[e>t.length?0:e])))>1e-12))for(let t=0;t<3;t++){let o=[e[t],e[(t+1)%3]],r=`${o[0]}-${o[1]}`;n.has(r)?n.delete(r):n.add(`${o[1]}-${o[0]}`)}}));const r=new Map;let i;if(n.forEach((e=>{e=e.split("-").map(Number),r.set(e[0],e[1]),i=e[0]})),void 0===i)return o;let u=i;do{o.push(u);let e=r.get(u);r.set(u,-1),u=e}while(u>-1&&u!==i);return o}(i,e),h=function(e,t){return function(n){const r=new Map,i=new Map;return e.forEach(((e,t)=>{const o=e.join("-");r.set(o,n[t]),i.set(o,!0)})),t.forEach((e=>{let t=0,n=-1;for(let i=0;i<3;i++){let u=o.extent([e[i],e[(i+1)%3]]).join("-");r.get(u)>t&&(t=r.get(u),n=u)}i.set(n,!1)})),e.map((e=>i.get(e.join("-"))))}}(u,i);return{delaunay:r,edges:u,triangles:i,centers:f,neighbors:a,polygons:c,mesh:p,hull:d,urquhart:h,find:s}}function x(e,t,n){e=b(e),t=b(t),n=b(n);const o=h(y(m(t,e),n));return M(_(v(e,t)).map((e=>o*e)))}e.geoContour=function(){let e;return r.tricontour().triangulate(((t,n,o)=>(e=E(t.map((e=>[n(e),o(e)]))),e.delaunay))).pointInterpolate(((t,o,r)=>{const{points:i,projection:u}=e.delaunay,a=u.invert([i[2*t],i[2*t+1]]),s=u.invert([i[2*o],i[2*o+1]]);return n.geoInterpolate(a,s)(r)})).ringsort((e=>(e.length&&!e[0].reversed&&(e.forEach((e=>e.reverse())),e[0].reversed=!0),[e])))},e.geoDelaunay=E,e.geoVoronoi=function(e){const t=function(e){if(t.delaunay=null,t._data=e,"object"==typeof t._data&&"FeatureCollection"===t._data.type&&(t._data=t._data.features),"object"==typeof t._data){const e=t._data.map((e=>[t._vx(e),t._vy(e),e])).filter((e=>isFinite(e[0]+e[1])));t.points=e.map((e=>[e[0],e[1]])),t.valid=e.map((e=>e[2])),t.delaunay=E(t.points)}return t};return t._vx=function(e){return"object"==typeof e&&"type"in e?n.geoCentroid(e)[0]:0 in e?e[0]:void 0},t._vy=function(e){return"object"==typeof e&&"type"in e?n.geoCentroid(e)[1]:1 in e?e[1]:void 0},t.x=function(e){return e?(t._vx=e,t):t._vx},t.y=function(e){return e?(t._vy=e,t):t._vy},t.polygons=function(e){if(void 0!==e&&t(e),!t.delaunay)return!1;const n={type:"FeatureCollection",features:[]};return 0===t.valid.length||(t.delaunay.polygons.forEach(((e,o)=>n.features.push({type:"Feature",geometry:e?{type:"Polygon",coordinates:[[...e,e[0]].map((e=>t.delaunay.centers[e]))]}:null,properties:{site:t.valid[o],sitecoordinates:t.points[o],neighbours:t.delaunay.neighbors[o]}}))),1===t.valid.length&&n.features.push({type:"Feature",geometry:{type:"Sphere"},properties:{site:t.valid[0],sitecoordinates:t.points[0],neighbours:[]}})),n},t.triangles=function(e){return void 0!==e&&t(e),!!t.delaunay&&{type:"FeatureCollection",features:t.delaunay.triangles.map(((e,n)=>((e=e.map((e=>t.points[e]))).center=t.delaunay.centers[n],e))).filter((e=>j(e)>0)).map((e=>({type:"Feature",properties:{circumcenter:e.center},geometry:{type:"Polygon",coordinates:[[...e,e[0]]]}})))}},t.links=function(e){if(void 0!==e&&t(e),!t.delaunay)return!1;const o=t.delaunay.edges.map((e=>n.geoDistance(t.points[e[0]],t.points[e[1]]))),r=t.delaunay.urquhart(o);return{type:"FeatureCollection",features:t.delaunay.edges.map(((e,n)=>({type:"Feature",properties:{source:t.valid[e[0]],target:t.valid[e[1]],length:o[n],urquhart:!!r[n]},geometry:{type:"LineString",coordinates:[t.points[e[0]],t.points[e[1]]]}})))}},t.mesh=function(e){return void 0!==e&&t(e),!!t.delaunay&&{type:"MultiLineString",coordinates:t.delaunay.edges.map((e=>[t.points[e[0]],t.points[e[1]]]))}},t.cellMesh=function(e){if(void 0!==e&&t(e),!t.delaunay)return!1;const{centers:n,polygons:o}=t.delaunay,r=[];for(const e of o)if(e)for(let t=e.length,o=e[t-1],i=e[0],u=0;u<t;o=i,i=e[++u])i>o&&r.push([n[o],n[i]]);return{type:"MultiLineString",coordinates:r}},t._found=void 0,t.find=function(e,o,r){if(t._found=t.delaunay.find(e,o,t._found),!r||n.geoDistance([e,o],t.points[t._found])<r)return t._found},t.hull=function(e){void 0!==e&&t(e);const n=t.delaunay.hull,o=t.points;return 0===n.length?null:{type:"Polygon",coordinates:[[...n.map((e=>o[e])),o[n[0]]]]}},e?t(e):t},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
// https://github.com/Fil/d3-geo-voronoi v2.1.0 Copyright 2024 Philippe Rivière | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-delaunay"),require("d3-geo"),require("d3-array"),require("d3-tricontour")):"function"==typeof define&&define.amd?define(["exports","d3-delaunay","d3-geo","d3-array","d3-tricontour"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).d3=e.d3||{},e.d3,e.d3,e.d3,e.d3)}(this,(function(e,t,n,o,r){"use strict";const i=Math.PI,u=i/2,a=180/i,s=i/180,l=Math.atan2,c=Math.cos,f=Math.max,p=Math.min,d=Math.sin,h=Math.sign||function(e){return e>0?1:e<0?-1:0},g=Math.sqrt;function y(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function m(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function v(e,t){return[e[0]+t[0],e[1]+t[1],e[2]+t[2]]}function _(e){var t=g(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);return[e[0]/t,e[1]/t,e[2]/t]}function M(e){return[l(e[1],e[0])*a,(t=f(-1,p(1,e[2])),(t>1?u:t<-1?-u:Math.asin(t))*a)];var t}function b(e){const t=e[0]*s,n=e[1]*s,o=c(n);return[o*c(t),o*d(t),d(n)]}function j(e){return y((e=e.map((e=>b(e))))[0],m(e[2],e[1]))}function E(e){const r=function(e){if(e.length<2)return{};let o=0;for(;isNaN(e[o][0]+e[o][1])&&o++<e.length;);const r=n.geoRotation(e[o]),i=n.geoStereographic().translate([0,0]).scale(1).rotate(r.invert([180,0]));e=e.map(i);const u=[];let a=1;for(let t=0,n=e.length;t<n;t++){let n=e[t][0]**2+e[t][1]**2;!isFinite(n)||n>1e32?u.push(t):n>a&&(a=n)}const s=1e6*g(a);u.forEach((t=>e[t]=[s,0])),e.push([0,s]),e.push([-s,0]),e.push([0,-s]);const l=t.Delaunay.from(e);l.projection=i;const{triangles:c,halfedges:f,inedges:p}=l;for(let t=0,n=f.length;t<n;t++)if(f[t]<0){const e=t%3==2?t-2:t+1,n=t%3==0?t+2:t-1,r=f[e],i=f[n];f[r]=i,f[i]=r,f[e]=f[n]=-1,c[t]=c[e]=c[n]=o,p[c[r]]=r%3==0?r+2:r-1,p[c[i]]=i%3==0?i+2:i-1,t+=2-t%3}else c[t]>e.length-3-1&&(c[t]=o);return l}(e),i=function(e){const{triangles:t}=e;if(!t)return[];const n=[];for(let e=0,o=t.length/3;e<o;e++){const o=t[3*e],r=t[3*e+1],i=t[3*e+2];o!==r&&r!==i&&n.push([o,i,r])}return n}(r),u=function(e,t){const n=new Set;return 2===t.length?[[0,1]]:(e.forEach((e=>{if(e[0]!==e[1]&&!(j(e.map((e=>t[e])))<0))for(let t,r=0;r<3;r++)t=(r+1)%3,n.add(o.extent([e[r],e[t]]).join("-"))})),Array.from(n,(e=>e.split("-").map(Number))))}(i,e),a=function(e,t){const n=[];e.forEach((e=>{for(let t=0;t<3;t++){const o=e[t],r=e[(t+1)%3];n[o]=n[o]||[],n[o].push(r)}})),0===e.length&&(2===t?(n[0]=[1],n[1]=[0]):1===t&&(n[0]=[]));return n}(i,e.length),s=function(e,t){function n(e,t){let n=e[0]-t[0],o=e[1]-t[1],r=e[2]-t[2];return n*n+o*o+r*r}return function(o,r,i){void 0===i&&(i=0);let u,a,s=i;const l=b([o,r]);do{u=i,i=null,a=n(l,b(t[u])),e[u].forEach((e=>{let o=n(l,b(t[e]));if(o<a)return a=o,i=e,void(s=e)}))}while(null!==i);return s}}(a,e),l=function(e,t){return e.map((e=>{const n=e.map((e=>t[e])).map(b);return M(_(v(v(m(n[1],n[0]),m(n[2],n[1])),m(n[0],n[2]))))}))}(i,e),{polygons:c,centers:f}=function(e,t,n){const o=[],r=e.slice();if(0===t.length){if(n.length<2)return{polygons:o,centers:r};if(2===n.length){const e=b(n[0]),t=b(n[1]),i=_(v(e,t)),a=_(m(e,t)),s=m(i,a),l=[i,m(i,s),m(m(i,s),s),m(m(m(i,s),s),s)].map(M).map(u);return o.push(l),o.push(l.slice().reverse()),{polygons:o,centers:r}}}t.forEach(((e,t)=>{for(let n=0;n<3;n++){const r=e[n],i=e[(n+1)%3],u=e[(n+2)%3];o[r]=o[r]||[],o[r].push([i,u,t,[r,i,u]])}}));const i=o.map((e=>{const t=[e[0][2]];let o=e[0][1];for(let n=1;n<e.length;n++)for(let n=0;n<e.length;n++)if(e[n][0]==o){o=e[n][1],t.push(e[n][2]);break}if(t.length>2)return t;if(2==t.length){const o=x(n[e[0][3][0]],n[e[0][3][1]],r[t[0]]),i=x(n[e[0][3][2]],n[e[0][3][0]],r[t[0]]),a=u(o),s=u(i);return[t[0],s,t[1],a]}}));function u(e){let n=-1;return r.slice(t.length,1/0).forEach(((o,r)=>{o[0]===e[0]&&o[1]===e[1]&&(n=r+t.length)})),n<0&&(n=r.length,r.push(e)),n}return{polygons:i,centers:r}}(l,i,e),p=function(e){const t=[];return e.forEach((e=>{if(!e)return;let n=e[e.length-1];for(let o of e)o>n&&t.push([n,o]),n=o})),t}(c),d=function(e,t){const n=new Set,o=[];e.map((e=>{if(!(j(e.map((e=>t[e>t.length?0:e])))>1e-12))for(let t=0;t<3;t++){let o=[e[t],e[(t+1)%3]],r=`${o[0]}-${o[1]}`;n.has(r)?n.delete(r):n.add(`${o[1]}-${o[0]}`)}}));const r=new Map;let i;if(n.forEach((e=>{e=e.split("-").map(Number),r.set(e[0],e[1]),i=e[0]})),void 0===i)return o;let u=i;do{o.push(u);let e=r.get(u);r.set(u,-1),u=e}while(u>-1&&u!==i);return o}(i,e),h=function(e,t){return function(n){const r=new Map,i=new Map;return e.forEach(((e,t)=>{const o=e.join("-");r.set(o,n[t]),i.set(o,!0)})),t.forEach((e=>{let t=0,n=-1;for(let i=0;i<3;i++){let u=o.extent([e[i],e[(i+1)%3]]).join("-");r.get(u)>t&&(t=r.get(u),n=u)}i.set(n,!1)})),e.map((e=>i.get(e.join("-"))))}}(u,i);return{delaunay:r,edges:u,triangles:i,centers:f,neighbors:a,polygons:c,mesh:p,hull:d,urquhart:h,find:s}}function x(e,t,n){e=b(e),t=b(t),n=b(n);const o=h(y(m(t,e),n));return M(_(v(e,t)).map((e=>o*e)))}e.geoContour=function(){let e;return r.tricontour().triangulate(((t,n,o)=>(e=E(t.map(((e,t)=>[n(e,t),o(e,t)]))),e.delaunay))).pointInterpolate(((t,o,r)=>{const{points:i,projection:u}=e.delaunay,a=u.invert([i[2*t],i[2*t+1]]),s=u.invert([i[2*o],i[2*o+1]]);return n.geoInterpolate(a,s)(r)})).ringsort((e=>(e.length&&!e[0].reversed&&(e.forEach((e=>e.reverse())),e[0].reversed=!0),[e])))},e.geoDelaunay=E,e.geoVoronoi=function(e){const t=function(e){if(t.delaunay=null,t._data=e,"object"==typeof t._data&&"FeatureCollection"===t._data.type&&(t._data=t._data.features),"object"==typeof t._data){const e=t._data.map((e=>[t._vx(e),t._vy(e),e])).filter((e=>isFinite(e[0]+e[1])));t.points=e.map((e=>[e[0],e[1]])),t.valid=e.map((e=>e[2])),t.delaunay=E(t.points)}return t};return t._vx=function(e){return"object"==typeof e&&"type"in e?n.geoCentroid(e)[0]:0 in e?e[0]:void 0},t._vy=function(e){return"object"==typeof e&&"type"in e?n.geoCentroid(e)[1]:1 in e?e[1]:void 0},t.x=function(e){return e?(t._vx=e,t):t._vx},t.y=function(e){return e?(t._vy=e,t):t._vy},t.polygons=function(e){if(void 0!==e&&t(e),!t.delaunay)return!1;const n={type:"FeatureCollection",features:[]};return 0===t.valid.length||(t.delaunay.polygons.forEach(((e,o)=>n.features.push({type:"Feature",geometry:e?{type:"Polygon",coordinates:[[...e,e[0]].map((e=>t.delaunay.centers[e]))]}:null,properties:{site:t.valid[o],sitecoordinates:t.points[o],neighbours:t.delaunay.neighbors[o]}}))),1===t.valid.length&&n.features.push({type:"Feature",geometry:{type:"Sphere"},properties:{site:t.valid[0],sitecoordinates:t.points[0],neighbours:[]}})),n},t.triangles=function(e){return void 0!==e&&t(e),!!t.delaunay&&{type:"FeatureCollection",features:t.delaunay.triangles.map(((e,n)=>((e=e.map((e=>t.points[e]))).center=t.delaunay.centers[n],e))).filter((e=>j(e)>0)).map((e=>({type:"Feature",properties:{circumcenter:e.center},geometry:{type:"Polygon",coordinates:[[...e,e[0]]]}})))}},t.links=function(e){if(void 0!==e&&t(e),!t.delaunay)return!1;const o=t.delaunay.edges.map((e=>n.geoDistance(t.points[e[0]],t.points[e[1]]))),r=t.delaunay.urquhart(o);return{type:"FeatureCollection",features:t.delaunay.edges.map(((e,n)=>({type:"Feature",properties:{source:t.valid[e[0]],target:t.valid[e[1]],length:o[n],urquhart:!!r[n]},geometry:{type:"LineString",coordinates:[t.points[e[0]],t.points[e[1]]]}})))}},t.mesh=function(e){return void 0!==e&&t(e),!!t.delaunay&&{type:"MultiLineString",coordinates:t.delaunay.edges.map((e=>[t.points[e[0]],t.points[e[1]]]))}},t.cellMesh=function(e){if(void 0!==e&&t(e),!t.delaunay)return!1;const{centers:n,polygons:o}=t.delaunay,r=[];for(const e of o)if(e)for(let t=e.length,o=e[t-1],i=e[0],u=0;u<t;o=i,i=e[++u])i>o&&r.push([n[o],n[i]]);return{type:"MultiLineString",coordinates:r}},t._found=void 0,t.find=function(e,o,r){if(t._found=t.delaunay.find(e,o,t._found),!r||n.geoDistance([e,o],t.points[t._found])<r)return t._found},t.hull=function(e){void 0!==e&&t(e);const n=t.delaunay.hull,o=t.points;return 0===n.length?null:{type:"Polygon",coordinates:[[...n.map((e=>o[e])),o[n[0]]]]}},e?t(e):t},Object.defineProperty(e,"__esModule",{value:!0})})); |
{ | ||
"name": "d3-geo-voronoi", | ||
"version": "2.0.1", | ||
"version": "2.1.0", | ||
"description": "Spherical Voronoi Diagram and Delaunay Triangulation", | ||
@@ -43,3 +43,3 @@ "homepage": "https://github.com/Fil/d3-geo-voronoi", | ||
"eslint": "7", | ||
"mocha": "8", | ||
"mocha": "10", | ||
"package-preamble": "0.1", | ||
@@ -46,0 +46,0 @@ "rollup": "2", |
@@ -192,3 +192,3 @@ # d3-geo-voronoi | ||
<a href="#geocontour" name="geocontour">#</a> d3.<b>geoContour</b>() | ||
· [Source](https://github.com/Fil/d3-geo-voronoi/blob/main/src/contour.js), [Examples](https://observablehq.com/collection/@fil/tricontours) | ||
· [Source](https://github.com/Fil/d3-geo-voronoi/blob/main/src/contour.js), [Examples](https://observablehq.com/@fil/spherical-contours) | ||
@@ -200,3 +200,3 @@ Constructs a new geocontour generator with the default settings. | ||
<a href="#_geocontour" name="_geocontour">#</a> _geocontour_(_data_) · [Examples](https://observablehq.com/@fil/tricontours) | ||
<a href="#_geocontour" name="_geocontour">#</a> _geocontour_(_data_) · [Examples](https://observablehq.com/@fil/spherical-contours) | ||
@@ -203,0 +203,0 @@ Returns an array of contours, one for each threshold. The contours are MultiPolygons in GeoJSON format, that contain all the points with a value larger than the threshold. The value is indicated as _geometry_.value. |
@@ -8,3 +8,3 @@ import { asin, atan2, cos, sin, sqrt } from "./math.js"; | ||
export function cartesian(spherical) { | ||
var lambda = spherical[0], | ||
const lambda = spherical[0], | ||
phi = spherical[1], | ||
@@ -23,3 +23,3 @@ cosPhi = cos(phi); | ||
a[2] * b[0] - a[0] * b[2], | ||
a[0] * b[1] - a[1] * b[0] | ||
a[0] * b[1] - a[1] * b[0], | ||
]; | ||
@@ -26,0 +26,0 @@ } |
@@ -1,4 +0,4 @@ | ||
import {geoDelaunay} from "./delaunay.js"; | ||
import {geoInterpolate} from "d3-geo"; | ||
import {tricontour} from "d3-tricontour"; | ||
import { geoDelaunay } from "./delaunay.js"; | ||
import { geoInterpolate } from "d3-geo"; | ||
import { tricontour } from "d3-tricontour"; | ||
@@ -9,3 +9,3 @@ export function geoContour() { | ||
.triangulate((data, x, y) => { | ||
v = geoDelaunay(data.map(d => [x(d), y(d)])); | ||
v = geoDelaunay(data.map((d, i) => [x(d, i), y(d, i)])); | ||
return v.delaunay; | ||
@@ -16,6 +16,6 @@ }) | ||
const A = projection.invert([points[2 * i], points[2 * i + 1]]), | ||
B = projection.invert([points[2 * j], points[2 * j + 1]]); | ||
B = projection.invert([points[2 * j], points[2 * j + 1]]); | ||
return geoInterpolate(A, B)(a); | ||
}) | ||
.ringsort(rings => { | ||
.ringsort((rings) => { | ||
// tricky thing: in isobands this function is called twice, | ||
@@ -25,3 +25,3 @@ // we want to reverse the polygons’s winding order only in tricontour() | ||
if (rings.length && !rings[0].reversed) { | ||
rings.forEach(ring => ring.reverse()); | ||
rings.forEach((ring) => ring.reverse()); | ||
rings[0].reversed = true; | ||
@@ -28,0 +28,0 @@ } |
@@ -14,3 +14,3 @@ import { Delaunay } from "d3-delaunay"; | ||
sin, | ||
sqrt | ||
sqrt, | ||
} from "./math.js"; | ||
@@ -21,3 +21,3 @@ import { | ||
cartesianDot as dot, | ||
cartesianAdd | ||
cartesianAdd, | ||
} from "./cartesian.js"; | ||
@@ -29,3 +29,3 @@ | ||
atan2(cartesian[1], cartesian[0]) * degrees, | ||
asin(max(-1, min(1, cartesian[2]))) * degrees | ||
asin(max(-1, min(1, cartesian[2]))) * degrees, | ||
]; | ||
@@ -44,3 +44,3 @@ } | ||
export function excess(triangle) { | ||
triangle = triangle.map(p => cartesian(p)); | ||
triangle = triangle.map((p) => cartesian(p)); | ||
return dot(triangle[0], cross(triangle[2], triangle[1])); | ||
@@ -72,3 +72,3 @@ } | ||
urquhart, | ||
find | ||
find, | ||
}; | ||
@@ -78,6 +78,6 @@ } | ||
function geo_find(neighbors, points) { | ||
function distance2(a,b) { | ||
function distance2(a, b) { | ||
let x = a[0] - b[0], | ||
y = a[1] - b[1], | ||
z = a[2] - b[2]; | ||
y = a[1] - b[1], | ||
z = a[2] - b[2]; | ||
return x * x + y * y + z * z; | ||
@@ -96,3 +96,3 @@ } | ||
dist = distance2(xyz, cartesian(points[cell])); | ||
neighbors[cell].forEach(i => { | ||
neighbors[cell].forEach((i) => { | ||
let ndist = distance2(xyz, cartesian(points[i])); | ||
@@ -117,3 +117,3 @@ if (ndist < dist) { | ||
let pivot = 0; | ||
while (isNaN(points[pivot][0]+points[pivot][1]) && pivot++ < points.length); | ||
while (isNaN(points[pivot][0] + points[pivot][1]) && pivot++ < points.length); | ||
@@ -137,8 +137,8 @@ const r = geoRotation(points[pivot]), | ||
zeros.forEach(i => (points[i] = [FAR, 0])); | ||
zeros.forEach((i) => (points[i] = [FAR, 0])); | ||
// Add infinite horizon points | ||
points.push([0,FAR]); | ||
points.push([-FAR,0]); | ||
points.push([0,-FAR]); | ||
points.push([0, FAR]); | ||
points.push([-FAR, 0]); | ||
points.push([0, -FAR]); | ||
@@ -150,3 +150,3 @@ const delaunay = Delaunay.from(points); | ||
// clean up the triangulation | ||
const {triangles, halfedges, inedges} = delaunay; | ||
const { triangles, halfedges, inedges } = delaunay; | ||
const degenerate = []; | ||
@@ -165,4 +165,4 @@ for (let i = 0, l = halfedges.length; i < l; i++) { | ||
inedges[triangles[b]] = b % 3 == 0 ? b + 2 : b - 1; | ||
degenerate.push(Math.min(i,j,k)); | ||
i += 2 - i % 3; | ||
degenerate.push(Math.min(i, j, k)); | ||
i += 2 - (i % 3); | ||
} else if (triangles[i] > points.length - 3 - 1) { | ||
@@ -172,3 +172,3 @@ triangles[i] = pivot; | ||
} | ||
// there should always be 4 degenerate triangles | ||
@@ -180,7 +180,7 @@ // console.warn(degenerate); | ||
function geo_edges(triangles, points) { | ||
const _index = new Set; | ||
const _index = new Set(); | ||
if (points.length === 2) return [[0, 1]]; | ||
triangles.forEach(tri => { | ||
triangles.forEach((tri) => { | ||
if (tri[0] === tri[1]) return; | ||
if (excess(tri.map(i => points[i])) < 0) return; | ||
if (excess(tri.map((i) => points[i])) < 0) return; | ||
for (let i = 0, j; i < 3; i++) { | ||
@@ -191,7 +191,7 @@ j = (i + 1) % 3; | ||
}); | ||
return Array.from(_index, d => d.split("-").map(Number)); | ||
return Array.from(_index, (d) => d.split("-").map(Number)); | ||
} | ||
function geo_triangles(delaunay) { | ||
const {triangles} = delaunay; | ||
const { triangles } = delaunay; | ||
if (!triangles) return []; | ||
@@ -213,4 +213,4 @@ | ||
// if (!use_centroids) { | ||
return triangles.map(tri => { | ||
const c = tri.map(i => points[i]).map(cartesian), | ||
return triangles.map((tri) => { | ||
const c = tri.map((i) => points[i]).map(cartesian), | ||
V = cartesianAdd( | ||
@@ -234,3 +234,3 @@ cartesianAdd(cross(c[1], c[0]), cross(c[2], c[1])), | ||
const neighbors = []; | ||
triangles.forEach(tri => { | ||
triangles.forEach((tri) => { | ||
for (let j = 0; j < 3; j++) { | ||
@@ -271,3 +271,3 @@ const a = tri[j], | ||
cross(cross(m, c), c), | ||
cross(cross(cross(m, c), c), c) | ||
cross(cross(cross(m, c), c), c), | ||
] | ||
@@ -295,3 +295,3 @@ .map(spherical) | ||
// reorder each polygon | ||
const reordered = polygons.map(poly => { | ||
const reordered = polygons.map((poly) => { | ||
const p = [poly[0][2]]; // t | ||
@@ -346,3 +346,3 @@ let k = poly[0][1]; // k = c | ||
const s = sign(dot(cross(b, a), c)); | ||
return spherical(normalize(cartesianAdd(a, b)).map(d => s * d)); | ||
return spherical(normalize(cartesianAdd(a, b)).map((d) => s * d)); | ||
} | ||
@@ -352,3 +352,3 @@ | ||
const mesh = []; | ||
polygons.forEach(poly => { | ||
polygons.forEach((poly) => { | ||
if (!poly) return; | ||
@@ -365,3 +365,3 @@ let p = poly[poly.length - 1]; | ||
function geo_urquhart(edges, triangles) { | ||
return function(distances) { | ||
return function (distances) { | ||
const _lengths = new Map(), | ||
@@ -375,3 +375,3 @@ _urquhart = new Map(); | ||
triangles.forEach(tri => { | ||
triangles.forEach((tri) => { | ||
let l = 0, | ||
@@ -386,6 +386,6 @@ remove = -1; | ||
} | ||
_urquhart.set(remove, false); | ||
_urquhart.set(remove, false); | ||
}); | ||
return edges.map(edge => _urquhart.get(edge.join("-"))); | ||
return edges.map((edge) => _urquhart.get(edge.join("-"))); | ||
}; | ||
@@ -397,4 +397,5 @@ } | ||
hull = []; | ||
triangles.map(tri => { | ||
if (excess(tri.map(i => points[i > points.length ? 0 : i])) > 1e-12) return; | ||
triangles.map((tri) => { | ||
if (excess(tri.map((i) => points[i > points.length ? 0 : i])) > 1e-12) | ||
return; | ||
for (let i = 0; i < 3; i++) { | ||
@@ -408,7 +409,7 @@ let e = [tri[i], tri[(i + 1) % 3]], | ||
const _index = new Map; | ||
const _index = new Map(); | ||
let start; | ||
_hull.forEach(e => { | ||
_hull.forEach((e) => { | ||
e = e.split("-").map(Number); | ||
_index.set(e[0],e[1]); | ||
_index.set(e[0], e[1]); | ||
start = e[0]; | ||
@@ -415,0 +416,0 @@ }); |
@@ -1,3 +0,3 @@ | ||
export {geoDelaunay} from "./delaunay.js"; | ||
export {geoVoronoi} from "./voronoi.js"; | ||
export {geoContour} from "./contour.js"; | ||
export { geoDelaunay } from "./delaunay.js"; | ||
export { geoVoronoi } from "./voronoi.js"; | ||
export { geoContour } from "./contour.js"; |
@@ -25,3 +25,3 @@ export const epsilon = 1e-6; | ||
Math.sign || | ||
function(x) { | ||
function (x) { | ||
return x > 0 ? 1 : x < 0 ? -1 : 0; | ||
@@ -28,0 +28,0 @@ }; |
@@ -5,3 +5,3 @@ import { geoCentroid, geoDistance } from "d3-geo"; | ||
export function geoVoronoi(data) { | ||
const v = function(data) { | ||
const v = function (data) { | ||
v.delaunay = null; | ||
@@ -15,6 +15,6 @@ v._data = data; | ||
const temp = v._data | ||
.map(d => [v._vx(d), v._vy(d), d]) | ||
.filter(d => isFinite(d[0] + d[1])); | ||
v.points = temp.map(d => [d[0], d[1]]); | ||
v.valid = temp.map(d => d[2]); | ||
.map((d) => [v._vx(d), v._vy(d), d]) | ||
.filter((d) => isFinite(d[0] + d[1])); | ||
v.points = temp.map((d) => [d[0], d[1]]); | ||
v.valid = temp.map((d) => d[2]); | ||
v.delaunay = geoDelaunay(v.points); | ||
@@ -25,3 +25,3 @@ } | ||
v._vx = function(d) { | ||
v._vx = function (d) { | ||
if (typeof d == "object" && "type" in d) { | ||
@@ -32,3 +32,3 @@ return geoCentroid(d)[0]; | ||
}; | ||
v._vy = function(d) { | ||
v._vy = function (d) { | ||
if (typeof d == "object" && "type" in d) { | ||
@@ -40,3 +40,3 @@ return geoCentroid(d)[1]; | ||
v.x = function(f) { | ||
v.x = function (f) { | ||
if (!f) return v._vx; | ||
@@ -46,3 +46,3 @@ v._vx = f; | ||
}; | ||
v.y = function(f) { | ||
v.y = function (f) { | ||
if (!f) return v._vy; | ||
@@ -53,3 +53,3 @@ v._vy = f; | ||
v.polygons = function(data) { | ||
v.polygons = function (data) { | ||
if (data !== undefined) { | ||
@@ -62,3 +62,3 @@ v(data); | ||
type: "FeatureCollection", | ||
features: [] | ||
features: [], | ||
}; | ||
@@ -73,3 +73,5 @@ if (v.valid.length === 0) return coll; | ||
type: "Polygon", | ||
coordinates: [[...poly, poly[0]].map(i => v.delaunay.centers[i])] | ||
coordinates: [ | ||
[...poly, poly[0]].map((i) => v.delaunay.centers[i]), | ||
], | ||
}, | ||
@@ -79,4 +81,4 @@ properties: { | ||
sitecoordinates: v.points[i], | ||
neighbours: v.delaunay.neighbors[i] // not part of the public API | ||
} | ||
neighbours: v.delaunay.neighbors[i], // not part of the public API | ||
}, | ||
}) | ||
@@ -91,4 +93,4 @@ ); | ||
sitecoordinates: v.points[0], | ||
neighbours: [] | ||
} | ||
neighbours: [], | ||
}, | ||
}); | ||
@@ -98,3 +100,3 @@ return coll; | ||
v.triangles = function(data) { | ||
v.triangles = function (data) { | ||
if (data !== undefined) { | ||
@@ -109,21 +111,21 @@ v(data); | ||
.map((tri, index) => { | ||
tri = tri.map(i => v.points[i]); | ||
tri = tri.map((i) => v.points[i]); | ||
tri.center = v.delaunay.centers[index]; | ||
return tri; | ||
}) | ||
.filter(tri => excess(tri) > 0) | ||
.map(tri => ({ | ||
.filter((tri) => excess(tri) > 0) | ||
.map((tri) => ({ | ||
type: "Feature", | ||
properties: { | ||
circumcenter: tri.center | ||
circumcenter: tri.center, | ||
}, | ||
geometry: { | ||
type: "Polygon", | ||
coordinates: [[...tri, tri[0]]] | ||
} | ||
})) | ||
coordinates: [[...tri, tri[0]]], | ||
}, | ||
})), | ||
}; | ||
}; | ||
v.links = function(data) { | ||
v.links = function (data) { | ||
if (data !== undefined) { | ||
@@ -133,3 +135,3 @@ v(data); | ||
if (!v.delaunay) return false; | ||
const _distances = v.delaunay.edges.map(e => | ||
const _distances = v.delaunay.edges.map((e) => | ||
geoDistance(v.points[e[0]], v.points[e[1]]) | ||
@@ -146,13 +148,13 @@ ), | ||
length: _distances[i], | ||
urquhart: !!_urquart[i] | ||
urquhart: !!_urquart[i], | ||
}, | ||
geometry: { | ||
type: "LineString", | ||
coordinates: [v.points[e[0]], v.points[e[1]]] | ||
} | ||
})) | ||
coordinates: [v.points[e[0]], v.points[e[1]]], | ||
}, | ||
})), | ||
}; | ||
}; | ||
v.mesh = function(data) { | ||
v.mesh = function (data) { | ||
if (data !== undefined) { | ||
@@ -164,7 +166,10 @@ v(data); | ||
type: "MultiLineString", | ||
coordinates: v.delaunay.edges.map(e => [v.points[e[0]], v.points[e[1]]]) | ||
coordinates: v.delaunay.edges.map((e) => [ | ||
v.points[e[0]], | ||
v.points[e[1]], | ||
]), | ||
}; | ||
}; | ||
v.cellMesh = function(data) { | ||
v.cellMesh = function (data) { | ||
if (data !== undefined) { | ||
@@ -190,3 +195,3 @@ v(data); | ||
type: "MultiLineString", | ||
coordinates | ||
coordinates, | ||
}; | ||
@@ -196,3 +201,3 @@ }; | ||
v._found = undefined; | ||
v.find = function(x, y, radius) { | ||
v.find = function (x, y, radius) { | ||
v._found = v.delaunay.find(x, y, v._found); | ||
@@ -203,3 +208,3 @@ if (!radius || geoDistance([x, y], v.points[v._found]) < radius) | ||
v.hull = function(data) { | ||
v.hull = function (data) { | ||
if (data !== undefined) { | ||
@@ -214,3 +219,3 @@ v(data); | ||
type: "Polygon", | ||
coordinates: [[...hull.map(i => points[i]), points[hull[0]]]] | ||
coordinates: [[...hull.map((i) => points[i]), points[hull[0]]]], | ||
}; | ||
@@ -217,0 +222,0 @@ }; |
61178
1288