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/planar-dual/loops.js

130 lines
2.8 KiB

"use strict"
module.exports = planarDual
var compareAngle = require("compare-angle")
function planarDual(cells, positions) {
var numVertices = positions.length|0
var numEdges = cells.length
var adj = [new Array(numVertices), new Array(numVertices)]
for(var i=0; i<numVertices; ++i) {
adj[0][i] = []
adj[1][i] = []
}
for(var i=0; i<numEdges; ++i) {
var c = cells[i]
adj[0][c[0]].push(c)
adj[1][c[1]].push(c)
}
var cycles = []
//Add isolated vertices as trivial case
for(var i=0; i<numVertices; ++i) {
if(adj[0][i].length + adj[1][i].length === 0) {
cycles.push( [i] )
}
}
//Remove a half edge
function cut(c, i) {
var a = adj[i][c[i]]
a.splice(a.indexOf(c), 1)
}
//Find next vertex and cut edge
function next(a, b, noCut) {
var nextCell, nextVertex, nextDir
for(var i=0; i<2; ++i) {
if(adj[i][b].length > 0) {
nextCell = adj[i][b][0]
nextDir = i
break
}
}
nextVertex = nextCell[nextDir^1]
for(var dir=0; dir<2; ++dir) {
var nbhd = adj[dir][b]
for(var k=0; k<nbhd.length; ++k) {
var e = nbhd[k]
var p = e[dir^1]
var cmp = compareAngle(
positions[a],
positions[b],
positions[nextVertex],
positions[p])
if(cmp > 0) {
nextCell = e
nextVertex = p
nextDir = dir
}
}
}
if(noCut) {
return nextVertex
}
if(nextCell) {
cut(nextCell, nextDir)
}
return nextVertex
}
function extractCycle(v, dir) {
var e0 = adj[dir][v][0]
var cycle = [v]
cut(e0, dir)
var u = e0[dir^1]
var d0 = dir
while(true) {
while(u !== v) {
cycle.push(u)
u = next(cycle[cycle.length-2], u, false)
}
if(adj[0][v].length + adj[1][v].length === 0) {
break
}
var a = cycle[cycle.length-1]
var b = v
var c = cycle[1]
var d = next(a, b, true)
if(compareAngle(positions[a], positions[b], positions[c], positions[d]) < 0) {
break
}
cycle.push(v)
u = next(a, b)
}
return cycle
}
function shouldGlue(pcycle, ncycle) {
return (ncycle[1] === ncycle[ncycle.length-1])
}
for(var i=0; i<numVertices; ++i) {
for(var j=0; j<2; ++j) {
var pcycle = []
while(adj[j][i].length > 0) {
var ni = adj[0][i].length
var ncycle = extractCycle(i,j)
if(shouldGlue(pcycle, ncycle)) {
//Glue together trivial cycles
pcycle.push.apply(pcycle, ncycle)
} else {
if(pcycle.length > 0) {
cycles.push(pcycle)
}
pcycle = ncycle
}
}
if(pcycle.length > 0) {
cycles.push(pcycle)
}
}
}
//Combine paths and loops together
return cycles
}