@willcgage/module-schematic 0.31.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +108 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -1
- package/dist/index.d.ts +48 -1
- package/dist/index.js +105 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -211,6 +211,24 @@ function sectionBreaksFromSections(doc) {
|
|
|
211
211
|
const spans = sectionSpans(doc);
|
|
212
212
|
return spans.slice(0, -1).map((sp) => sp.toPos);
|
|
213
213
|
}
|
|
214
|
+
function sectionedEndPose(doc) {
|
|
215
|
+
const secs = moduleSections(doc).filter(
|
|
216
|
+
(sec) => typeof sec.lengthInches === "number" && sec.lengthInches > 0
|
|
217
|
+
);
|
|
218
|
+
if (!secs.length) return null;
|
|
219
|
+
let ox = 0;
|
|
220
|
+
let oy = 0;
|
|
221
|
+
let heading = 0;
|
|
222
|
+
for (const sec of secs) {
|
|
223
|
+
const local = sectionCenterlineLocal(sec);
|
|
224
|
+
const c = Math.cos(heading * DEG_FP);
|
|
225
|
+
const sn = Math.sin(heading * DEG_FP);
|
|
226
|
+
ox += local.endX * c - local.endY * sn;
|
|
227
|
+
oy += local.endX * sn + local.endY * c;
|
|
228
|
+
heading += local.endHeadingDeg;
|
|
229
|
+
}
|
|
230
|
+
return { x: ox, y: oy, heading };
|
|
231
|
+
}
|
|
214
232
|
function sectionedCenterline(doc) {
|
|
215
233
|
const secs = moduleSections(doc).filter(
|
|
216
234
|
(sec) => typeof sec.lengthInches === "number" && sec.lengthInches > 0
|
|
@@ -327,6 +345,79 @@ function sectionBand(center, fromPos, toPos, widthA = FREEMO_ENDPLATE_WIDTH_RECO
|
|
|
327
345
|
}));
|
|
328
346
|
return [...left, ...right.reverse()];
|
|
329
347
|
}
|
|
348
|
+
function ringEdges(pts) {
|
|
349
|
+
const out = [];
|
|
350
|
+
for (let i = 0; i < pts.length; i++) out.push([pts[i], pts[(i + 1) % pts.length]]);
|
|
351
|
+
return out;
|
|
352
|
+
}
|
|
353
|
+
function sharedEdgeLength(e1, e2, gap, angleDeg) {
|
|
354
|
+
const ux = e1[1].x - e1[0].x;
|
|
355
|
+
const uy = e1[1].y - e1[0].y;
|
|
356
|
+
const ul = Math.hypot(ux, uy);
|
|
357
|
+
const vx = e2[1].x - e2[0].x;
|
|
358
|
+
const vy = e2[1].y - e2[0].y;
|
|
359
|
+
const vl = Math.hypot(vx, vy);
|
|
360
|
+
if (ul < 1e-6 || vl < 1e-6) return 0;
|
|
361
|
+
const dx = ux / ul;
|
|
362
|
+
const dy = uy / ul;
|
|
363
|
+
const cross = Math.abs((dx * vy - dy * vx) / vl);
|
|
364
|
+
if (cross > Math.sin(angleDeg * Math.PI / 180)) return 0;
|
|
365
|
+
const perp = (q) => Math.abs((q.x - e1[0].x) * -dy + (q.y - e1[0].y) * dx);
|
|
366
|
+
if (perp(e2[0]) > gap || perp(e2[1]) > gap) return 0;
|
|
367
|
+
const proj = (q) => (q.x - e1[0].x) * dx + (q.y - e1[0].y) * dy;
|
|
368
|
+
const t1 = proj(e2[0]);
|
|
369
|
+
const t2 = proj(e2[1]);
|
|
370
|
+
return Math.max(0, Math.min(ul, Math.max(t1, t2)) - Math.max(0, Math.min(t1, t2)));
|
|
371
|
+
}
|
|
372
|
+
function sectionAdjacency(footprints, opts) {
|
|
373
|
+
const gap = opts?.gapInches ?? 0.5;
|
|
374
|
+
const angle = opts?.angleDegrees ?? 3;
|
|
375
|
+
const min = opts?.minOverlapInches ?? 1;
|
|
376
|
+
const edges = footprints.map((f) => ringEdges(f.outline));
|
|
377
|
+
const out = [];
|
|
378
|
+
for (let i = 0; i < footprints.length; i++) {
|
|
379
|
+
for (let j = i + 1; j < footprints.length; j++) {
|
|
380
|
+
let total = 0;
|
|
381
|
+
for (const e1 of edges[i])
|
|
382
|
+
for (const e2 of edges[j]) total += sharedEdgeLength(e1, e2, gap, angle);
|
|
383
|
+
if (total >= min)
|
|
384
|
+
out.push({
|
|
385
|
+
a: footprints[i].id,
|
|
386
|
+
b: footprints[j].id,
|
|
387
|
+
lengthInches: Math.round(total * 1e3) / 1e3
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return out;
|
|
392
|
+
}
|
|
393
|
+
function sectionNeighbours(id, adj) {
|
|
394
|
+
return adj.filter((x) => x.a === id || x.b === id).map((x) => x.a === id ? x.b : x.a);
|
|
395
|
+
}
|
|
396
|
+
function sectionComponents(ids, adj) {
|
|
397
|
+
const parent = new Map(ids.map((id) => [id, id]));
|
|
398
|
+
const find = (x) => {
|
|
399
|
+
let r = x;
|
|
400
|
+
while (parent.get(r) !== r) r = parent.get(r);
|
|
401
|
+
while (parent.get(x) !== r) {
|
|
402
|
+
const nx = parent.get(x);
|
|
403
|
+
parent.set(x, r);
|
|
404
|
+
x = nx;
|
|
405
|
+
}
|
|
406
|
+
return r;
|
|
407
|
+
};
|
|
408
|
+
for (const { a, b } of adj) {
|
|
409
|
+
if (!parent.has(a) || !parent.has(b)) continue;
|
|
410
|
+
const ra = find(a);
|
|
411
|
+
const rb = find(b);
|
|
412
|
+
if (ra !== rb) parent.set(ra, rb);
|
|
413
|
+
}
|
|
414
|
+
const groups = /* @__PURE__ */ new Map();
|
|
415
|
+
for (const id of ids) {
|
|
416
|
+
const r = find(id);
|
|
417
|
+
groups.set(r, [...groups.get(r) ?? [], id]);
|
|
418
|
+
}
|
|
419
|
+
return [...groups.values()];
|
|
420
|
+
}
|
|
330
421
|
function endplateFaceSegments(center, widthA = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, widthB = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, offsetA = 0, offsetB = 0) {
|
|
331
422
|
if (center.length < 2) return [];
|
|
332
423
|
const n = centerlineNormals(center);
|
|
@@ -1210,7 +1301,19 @@ function deriveEndplatePoses(geo) {
|
|
|
1210
1301
|
})
|
|
1211
1302
|
);
|
|
1212
1303
|
const noB = geo.geometryType === "dead_end";
|
|
1213
|
-
|
|
1304
|
+
const end = sectionedEndPose({ sections: geo.sections });
|
|
1305
|
+
if (!noB && end) {
|
|
1306
|
+
poses.push(
|
|
1307
|
+
withOverride({
|
|
1308
|
+
id: "B",
|
|
1309
|
+
x: end.x,
|
|
1310
|
+
y: end.y,
|
|
1311
|
+
heading: norm360(end.heading),
|
|
1312
|
+
trackConfig: cfg(1),
|
|
1313
|
+
trackOffsets: offsetsFor(cfg(1), half)
|
|
1314
|
+
})
|
|
1315
|
+
);
|
|
1316
|
+
} else if (!noB) {
|
|
1214
1317
|
const turn = geometryTurnDegrees(geo.geometryType, geo.geometryDegrees);
|
|
1215
1318
|
let bx;
|
|
1216
1319
|
let by;
|
|
@@ -1310,11 +1413,15 @@ exports.poseOverridesFromDoc = poseOverridesFromDoc;
|
|
|
1310
1413
|
exports.sampleBenchworkOutline = sampleBenchworkOutline;
|
|
1311
1414
|
exports.samplePath = samplePath;
|
|
1312
1415
|
exports.scaleFeetToInches = scaleFeetToInches;
|
|
1416
|
+
exports.sectionAdjacency = sectionAdjacency;
|
|
1313
1417
|
exports.sectionBand = sectionBand;
|
|
1314
1418
|
exports.sectionBreaksFromSections = sectionBreaksFromSections;
|
|
1419
|
+
exports.sectionComponents = sectionComponents;
|
|
1315
1420
|
exports.sectionFootprints = sectionFootprints;
|
|
1421
|
+
exports.sectionNeighbours = sectionNeighbours;
|
|
1316
1422
|
exports.sectionSpans = sectionSpans;
|
|
1317
1423
|
exports.sectionedCenterline = sectionedCenterline;
|
|
1424
|
+
exports.sectionedEndPose = sectionedEndPose;
|
|
1318
1425
|
exports.sliceCenterline = sliceCenterline;
|
|
1319
1426
|
exports.stateToDoc = stateToDoc;
|
|
1320
1427
|
exports.trackPath = trackPath;
|