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

sweepline-intersections

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sweepline-intersections - npm Package Compare versions

Comparing version 1.0.1 to 1.1.1

CHANGELOG.md

159

dist/sweeplineIntersections.esm.js

@@ -80,15 +80,7 @@ class TinyQueue {

class Segment {
constructor (event) {
this.leftSweepEvent = event;
this.rightSweepEvent = event.otherEvent;
}
}
function checkWhichEventIsLeft (e1, e2) {
if (e1.p.x > e2.p.x) return 1;
if (e1.p.x < e2.p.x) return -1;
if (e1.p.x > e2.p.x) return 1
if (e1.p.x < e2.p.x) return -1
if (e1.p.y !== e2.p.y) return e1.p.y > e2.p.y ? 1 : -1;
if (e1.p.y !== e2.p.y) return e1.p.y > e2.p.y ? 1 : -1
return 1

@@ -98,6 +90,6 @@ }

function checkWhichSegmentHasRightEndpointFirst (seg1, seg2) {
if (seg1.rightSweepEvent.p.x > seg2.rightSweepEvent.p.x) return 1;
if (seg1.rightSweepEvent.p.x < seg2.rightSweepEvent.p.x) return -1;
if (seg1.rightSweepEvent.p.x > seg2.rightSweepEvent.p.x) return 1
if (seg1.rightSweepEvent.p.x < seg2.rightSweepEvent.p.x) return -1
if (seg1.rightSweepEvent.p.y !== seg2.rightSweepEvent.p.y) return seg1.rightSweepEvent.p.y < seg2.rightSweepEvent.p.y ? 1 : -1;
if (seg1.rightSweepEvent.p.y !== seg2.rightSweepEvent.p.y) return seg1.rightSweepEvent.p.y < seg2.rightSweepEvent.p.y ? 1 : -1
return 1

@@ -118,3 +110,3 @@ }

isSamePoint(eventToCheck) {
isSamePoint (eventToCheck) {
return this.p.x === eventToCheck.p.x && this.p.y === eventToCheck.p.y

@@ -125,32 +117,44 @@ }

function fillEventQueue (geojson, eventQueue) {
const geom = geojson.type === 'Feature' ? geojson.geometry : geojson;
if (geojson.type === 'FeatureCollection') {
const features = geojson.features;
for (let i = 0; i < features.length; i++) {
processFeature(features[i], eventQueue);
}
} else {
processFeature(geojson, eventQueue);
}
}
function processFeature (featureOrGeometry, eventQueue) {
const geom = featureOrGeometry.type === 'Feature' ? featureOrGeometry.geometry : featureOrGeometry;
let coords = geom.coordinates;
// standardise the input
if (geom.type === 'Polygon') coords = [coords];
if (geom.type === 'Polygon' || geom.type === 'MultiLineString') coords = [coords];
if (geom.type === 'LineString') coords = [[coords]];
for (let i = 0; i < coords[0].length; i++) {
let currentP = coords[0][i][0];
let nextP = null;
for (let i = 0; i < coords.length; i++) {
for (let ii = 0; ii < coords[i].length; ii++) {
let currentP = coords[i][ii][0];
let nextP = null;
for (let ii = 0; ii < coords[0][i].length - 1; ii++) {
nextP = coords[0][i][ii + 1];
for (let iii = 0; iii < coords[i][ii].length - 1; iii++) {
nextP = coords[i][ii][iii + 1];
const e1 = new Event(currentP);
const e2 = new Event(nextP);
const e1 = new Event(currentP);
const e2 = new Event(nextP);
e1.otherEvent = e2;
e2.otherEvent = e1;
e1.otherEvent = e2;
e2.otherEvent = e1;
if (checkWhichEventIsLeft(e1, e2) > 0) {
e2.isLeftEndpoint = true;
e1.isLeftEndpoint = false;
} else {
e1.isLeftEndpoint = true;
e2.isLeftEndpoint = false;
if (checkWhichEventIsLeft(e1, e2) > 0) {
e2.isLeftEndpoint = true;
e1.isLeftEndpoint = false;
} else {
e1.isLeftEndpoint = true;
e2.isLeftEndpoint = false;
}
eventQueue.push(e1);
eventQueue.push(e2);
currentP = nextP;
}
eventQueue.push(e1);
eventQueue.push(e2);
currentP = nextP;
}

@@ -160,47 +164,51 @@ }

function testSegmentIntersect (seg1, seg2) {
if (seg1 === null || seg2 === null) return false
class Segment {
if (seg1.rightSweepEvent.isSamePoint(seg2.leftSweepEvent) ||
seg1.rightSweepEvent.isSamePoint(seg2.rightSweepEvent) ||
seg1.leftSweepEvent.isSamePoint(seg2.leftSweepEvent) ||
seg1.leftSweepEvent.isSamePoint(seg2.rightSweepEvent)) return false
constructor (event) {
this.leftSweepEvent = event;
this.rightSweepEvent = event.otherEvent;
}
}
const x1 = seg1.leftSweepEvent.p.x;
const y1 = seg1.leftSweepEvent.p.y;
const x2 = seg1.rightSweepEvent.p.x;
const y2 = seg1.rightSweepEvent.p.y;
const x3 = seg2.leftSweepEvent.p.x;
const y3 = seg2.leftSweepEvent.p.y;
const x4 = seg2.rightSweepEvent.p.x;
const y4 = seg2.rightSweepEvent.p.y;
function testSegmentIntersect (seg1, seg2) {
if (seg1 === null || seg2 === null) return false
const denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));
const numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
const numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));
if (seg1.rightSweepEvent.isSamePoint(seg2.leftSweepEvent) ||
seg1.rightSweepEvent.isSamePoint(seg2.rightSweepEvent) ||
seg1.leftSweepEvent.isSamePoint(seg2.leftSweepEvent) ||
seg1.leftSweepEvent.isSamePoint(seg2.rightSweepEvent)) return false
if (denom === 0) {
if (numeA === 0 && numeB === 0) return false
return false
}
const x1 = seg1.leftSweepEvent.p.x;
const y1 = seg1.leftSweepEvent.p.y;
const x2 = seg1.rightSweepEvent.p.x;
const y2 = seg1.rightSweepEvent.p.y;
const x3 = seg2.leftSweepEvent.p.x;
const y3 = seg2.leftSweepEvent.p.y;
const x4 = seg2.rightSweepEvent.p.x;
const y4 = seg2.rightSweepEvent.p.y;
const uA = numeA / denom;
const uB = numeB / denom;
const denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));
const numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
const numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
const x = x1 + (uA * (x2 - x1));
const y = y1 + (uA * (y2 - y1));
return [x, y]
}
if (denom === 0) {
if (numeA === 0 && numeB === 0) return false
return false
}
const uA = numeA / denom;
const uB = numeB / denom;
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
const x = x1 + (uA * (x2 - x1));
const y = y1 + (uA * (y2 - y1));
return [x, y]
}
return false
}
// import {debugEventAndSegments, debugRemovingSegment} from './debug'
function bentleyOttmann (geojson) {
function runCheck (eventQueue) {
const intersectionPoints = [];
const eventQueue = new TinyQueue([], checkWhichEventIsLeft);
fillEventQueue(geojson, eventQueue);
const outQueue = new TinyQueue([], checkWhichSegmentHasRightEndpointFirst);

@@ -219,3 +227,4 @@

} else if (event.isLeftEndpoint === false) {
const seg = outQueue.pop();
outQueue.pop();
// const seg = outQueue.pop()
// debugRemovingSegment(event.p, seg)

@@ -227,2 +236,8 @@ }

export default bentleyOttmann;
function sweeplineIntersections (geojson) {
const eventQueue = new TinyQueue([], checkWhichEventIsLeft);
fillEventQueue(geojson, eventQueue);
return runCheck(eventQueue)
}
export default sweeplineIntersections;

@@ -5,3 +5,3 @@ (function (global, factory) {

(global = global || self, global.sweeplineIntersections = factory());
}(this, function () { 'use strict';
}(this, (function () { 'use strict';

@@ -87,15 +87,7 @@ class TinyQueue {

class Segment {
constructor (event) {
this.leftSweepEvent = event;
this.rightSweepEvent = event.otherEvent;
}
}
function checkWhichEventIsLeft (e1, e2) {
if (e1.p.x > e2.p.x) return 1;
if (e1.p.x < e2.p.x) return -1;
if (e1.p.x > e2.p.x) return 1
if (e1.p.x < e2.p.x) return -1
if (e1.p.y !== e2.p.y) return e1.p.y > e2.p.y ? 1 : -1;
if (e1.p.y !== e2.p.y) return e1.p.y > e2.p.y ? 1 : -1
return 1

@@ -105,6 +97,6 @@ }

function checkWhichSegmentHasRightEndpointFirst (seg1, seg2) {
if (seg1.rightSweepEvent.p.x > seg2.rightSweepEvent.p.x) return 1;
if (seg1.rightSweepEvent.p.x < seg2.rightSweepEvent.p.x) return -1;
if (seg1.rightSweepEvent.p.x > seg2.rightSweepEvent.p.x) return 1
if (seg1.rightSweepEvent.p.x < seg2.rightSweepEvent.p.x) return -1
if (seg1.rightSweepEvent.p.y !== seg2.rightSweepEvent.p.y) return seg1.rightSweepEvent.p.y < seg2.rightSweepEvent.p.y ? 1 : -1;
if (seg1.rightSweepEvent.p.y !== seg2.rightSweepEvent.p.y) return seg1.rightSweepEvent.p.y < seg2.rightSweepEvent.p.y ? 1 : -1
return 1

@@ -125,3 +117,3 @@ }

isSamePoint(eventToCheck) {
isSamePoint (eventToCheck) {
return this.p.x === eventToCheck.p.x && this.p.y === eventToCheck.p.y

@@ -132,32 +124,44 @@ }

function fillEventQueue (geojson, eventQueue) {
const geom = geojson.type === 'Feature' ? geojson.geometry : geojson;
if (geojson.type === 'FeatureCollection') {
const features = geojson.features;
for (let i = 0; i < features.length; i++) {
processFeature(features[i], eventQueue);
}
} else {
processFeature(geojson, eventQueue);
}
}
function processFeature (featureOrGeometry, eventQueue) {
const geom = featureOrGeometry.type === 'Feature' ? featureOrGeometry.geometry : featureOrGeometry;
let coords = geom.coordinates;
// standardise the input
if (geom.type === 'Polygon') coords = [coords];
if (geom.type === 'Polygon' || geom.type === 'MultiLineString') coords = [coords];
if (geom.type === 'LineString') coords = [[coords]];
for (let i = 0; i < coords[0].length; i++) {
let currentP = coords[0][i][0];
let nextP = null;
for (let i = 0; i < coords.length; i++) {
for (let ii = 0; ii < coords[i].length; ii++) {
let currentP = coords[i][ii][0];
let nextP = null;
for (let ii = 0; ii < coords[0][i].length - 1; ii++) {
nextP = coords[0][i][ii + 1];
for (let iii = 0; iii < coords[i][ii].length - 1; iii++) {
nextP = coords[i][ii][iii + 1];
const e1 = new Event(currentP);
const e2 = new Event(nextP);
const e1 = new Event(currentP);
const e2 = new Event(nextP);
e1.otherEvent = e2;
e2.otherEvent = e1;
e1.otherEvent = e2;
e2.otherEvent = e1;
if (checkWhichEventIsLeft(e1, e2) > 0) {
e2.isLeftEndpoint = true;
e1.isLeftEndpoint = false;
} else {
e1.isLeftEndpoint = true;
e2.isLeftEndpoint = false;
if (checkWhichEventIsLeft(e1, e2) > 0) {
e2.isLeftEndpoint = true;
e1.isLeftEndpoint = false;
} else {
e1.isLeftEndpoint = true;
e2.isLeftEndpoint = false;
}
eventQueue.push(e1);
eventQueue.push(e2);
currentP = nextP;
}
eventQueue.push(e1);
eventQueue.push(e2);
currentP = nextP;
}

@@ -167,47 +171,51 @@ }

function testSegmentIntersect (seg1, seg2) {
if (seg1 === null || seg2 === null) return false
class Segment {
if (seg1.rightSweepEvent.isSamePoint(seg2.leftSweepEvent) ||
seg1.rightSweepEvent.isSamePoint(seg2.rightSweepEvent) ||
seg1.leftSweepEvent.isSamePoint(seg2.leftSweepEvent) ||
seg1.leftSweepEvent.isSamePoint(seg2.rightSweepEvent)) return false
constructor (event) {
this.leftSweepEvent = event;
this.rightSweepEvent = event.otherEvent;
}
}
const x1 = seg1.leftSweepEvent.p.x;
const y1 = seg1.leftSweepEvent.p.y;
const x2 = seg1.rightSweepEvent.p.x;
const y2 = seg1.rightSweepEvent.p.y;
const x3 = seg2.leftSweepEvent.p.x;
const y3 = seg2.leftSweepEvent.p.y;
const x4 = seg2.rightSweepEvent.p.x;
const y4 = seg2.rightSweepEvent.p.y;
function testSegmentIntersect (seg1, seg2) {
if (seg1 === null || seg2 === null) return false
const denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));
const numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
const numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));
if (seg1.rightSweepEvent.isSamePoint(seg2.leftSweepEvent) ||
seg1.rightSweepEvent.isSamePoint(seg2.rightSweepEvent) ||
seg1.leftSweepEvent.isSamePoint(seg2.leftSweepEvent) ||
seg1.leftSweepEvent.isSamePoint(seg2.rightSweepEvent)) return false
if (denom === 0) {
if (numeA === 0 && numeB === 0) return false
return false
}
const x1 = seg1.leftSweepEvent.p.x;
const y1 = seg1.leftSweepEvent.p.y;
const x2 = seg1.rightSweepEvent.p.x;
const y2 = seg1.rightSweepEvent.p.y;
const x3 = seg2.leftSweepEvent.p.x;
const y3 = seg2.leftSweepEvent.p.y;
const x4 = seg2.rightSweepEvent.p.x;
const y4 = seg2.rightSweepEvent.p.y;
const uA = numeA / denom;
const uB = numeB / denom;
const denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));
const numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
const numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
const x = x1 + (uA * (x2 - x1));
const y = y1 + (uA * (y2 - y1));
return [x, y]
}
if (denom === 0) {
if (numeA === 0 && numeB === 0) return false
return false
}
const uA = numeA / denom;
const uB = numeB / denom;
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
const x = x1 + (uA * (x2 - x1));
const y = y1 + (uA * (y2 - y1));
return [x, y]
}
return false
}
// import {debugEventAndSegments, debugRemovingSegment} from './debug'
function bentleyOttmann (geojson) {
function runCheck (eventQueue) {
const intersectionPoints = [];
const eventQueue = new TinyQueue([], checkWhichEventIsLeft);
fillEventQueue(geojson, eventQueue);
const outQueue = new TinyQueue([], checkWhichSegmentHasRightEndpointFirst);

@@ -226,3 +234,4 @@

} else if (event.isLeftEndpoint === false) {
const seg = outQueue.pop();
outQueue.pop();
// const seg = outQueue.pop()
// debugRemovingSegment(event.p, seg)

@@ -234,4 +243,10 @@ }

return bentleyOttmann;
function sweeplineIntersections (geojson) {
const eventQueue = new TinyQueue([], checkWhichEventIsLeft);
fillEventQueue(geojson, eventQueue);
return runCheck(eventQueue)
}
}));
return sweeplineIntersections;
})));

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

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).sweeplineIntersections=e()}(this,function(){"use strict";class t{constructor(t=[],e=function(t,e){return t<e?-1:t>e?1:0}){if(this.data=t,this.length=this.data.length,this.compare=e,this.length>0)for(let t=(this.length>>1)-1;t>=0;t--)this._down(t)}push(t){this.data.push(t),this.length++,this._up(this.length-1)}pop(){if(0===this.length)return;const t=this.data[0];return this.length--,this.length>0&&(this.data[0]=this.data[this.length],this._down(0)),this.data.pop(),t}peek(){return this.data[0]}_up(t){const{data:e,compare:n}=this,i=e[t];for(;t>0;){const p=t-1>>1,s=e[p];if(n(i,s)>=0)break;e[t]=s,t=p}e[t]=i}_down(t){const{data:e,compare:n}=this,i=this.length>>1,p=e[t];for(;t<i;){let i=1+(t<<1),s=e[i];const h=i+1;if(h<this.length&&n(e[h],s)<0&&(i=h,s=e[h]),n(s,p)>=0)break;e[t]=s,t=i}e[t]=p}}class e{constructor(t){this.leftSweepEvent=t,this.rightSweepEvent=t.otherEvent}}function n(t,e){return t.p.x>e.p.x?1:t.p.x<e.p.x?-1:t.p.y!==e.p.y?t.p.y>e.p.y?1:-1:1}function i(t,e){return t.rightSweepEvent.p.x>e.rightSweepEvent.p.x?1:t.rightSweepEvent.p.x<e.rightSweepEvent.p.x?-1:t.rightSweepEvent.p.y!==e.rightSweepEvent.p.y?t.rightSweepEvent.p.y<e.rightSweepEvent.p.y?1:-1:1}class p{constructor(t){this.p={x:t[0],y:t[1]},this.otherEvent=null,this.isLeftEndpoint=null}isSamePoint(t){return this.p.x===t.p.x&&this.p.y===t.p.y}}function s(t,e){if(null===t||null===e)return!1;if(t.rightSweepEvent.isSamePoint(e.leftSweepEvent)||t.rightSweepEvent.isSamePoint(e.rightSweepEvent)||t.leftSweepEvent.isSamePoint(e.leftSweepEvent)||t.leftSweepEvent.isSamePoint(e.rightSweepEvent))return!1;const n=t.leftSweepEvent.p.x,i=t.leftSweepEvent.p.y,p=t.rightSweepEvent.p.x,s=t.rightSweepEvent.p.y,h=e.leftSweepEvent.p.x,o=e.leftSweepEvent.p.y,r=e.rightSweepEvent.p.x,l=e.rightSweepEvent.p.y,f=(l-o)*(p-n)-(r-h)*(s-i),u=(r-h)*(i-o)-(l-o)*(n-h),a=(p-n)*(i-o)-(s-i)*(n-h);if(0===f)return!1;const c=u/f,E=a/f;if(c>=0&&c<=1&&E>=0&&E<=1){return[n+c*(p-n),i+c*(s-i)]}return!1}return function(h){const o=[],r=new t([],n);!function(t,e){const i="Feature"===t.type?t.geometry:t;let s=i.coordinates;"Polygon"===i.type&&(s=[s]);for(let t=0;t<s[0].length;t++){let i=s[0][t][0],h=null;for(let o=0;o<s[0][t].length-1;o++){h=s[0][t][o+1];const r=new p(i),l=new p(h);r.otherEvent=l,l.otherEvent=r,n(r,l)>0?(l.isLeftEndpoint=!0,r.isLeftEndpoint=!1):(r.isLeftEndpoint=!0,l.isLeftEndpoint=!1),e.push(r),e.push(l),i=h}}}(h,r);const l=new t([],i);for(;r.length;){const t=r.pop();if(t.isLeftEndpoint){const n=new e(t);for(let t=0;t<l.data.length;t++){const e=s(n,l.data[t]);!1!==e&&o.push(e)}l.push(n)}else!1===t.isLeftEndpoint&&l.pop()}return o}});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).sweeplineIntersections=e()}(this,function(){"use strict";class t{constructor(t=[],e=function(t,e){return t<e?-1:t>e?1:0}){if(this.data=t,this.length=this.data.length,this.compare=e,this.length>0)for(let t=(this.length>>1)-1;t>=0;t--)this._down(t)}push(t){this.data.push(t),this.length++,this._up(this.length-1)}pop(){if(0===this.length)return;const t=this.data[0];return this.length--,this.length>0&&(this.data[0]=this.data[this.length],this._down(0)),this.data.pop(),t}peek(){return this.data[0]}_up(t){const{data:e,compare:n}=this,i=e[t];for(;t>0;){const p=t-1>>1,s=e[p];if(n(i,s)>=0)break;e[t]=s,t=p}e[t]=i}_down(t){const{data:e,compare:n}=this,i=this.length>>1,p=e[t];for(;t<i;){let i=1+(t<<1),s=e[i];const o=i+1;if(o<this.length&&n(e[o],s)<0&&(i=o,s=e[o]),n(s,p)>=0)break;e[t]=s,t=i}e[t]=p}}function e(t,e){return t.p.x>e.p.x?1:t.p.x<e.p.x?-1:t.p.y!==e.p.y?t.p.y>e.p.y?1:-1:1}function n(t,e){return t.rightSweepEvent.p.x>e.rightSweepEvent.p.x?1:t.rightSweepEvent.p.x<e.rightSweepEvent.p.x?-1:t.rightSweepEvent.p.y!==e.rightSweepEvent.p.y?t.rightSweepEvent.p.y<e.rightSweepEvent.p.y?1:-1:1}class i{constructor(t){this.p={x:t[0],y:t[1]},this.otherEvent=null,this.isLeftEndpoint=null}isSamePoint(t){return this.p.x===t.p.x&&this.p.y===t.p.y}}function p(t,n){const p="Feature"===t.type?t.geometry:t;let s=p.coordinates;"Polygon"!==p.type&&"MultiLineString"!==p.type||(s=[s]),"LineString"===p.type&&(s=[[s]]);for(let t=0;t<s.length;t++)for(let p=0;p<s[t].length;p++){let o=s[t][p][0],r=null;for(let h=0;h<s[t][p].length-1;h++){r=s[t][p][h+1];const l=new i(o),f=new i(r);l.otherEvent=f,f.otherEvent=l,e(l,f)>0?(f.isLeftEndpoint=!0,l.isLeftEndpoint=!1):(l.isLeftEndpoint=!0,f.isLeftEndpoint=!1),n.push(l),n.push(f),o=r}}}class s{constructor(t){this.leftSweepEvent=t,this.rightSweepEvent=t.otherEvent}}function o(t,e){if(null===t||null===e)return!1;if(t.rightSweepEvent.isSamePoint(e.leftSweepEvent)||t.rightSweepEvent.isSamePoint(e.rightSweepEvent)||t.leftSweepEvent.isSamePoint(e.leftSweepEvent)||t.leftSweepEvent.isSamePoint(e.rightSweepEvent))return!1;const n=t.leftSweepEvent.p.x,i=t.leftSweepEvent.p.y,p=t.rightSweepEvent.p.x,s=t.rightSweepEvent.p.y,o=e.leftSweepEvent.p.x,r=e.leftSweepEvent.p.y,h=e.rightSweepEvent.p.x,l=e.rightSweepEvent.p.y,f=(l-r)*(p-n)-(h-o)*(s-i),u=(h-o)*(i-r)-(l-r)*(n-o),c=(p-n)*(i-r)-(s-i)*(n-o);if(0===f)return!1;const a=u/f,g=c/f;if(a>=0&&a<=1&&g>=0&&g<=1){return[n+a*(p-n),i+a*(s-i)]}return!1}return function(i){const r=new t([],e);return function(t,e){if("FeatureCollection"===t.type){const n=t.features;for(let t=0;t<n.length;t++)p(n[t],e)}else p(t,e)}(i,r),function(e){const i=[],p=new t([],n);for(;e.length;){const t=e.pop();if(t.isLeftEndpoint){const e=new s(t);for(let t=0;t<p.data.length;t++){const n=o(e,p.data[t]);!1!==n&&i.push(n)}p.push(e)}else!1===t.isLeftEndpoint&&p.pop()}return i}(r)}});
{
"name": "sweepline-intersections",
"version": "1.0.1",
"version": "1.1.1",
"description": "A module to check if a polygon self-intersects using a sweepline algorithm",

@@ -32,2 +32,5 @@ "main": "dist/sweeplineIntersections.js",

"2d-polygon-self-intersections": "^1.3.1",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-node-resolve": "^7.1.3",
"@rollup/plugin-strip": "^1.3.2",
"ava": "^1.0.1",

@@ -48,6 +51,3 @@ "benchmark": "^2.1.4",

"nyc": "^13.1.0",
"rollup": "^1.16.2",
"rollup-plugin-commonjs": "^10.0.1",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-strip": "^1.2.1",
"rollup": "^2.7.6",
"rollup-plugin-terser": "^4.0.2",

@@ -54,0 +54,0 @@ "vue": "^2.5.22",

# sweepline-intersections
A small module using a sweepline algorithm to detect self-intersections in polygons or polylines.
A small and fast module using a sweepline algorithm to detect intersections between polygons and/or polylines.
## Install
## Documentation
### Install
````

@@ -9,5 +11,7 @@ npm install sweepline-intersections

## Documentation
Valid inputs: Geojson `Polygon`, `MultiPolygon`, `LineString`, `MultiLineString`
### Basic Use
Valid inputs: Geojson `Feature` or `Geometry` including `Polygon`, `LineString`, `MultiPolygon`, `MultiLineString`, as well as `FeatureCollection`'s.
Returns an array[{x, y}] of intersection points
````js

@@ -17,7 +21,39 @@ const findIntersections = require('sweepline-intersections')

const box = {type: 'Polygon', coordinates: [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]]}
findIntersections(box)
// returns array of intersection points
const intersections = findIntersections(box)
// returns an array of intersection points
````
### Complex Use
This library also provide a class-based approach which is helpful if you need to check multiple geometries against a single geometry. This allows you to save the state of the initial event queue with the primary geometry.
````js
import SweeplineIntersectionsClass from 'sweepline-intersections/dist/SweeplineIntersectionsClass'
// create the base instance
const sl = new SweeplineIntersectionsClass()
// populate the event queue with your primary geometry
sl.addData(largeGeoJson)
// clone the event queue in the original state so you can reuse it
const origQueue = sl.cloneEventQueue()
// now you can iterate through some other set of features saving
// the overhead of having to populate the complete queue multiple times
someOtherFeatureCollection.features.forEach(feature => {
// add another feature to test against your original data
sl.addData(feature, origQueue)
// check if those two features intersect
const intersectionPoints = sl.getIntersections()
})
````
#### API
`new SweeplineIntersectionsClass()` - creates a new instance
`.addData(geojson, existingQueue)` - add geojson to the event queue. The second argument for an `existingQueue` is optional, and takes a queue generated from `.cloneEventQueue()`
`.cloneEventQueue()` - clones the state of the existing event queue that's been populated with geojson. Returns a queue that you can pass to the `addData` method
`.intersect()` - Checks for segment intersections. Returns `true` if there are no segment intersections or `false` if there are intersections.
## Benchmarks

@@ -34,3 +70,3 @@ Tested against

// isects x 14.29 ops/sec ±2.16% (40 runs sampled)
// - Fastest is sweepline
// - Fastest is sweepline (this library)

@@ -41,3 +77,8 @@ // Simple Case (6 vertices)

// sweepline x 1,157,425 ops/sec ±1.04% (94 runs sampled)
// - Fastest is sweepline
// - Fastest is sweepline (this library)
// Chile - Vertical geometry (17,000 vertices)
// bentleyOttmann x 50.22 ops/sec ±1.75% (65 runs sampled)
// sweepline x 35.64 ops/sec ±1.20% (62 runs sampled)
// - Fastest is bentleyOttmann (although it doesn't find intersection)
````

@@ -60,6 +101,7 @@

The package size of this module is 3kb compared to my implementation of the bentley-ottmann algorithm which is 16kb while performance is typically faster than bentley-ottmann.
The package size of this module is 3kb compared to my implementation of the bentley-ottmann algorithm which is 16kb while performance is typically faster than bentley-ottmann.
I did have some concerns that a really vertical geometry (eg think of the border of the Chile) would not perform well but it still beat the bentley ottman implementation.
Bentley-ottman only outperforms this library when there are several thousands vertices, however I'm also less confident in the results of my bentley-ottman lib as it occassionally misses intersections and is much harder to write tests for due to the more complex logic.
### Algorithm Steps

@@ -66,0 +108,0 @@ - Vertices are entered into a priority queue sorted from left to right

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

import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import strip from '@rollup/plugin-strip'
import {terser} from 'rollup-plugin-terser'
import strip from 'rollup-plugin-strip'

@@ -6,0 +6,0 @@ const output = (file, format, plugins) => ({

Sorry, the diff of this file is not supported yet

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