repair gaps in the gyroid
This commit is contained in:
parent
ab2e2f7987
commit
75405eb66b
3 changed files with 56 additions and 70 deletions
|
|
@ -60,7 +60,7 @@ var gs_base_gyroid = exports;
|
|||
let lval = vals[vals.length-1][x];
|
||||
for (let y=0; y<rez; y++) {
|
||||
let val = vals[y][x];
|
||||
if (lval <= 0 && val >= 0) {
|
||||
if ((lval <= 0 && val >= 0) || (lval >= 0 && val <= 0)) {
|
||||
if (edge[y][x]) {
|
||||
edge[y][x] = 3;
|
||||
} else {
|
||||
|
|
@ -119,7 +119,7 @@ var gs_base_gyroid = exports;
|
|||
for (let i=0; i<sparse.length; i++) {
|
||||
let test_el = sparse[i];
|
||||
if (test_el) {
|
||||
let dst = dist(target, test_el, dir);
|
||||
let dst = distTo(target, test_el, dir);
|
||||
if (cl_idx === null || dst < cl_dst) {
|
||||
cl_idx = i;
|
||||
cl_elm = test_el;
|
||||
|
|
@ -139,73 +139,49 @@ var gs_base_gyroid = exports;
|
|||
} while (added);
|
||||
} while (cleared < sparse.length);
|
||||
|
||||
return {edge, points, dir, polys: polys.map(poly => filter(poly,inc))};
|
||||
let psimple = polys
|
||||
.map(poly => filter(poly, 0))
|
||||
.map(poly => filter(poly, inc));
|
||||
|
||||
return {edge, points, dir, polys: psimple};
|
||||
}
|
||||
|
||||
// merge x/y co-linear
|
||||
function filter(poly,inc) {
|
||||
if (poly.length === 1) {
|
||||
// merge co-linear and distance threshold
|
||||
function filter(poly, inc) {
|
||||
if (poly.length <= 2) {
|
||||
return poly;
|
||||
}
|
||||
let nuchain = [];
|
||||
let e1 = poly[0];
|
||||
let nupoly = [ poly[0] ];
|
||||
let e1 = poly[1];
|
||||
let e2 = null;
|
||||
let last = poly.length - 1;
|
||||
let last = poly.length - 2;
|
||||
for (let i=1; i<poly.length; i++) {
|
||||
let el = poly[i];
|
||||
if (e1.x === el.x || e1.y === el.y) {
|
||||
let drop = inc ?
|
||||
(distTo(e1, el) <= inc) :
|
||||
(e1.x === el.x || e1.y === el.y);
|
||||
if (drop) {
|
||||
e2 = el;
|
||||
if (i < last) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (e2) {
|
||||
nuchain.push({x:(e1.x + e2.x)/2, y:(e1.y + e2.y)/2});
|
||||
nupoly.push({x:(e1.x + e2.x)/2, y:(e1.y + e2.y)/2});
|
||||
e2 = null;
|
||||
} else {
|
||||
nuchain.push(e1);
|
||||
nupoly.push(e1);
|
||||
if (i === last) {
|
||||
nuchain.push(el);
|
||||
nupoly.push(el);
|
||||
}
|
||||
}
|
||||
e1 = el;
|
||||
}
|
||||
return filter2(nuchain,inc);
|
||||
nupoly.push(poly[poly.length-1]);
|
||||
return nupoly;
|
||||
}
|
||||
|
||||
// merge points within radius
|
||||
function filter2(poly,inc) {
|
||||
if (poly.length === 1) {
|
||||
return poly;
|
||||
}
|
||||
let nuchain = [];
|
||||
let e1 = poly[0];
|
||||
let e2 = null;
|
||||
let last = poly.length - 1;
|
||||
let merge = inc;
|
||||
for (let i=1; i<poly.length; i++) {
|
||||
let el = poly[i];
|
||||
if (dist(e1, el) <= merge) {
|
||||
e2 = el;
|
||||
if (i < last) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (e2) {
|
||||
nuchain.push({x:(e1.x + e2.x)/2, y:(e1.y + e2.y)/2});
|
||||
e2 = null;
|
||||
} else {
|
||||
nuchain.push(e1);
|
||||
if (i === last) {
|
||||
nuchain.push(el);
|
||||
}
|
||||
}
|
||||
e1 = el;
|
||||
}
|
||||
return nuchain;
|
||||
}
|
||||
|
||||
function dist(a, b, dir) {
|
||||
function distTo(a, b, dir) {
|
||||
let dx = a.x - b.x;
|
||||
let dy = a.y - b.y;
|
||||
// bias distance by prevailing direction of discovery to join stragglers
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
var exports = {
|
||||
COPYRIGHT:"Copyright (C) 2014-2019 Stewart Allen <sa@grid.space> - All Rights Reserved",
|
||||
LICENSE:"See the license.md file included with the source distribution",
|
||||
VERSION:"1.2.6b"
|
||||
VERSION:"1.2.6c"
|
||||
};
|
||||
if (!module) var module = {};
|
||||
module.exports = exports;
|
||||
|
|
|
|||
|
|
@ -97,23 +97,23 @@
|
|||
// left-right threshold search (red)
|
||||
vals.forEach((vrow, y) => {
|
||||
let erow = edge[y];
|
||||
let lval = vrow[vrow.length - 1];
|
||||
vrow.forEach((val, x) => {
|
||||
if ((lval <= 0 && val >= 0) || (lval >= 0 && val <= 0)) {
|
||||
let v0 = vrow[vrow.length - 1];
|
||||
vrow.forEach((v1, x) => {
|
||||
if ((v0 <= 0 && v1 >= 0) || (v0 >= 0 && v1 <= 0)) {
|
||||
erow[x] = 1;
|
||||
points++;
|
||||
points_lr++;
|
||||
}
|
||||
lval = val;
|
||||
v0 = v1;
|
||||
})
|
||||
});
|
||||
|
||||
// top-down threshold search (green)
|
||||
for (let x=0; x<rez; x++) {
|
||||
let lval = vals[vals.length-1][x];
|
||||
let v0 = vals[vals.length-1][x];
|
||||
for (let y=0; y<rez; y++) {
|
||||
let val = vals[y][x];
|
||||
if (lval <= 0 && val >= 0) {
|
||||
let v1 = vals[y][x];
|
||||
if ((v0 <= 0 && v1 >= 0) || (v0 >= 0 && v1 <= 0)) {
|
||||
if (edge[y][x]) {
|
||||
edge[y][x] = 3;
|
||||
} else {
|
||||
|
|
@ -122,7 +122,7 @@
|
|||
}
|
||||
points_td++;
|
||||
}
|
||||
lval = val;
|
||||
v0 = v1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,6 +145,9 @@
|
|||
return b.dist - a.dist;
|
||||
});
|
||||
|
||||
// preserve sparse points for rendering
|
||||
let raw = sparse.slice();
|
||||
|
||||
// join sparse points array by closest distance
|
||||
let polys = [];
|
||||
let chain;
|
||||
|
|
@ -195,17 +198,17 @@
|
|||
// simplify poly
|
||||
polys = polys.map(poly => filter(poly));
|
||||
|
||||
return zcache[zkey] = {edge, points, dir, polys};
|
||||
return zcache[zkey] = { raw, points, dir, polys };
|
||||
}
|
||||
|
||||
function filter(poly) {
|
||||
if (poly.length === 1) {
|
||||
if (poly.length <= 2) {
|
||||
return poly;
|
||||
}
|
||||
let nuchain = [];
|
||||
let e1 = poly[0];
|
||||
let nuchain = [ poly[0] ];
|
||||
let e1 = poly[1];
|
||||
let e2 = null;
|
||||
let last = poly.length - 1;
|
||||
let last = poly.length - 2;
|
||||
for (let i=1; i<poly.length; i++) {
|
||||
let el = poly[i];
|
||||
if (e1.x === el.x || e1.y === el.y) {
|
||||
|
|
@ -225,6 +228,7 @@
|
|||
}
|
||||
e1 = el;
|
||||
}
|
||||
nuchain.push(poly[poly.length-1]);
|
||||
return nuchain;
|
||||
}
|
||||
|
||||
|
|
@ -238,10 +242,10 @@
|
|||
}
|
||||
|
||||
function render(z) {
|
||||
let size = 800;
|
||||
let size = 600;
|
||||
let wh = size / rez;
|
||||
let html = [`<svg width=${size} height=${size}>`];
|
||||
let { edge, points, dir, polys } = generate(z);
|
||||
let { raw, points, dir, polys } = generate(z);
|
||||
|
||||
$('points').value = points;
|
||||
$('direction').value = dir;
|
||||
|
|
@ -249,14 +253,20 @@
|
|||
|
||||
// raw threshold points
|
||||
html.push('<g>');
|
||||
polys.forEach(poly => {
|
||||
poly.forEach(point => {
|
||||
let x = point.x;
|
||||
let y = point.y;
|
||||
let color = ['black','#f00a','#0f0a','#00fa'][point.val];
|
||||
html.push(`<rect dist="${point.dist}" x="${x*wh}" y="${y*wh}" width="${wh}" height="${wh}" style="fill:${color};stroke-width:0"/>`);
|
||||
});
|
||||
});
|
||||
raw.forEach(point => {
|
||||
let x = point.x;
|
||||
let y = point.y;
|
||||
let color = ['black','#f00a','#0f0a','#00fa'][point.val];
|
||||
html.push(`<rect dist="${point.dist}" x="${x*wh}" y="${y*wh}" width="${wh}" height="${wh}" style="fill:${color};stroke-width:0"/>`);
|
||||
})
|
||||
// polys.forEach(poly => {
|
||||
// poly.forEach(point => {
|
||||
// let x = point.x;
|
||||
// let y = point.y;
|
||||
// let color = ['black','#f00a','#0f0a','#00fa'][point.val];
|
||||
// html.push(`<rect dist="${point.dist}" x="${x*wh}" y="${y*wh}" width="${wh}" height="${wh}" style="fill:${color};stroke-width:0"/>`);
|
||||
// });
|
||||
// });
|
||||
html.push('</g>');
|
||||
|
||||
// points joined into poly lines
|
||||
|
|
|
|||
Loading…
Reference in a new issue