From 32d4b7e62a37782c6543b74711dc8fb629c34cbb Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Mon, 15 Sep 2025 17:11:56 -0400 Subject: [PATCH] fix thin3 chain marking and shortening --- src/geo/polygon.js | 2 +- src/kiri/mode/fdm/post.js | 123 ++++++++++++++++++++++++++------------ 2 files changed, 86 insertions(+), 39 deletions(-) diff --git a/src/geo/polygon.js b/src/geo/polygon.js index e0226946..846515f9 100644 --- a/src/geo/polygon.js +++ b/src/geo/polygon.js @@ -258,7 +258,7 @@ export class Polygon { // of the polygon with the noodle removed (for the next pass) noodle(width) { let clone = this.clone(true); - let ins = clone.offset(width); + let ins = clone.offset(width) ?? []; let remain = ins.clone(true); let nood = POLY.nest(POLY.flatten([ clone, ...ins ], [], true)); return { noodle: nood, remain }; diff --git a/src/kiri/mode/fdm/post.js b/src/kiri/mode/fdm/post.js index 568b793b..b9818762 100644 --- a/src/kiri/mode/fdm/post.js +++ b/src/kiri/mode/fdm/post.js @@ -182,11 +182,13 @@ function thin_type_3(params) { let mergeChains = true; let interpolateShortSpur = true; let showChainInterpPoints = true; + let showCross = false; + let showPoint = true; let showChainRawPoints = false; let showNoodle = false; let showMid = true; - let showCross = true; let showRad = false; + let showNexus = false; let pointMap = new Map(); let lineMap = new Map(); @@ -354,37 +356,6 @@ function thin_type_3(params) { chains = chains.filter(c => c.total >= minR); chains.sort((c1,c2) => c2.total - c1.total); - // map chains to nexus via endpoints - let nexus = {}; - function addEp(point, chain) { - let key = point.key; - let rec = nexus[key]; - if (!rec) rec = nexus[key] = { point, chains: [] }; - if (rec.chains.indexOf(chain) < 0) rec.chains.push(chain); - } - // since chains are sorted longest to shortest, - // they will appear in the nexus record longest to shortest - for (let chain of chains) { - addEp(chain[0], chain); - addEp(chain.peek(), chain); - } - - // mark spurs - for (let [key, rec] of Object.entries(nexus)) { - if (rec.chains.length === 1) { - rec.chains[0].spur = true; - delete nexus[key]; - // console.log({ delete_nexus: key }); - } - } - - // detach spurs from nexus and shorten by ? - // for (let [key,val] of Object.entries(nexus)) { - // nexus[key].chains = val.chains.filter(c => !c.spur); - // } - - console.log({ chains, nexus }); - function merge1chain() { let clen = chains.length; for (let i=0; i=1 && rem < minR; i--) { + let c1 = chain[i]; + let c2 = chain[i-1]; + let d = pointDist(c1,c2); + if (rem + d <= minR) { + chain.pop(); + rem += d; + } else { + let diff = minR - rem; + // move c1 toward c2 + let pct = diff / d; + let dx = c1.x - c2.x; + let dy = c1.y - c2.y; + chain[i] = { + x: c1.x - dx * pct, + y: c1.y - dy * pct, + r: c1.r + }; + rem = 0; + break; + } + } + } + + // add chains + + // shorten chains terminating at nexus by midR + for (let rec of Object.values(nexus)) { + let { point } = rec; + rec.shorts = 0; + if (rec.chains.length < 3) continue; + for (let chain of chains.filter(c => !c.closed)) { + if (pointDist(chain[0], point) < minR) { + chain.reverse(); + shorten(chain); + chain.reverse(); + rec.shorts++; + } else if (chain.peek() === point) { + shorten(chain); + rec.shorts++; + } + } + } + + if (showNexus) + for (let rec of Object.values(nexus)) { + let { point, chains } = rec; + // console.log(rec); + top.shells.push(newPolygon().centerCircle(point, 0.2, 6 - rec.shorts)); } // gather point offsets into shells - // todo: order outer shell innersection to inner + let zi = z; for (let chain of chains) { + // zi += 0.1; if (showChainRawPoints) for (let pt of chain) { top.shells.push(newPolygon().centerCircle(pt, pt.r ?? 0.1, 10)); @@ -447,8 +493,8 @@ function thin_type_3(params) { for (let i=0; i