fix ray/line. add max inset visalization

This commit is contained in:
Stewart Allen 2025-09-18 14:42:41 -04:00
commit 43a083a93a
4 changed files with 78 additions and 28 deletions

View file

@ -91,11 +91,11 @@ function area2(p1, p2, p3) {
}
function isCloseTo(v1, v2, dist) {
return Math.abs(v1 - v2) <= (dist || base.config.precision_merge);
return Math.abs(v1 - v2) <= (dist ?? base.config.precision_merge);
}
function inCloseRange(val, min, max) {
return (isCloseTo(val, min) || val >= min) && (isCloseTo(val, max) || val <= max);
function inCloseRange(val, min, max, precisiom) {
return (isCloseTo(val, min, precisiom) || val >= min) && (isCloseTo(val, max, precisiom) || val <= max);
}
/**
@ -232,7 +232,7 @@ function intersect(p1, p2, p3, p4, test, parallelok) {
/**
* used by {@link rayIntersect} and {@link Polygon.trace}
*/
function intersectRayLine(ro, s1, p1, p2, infinite) {
function intersectRayLine(ro, s1, p1, p2) {
let keys = base.key,
p1x = ro.x,
p1y = ro.y,
@ -259,11 +259,11 @@ function intersectRayLine(ro, s1, p1, p2, infinite) {
a = n1 / d;
b = n2 / d;
if (infinite || (inCloseRange(b, 0, 1) && a >= 0)) {
if (inCloseRange(b, 0, 1, 0.00) && a >= 0) {
let ip = newPoint(
p1x + (a * s1x),
p1y + (a * s1y),
p2.z || ro.z,
p2.z ?? ro.z,
keys.NONE
);
ip.dist = a;

View file

@ -2042,13 +2042,9 @@ export class Polygon {
// use expand / deflate technique instead
if (opt.pump) {
let p2 = POLY.offset([this], opt.pump, {
z
});
let p2 = POLY.offset([this], opt.pump, { z });
if (p2) {
p2 = POLY.offset(p2, -opt.pump, {
z
});
p2 = POLY.offset(p2, -opt.pump, { z });
return p2;
}
return null;

View file

@ -871,6 +871,7 @@ export function fillArea(polys, angle, spacing, output, minLen, maxLen) {
* @returns {Point[]}
*/
export function rayIntersect(start, slope, polygons, for_fill) {
throw "deprecated";
let i = 0,
flat = [],
points = [],

View file

@ -175,7 +175,8 @@ function thin_type_3(params) {
let simplifyChain = false;
let shortenAtNexus = false;
let shortenEdgeSpur = false;
let intersectChains = true;
let intersectChains = false;
let maxInsetBypass = true;
let showNoodle = false;
let showExtrusion = true;
@ -185,7 +186,7 @@ function thin_type_3(params) {
let showChainInterpPoints = true;
let showChainIntersect = false;
let showNuMedLine = false;
let showMedLine = false;
let showMedLine = true;
let showMedPoints = false;
let showMedNormals = false;
let showMedRadii = false;
@ -201,38 +202,90 @@ function thin_type_3(params) {
let maxF = midR * 2; // max interior extrusion width
let minSpur = offsetN * 1;
let insets = [];
let inset;
let dstep = minR / 4;
let dtotl = 0;
top.gaps = remain;
if (true) {
let dtotl = 0;
if (maxInsetBypass || intersectChains) {
inset = POLY.offset(noodle, -dstep, {
join: ClipperLib.JoinType.jtRound,
arc: (1/dstep) * 4
});
while (inset && inset.length) {
dtotl += dstep;
for (let p of POLY.flatten(inset, [])) {
p.dtotl = dtotl;
}
insets.push(inset);
let ps = POLY.flatten(inset);
for (let poly of ps) {
for (let p of poly.segment(minR).points) {
let d = dtotl * 0+0.05;
// let z = dtotl * 10;
if (showInsetPoints)
shells.append( newPolygon().centerCircle(p, d, 10).setZ(z) );
}
}
POLY.setZ(inset, z);
shells.appendAll(inset);
if (true || dtotl >= maxR) {
if (intersectChains) {
break;
}
inset = POLY.expand(inset, -dstep);
// if (dtotl >= maxR * 3) {
// break;
// }
inset = POLY.offset(inset, -dstep, {
// join: ClipperLib.JoinType.jtRound,
// arc: (1/dstep) * 4
minArea: 0
});
}
}
// project from first inset and find greated offset intersection
if (maxInsetBypass) {
// shells.appendAll(noodle);
// return { last, gaps };
let { intersectRayLine } = base.util;
let tests = insets.slice(1);
let source = POLY.flatten(insets[0], []);
console.log({ source, tests });
for (let poly of source) {
// segment the smallest inset and test against all other insets
poly.segment(minR).forEachSegment((p1, p2) => {
let np1 = { x:(p1.x+p2.x)/2, y:(p1.y+p2.y)/2 };
let len = pointDist(p1, p2);
let dx = (p1.x - p2.x) / len;
let dy = (p1.y - p2.y) / len;
let np2 = { x: np1.x + dy * 10, y: np1.y - dx * 10 };
let max = { dtotl: poly.dtotl, dist: Infinity, maxd: Infinity };
let term = false;
outer: for (let test of tests) {
for (let tpoly of POLY.flatten(test, [])) {
tpoly.forEachSegment((tp1, tp2) => {
let int = intersectRayLine(np1, { dx: dy, dy: -dx }, tp1, tp2);
if (int && int.dist > int.p1.poly.dtotl) {
return;
}
if (int && int.dist <= max.maxd && int.p1.poly.dtotl > max.dtotl) {
max.dtotl = int.p1.poly.dtotl;
max.dist = int.dist;
max.int = int;
} else if (int && int.dist <= max.maxd && int.p1.poly.dtotl === max.dtotl && int.dist < max.dist) {
max.dtotl = int.p1.poly.dtotl;
max.dist = int.dist;
max.int = int;
}
});
if (term) {
break outer;
}
}
}
if (max.int) {
thin.push(new Point(np1.x, np1.y, z));
thin.push(new Point(max.int.x, max.int.y, z));
}
});
}
shells.appendAll(noodle);
return { last, gaps };
}
let pointMap = new Map();
let lineMap = new Map();