curvy 2.0.0-alpha.13 → 2.0.0-alpha.14

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.
Files changed (93) hide show
  1. package/dist/characteristic/index.mjs +1 -1
  2. package/dist/curve/cubic2d.d.ts +102 -3
  3. package/dist/curve/curve2d.d.ts +81 -0
  4. package/dist/curve/index.mjs +1 -1
  5. package/dist/curve/linear2d.d.ts +122 -3
  6. package/dist/curve/quadratic2d.d.ts +103 -3
  7. package/dist/curve/rationalCubic2d.d.ts +100 -38
  8. package/dist/interval/index.mjs +2 -2
  9. package/dist/matrix/index.mjs +47 -1
  10. package/dist/matrix/index.mjs.map +1 -1
  11. package/dist/matrix/matrix3x3.d.ts +87 -1
  12. package/dist/matrix/matrix4x4.d.ts +57 -6
  13. package/dist/matrix/traits.d.ts +34 -0
  14. package/dist/monotonicity/index.mjs +1 -1
  15. package/dist/monotonicity/monotonicity.d.ts +25 -0
  16. package/dist/number.d.ts +53 -0
  17. package/dist/number.mjs +56 -1
  18. package/dist/number.mjs.map +1 -1
  19. package/dist/path/cubic2d.d.ts +22 -0
  20. package/dist/path/index.mjs +25 -149
  21. package/dist/path/index.mjs.map +1 -1
  22. package/dist/path/linear2d.d.ts +24 -0
  23. package/dist/path/path2d.d.ts +54 -0
  24. package/dist/path/quadratic2d.d.ts +22 -0
  25. package/dist/path/rationalCubic2d.d.ts +21 -0
  26. package/dist/polynomial/index.mjs +2 -2
  27. package/dist/shared/affine2d-Dvna84gc.mjs +332 -0
  28. package/dist/shared/affine2d-Dvna84gc.mjs.map +1 -0
  29. package/dist/shared/{characteristic-BkEr-rr8.mjs → characteristic--7nC4Q_a.mjs} +4 -5
  30. package/dist/shared/characteristic--7nC4Q_a.mjs.map +1 -0
  31. package/dist/shared/{cubic-BL6dpuHh.mjs → cubic-BiGuAnZ0.mjs} +56 -27
  32. package/dist/shared/cubic-BiGuAnZ0.mjs.map +1 -0
  33. package/dist/shared/{interval-Dm35Xhy4.mjs → interval-Dcqpo73t.mjs} +5 -5
  34. package/dist/shared/interval-Dcqpo73t.mjs.map +1 -0
  35. package/dist/shared/{interval2d-AtneyI45.mjs → interval2d-C2Pk66-2.mjs} +3 -3
  36. package/dist/shared/{interval2d-AtneyI45.mjs.map → interval2d-C2Pk66-2.mjs.map} +1 -1
  37. package/dist/shared/matrix3x3.internal-Cod-r7H3.mjs +233 -0
  38. package/dist/shared/matrix3x3.internal-Cod-r7H3.mjs.map +1 -0
  39. package/dist/shared/{matrix4x4-BWmf4lZM.mjs → matrix4x4-BrqgYZCD.mjs} +72 -223
  40. package/dist/shared/matrix4x4-BrqgYZCD.mjs.map +1 -0
  41. package/dist/shared/monotonicity-DNxBoC7F.mjs +64 -0
  42. package/dist/shared/monotonicity-DNxBoC7F.mjs.map +1 -0
  43. package/dist/shared/{quadratic-DPrUsFCp.mjs → quadratic-BmMqkvxx.mjs} +2 -2
  44. package/dist/shared/{quadratic-DPrUsFCp.mjs.map → quadratic-BmMqkvxx.mjs.map} +1 -1
  45. package/dist/shared/{rationalCubic2d-CeHgpNht.mjs → rationalCubic2d-CZSwwKtS.mjs} +591 -125
  46. package/dist/shared/rationalCubic2d-CZSwwKtS.mjs.map +1 -0
  47. package/dist/shared/{rationalCubic2d-H1J2Fjyy.mjs → rationalCubic2d-bveuGqBZ.mjs} +282 -326
  48. package/dist/shared/rationalCubic2d-bveuGqBZ.mjs.map +1 -0
  49. package/dist/shared/{solution-B2JdOZpe.mjs → solution-BW0BBMXI.mjs} +22 -6
  50. package/dist/shared/solution-BW0BBMXI.mjs.map +1 -0
  51. package/dist/shared/{vector2-CSkaMXvp.mjs → vector2-DuA3EmfL.mjs} +5 -3
  52. package/dist/shared/vector2-DuA3EmfL.mjs.map +1 -0
  53. package/dist/shared/{vector2.internal-DP1nTBdS.mjs → vector2.internal-rPnW0RCx.mjs} +10 -5
  54. package/dist/shared/vector2.internal-rPnW0RCx.mjs.map +1 -0
  55. package/dist/shared/{vector3-CR2LPV03.mjs → vector3-oxtggkDp.mjs} +2 -2
  56. package/dist/shared/{vector3-CR2LPV03.mjs.map → vector3-oxtggkDp.mjs.map} +1 -1
  57. package/dist/shared/vector3.internal-CfWHl9SG.mjs +135 -0
  58. package/dist/shared/vector3.internal-CfWHl9SG.mjs.map +1 -0
  59. package/dist/shared/{vector4-PO_7EYd-.mjs → vector4-DGHuCvTV.mjs} +2 -2
  60. package/dist/shared/{vector4-PO_7EYd-.mjs.map → vector4-DGHuCvTV.mjs.map} +1 -1
  61. package/dist/shared/vector4.internal-DH5DzNYO.mjs +116 -0
  62. package/dist/shared/vector4.internal-DH5DzNYO.mjs.map +1 -0
  63. package/dist/solution/index.mjs +1 -1
  64. package/dist/solution/solution.d.ts +16 -0
  65. package/dist/splines/basis2d.d.ts +64 -0
  66. package/dist/splines/bezier2d.d.ts +72 -0
  67. package/dist/splines/cardinal2d.d.ts +78 -0
  68. package/dist/splines/hermite2d.d.ts +76 -0
  69. package/dist/splines/index.mjs +109 -15
  70. package/dist/splines/index.mjs.map +1 -1
  71. package/dist/splines/linear2d.d.ts +65 -0
  72. package/dist/splines/rationalBezier2d.d.ts +76 -0
  73. package/dist/transform/affine2d.d.ts +339 -0
  74. package/dist/transform/affine2d.internal.d.ts +2 -0
  75. package/dist/transform/index.d.ts +3 -0
  76. package/dist/transform/index.mjs +2 -0
  77. package/dist/transform/traits.d.ts +19 -0
  78. package/dist/vector/index.mjs +3 -3
  79. package/dist/vector/vector2.d.ts +49 -0
  80. package/package.json +5 -1
  81. package/dist/shared/characteristic-BkEr-rr8.mjs.map +0 -1
  82. package/dist/shared/cubic-BL6dpuHh.mjs.map +0 -1
  83. package/dist/shared/interval-Dm35Xhy4.mjs.map +0 -1
  84. package/dist/shared/matrix4x4-BWmf4lZM.mjs.map +0 -1
  85. package/dist/shared/monotonicity-BdebFOtv.mjs +0 -34
  86. package/dist/shared/monotonicity-BdebFOtv.mjs.map +0 -1
  87. package/dist/shared/rationalCubic2d-CeHgpNht.mjs.map +0 -1
  88. package/dist/shared/rationalCubic2d-H1J2Fjyy.mjs.map +0 -1
  89. package/dist/shared/solution-B2JdOZpe.mjs.map +0 -1
  90. package/dist/shared/vector2-CSkaMXvp.mjs.map +0 -1
  91. package/dist/shared/vector2.internal-DP1nTBdS.mjs.map +0 -1
  92. package/dist/shared/vector4.internal-BJ1QN2Ck.mjs +0 -246
  93. package/dist/shared/vector4.internal-BJ1QN2Ck.mjs.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import type { CubicPath2d } from '../path/cubic2d.ts';
2
+ import type { Affine2d } from '../transform/affine2d.ts';
2
3
  import type { Pipeable } from '../utils.ts';
3
4
  import type { Vector2 } from '../vector/vector2.ts';
4
5
  import type { Bezier2d } from './bezier2d.ts';
@@ -244,6 +245,83 @@ export declare const withOptions: {
244
245
  */
245
246
  (c: Cardinal2d, options: Options): Cardinal2d;
246
247
  };
248
+ export declare const mapPoints: {
249
+ /**
250
+ * Applies a per-point transform to every control point in a `Cardinal2d`,
251
+ * preserving point count, tension, and alpha.
252
+ *
253
+ * @param f - The point transform.
254
+ * @returns A function that takes a `Cardinal2d` and returns the mapped spline.
255
+ * @since 2.0.0
256
+ */
257
+ (f: (p: Vector2) => Vector2): (s: Cardinal2d) => Cardinal2d;
258
+ /**
259
+ * Applies a per-point transform to every control point in a `Cardinal2d`.
260
+ *
261
+ * @param s - The cardinal spline.
262
+ * @param f - The point transform.
263
+ * @returns A new `Cardinal2d` with the transform applied to each control point.
264
+ * @since 2.0.0
265
+ */
266
+ (s: Cardinal2d, f: (p: Vector2) => Vector2): Cardinal2d;
267
+ };
268
+ export declare const flatMap: {
269
+ /**
270
+ * Hands the spline's full control-point array to `f` and uses its returned
271
+ * `Cardinal2d` as the result. The returned spline's tension and alpha come
272
+ * from the mapper's output, not the input — to preserve the input's
273
+ * parameterization, the mapper should re-supply it (e.g. by reading the
274
+ * original spline in the data-first form, or chaining `withOptions`
275
+ * afterward).
276
+ *
277
+ * @param f - The bulk transform.
278
+ * @returns A function that takes a `Cardinal2d` and returns the rebuilt spline.
279
+ * @since 2.0.0
280
+ */
281
+ (f: (points: ReadonlyArray<Vector2>) => Cardinal2d): (s: Cardinal2d) => Cardinal2d;
282
+ /**
283
+ * Hands the spline's full control-point array to `f` and uses its returned
284
+ * `Cardinal2d` as the result.
285
+ *
286
+ * @param s - The cardinal spline.
287
+ * @param f - The bulk transform.
288
+ * @returns The `Cardinal2d` returned by `f`.
289
+ * @since 2.0.0
290
+ */
291
+ (s: Cardinal2d, f: (points: ReadonlyArray<Vector2>) => Cardinal2d): Cardinal2d;
292
+ };
293
+ export declare const transform: {
294
+ /**
295
+ * Applies an `Affine2d` transform to every control point of a `Cardinal2d`,
296
+ * preserving the spline's `tension` and `alpha`.
297
+ *
298
+ * **Exactness depends on parameterization.** With `alpha = 0` (uniform
299
+ * Catmull-Rom) the affine basis commutes exactly with evaluation, so the
300
+ * result parameterizes the affine image of the original curve. With
301
+ * `alpha != 0` (centripetal / chordal), chord lengths between control points
302
+ * drive the parameterization and a non-uniform-scaling transform changes
303
+ * those chord lengths in axis-dependent ways. In that case the returned
304
+ * curve is still a sensible Cardinal spline on the transformed control
305
+ * points, but it no longer matches the affine image of the original
306
+ * pointwise. For pixel-exact transforms of centripetal splines, convert to
307
+ * `Bezier2d` via {@link toBezier} first, then transform.
308
+ *
309
+ * @param s - The cardinal spline.
310
+ * @param a - The affine transform.
311
+ * @returns A new `Cardinal2d` whose control points are the affine images of
312
+ * the input's, with the same parameterization.
313
+ * @since 2.0.0
314
+ */
315
+ (s: Cardinal2d, a: Affine2d): Cardinal2d;
316
+ /**
317
+ * Applies an `Affine2d` transform to every control point of a `Cardinal2d`.
318
+ *
319
+ * @param a - The affine transform.
320
+ * @returns A function that takes a `Cardinal2d` and returns the transformed spline.
321
+ * @since 2.0.0
322
+ */
323
+ (a: Affine2d): (s: Cardinal2d) => Cardinal2d;
324
+ };
247
325
  /**
248
326
  * Converts a `Cardinal2d` to a `CubicPath2d` using the spline's `tension` and
249
327
  * `alpha`. With the default options (`{ tension: 0.5, alpha: 0.5 }`) the
@@ -1,4 +1,5 @@
1
1
  import type { CubicPath2d } from '../path/cubic2d.ts';
2
+ import type { Affine2d } from '../transform/affine2d.ts';
2
3
  import type { Pipeable } from '../utils.ts';
3
4
  import type { Vector2 } from '../vector/vector2.ts';
4
5
  import type { Bezier2d } from './bezier2d.ts';
@@ -95,6 +96,81 @@ export declare const prepend: {
95
96
  */
96
97
  (p: Hermite2d, p0: Vector2, v0: Vector2): Hermite2d;
97
98
  };
99
+ export declare const mapPoints: {
100
+ /**
101
+ * Applies a per-point transform to every entry in a `Hermite2d`, preserving
102
+ * the alternating position/velocity layout and total point count.
103
+ *
104
+ * The transform receives both positions and velocity vectors as plain
105
+ * `Vector2`s — Hermite splines store them in interleaved slots without a
106
+ * structural distinction. Linear transforms (rotation, scaling) act
107
+ * correctly on both slot kinds, but a uniform translation will offset the
108
+ * velocity slots as well as the positions; to translate positions only,
109
+ * reach for {@link flatMap} and split the array yourself.
110
+ *
111
+ * @param f - The point transform.
112
+ * @returns A function that takes a `Hermite2d` and returns the mapped spline.
113
+ * @since 2.0.0
114
+ */
115
+ (f: (p: Vector2) => Vector2): (s: Hermite2d) => Hermite2d;
116
+ /**
117
+ * Applies a per-point transform to every entry in a `Hermite2d`.
118
+ *
119
+ * @param s - The hermite spline.
120
+ * @param f - The point transform.
121
+ * @returns A new `Hermite2d` with the transform applied to each entry.
122
+ * @since 2.0.0
123
+ */
124
+ (s: Hermite2d, f: (p: Vector2) => Vector2): Hermite2d;
125
+ };
126
+ export declare const flatMap: {
127
+ /**
128
+ * Hands the spline's full entry array to `f` (alternating positions and
129
+ * velocities) and uses its returned `Hermite2d` as the result. The returned
130
+ * spline goes through this module's builders, so the even-arity and
131
+ * minimum-4-entry invariants are enforced at construction.
132
+ *
133
+ * @param f - The bulk transform.
134
+ * @returns A function that takes a `Hermite2d` and returns the rebuilt spline.
135
+ * @since 2.0.0
136
+ */
137
+ (f: (points: ReadonlyArray<Vector2>) => Hermite2d): (s: Hermite2d) => Hermite2d;
138
+ /**
139
+ * Hands the spline's full entry array to `f` and uses its returned
140
+ * `Hermite2d` as the result.
141
+ *
142
+ * @param s - The hermite spline.
143
+ * @param f - The bulk transform.
144
+ * @returns The `Hermite2d` returned by `f`.
145
+ * @since 2.0.0
146
+ */
147
+ (s: Hermite2d, f: (points: ReadonlyArray<Vector2>) => Hermite2d): Hermite2d;
148
+ };
149
+ export declare const transform: {
150
+ /**
151
+ * Applies an `Affine2d` transform to a `Hermite2d`, treating the entries
152
+ * correctly by kind: positions (even indices) receive the full affine, and
153
+ * tangent vectors (odd indices) receive only the linear part — translation
154
+ * doesn't move tangents, only the linear map does.
155
+ *
156
+ * The result exactly parameterizes the affine image of the original curve.
157
+ *
158
+ * @param s - The hermite spline.
159
+ * @param a - The affine transform.
160
+ * @returns A new `Hermite2d` with positions and tangents transformed
161
+ * appropriately.
162
+ * @since 2.0.0
163
+ */
164
+ (s: Hermite2d, a: Affine2d): Hermite2d;
165
+ /**
166
+ * Applies an `Affine2d` transform to a `Hermite2d`.
167
+ *
168
+ * @param a - The affine transform.
169
+ * @returns A function that takes a `Hermite2d` and returns the transformed spline.
170
+ * @since 2.0.0
171
+ */
172
+ (a: Affine2d): (s: Hermite2d) => Hermite2d;
173
+ };
98
174
  /**
99
175
  * Creates a new `CubicPath2d` instance from a `Hermite2d`.
100
176
  *
@@ -1,14 +1,15 @@
1
1
  import { t as __exportAll } from "../shared/chunk-25Hzd3z8.mjs";
2
2
  import { Pipeable, dual, invariant } from "../utils.mjs";
3
- import { epsEquals } from "../number.mjs";
4
- import { a as make$12, c as subtract, i as magnitude, o as makeWeighted, r as isVector2, s as scale, t as add } from "../shared/vector2-CSkaMXvp.mjs";
5
- import { t as make$13 } from "../shared/vector3-CR2LPV03.mjs";
6
- import { n as transpose, t as make$14 } from "../shared/vector4-PO_7EYd-.mjs";
7
- import { a as vectorProductLeft, i as multiply, t as inverse } from "../shared/matrix4x4-BWmf4lZM.mjs";
8
- import { o as none, s as one } from "../shared/solution-B2JdOZpe.mjs";
9
- import { S as fromEndpoints, c as fromCoefficients, l as fromPolynomials, r as fromBezierPoints } from "../shared/rationalCubic2d-CeHgpNht.mjs";
10
- import { a as cubicHermite, i as cubicBezier, r as cubicBasisSpline, t as apply } from "../shared/characteristic-BkEr-rr8.mjs";
11
- import { a as fromArray$13, i as make$15, t as fromArray$12 } from "../shared/rationalCubic2d-H1J2Fjyy.mjs";
3
+ import { coincident } from "../number.mjs";
4
+ import { a as magnitude, c as scale, i as liftWithWeight, l as subtract, o as make$12, r as isVector2, s as makeWeighted, t as add } from "../shared/vector2-DuA3EmfL.mjs";
5
+ import { t as make$13 } from "../shared/vector3-oxtggkDp.mjs";
6
+ import { n as transpose, t as make$14 } from "../shared/vector4-DGHuCvTV.mjs";
7
+ import { c as one, s as none } from "../shared/solution-BW0BBMXI.mjs";
8
+ import { a as vectorProductLeft, i as multiply, t as inverseUnsafe } from "../shared/matrix4x4-BrqgYZCD.mjs";
9
+ import { l as fromCoefficients, r as fromBezierPoints, u as fromPolynomials, v as fromEndpoints } from "../shared/rationalCubic2d-CZSwwKtS.mjs";
10
+ import { a as cubicHermite, i as cubicBezier, r as cubicBasisSpline, t as apply } from "../shared/characteristic--7nC4Q_a.mjs";
11
+ import { a as fromArray$13, i as make$15, t as fromArray$12 } from "../shared/rationalCubic2d-bveuGqBZ.mjs";
12
+ import { i as linearPart, n as apply$1, r as applyTo } from "../shared/affine2d-Dvna84gc.mjs";
12
13
  //#region src/splines/rationalBezier2d.internal.ts
13
14
  const RationalBezier2dTypeId = Symbol("curvy/splines/rationalBezier2d");
14
15
  var RationalBezier2dImpl = class extends Pipeable {
@@ -68,6 +69,17 @@ const toPath$11 = (r) => {
68
69
  return fromArray$12(curves);
69
70
  };
70
71
  /** @internal */
72
+ const mapPoints$11 = dual(2, (s, f) => {
73
+ const homogeneous = homogeneousOf(s);
74
+ const mapped = [];
75
+ for (const h of homogeneous) mapped.push(lift(f(makeWeighted(h.x / h.z, h.y / h.z, h.z))));
76
+ return new RationalBezier2dImpl(mapped);
77
+ });
78
+ /** @internal */
79
+ const flatMap$11 = dual(2, (s, f) => f([...s]));
80
+ /** @internal */
81
+ const transform$11 = dual(2, (s, a) => mapPoints$11(s, liftWithWeight(applyTo(a))));
82
+ /** @internal */
71
83
  const subdivide$3 = dual(2, (r, u) => {
72
84
  invariant(u > 0 && u < 1, "subdivide parameter u must be in the open interval (0, 1)");
73
85
  const homogeneous = homogeneousOf(r);
@@ -123,7 +135,7 @@ const toBezierPoints = (r) => {
123
135
  const w0 = homogeneous[0].z;
124
136
  const points = [];
125
137
  for (const h of homogeneous) {
126
- if (!epsEquals(h.z, w0)) return none;
138
+ if (!coincident(h.z, w0)) return none;
127
139
  points.push(make$12(h.x / h.z, h.y / h.z));
128
140
  }
129
141
  return one(points);
@@ -175,7 +187,7 @@ function* toCurves(points, matrix, stride) {
175
187
  }
176
188
  //#endregion
177
189
  //#region src/splines/bezier2d.internal.ts
178
- const characteristicInverse = inverse(cubicBezier);
190
+ const characteristicInverse = inverseUnsafe(cubicBezier);
179
191
  const conversionCache = /* @__PURE__ */ new WeakMap();
180
192
  const getConversionMatrix = (source) => {
181
193
  let combined = conversionCache.get(source);
@@ -254,6 +266,14 @@ const appendAccelerationAligned$1 = dual(2, (p, p6) => {
254
266
  return append$9(p, make$12(2 * p3.x - p2.x, 2 * p3.y - p2.y), make$12(p1.x + 4 * (p3.x - p2.x), p1.y + 4 * (p3.y - p2.y)), p6);
255
267
  });
256
268
  /** @internal */
269
+ const mapPoints$10 = dual(2, (s, f) => {
270
+ return new Bezier2dImpl((s instanceof Bezier2dImpl ? s.points : [...s]).map(f));
271
+ });
272
+ /** @internal */
273
+ const flatMap$10 = dual(2, (s, f) => f(s instanceof Bezier2dImpl ? s.points : [...s]));
274
+ /** @internal */
275
+ const transform$10 = dual(2, (s, a) => mapPoints$10(s, applyTo(a)));
276
+ /** @internal */
257
277
  const toPath$10 = (p) => make$15(...toCurves(p, cubicBezier, 3));
258
278
  /** @internal */
259
279
  const fromRational$1 = (r) => {
@@ -313,13 +333,16 @@ var bezier2d_exports = /* @__PURE__ */ __exportAll({
313
333
  appendCurvatureAligned: () => appendCurvatureAligned,
314
334
  appendTangentAligned: () => appendTangentAligned,
315
335
  appendVelocityAligned: () => appendVelocityAligned,
336
+ flatMap: () => flatMap$9,
316
337
  fromArray: () => fromArray$9,
317
338
  fromRational: () => fromRational,
318
339
  fromTuples: () => fromTuples$9,
319
340
  isCubicBezier2d: () => isCubicBezier2d,
320
341
  make: () => make$9,
342
+ mapPoints: () => mapPoints$9,
321
343
  subdivide: () => subdivide$1,
322
- toPath: () => toPath$9
344
+ toPath: () => toPath$9,
345
+ transform: () => transform$9
323
346
  });
324
347
  /**
325
348
  * Creates a new `Bezier2d` instance.
@@ -362,6 +385,9 @@ const appendTangentAligned = appendTangentAligned$1;
362
385
  const appendCurvatureAligned = appendCurvatureAligned$1;
363
386
  const appendVelocityAligned = appendVelocityAligned$1;
364
387
  const appendAccelerationAligned = appendAccelerationAligned$1;
388
+ const mapPoints$9 = mapPoints$10;
389
+ const flatMap$9 = flatMap$10;
390
+ const transform$9 = transform$10;
365
391
  /**
366
392
  * Converts a `Bezier2d` to a `CubicPath2d`.
367
393
  *
@@ -464,6 +490,14 @@ const withTension$1 = dual(2, (p, tension) => new Cardinal2dImpl(p.points, tensi
464
490
  const withAlpha$1 = dual(2, (p, alpha) => new Cardinal2dImpl(p.points, p.tension, alpha));
465
491
  /** @internal */
466
492
  const withOptions$1 = dual(2, (p, options) => new Cardinal2dImpl(p.points, options.tension ?? p.tension, options.alpha ?? p.alpha));
493
+ /** @internal */
494
+ const mapPoints$8 = dual(2, (s, f) => {
495
+ return new Cardinal2dImpl((s instanceof Cardinal2dImpl ? s.points : [...s]).map(f), s.tension, s.alpha);
496
+ });
497
+ /** @internal */
498
+ const flatMap$8 = dual(2, (s, f) => f(s instanceof Cardinal2dImpl ? s.points : [...s]));
499
+ /** @internal */
500
+ const transform$8 = dual(2, (s, a) => mapPoints$8(s, applyTo(a)));
467
501
  const buildCardinalSegment = (p0, p1, p2, p3, tension, alpha) => {
468
502
  const d01 = magnitude(subtract(p1, p0)) ** alpha;
469
503
  const d12 = magnitude(subtract(p2, p1)) ** alpha;
@@ -514,13 +548,16 @@ const toBezier$5 = (p) => {
514
548
  //#region src/splines/cardinal2d.ts
515
549
  var cardinal2d_exports = /* @__PURE__ */ __exportAll({
516
550
  append: () => append$6,
551
+ flatMap: () => flatMap$7,
517
552
  fromArray: () => fromArray$7,
518
553
  fromTuples: () => fromTuples$7,
519
554
  isCardinal2d: () => isCardinal2d,
520
555
  make: () => make$7,
556
+ mapPoints: () => mapPoints$7,
521
557
  prepend: () => prepend$6,
522
558
  toBezier: () => toBezier$4,
523
559
  toPath: () => toPath$7,
560
+ transform: () => transform$7,
524
561
  withAlpha: () => withAlpha,
525
562
  withDuplicatedEndpoints: () => withDuplicatedEndpoints,
526
563
  withInterpolatedEndpoints: () => withInterpolatedEndpoints,
@@ -584,6 +621,9 @@ const withReflectedEndpoints = withReflectedEndpoints$1;
584
621
  const withTension = withTension$1;
585
622
  const withAlpha = withAlpha$1;
586
623
  const withOptions = withOptions$1;
624
+ const mapPoints$7 = mapPoints$8;
625
+ const flatMap$7 = flatMap$8;
626
+ const transform$7 = transform$8;
587
627
  /**
588
628
  * Converts a `Cardinal2d` to a `CubicPath2d` using the spline's `tension` and
589
629
  * `alpha`. With the default options (`{ tension: 0.5, alpha: 0.5 }`) the
@@ -646,6 +686,20 @@ const prepend$5 = dual(3, (p, p0, v0) => {
646
686
  return new Hermite2dImpl([p0, v0].concat(points));
647
687
  });
648
688
  /** @internal */
689
+ const mapPoints$6 = dual(2, (s, f) => {
690
+ return new Hermite2dImpl((s instanceof Hermite2dImpl ? s.points : [...s]).map(f));
691
+ });
692
+ /** @internal */
693
+ const flatMap$6 = dual(2, (s, f) => f(s instanceof Hermite2dImpl ? s.points : [...s]));
694
+ /** @internal */
695
+ const transform$6 = dual(2, (s, a) => {
696
+ const points = s instanceof Hermite2dImpl ? s.points : [...s];
697
+ const linear = linearPart(a);
698
+ const next = Array.from({ length: points.length });
699
+ for (let i = 0; i < points.length; i++) next[i] = apply$1(i % 2 === 0 ? a : linear, points[i]);
700
+ return new Hermite2dImpl(next);
701
+ });
702
+ /** @internal */
649
703
  const toPath$6 = (p) => make$15(...toCurves(p, cubicHermite, 2));
650
704
  /** @internal */
651
705
  const toBezier$3 = (p) => fromBasis(p, cubicHermite, 2);
@@ -653,13 +707,16 @@ const toBezier$3 = (p) => fromBasis(p, cubicHermite, 2);
653
707
  //#region src/splines/hermite2d.ts
654
708
  var hermite2d_exports = /* @__PURE__ */ __exportAll({
655
709
  append: () => append$4,
710
+ flatMap: () => flatMap$5,
656
711
  fromArray: () => fromArray$5,
657
712
  fromTuples: () => fromTuples$5,
658
713
  isHermite2d: () => isHermite2d,
659
714
  make: () => make$5,
715
+ mapPoints: () => mapPoints$5,
660
716
  prepend: () => prepend$4,
661
717
  toBezier: () => toBezier$2,
662
- toPath: () => toPath$5
718
+ toPath: () => toPath$5,
719
+ transform: () => transform$5
663
720
  });
664
721
  /**
665
722
  * Checks if a value is a `Hermite2d`.
@@ -699,6 +756,9 @@ const fromArray$5 = fromArray$6;
699
756
  const fromTuples$5 = fromTuples$6;
700
757
  const append$4 = append$5;
701
758
  const prepend$4 = prepend$5;
759
+ const mapPoints$5 = mapPoints$6;
760
+ const flatMap$5 = flatMap$6;
761
+ const transform$5 = transform$6;
702
762
  /**
703
763
  * Creates a new `CubicPath2d` instance from a `Hermite2d`.
704
764
  *
@@ -759,6 +819,14 @@ const withTriplicatedEndpoints$1 = (p) => {
759
819
  ]);
760
820
  };
761
821
  /** @internal */
822
+ const mapPoints$4 = dual(2, (s, f) => {
823
+ return new Basis2dImpl((s instanceof Basis2dImpl ? s.points : [...s]).map(f));
824
+ });
825
+ /** @internal */
826
+ const flatMap$4 = dual(2, (s, f) => f(s instanceof Basis2dImpl ? s.points : [...s]));
827
+ /** @internal */
828
+ const transform$4 = dual(2, (s, a) => mapPoints$4(s, applyTo(a)));
829
+ /** @internal */
762
830
  const toPath$4 = (p) => make$15(...toCurves(p, cubicBasisSpline, 1));
763
831
  /** @internal */
764
832
  const toBezier$1 = (p) => fromBasis(p, cubicBasisSpline, 1);
@@ -766,13 +834,16 @@ const toBezier$1 = (p) => fromBasis(p, cubicBasisSpline, 1);
766
834
  //#region src/splines/basis2d.ts
767
835
  var basis2d_exports = /* @__PURE__ */ __exportAll({
768
836
  append: () => append$2,
837
+ flatMap: () => flatMap$3,
769
838
  fromArray: () => fromArray$3,
770
839
  fromTuples: () => fromTuples$3,
771
840
  isBasis2d: () => isBasis2d,
772
841
  make: () => make$3,
842
+ mapPoints: () => mapPoints$3,
773
843
  prepend: () => prepend$2,
774
844
  toBezier: () => toBezier,
775
845
  toPath: () => toPath$3,
846
+ transform: () => transform$3,
776
847
  withTriplicatedEndpoints: () => withTriplicatedEndpoints
777
848
  });
778
849
  /**
@@ -812,6 +883,9 @@ const fromArray$3 = fromArray$4;
812
883
  const fromTuples$3 = fromTuples$4;
813
884
  const append$2 = append$3;
814
885
  const prepend$2 = prepend$3;
886
+ const mapPoints$3 = mapPoints$4;
887
+ const flatMap$3 = flatMap$4;
888
+ const transform$3 = transform$4;
815
889
  /**
816
890
  * Triplicates the endpoints of a `Basis2d`.
817
891
  *
@@ -870,6 +944,14 @@ const append$1 = dual((args) => isLinear2d$1(args[0]), (p, ...points) => new Lin
870
944
  /** @internal */
871
945
  const prepend$1 = dual((args) => isLinear2d$1(args[0]), (p, ...points) => new Linear2dImpl([...points, ...p]));
872
946
  /** @internal */
947
+ const mapPoints$2 = dual(2, (s, f) => {
948
+ return new Linear2dImpl((s instanceof Linear2dImpl ? s.points : [...s]).map(f));
949
+ });
950
+ /** @internal */
951
+ const flatMap$2 = dual(2, (s, f) => f(s instanceof Linear2dImpl ? s.points : [...s]));
952
+ /** @internal */
953
+ const transform$2 = dual(2, (s, a) => mapPoints$2(s, applyTo(a)));
954
+ /** @internal */
873
955
  const toPath$2 = (p) => {
874
956
  const points = p instanceof Linear2dImpl ? p.points : [...p];
875
957
  const segments = [];
@@ -880,12 +962,15 @@ const toPath$2 = (p) => {
880
962
  //#region src/splines/linear2d.ts
881
963
  var linear2d_exports = /* @__PURE__ */ __exportAll({
882
964
  append: () => append,
965
+ flatMap: () => flatMap$1,
883
966
  fromArray: () => fromArray$1,
884
967
  fromTuples: () => fromTuples$1,
885
968
  isLinear2d: () => isLinear2d,
886
969
  make: () => make$1,
970
+ mapPoints: () => mapPoints$1,
887
971
  prepend: () => prepend,
888
- toPath: () => toPath$1
972
+ toPath: () => toPath$1,
973
+ transform: () => transform$1
889
974
  });
890
975
  /**
891
976
  * Checks if a value is a `Linear2d`.
@@ -925,6 +1010,9 @@ const fromArray$1 = fromArray$2;
925
1010
  const fromTuples$1 = fromTuples$2;
926
1011
  const append = append$1;
927
1012
  const prepend = prepend$1;
1013
+ const mapPoints$1 = mapPoints$2;
1014
+ const flatMap$1 = flatMap$2;
1015
+ const transform$1 = transform$2;
928
1016
  /**
929
1017
  * Converts a `Linear2d` to a `LinearPath2d` by joining consecutive points
930
1018
  * with straight segments. The result is unbranded; assert
@@ -939,14 +1027,17 @@ const toPath$1 = toPath$2;
939
1027
  //#endregion
940
1028
  //#region src/splines/rationalBezier2d.ts
941
1029
  var rationalBezier2d_exports = /* @__PURE__ */ __exportAll({
1030
+ flatMap: () => flatMap,
942
1031
  fromArray: () => fromArray,
943
1032
  fromBezier: () => fromBezier,
944
1033
  fromPoints: () => fromPoints,
945
1034
  fromTuples: () => fromTuples,
946
1035
  isRationalBezier2d: () => isRationalBezier2d,
947
1036
  make: () => make,
1037
+ mapPoints: () => mapPoints,
948
1038
  subdivide: () => subdivide,
949
- toPath: () => toPath
1039
+ toPath: () => toPath,
1040
+ transform: () => transform
950
1041
  });
951
1042
  /**
952
1043
  * Checks if a value is a `RationalBezier2d`.
@@ -1037,6 +1128,9 @@ const fromBezier = fromBezier$1;
1037
1128
  * @since 2.0.0
1038
1129
  */
1039
1130
  const toPath = toPath$11;
1131
+ const mapPoints = mapPoints$11;
1132
+ const flatMap = flatMap$11;
1133
+ const transform = transform$11;
1040
1134
  const subdivide = subdivide$3;
1041
1135
  //#endregion
1042
1136
  export { basis2d_exports as Basis2d, bezier2d_exports as Bezier2d, cardinal2d_exports as Cardinal2d, hermite2d_exports as Hermite2d, linear2d_exports as Linear2d, rationalBezier2d_exports as RationalBezier2d };