/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */ "use strict"; var gs_base_gyroid = exports; (function() { if (!self.base) self.base = {}; if (self.base.gyroid) return; var base = self.base; let PI2 = Math.PI * 2; /** * @param off {number} z offset value from 0-1 * @param res {number} resolution (pixels/slices per side) */ function slice(off, res) { let rez = parseInt(res || 200); let inc = PI2 / rez; let z = PI2 * off; let edge = []; let vals = []; let points = 0; let points_lr = 0; let points_td = 0; for (let x=0; x { let erow = edge[y]; let lval = vrow[vrow.length - 1]; vrow.forEach((val, x) => { if ((lval <= 0 && val >= 0) || (lval >= 0 && val <= 0)) { erow[x] = 1; points++; points_lr++; } lval = val; }) }); // top-down threshold search (green) for (let x=0; x= 0) || (lval >= 0 && val <= 0)) { if (edge[y][x]) { edge[y][x] = 3; } else { edge[y][x] = 2; points++ } points_td++; } lval = val; } } // deterime prevailing direction for chaining let dir = points_td > points_lr ? 'lr' : 'td'; // create sparse representation let sparse = []; let center = rez / 2; edge.forEach((row,y) => { row.forEach((val,x) => { if (val) { let dx = Math.abs(x - center); let dy = Math.abs(y - center); sparse.push({x: x/rez, y: y/rez, val, dist: Math.max(dx,dy)}); } }); }); sparse.sort((a,b) => { return b.dist - a.dist; }); // join sparse points array by closest distance let polys = []; let chain; let added; let cleared = 0; let maxdist = 0.05; do { chain = null; for (let i=0; i maxdist) { break; } sparse[cl_idx] = null; cleared++; chain.push(cl_elm); added = true; } } while (added); } while (cleared < sparse.length); let psimple = polys .map(poly => filter(poly, 0)) .map(poly => filter(poly, inc)); return {edge, points, dir, polys: psimple}; } // merge co-linear and distance threshold function filter(poly, inc) { if (poly.length <= 2) { return poly; } let nupoly = [ poly[0] ]; let e1 = poly[1]; let e2 = null; let last = poly.length - 2; for (let i=1; i