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.
151 lines
3.2 KiB
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)
|
||
|
}
|
||
|
}
|