@rig-c/core 2.69.0 → 2.71.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/src/trackgen.ts CHANGED
@@ -113,6 +113,17 @@ export interface TrackDeriveTurn {
113
113
  carried?: number;
114
114
  /** Where the axis crosses the driving coordinate, in the members' shared parent's space. Default 0. */
115
115
  about?: number;
116
+ /**
117
+ * Whether the displacement includes the foreshortening of the member's setup
118
+ * position `(at − about)·(cos t − 1)`. Default `true`.
119
+ *
120
+ * When `false`, the displacement is `−(depth − carried)·sin t` — the depth
121
+ * shift alone, for a rig whose plate proportions are held at their front-view
122
+ * width across the turn (issue #1584). Valid on the displacement projection
123
+ * (`translatex` / `translatey`) only; refused on the foreshortening projection
124
+ * (`scalex` / `scaley`).
125
+ */
126
+ narrowing?: boolean;
116
127
  }
117
128
 
118
129
  export type TrackDerive = TrackDeriveTurn;
@@ -226,7 +237,16 @@ export function evaluateTrackDerive(
226
237
  `axis. "carried" belongs on the "${projections.shift}" track, whose shared shift is the thing it names.`, 'CE_TRACK_CARRIED_PROJECTION',
227
238
  );
228
239
  }
240
+ if (projection === 'foreshorten' && turn.narrowing !== undefined) {
241
+ throw new CompileError(
242
+ `${where}: derive ${kind} states narrowing=${JSON.stringify(turn.narrowing)} on a "${property}" track, and a ` +
243
+ `"${property}" track IS the foreshortening — its whole output is cos(α − t)/cos α. "narrowing" belongs on the ` +
244
+ `"${projections.shift}" track, where it drops (${projections.coordinate}−about)·(cos t − 1) from the displacement; ` +
245
+ `to turn without narrowing the plate's scale, omit the "${property}" track.`, 'CE_TRACK_NARROWING_PROJECTION',
246
+ );
247
+ }
229
248
  const carried = turn.carried === undefined ? 0 : num(turn.carried, 'carried', where);
249
+ const narrowing = turn.narrowing !== false;
230
250
 
231
251
  const rad = (degrees * Math.PI) / 180;
232
252
  const cosMinus1 = Math.cos(rad) - 1;
@@ -237,7 +257,7 @@ export function evaluateTrackDerive(
237
257
  const depth = depthOf(turn.depth, member.name, members, where, kind);
238
258
  const u = member.at - about;
239
259
  if (projection === 'shift') {
240
- values.push({ member: member.name, at: u, depth, value: round(u * cosMinus1 - (depth - carried) * sin) });
260
+ values.push({ member: member.name, at: u, depth, value: round((narrowing ? u * cosMinus1 : 0) - (depth - carried) * sin) });
241
261
  continue;
242
262
  }
243
263
  // A part behind the axis has no patch of front surface to foreshorten, and
@@ -270,16 +290,19 @@ export function evaluateTrackDerive(
270
290
  const stated =
271
291
  `degrees=${degrees}` +
272
292
  (projection === 'shift' && turn.carried !== undefined ? ` carried=${carried}` : '') +
273
- (turn.about === undefined ? '' : ` about=${about}`);
293
+ (turn.about === undefined ? '' : ` about=${about}`) +
294
+ (projection === 'shift' && !narrowing ? ' narrowing=false' : '');
274
295
  const formula =
275
296
  projection === 'shift'
276
- ? `d${c} = (${c}−about)·(cos t − 1) − (depth − carried)·sin t`
297
+ ? narrowing
298
+ ? `d${c} = (${c}−about)·(cos t − 1) − (depth − carried)·sin t`
299
+ : `d${c} = −(depth − carried)·sin t`
277
300
  : `scale${c.toUpperCase()} = cos(α − t) / cos α, α = atan2(${c}−about, depth)`;
278
301
  const derived =
279
302
  projection === 'shift'
280
303
  ? [
281
304
  `t = ${round(rad)} rad`,
282
- `cos t − 1 = ${round(cosMinus1)}`,
305
+ ...(narrowing ? [`cos t − 1 = ${round(cosMinus1)}`] : []),
283
306
  `sin t = ${round(sin)}`,
284
307
  `shift the parent carries = −carried·sin t = ${round(-carried * sin)}`,
285
308
  ]