skip chains and use medial axis segments directly

This commit is contained in:
Stewart Allen 2025-09-18 18:28:53 -04:00
commit ddf3972f35

View file

@ -186,7 +186,7 @@ function thin_type_3(params) {
let showChainRawPoints = false; let showChainRawPoints = false;
let showChainInterpPoints = true; let showChainInterpPoints = true;
let showChainIntersect = false; let showChainIntersect = false;
let showNuMedLine = false; let showNuMedLine = true;
let showMedPoints = false; let showMedPoints = false;
let showMedNormals = false; let showMedNormals = false;
let showMedRadii = false; let showMedRadii = false;
@ -627,6 +627,7 @@ function thin_type_3(params) {
// gather point offsets into shells // gather point offsets into shells
let zi = z; let zi = z;
let nuchains = []; let nuchains = [];
let nusegs = [];
for (let chain of chains) { for (let chain of chains) {
let nuchain = []; let nuchain = [];
nuchains.push(nuchain); nuchains.push(nuchain);
@ -727,6 +728,7 @@ function thin_type_3(params) {
for (let i=0; i<nuchain.length-1; i++) { for (let i=0; i<nuchain.length-1; i++) {
let p0 = nuchain[i]; let p0 = nuchain[i];
let p1 = nuchain[i+1]; let p1 = nuchain[i+1];
nusegs.push({ p0, p1 });
thin.push(new Point(p0.x, p0.y, z)); thin.push(new Point(p0.x, p0.y, z));
thin.push(new Point(p1.x, p1.y, z)); thin.push(new Point(p1.x, p1.y, z));
} }
@ -748,20 +750,27 @@ function thin_type_3(params) {
let len = pointDist(p1, p2); let len = pointDist(p1, p2);
let dx = (p1.x - p2.x) / len; let dx = (p1.x - p2.x) / len;
let dy = (p1.y - p2.y) / len; let dy = (p1.y - p2.y) / len;
let np2 = { x: np1.x + dy * 10, y: np1.y - dx * 10 };
let min = { dist: Infinity }; let min = { dist: Infinity };
for (let chain of nuchains) { // for (let chain of nuchains) {
for (let i=0; i<chain.length-1; i++) { // for (let i=0; i<chain.length-1; i++) {
let c1 = chain[i]; // let c1 = chain[i];
let c2 = chain[i+1]; // let c2 = chain[i+1];
let int = intersectRayLine(np1, { dx: dy, dy: -dx }, c1, c2); // let int = intersectRayLine(np1, { dx: dy, dy: -dx }, c1, c2);
if (int?.dist < min.dist && int?.dist < offsetN * count) { // if (int?.dist < min.dist && int?.dist < offsetN * count) {
min = int; // min = int;
} // }
// }
// }
for (let seg of nusegs) {
let { p0, p1 } = seg;
let int = intersectRayLine(np1, { dx: dy, dy: -dx }, p0, p1);
if (int?.dist < min.dist && int?.dist < offsetN * count) {
min = int;
min.seg = seg;
} }
} }
if (min.p1) { if (min.p1) {
let { p1, p2 } = min; let mp1 = min.seg;
if (showChainIntersect) { if (showChainIntersect) {
thin.push(new Point(np1.x, np1.y)); thin.push(new Point(np1.x, np1.y));
thin.push(new Point(min.x, min.y)); thin.push(new Point(min.x, min.y));
@ -774,10 +783,9 @@ function thin_type_3(params) {
let pop = div(mr); let pop = div(mr);
let odd = (pop.length % 2 === 1); let odd = (pop.length % 2 === 1);
let len = Math.ceil(pop.length / 2); let len = Math.ceil(pop.length / 2);
if (odd && p1.claimed) len--; // check if chain segment was claimed by a different originating segment
// implement first-to-intersect claim system
// for odd wall counts so that they're not emitted twice // for odd wall counts so that they're not emitted twice
// todo extend to all odd counts if (odd && mp1.claimed) len--;
if (len === 0) { if (len === 0) {
nupoly.push(new Point(min.x, min.y)); nupoly.push(new Point(min.x, min.y));
return; return;
@ -804,7 +812,9 @@ function thin_type_3(params) {
off += dstep / 2; off += dstep / 2;
nupoly.push(new Point(np1.x + dy * off * 2, np1.y - dx * off * 2)); nupoly.push(new Point(np1.x + dy * off * 2, np1.y - dx * off * 2));
} }
p1.claimed = true; if (odd && !mp1.claimed) {
mp1.claimed = true;
}
} }
}); });
if (showExtrudeInset) { if (showExtrudeInset) {