@willcgage/module-schematic 0.96.0 → 0.97.1
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 +52 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -2
- package/dist/index.d.ts +39 -2
- package/dist/index.js +51 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2019,14 +2019,14 @@ function storedPartToTrackPart(row) {
|
|
|
2019
2019
|
source: points.source === "measured" && frog.source === "measured" ? "measured" : "derived",
|
|
2020
2020
|
...note ? { note } : {}
|
|
2021
2021
|
} : dim(row.leadInches, row.leadSource);
|
|
2022
|
-
const kind = row.kind;
|
|
2022
|
+
const kind = TRACK_PART_KINDS.includes(row.kind) ? row.kind : "turnout";
|
|
2023
2023
|
const part = {
|
|
2024
2024
|
id: row.slug,
|
|
2025
2025
|
manufacturer: row.manufacturer,
|
|
2026
2026
|
line: row.line,
|
|
2027
2027
|
scale: "N",
|
|
2028
2028
|
name: row.name,
|
|
2029
|
-
kind
|
|
2029
|
+
kind
|
|
2030
2030
|
};
|
|
2031
2031
|
const numbers = {
|
|
2032
2032
|
...row.partNumberLeft ? { left: row.partNumberLeft } : {},
|
|
@@ -2061,6 +2061,9 @@ function storedPartToTrackPart(row) {
|
|
|
2061
2061
|
const inner = dim(row.innerRadiusInches, row.radiusSource);
|
|
2062
2062
|
if (outer) part.outerRadius = outer;
|
|
2063
2063
|
if (inner) part.innerRadius = inner;
|
|
2064
|
+
const radius = dim(row.radiusInches, row.radiusSource);
|
|
2065
|
+
if (radius) part.radius = radius;
|
|
2066
|
+
if (typeof row.arcDegrees === "number") part.arcDegrees = row.arcDegrees;
|
|
2064
2067
|
if (typeof row.actualAngleDeg === "number")
|
|
2065
2068
|
part.actualAngle = {
|
|
2066
2069
|
deg: row.actualAngleDeg,
|
|
@@ -2174,6 +2177,13 @@ function turnoutClosure(size, opts = {}) {
|
|
|
2174
2177
|
function partGeometryGap(part) {
|
|
2175
2178
|
if (part.kind === "flex") return null;
|
|
2176
2179
|
if (part.kind === "bumper") return null;
|
|
2180
|
+
if (part.kind === "straight")
|
|
2181
|
+
return part.overallLength ? null : "no overall length \u2014 a sectional straight IS its length";
|
|
2182
|
+
if (part.kind === "curve") {
|
|
2183
|
+
if (!part.radius) return "no radius \u2014 a sectional curve is a radius and an arc";
|
|
2184
|
+
if (part.arcDegrees == null) return "no arc \u2014 the radius alone does not say how far it turns";
|
|
2185
|
+
return null;
|
|
2186
|
+
}
|
|
2177
2187
|
if (part.kind === "crossover")
|
|
2178
2188
|
return "a crossover fixture builds one HALF of the assembly (piecesPerAssembly), so its published lengths describe a piece, not the finished part \u2014 the geometry of the whole crossover is not yet derivable from them";
|
|
2179
2189
|
if (part.kind === "crossing") return "crossing geometry is not modelled yet";
|
|
@@ -2187,6 +2197,18 @@ function partGeometryGap(part) {
|
|
|
2187
2197
|
}
|
|
2188
2198
|
function partGeometry(part, library = BUILT_IN_TRACK_PARTS) {
|
|
2189
2199
|
if (partGeometryGap(part)) return null;
|
|
2200
|
+
if (part.kind === "straight" || part.kind === "curve") {
|
|
2201
|
+
const end = part.kind === "curve" ? flexRunEnd(sectionalArcInches(part), part.radius.inches) : { x: part.overallLength.inches, y: 0, headingDeg: 0 };
|
|
2202
|
+
return {
|
|
2203
|
+
joints: [
|
|
2204
|
+
{ id: "a", role: "throat", x: 0, y: 0, angleDeg: 180 },
|
|
2205
|
+
{ id: "b", role: "through", x: end.x, y: end.y, angleDeg: end.headingDeg }
|
|
2206
|
+
],
|
|
2207
|
+
routes: [["a", "b"]],
|
|
2208
|
+
source: (part.kind === "curve" ? part.radius : part.overallLength)?.source ?? "unverified",
|
|
2209
|
+
divergingEndMeasured: false
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2190
2212
|
if (part.kind === "bumper") {
|
|
2191
2213
|
return {
|
|
2192
2214
|
joints: [{ id: "a", role: "throat", x: 0, y: 0, angleDeg: 180 }],
|
|
@@ -2291,6 +2313,16 @@ function pieceRoutePaths(piece, library = BUILT_IN_TRACK_PARTS) {
|
|
|
2291
2313
|
const len = part.overallLength?.inches ?? BUMPER_DRAWN_INCHES;
|
|
2292
2314
|
return [{ route: ["a", "a"], points: [{ x: at2.x, y: at2.y }, place(len, 0)] }];
|
|
2293
2315
|
}
|
|
2316
|
+
if (part.kind === "curve") {
|
|
2317
|
+
const a = joints.find((j) => j.joint === "a");
|
|
2318
|
+
const b = joints.find((j) => j.joint === "b");
|
|
2319
|
+
if (!a || !b) return out;
|
|
2320
|
+
const pts = flexRunPoints(sectionalArcInches(part), part.radius.inches).map(
|
|
2321
|
+
(q) => place(q.x, q.y)
|
|
2322
|
+
);
|
|
2323
|
+
pts[pts.length - 1] = { x: b.x, y: b.y };
|
|
2324
|
+
return [{ route: ["a", "b"], points: pts }];
|
|
2325
|
+
}
|
|
2294
2326
|
for (const route of geo.routes) {
|
|
2295
2327
|
const a = at(route[0]);
|
|
2296
2328
|
const b = at(route[1]);
|
|
@@ -2354,7 +2386,22 @@ function partsPlaceable(library = BUILT_IN_TRACK_PARTS) {
|
|
|
2354
2386
|
return { placeable, blocked };
|
|
2355
2387
|
}
|
|
2356
2388
|
var JOINT_SNAP_INCHES = 0.01;
|
|
2389
|
+
var TRACK_PART_KINDS = [
|
|
2390
|
+
"turnout",
|
|
2391
|
+
"wye",
|
|
2392
|
+
"curved-turnout",
|
|
2393
|
+
"crossover",
|
|
2394
|
+
"crossing",
|
|
2395
|
+
"flex",
|
|
2396
|
+
"straight",
|
|
2397
|
+
"curve",
|
|
2398
|
+
"bumper"
|
|
2399
|
+
];
|
|
2357
2400
|
var BUMPER_DRAWN_INCHES = 0.75;
|
|
2401
|
+
function sectionalArcInches(part) {
|
|
2402
|
+
if (part.kind !== "curve" || !part.radius || part.arcDegrees == null) return 0;
|
|
2403
|
+
return part.radius.inches * Math.abs(part.arcDegrees) * Math.PI / 180;
|
|
2404
|
+
}
|
|
2358
2405
|
function flexRunEnd(lengthInches, radiusInches) {
|
|
2359
2406
|
const L = lengthInches;
|
|
2360
2407
|
const R = radiusInches;
|
|
@@ -2530,6 +2577,7 @@ function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS)
|
|
|
2530
2577
|
const piece = pieceById.get(a.piece);
|
|
2531
2578
|
const part = piece ? partOf(a.piece) : void 0;
|
|
2532
2579
|
if (piece && part?.kind === "flex") return piece.lengthInches ?? 0;
|
|
2580
|
+
if (part?.kind === "curve") return sectionalArcInches(part);
|
|
2533
2581
|
}
|
|
2534
2582
|
return Math.hypot(a.x - b.x, a.y - b.y);
|
|
2535
2583
|
};
|
|
@@ -3541,6 +3589,7 @@ exports.N_SCALE_RATIO = N_SCALE_RATIO;
|
|
|
3541
3589
|
exports.PINCH_EASE_INCHES = PINCH_EASE_INCHES;
|
|
3542
3590
|
exports.RAIL_GAUGE_INCHES = RAIL_GAUGE_INCHES;
|
|
3543
3591
|
exports.TIE_HALF_LENGTH_INCHES = TIE_HALF_LENGTH_INCHES;
|
|
3592
|
+
exports.TRACK_PART_KINDS = TRACK_PART_KINDS;
|
|
3544
3593
|
exports.TURNOUT_LEAD_INCHES_PER_FROG = TURNOUT_LEAD_INCHES_PER_FROG;
|
|
3545
3594
|
exports.WHOLE_MODULE_SECTION_ID = WHOLE_MODULE_SECTION_ID;
|
|
3546
3595
|
exports.asModuleSchematic = asModuleSchematic;
|
|
@@ -3625,6 +3674,7 @@ exports.sectionFootprints = sectionFootprints;
|
|
|
3625
3674
|
exports.sectionNeighbours = sectionNeighbours;
|
|
3626
3675
|
exports.sectionSpans = sectionSpans;
|
|
3627
3676
|
exports.sectionSpansOrWhole = sectionSpansOrWhole;
|
|
3677
|
+
exports.sectionalArcInches = sectionalArcInches;
|
|
3628
3678
|
exports.sectionedCenterline = sectionedCenterline;
|
|
3629
3679
|
exports.sectionedEndPose = sectionedEndPose;
|
|
3630
3680
|
exports.sliceCenterline = sliceCenterline;
|