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.
116 lines
2.4 KiB
116 lines
2.4 KiB
4 years ago
|
'use strict'
|
||
|
|
||
|
var inCircle = require('robust-in-sphere')[4]
|
||
|
var bsearch = require('binary-search-bounds')
|
||
|
|
||
|
module.exports = delaunayRefine
|
||
|
|
||
|
function testFlip(points, triangulation, stack, a, b, x) {
|
||
|
var y = triangulation.opposite(a, b)
|
||
|
|
||
|
//Test boundary edge
|
||
|
if(y < 0) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
//Swap edge if order flipped
|
||
|
if(b < a) {
|
||
|
var tmp = a
|
||
|
a = b
|
||
|
b = tmp
|
||
|
tmp = x
|
||
|
x = y
|
||
|
y = tmp
|
||
|
}
|
||
|
|
||
|
//Test if edge is constrained
|
||
|
if(triangulation.isConstraint(a, b)) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
//Test if edge is delaunay
|
||
|
if(inCircle(points[a], points[b], points[x], points[y]) < 0) {
|
||
|
stack.push(a, b)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Assume edges are sorted lexicographically
|
||
|
function delaunayRefine(points, triangulation) {
|
||
|
var stack = []
|
||
|
|
||
|
var numPoints = points.length
|
||
|
var stars = triangulation.stars
|
||
|
for(var a=0; a<numPoints; ++a) {
|
||
|
var star = stars[a]
|
||
|
for(var j=1; j<star.length; j+=2) {
|
||
|
var b = star[j]
|
||
|
|
||
|
//If order is not consistent, then skip edge
|
||
|
if(b < a) {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
//Check if edge is constrained
|
||
|
if(triangulation.isConstraint(a, b)) {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
//Find opposite edge
|
||
|
var x = star[j-1], y = -1
|
||
|
for(var k=1; k<star.length; k+=2) {
|
||
|
if(star[k-1] === b) {
|
||
|
y = star[k]
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//If this is a boundary edge, don't flip it
|
||
|
if(y < 0) {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
//If edge is in circle, flip it
|
||
|
if(inCircle(points[a], points[b], points[x], points[y]) < 0) {
|
||
|
stack.push(a, b)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
while(stack.length > 0) {
|
||
|
var b = stack.pop()
|
||
|
var a = stack.pop()
|
||
|
|
||
|
//Find opposite pairs
|
||
|
var x = -1, y = -1
|
||
|
var star = stars[a]
|
||
|
for(var i=1; i<star.length; i+=2) {
|
||
|
var s = star[i-1]
|
||
|
var t = star[i]
|
||
|
if(s === b) {
|
||
|
y = t
|
||
|
} else if(t === b) {
|
||
|
x = s
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//If x/y are both valid then skip edge
|
||
|
if(x < 0 || y < 0) {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
//If edge is now delaunay, then don't flip it
|
||
|
if(inCircle(points[a], points[b], points[x], points[y]) >= 0) {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
//Flip the edge
|
||
|
triangulation.flip(a, b)
|
||
|
|
||
|
//Test flipping neighboring edges
|
||
|
testFlip(points, triangulation, stack, x, a, y)
|
||
|
testFlip(points, triangulation, stack, a, y, x)
|
||
|
testFlip(points, triangulation, stack, y, b, x)
|
||
|
testFlip(points, triangulation, stack, b, x, y)
|
||
|
}
|
||
|
}
|