@willcgage/module-schematic 0.18.0 → 0.20.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 +59 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -2
- package/dist/index.d.ts +40 -2
- package/dist/index.js +58 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,45 @@ function sampleBenchworkOutline(pts, segsPerArc = 20) {
|
|
|
45
45
|
}
|
|
46
46
|
return out;
|
|
47
47
|
}
|
|
48
|
+
function samplePath(pts, segsPerArc = 20) {
|
|
49
|
+
const n = pts.length;
|
|
50
|
+
if (n < 2) return pts.map((p) => ({ x: p.x, y: p.y }));
|
|
51
|
+
const out = [];
|
|
52
|
+
for (let i = 0; i < n - 1; i++) {
|
|
53
|
+
const p0 = pts[i];
|
|
54
|
+
const p1 = pts[i + 1];
|
|
55
|
+
out.push({ x: p0.x, y: p0.y });
|
|
56
|
+
const bulge = p0.bulge ?? 0;
|
|
57
|
+
if (!bulge) continue;
|
|
58
|
+
const dx = p1.x - p0.x;
|
|
59
|
+
const dy = p1.y - p0.y;
|
|
60
|
+
const c = Math.hypot(dx, dy);
|
|
61
|
+
if (c < 1e-6) continue;
|
|
62
|
+
const nx = -dy / c;
|
|
63
|
+
const ny = dx / c;
|
|
64
|
+
const mid = { x: (p0.x + p1.x) / 2 + nx * bulge, y: (p0.y + p1.y) / 2 + ny * bulge };
|
|
65
|
+
const circ = circleThrough(p0, mid, p1);
|
|
66
|
+
if (!circ) continue;
|
|
67
|
+
const a0 = Math.atan2(p0.y - circ.cy, p0.x - circ.cx);
|
|
68
|
+
const am = Math.atan2(mid.y - circ.cy, mid.x - circ.cx);
|
|
69
|
+
const a1 = Math.atan2(p1.y - circ.cy, p1.x - circ.cx);
|
|
70
|
+
const sweep = arcSweep(a0, a1, am);
|
|
71
|
+
for (let s = 1; s < segsPerArc; s++) {
|
|
72
|
+
const a = a0 + sweep * s / segsPerArc;
|
|
73
|
+
out.push({ x: circ.cx + circ.r * Math.cos(a), y: circ.cy + circ.r * Math.sin(a) });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
out.push({ x: pts[n - 1].x, y: pts[n - 1].y });
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
function trackPath(path) {
|
|
80
|
+
const pts = (path ?? []).filter((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y)).map((p) => ({
|
|
81
|
+
x: p.x,
|
|
82
|
+
y: p.y,
|
|
83
|
+
...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
|
|
84
|
+
}));
|
|
85
|
+
return pts.length >= 2 ? pts : null;
|
|
86
|
+
}
|
|
48
87
|
function circleThrough(a, b, c) {
|
|
49
88
|
const d = 2 * (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
|
|
50
89
|
if (Math.abs(d) < 1e-9) return null;
|
|
@@ -67,6 +106,8 @@ function arcSweep(a0, a1, am) {
|
|
|
67
106
|
}
|
|
68
107
|
var DEG_FP = Math.PI / 180;
|
|
69
108
|
function moduleCenterline(input) {
|
|
109
|
+
const drawn = trackPath(input.mainPath);
|
|
110
|
+
if (drawn) return samplePath(drawn);
|
|
70
111
|
const L = input.lengthInches > 0 ? input.lengthInches : 24;
|
|
71
112
|
const gt = input.geometryType;
|
|
72
113
|
if (gt === "dead_end") return [{ x: 0, y: 0 }];
|
|
@@ -176,7 +217,8 @@ function emptyEditorState(lengthInches) {
|
|
|
176
217
|
endplateWidths: {},
|
|
177
218
|
outline: [],
|
|
178
219
|
controlPoints: [],
|
|
179
|
-
industries: []
|
|
220
|
+
industries: [],
|
|
221
|
+
mainPath: []
|
|
180
222
|
};
|
|
181
223
|
}
|
|
182
224
|
function isTransitionTurnout(t) {
|
|
@@ -313,7 +355,8 @@ function stateToDoc(state, recordNumber) {
|
|
|
313
355
|
moduleTrackId: t.moduleTrackId,
|
|
314
356
|
trackName: t.trackName || void 0,
|
|
315
357
|
capacityFeet: Math.round(inchesToScaleFeet(Math.abs(t.toPos - t.fromPos))),
|
|
316
|
-
...state.loop && t.inLoop ? { inLoop: true } : {}
|
|
358
|
+
...state.loop && t.inLoop ? { inLoop: true } : {},
|
|
359
|
+
...t.path && t.path.length >= 2 ? { path: t.path } : {}
|
|
317
360
|
}))
|
|
318
361
|
],
|
|
319
362
|
turnouts: state.turnouts.map((t) => ({
|
|
@@ -322,7 +365,8 @@ function stateToDoc(state, recordNumber) {
|
|
|
322
365
|
onTrack: t.onTrack,
|
|
323
366
|
divergeTrack: t.divergeTrack,
|
|
324
367
|
kind: t.kind,
|
|
325
|
-
name: t.name || void 0
|
|
368
|
+
name: t.name || void 0,
|
|
369
|
+
...t.size ? { size: t.size } : {}
|
|
326
370
|
})),
|
|
327
371
|
...state.crossings.length > 0 ? {
|
|
328
372
|
crossings: state.crossings.map((x) => ({
|
|
@@ -363,7 +407,9 @@ function stateToDoc(state, recordNumber) {
|
|
|
363
407
|
} : {},
|
|
364
408
|
// Benchwork footprint outline (module-local inches); only when it's a real
|
|
365
409
|
// ring (≥ 3 vertices).
|
|
366
|
-
...state.outline.length >= 3 ? { outline: state.outline } : {}
|
|
410
|
+
...state.outline.length >= 3 ? { outline: state.outline } : {},
|
|
411
|
+
// Authored mainline path (module-local inches); only when it's a real path.
|
|
412
|
+
...state.mainPath.length >= 2 ? { mainPath: state.mainPath } : {}
|
|
367
413
|
};
|
|
368
414
|
}
|
|
369
415
|
function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
@@ -393,7 +439,9 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
393
439
|
toPos: t.toPos != null ? sc(t.toPos) : len,
|
|
394
440
|
moduleTrackId,
|
|
395
441
|
trackName: t.trackName ?? nameOf(moduleTrackId),
|
|
396
|
-
...t.inLoop ? { inLoop: true } : {}
|
|
442
|
+
...t.inLoop ? { inLoop: true } : {},
|
|
443
|
+
// Authored path kept as-drawn (a physical shape, not rescaled with length).
|
|
444
|
+
...trackPath(t.path) ? { path: trackPath(t.path) } : {}
|
|
397
445
|
});
|
|
398
446
|
}
|
|
399
447
|
}
|
|
@@ -442,6 +490,7 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
442
490
|
y: p.y,
|
|
443
491
|
...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
|
|
444
492
|
}));
|
|
493
|
+
const mainPath = trackPath(d.mainPath) ?? [];
|
|
445
494
|
return {
|
|
446
495
|
lengthInches: len,
|
|
447
496
|
loop,
|
|
@@ -458,6 +507,7 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
458
507
|
poseOverrides,
|
|
459
508
|
endplateWidths,
|
|
460
509
|
outline,
|
|
510
|
+
mainPath,
|
|
461
511
|
crossings: (d.crossings ?? []).map((x) => ({
|
|
462
512
|
id: x.id,
|
|
463
513
|
name: x.name ?? "",
|
|
@@ -472,7 +522,8 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
472
522
|
pos: sc(t.pos),
|
|
473
523
|
onTrack: t.onTrack,
|
|
474
524
|
divergeTrack: t.divergeTrack,
|
|
475
|
-
kind: t.kind ?? "right"
|
|
525
|
+
kind: t.kind ?? "right",
|
|
526
|
+
...t.size ? { size: t.size } : {}
|
|
476
527
|
})),
|
|
477
528
|
controlPoints: readControlPoints(d, sc),
|
|
478
529
|
industries: (d.industries ?? []).map((ind) => ({
|
|
@@ -974,7 +1025,9 @@ exports.nextId = nextId;
|
|
|
974
1025
|
exports.poseNeedsManual = poseNeedsManual;
|
|
975
1026
|
exports.poseOverridesFromDoc = poseOverridesFromDoc;
|
|
976
1027
|
exports.sampleBenchworkOutline = sampleBenchworkOutline;
|
|
1028
|
+
exports.samplePath = samplePath;
|
|
977
1029
|
exports.scaleFeetToInches = scaleFeetToInches;
|
|
978
1030
|
exports.stateToDoc = stateToDoc;
|
|
1031
|
+
exports.trackPath = trackPath;
|
|
979
1032
|
//# sourceMappingURL=index.cjs.map
|
|
980
1033
|
//# sourceMappingURL=index.cjs.map
|