StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
StackGenVis/frontend/node_modules/point-in-big-polygon/pnp-big.js

151 lines
3.2 KiB

4 years ago
module.exports = preprocessPolygon
var orient = require('robust-orientation')[3]
var makeSlabs = require('slab-decomposition')
var makeIntervalTree = require('interval-tree-1d')
var bsearch = require('binary-search-bounds')
function visitInterval() {
return true
}
function intervalSearch(table) {
return function(x, y) {
var tree = table[x]
if(tree) {
return !!tree.queryPoint(y, visitInterval)
}
return false
}
}
function buildVerticalIndex(segments) {
var table = {}
for(var i=0; i<segments.length; ++i) {
var s = segments[i]
var x = s[0][0]
var y0 = s[0][1]
var y1 = s[1][1]
var p = [ Math.min(y0, y1), Math.max(y0, y1) ]
if(x in table) {
table[x].push(p)
} else {
table[x] = [ p ]
}
}
var intervalTable = {}
var keys = Object.keys(table)
for(var i=0; i<keys.length; ++i) {
var segs = table[keys[i]]
intervalTable[keys[i]] = makeIntervalTree(segs)
}
return intervalSearch(intervalTable)
}
function buildSlabSearch(slabs, coordinates) {
return function(p) {
var bucket = bsearch.le(coordinates, p[0])
if(bucket < 0) {
return 1
}
var root = slabs[bucket]
if(!root) {
if(bucket > 0 && coordinates[bucket] === p[0]) {
root = slabs[bucket-1]
} else {
return 1
}
}
var lastOrientation = 1
while(root) {
var s = root.key
var o = orient(p, s[0], s[1])
if(s[0][0] < s[1][0]) {
if(o < 0) {
root = root.left
} else if(o > 0) {
lastOrientation = -1
root = root.right
} else {
return 0
}
} else {
if(o > 0) {
root = root.left
} else if(o < 0) {
lastOrientation = 1
root = root.right
} else {
return 0
}
}
}
return lastOrientation
}
}
function classifyEmpty(p) {
return 1
}
function createClassifyVertical(testVertical) {
return function classify(p) {
if(testVertical(p[0], p[1])) {
return 0
}
return 1
}
}
function createClassifyPointDegen(testVertical, testNormal) {
return function classify(p) {
if(testVertical(p[0], p[1])) {
return 0
}
return testNormal(p)
}
}
function preprocessPolygon(loops) {
//Compute number of loops
var numLoops = loops.length
//Unpack segments
var segments = []
var vsegments = []
var ptr = 0
for(var i=0; i<numLoops; ++i) {
var loop = loops[i]
var numVertices = loop.length
for(var s=numVertices-1,t=0; t<numVertices; s=(t++)) {
var a = loop[s]
var b = loop[t]
if(a[0] === b[0]) {
vsegments.push([a,b])
} else {
segments.push([a,b])
}
}
}
//Degenerate case: All loops are empty
if(segments.length === 0) {
if(vsegments.length === 0) {
return classifyEmpty
} else {
return createClassifyVertical(buildVerticalIndex(vsegments))
}
}
//Build slab decomposition
var slabs = makeSlabs(segments)
var testSlab = buildSlabSearch(slabs.slabs, slabs.coordinates)
if(vsegments.length === 0) {
return testSlab
} else {
return createClassifyPointDegen(
buildVerticalIndex(vsegments),
testSlab)
}
}