@willcgage/module-schematic 0.91.0 → 0.92.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 CHANGED
@@ -2268,8 +2268,16 @@ function pieceRoutePaths(piece, library = BUILT_IN_TRACK_PARTS) {
2268
2268
  const b = at(route[1]);
2269
2269
  if (!a || !b) continue;
2270
2270
  const ends = [{ x: a.x, y: a.y }, { x: b.x, y: b.y }];
2271
+ if (part.kind === "flex") {
2272
+ const pts2 = flexRunPoints(piece.lengthInches ?? 0, piece.radiusInches).map(
2273
+ (q) => place(q.x, q.y)
2274
+ );
2275
+ pts2[pts2.length - 1] = { x: b.x, y: b.y };
2276
+ out.push({ route, points: pts2 });
2277
+ continue;
2278
+ }
2271
2279
  const diverging = route.some((r) => r === "diverge" || r === "legA" || r === "legB");
2272
- if (!diverging || part.kind === "flex") {
2280
+ if (!diverging) {
2273
2281
  out.push({ route, points: ends });
2274
2282
  continue;
2275
2283
  }
@@ -2308,6 +2316,25 @@ function partsPlaceable(library = BUILT_IN_TRACK_PARTS) {
2308
2316
  return { placeable, blocked };
2309
2317
  }
2310
2318
  var JOINT_SNAP_INCHES = 0.01;
2319
+ function flexRunEnd(lengthInches, radiusInches) {
2320
+ const L = lengthInches;
2321
+ const R = radiusInches;
2322
+ if (!R || !Number.isFinite(R) || Math.abs(R) < 1e-6)
2323
+ return { x: L, y: 0, headingDeg: 0 };
2324
+ const theta = L / R;
2325
+ return {
2326
+ x: Math.abs(R) * Math.sin(Math.abs(theta)) * Math.sign(L || 1),
2327
+ y: R * (1 - Math.cos(theta)),
2328
+ headingDeg: theta * 180 / Math.PI
2329
+ };
2330
+ }
2331
+ function flexRunPoints(lengthInches, radiusInches, steps = 16) {
2332
+ if (!radiusInches || !Number.isFinite(radiusInches) || Math.abs(radiusInches) < 1e-6)
2333
+ return [{ x: 0, y: 0 }, { x: lengthInches, y: 0 }];
2334
+ const out = [];
2335
+ for (let i = 0; i <= steps; i++) out.push(flexRunEnd(lengthInches * i / steps, radiusInches));
2336
+ return out.map((p) => ({ x: p.x, y: p.y }));
2337
+ }
2311
2338
  function placedJoints(pieces, library = BUILT_IN_TRACK_PARTS) {
2312
2339
  const out = [];
2313
2340
  const RAD = Math.PI / 180;
@@ -2318,10 +2345,13 @@ function placedJoints(pieces, library = BUILT_IN_TRACK_PARTS) {
2318
2345
  if (!geo) continue;
2319
2346
  const c = Math.cos(p.rotationDeg * RAD);
2320
2347
  const s = Math.sin(p.rotationDeg * RAD);
2348
+ const run = part.kind === "flex" ? flexRunEnd(p.lengthInches ?? 0, p.radiusInches) : null;
2321
2349
  for (const j of geo.joints) {
2322
- const lx = part.kind === "flex" && j.id === "b" ? p.lengthInches ?? 0 : j.x;
2323
- const ly = p.flipped ? -j.y : j.y;
2324
- const h = (p.flipped ? -j.angleDeg : j.angleDeg) + p.rotationDeg;
2350
+ const far = run && j.id === "b";
2351
+ const lx = far ? run.x : j.x;
2352
+ const ly = p.flipped ? -(far ? run.y : j.y) : far ? run.y : j.y;
2353
+ const local = far ? run.headingDeg : j.angleDeg;
2354
+ const h = (p.flipped ? -local : local) + p.rotationDeg;
2325
2355
  out.push({
2326
2356
  key: `${p.id}.${j.id}`,
2327
2357
  piece: p.id,
@@ -2427,7 +2457,15 @@ function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS)
2427
2457
  const part = partOf(pid);
2428
2458
  return part ? partGeometry(part, library) : null;
2429
2459
  };
2430
- const gap = (a, b) => a && b ? Math.hypot(a.x - b.x, a.y - b.y) : 0;
2460
+ const gap = (a, b) => {
2461
+ if (!a || !b) return 0;
2462
+ if (a.piece === b.piece) {
2463
+ const piece = pieceById.get(a.piece);
2464
+ const part = piece ? partOf(a.piece) : void 0;
2465
+ if (piece && part?.kind === "flex") return piece.lengthInches ?? 0;
2466
+ }
2467
+ return Math.hypot(a.x - b.x, a.y - b.y);
2468
+ };
2431
2469
  const routes = [];
2432
2470
  const turnouts = [];
2433
2471
  const warnings = [];
@@ -3378,6 +3416,7 @@ exports.endplateWidthInches = endplateWidthInches;
3378
3416
  exports.flexPartFor = flexPartFor;
3379
3417
  exports.flexParts = flexParts;
3380
3418
  exports.flexPieces = flexPieces;
3419
+ exports.flexRunEnd = flexRunEnd;
3381
3420
  exports.flexUsage = flexUsage;
3382
3421
  exports.frogCasting = frogCasting;
3383
3422
  exports.frogNumberFromName = frogNumberFromName;