use intersect offset instead of approximate medial axis radius

This commit is contained in:
Stewart Allen 2025-09-18 16:39:28 -04:00
commit afcacc89b3

View file

@ -175,18 +175,18 @@ function thin_type_3(params) {
let simplifyChain = false; let simplifyChain = false;
let shortenAtNexus = false; let shortenAtNexus = false;
let shortenEdgeSpur = false; let shortenEdgeSpur = false;
let intersectChains = false; let intersectChains = true;
let maxInsetBypass = true; let maxInsetBypass = false;
let showNoodle = false; let showNoodle = false;
let showMedLine = false;
let showInset = false;
let showExtrusion = true; let showExtrusion = true;
let showExtrudeInset = false; let showExtrudeInset = false;
let showInsetPoints = false;
let showChainRawPoints = false; let showChainRawPoints = false;
let showChainInterpPoints = true; let showChainInterpPoints = true;
let showChainIntersect = false; let showChainIntersect = false;
let showNuMedLine = false; let showNuMedLine = false;
let showMedLine = true;
let showMedPoints = false; let showMedPoints = false;
let showMedNormals = false; let showMedNormals = false;
let showMedRadii = false; let showMedRadii = false;
@ -221,16 +221,13 @@ function thin_type_3(params) {
insets.push(inset); insets.push(inset);
let ps = POLY.flatten(inset); let ps = POLY.flatten(inset);
POLY.setZ(inset, z); POLY.setZ(inset, z);
shells.appendAll(inset); if (showInset) {
shells.appendAll(inset);
}
if (intersectChains) { if (intersectChains) {
break; break;
} }
// if (dtotl >= maxR * 3) {
// break;
// }
inset = POLY.offset(inset, -dstep, { inset = POLY.offset(inset, -dstep, {
// join: ClipperLib.JoinType.jtRound,
// arc: (1/dstep) * 4
minArea: 0 minArea: 0
}); });
} }
@ -238,8 +235,6 @@ function thin_type_3(params) {
// project from first inset and find greated offset intersection // project from first inset and find greated offset intersection
if (maxInsetBypass) { if (maxInsetBypass) {
// shells.appendAll(noodle);
// return { last, gaps };
let { intersectRayLine } = base.util; let { intersectRayLine } = base.util;
let tests = insets.slice(1); let tests = insets.slice(1);
let source = POLY.flatten(insets[0], []); let source = POLY.flatten(insets[0], []);
@ -739,12 +734,15 @@ function thin_type_3(params) {
} }
// project inset segment normals onto closest chain // project inset segment normals onto closest chain
if (intersectChains) { if (intersectChains) for (let insetp of inset) {
let { intersect } = base.util; let { intersectRayLine } = base.util;
let { SEGINT } = base.key; let parent = new Polygon();
inset = POLY.flatten(inset, []); let inner = [];
for (let poly of inset) { for (let poly of insetp.flattenTo([])) {
let nupoly = new Polygon(); let nupoly = poly.parent ? new Polygon() : parent;
if (poly.parent) {
inner.push(nupoly);
}
poly.segment(minR).forEachSegment((p1, p2) => { poly.segment(minR).forEachSegment((p1, p2) => {
let np1 = { x:(p1.x+p2.x)/2, y:(p1.y+p2.y)/2 }; let np1 = { x:(p1.x+p2.x)/2, y:(p1.y+p2.y)/2 };
let len = pointDist(p1, p2); let len = pointDist(p1, p2);
@ -756,8 +754,8 @@ function thin_type_3(params) {
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 = intersect(np1, np2, c1, c2, SEGINT); let int = intersectRayLine(np1, { dx: dy, dy: -dx }, c1, c2);
if (int?.dist < min.dist && int?.dist < midR) { if (int?.dist < min.dist && int?.dist < offsetN * count) {
min = int; min = int;
} }
} }
@ -768,8 +766,11 @@ function thin_type_3(params) {
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));
} }
let mr = Math.min(p1.r, p2.r); let mr = min.dist + dstep;
if (mr < minR) return; if (mr < minR) {
nupoly.push(new Point(min.x, min.y));
return;
}
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);
@ -778,6 +779,7 @@ function thin_type_3(params) {
// 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 // todo extend to all odd counts
if (len === 0) { if (len === 0) {
nupoly.push(new Point(min.x, min.y));
return; return;
} }
if (pop.length === 1) { if (pop.length === 1) {
@ -809,10 +811,14 @@ function thin_type_3(params) {
shells.push(...nupoly.clean().simplify()); shells.push(...nupoly.clean().simplify());
} }
} }
{
let cut = POLY.subtract([ parent ], inner, []);
console.log({ parent, cut });
shells.push(...cut);
}
} }
POLY.setZ([...thin, ...shells], z); POLY.setZ([...thin, ...shells], z);
// POLY.setZ([...shells], z);
return { last, gaps }; return { last, gaps };
} }