curvy 2.0.0-alpha.13 → 2.0.0-alpha.15

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 +92 -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 +113 -3
  6. package/dist/curve/quadratic2d.d.ts +92 -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-H1J2Fjyy.mjs → rationalCubic2d-CZiP8nIq.mjs} +282 -326
  46. package/dist/shared/rationalCubic2d-CZiP8nIq.mjs.map +1 -0
  47. package/dist/shared/{rationalCubic2d-CeHgpNht.mjs → rationalCubic2d-gM7VeiiT.mjs} +585 -125
  48. package/dist/shared/rationalCubic2d-gM7VeiiT.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,2 +1,2 @@
1
- import { n as characteristic_exports } from "../shared/characteristic-BkEr-rr8.mjs";
1
+ import { n as characteristic_exports } from "../shared/characteristic--7nC4Q_a.mjs";
2
2
  export { characteristic_exports as Characteristic };
@@ -5,6 +5,7 @@ import type { Pipeable } from '../utils.ts';
5
5
  import type { CubicPolynomial } from '../polynomial/cubic.ts';
6
6
  import type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts';
7
7
  import type * as Solution from '../solution/solution.ts';
8
+ import type { Affine2d } from '../transform/affine2d.ts';
8
9
  import type { Vector2 } from '../vector/vector2.ts';
9
10
  import type { CubicCurve2dTypeId } from './cubic2d.internal.ts';
10
11
  export type { Monotonic, Increasing, Decreasing } from '../polynomial/traits.ts';
@@ -193,13 +194,79 @@ export declare const curvature: {
193
194
  * @since 2.0.0
194
195
  */
195
196
  export declare const boundingBox: (c: CubicCurve2d) => Interval2d<Closed, Closed>;
197
+ /**
198
+ * Evaluates the curve at `t = 0` in closed form — `(c.x.c0, c.y.c0)`.
199
+ *
200
+ * @param c - The cubic curve.
201
+ * @returns The point at the start of the curve's parameter domain.
202
+ * @since 2.0.0
203
+ */
204
+ export declare const startPoint: (c: CubicCurve2d) => Vector2;
205
+ /**
206
+ * Evaluates the curve at `t = 1` in closed form — the sum of the per-axis
207
+ * monomial coefficients.
208
+ *
209
+ * @param c - The cubic curve.
210
+ * @returns The point at the end of the curve's parameter domain.
211
+ * @since 2.0.0
212
+ */
213
+ export declare const endPoint: (c: CubicCurve2d) => Vector2;
214
+ /**
215
+ * The tight `[min, max]` range of x over the curve's parameter domain `[0, 1]`,
216
+ * accounting for up to two interior extrema.
217
+ *
218
+ * @param c - The cubic curve.
219
+ * @returns The closed range of x over `[0, 1]`.
220
+ * @since 2.0.0
221
+ */
222
+ export declare const xRange: (c: CubicCurve2d) => Closed;
223
+ /**
224
+ * The tight `[min, max]` range of y over the curve's parameter domain `[0, 1]`,
225
+ * accounting for up to two interior extrema.
226
+ *
227
+ * @param c - The cubic curve.
228
+ * @returns The closed range of y over `[0, 1]`.
229
+ * @since 2.0.0
230
+ */
231
+ export declare const yRange: (c: CubicCurve2d) => Closed;
232
+ /**
233
+ * Renders the curve as a single SVG path-data drawing command — for a cubic
234
+ * curve, `C ctrl1X,ctrl1Y ctrl2X,ctrl2Y endX,endY`. Bernstein control points
235
+ * are recovered from the monomial coefficients in closed form. Does not
236
+ * include a leading `M`.
237
+ *
238
+ * @param c - The cubic curve.
239
+ * @returns The SVG drawing command for this segment, without a leading `M`.
240
+ * @since 2.0.0
241
+ */
242
+ export declare const toPathDataSegment: (c: CubicCurve2d) => string;
243
+ /**
244
+ * Type-narrowing predicate: refines the curve's x-axis trait to include
245
+ * `Monotonic` when the x polynomial is strictly monotonic on the unit
246
+ * interval `[0, 1]`. The y-axis trait is unchanged.
247
+ *
248
+ * @since 2.0.0
249
+ */
250
+ export declare const isMonotonicX: <XT, YT>(c: CubicCurve2d<XT, YT>) => c is CubicCurve2d<XT & Monotonic, YT>;
251
+ /** @since 2.0.0 */
252
+ export declare const isIncreasingX: <XT, YT>(c: CubicCurve2d<XT, YT>) => c is CubicCurve2d<XT & Increasing, YT>;
253
+ /** @since 2.0.0 */
254
+ export declare const isDecreasingX: <XT, YT>(c: CubicCurve2d<XT, YT>) => c is CubicCurve2d<XT & Decreasing, YT>;
255
+ /**
256
+ * Type-narrowing predicate: refines the curve's y-axis trait to include
257
+ * `Monotonic`. The x-axis trait is unchanged.
258
+ *
259
+ * @since 2.0.0
260
+ */
261
+ export declare const isMonotonicY: <XT, YT>(c: CubicCurve2d<XT, YT>) => c is CubicCurve2d<XT, YT & Monotonic>;
262
+ /** @since 2.0.0 */
263
+ export declare const isIncreasingY: <XT, YT>(c: CubicCurve2d<XT, YT>) => c is CubicCurve2d<XT, YT & Increasing>;
264
+ /** @since 2.0.0 */
265
+ export declare const isDecreasingY: <XT, YT>(c: CubicCurve2d<XT, YT>) => c is CubicCurve2d<XT, YT & Decreasing>;
196
266
  /**
197
267
  * Type-narrowing predicate: refines both axes' traits to include `Monotonic`
198
268
  * when both x and y polynomials are monotonic over the unit interval `[0, 1]`.
199
269
  *
200
- * For checking only one axis, call the polynomial-level refiner directly:
201
- * `CubicPolynomial.isMonotonic(curve.x, Interval.unit)`.
202
- *
203
270
  * @since 2.0.0
204
271
  */
205
272
  export declare const isMonotonic: <XT, YT>(c: CubicCurve2d<XT, YT>) => c is CubicCurve2d<XT & Monotonic, YT & Monotonic>;
@@ -213,3 +280,25 @@ export declare const asMonotonic: <XT, YT>(c: CubicCurve2d<XT, YT>) => CubicCurv
213
280
  export declare const asIncreasing: <XT, YT>(c: CubicCurve2d<XT, YT>) => CubicCurve2d<XT & Increasing, YT & Increasing>;
214
281
  /** @since 2.0.0 */
215
282
  export declare const asDecreasing: <XT, YT>(c: CubicCurve2d<XT, YT>) => CubicCurve2d<XT & Decreasing, YT & Decreasing>;
283
+ export declare const transform: {
284
+ /**
285
+ * Applies an `Affine2d` transform to a `CubicCurve2d`, returning a new
286
+ * curve whose image is the affine image of the original. Internally the
287
+ * transformation works directly on monomial coefficients — `c0` receives
288
+ * the full affine, `c1`/`c2`/`c3` receive only the linear part.
289
+ *
290
+ * @param c - The cubic curve.
291
+ * @param a - The affine transform.
292
+ * @returns The transformed cubic curve.
293
+ * @since 2.0.0
294
+ */
295
+ (c: CubicCurve2d, a: Affine2d): CubicCurve2d;
296
+ /**
297
+ * Applies an `Affine2d` transform to a `CubicCurve2d`.
298
+ *
299
+ * @param a - The affine transform.
300
+ * @returns A function that takes a `CubicCurve2d` and returns the transformed curve.
301
+ * @since 2.0.0
302
+ */
303
+ (a: Affine2d): (c: CubicCurve2d) => CubicCurve2d;
304
+ };
@@ -0,0 +1,81 @@
1
+ import type { Closed, Interval } from '../interval/interval.ts';
2
+ import type { Interval2d } from '../interval/interval2d.ts';
3
+ import type * as Solution from '../solution/solution.ts';
4
+ import type { Affine2d } from '../transform/affine2d.ts';
5
+ import type { Vector2 } from '../vector/vector2.ts';
6
+ /**
7
+ * The minimal operation bundle a curve module must provide for the generic
8
+ * `Path2d` to be built over it. Each polynomial curve module
9
+ * (`LinearCurve2d`, `QuadraticCurve2d`, `CubicCurve2d`) exports an `Ops`
10
+ * instance which the corresponding path module passes to
11
+ * `Path2d.make(ops)` to derive its operation surface.
12
+ *
13
+ * The interface is intentionally small — anything that isn't shared
14
+ * structurally across curve degrees stays on the per-degree module.
15
+ *
16
+ * @since 2.0.0
17
+ */
18
+ export interface Curve2dOps<C> {
19
+ /**
20
+ * Evaluate the curve at parameter `t ∈ [0, 1]`.
21
+ */
22
+ solve(c: C, t: number): Vector2;
23
+ /**
24
+ * Closed-form value at `t = 0`.
25
+ */
26
+ startPoint(c: C): Vector2;
27
+ /**
28
+ * Closed-form value at `t = 1`.
29
+ */
30
+ endPoint(c: C): Vector2;
31
+ /**
32
+ * Arc length over an interval of the curve's domain.
33
+ */
34
+ length(c: C, interval: Interval): number;
35
+ /**
36
+ * Axis-aligned bounding box over the unit interval `[0, 1]`.
37
+ */
38
+ boundingBox(c: C): Interval2d<Closed, Closed>;
39
+ /**
40
+ * Inverse solve for x. Path-level callers enforce single-valuedness via
41
+ * the path's `MonotonicX` brand, so the result is narrowed to `AtMostOne`.
42
+ */
43
+ solveAtX(c: C, x: number): Solution.AtMostOne<number>;
44
+ /**
45
+ * y-axis analog of {@link solveAtX}.
46
+ */
47
+ solveAtY(c: C, y: number): Solution.AtMostOne<number>;
48
+ /**
49
+ * SVG path-data drawing command for one segment (`L …`, `Q …`, `C …`),
50
+ * without a leading `M`. Move-insertion is decided by the path-level
51
+ * `toPathData` based on continuity with the previous segment.
52
+ */
53
+ toPathDataSegment(c: C): string;
54
+ /**
55
+ * Whether the curve's x is strictly increasing on `[0, 1]`.
56
+ */
57
+ isIncreasingX(c: C): boolean;
58
+ /**
59
+ * Whether the curve's x is strictly decreasing on `[0, 1]`.
60
+ */
61
+ isDecreasingX(c: C): boolean;
62
+ /**
63
+ * Whether the curve's y is strictly increasing on `[0, 1]`.
64
+ */
65
+ isIncreasingY(c: C): boolean;
66
+ /**
67
+ * Whether the curve's y is strictly decreasing on `[0, 1]`.
68
+ */
69
+ isDecreasingY(c: C): boolean;
70
+ /**
71
+ * Apply an affine transform to the curve, returning a new curve whose
72
+ * geometric image is the affine image of the original.
73
+ *
74
+ * For non-rational coefficient-form curves this is per-coefficient: the
75
+ * constant coefficient receives the full affine, and all higher-degree
76
+ * coefficients receive only the linear part. For rational curves the
77
+ * translation is folded into the numerator polynomials weighted by the
78
+ * denominator. Path-level callers route through this op per curve.
79
+ */
80
+ transform(c: C, a: Affine2d): C;
81
+ }
@@ -1,2 +1,2 @@
1
- import { _ as quadratic2d_exports, i as rationalCubic2d_exports, s as cubic2d_exports, w as linear2d_exports } from "../shared/rationalCubic2d-CeHgpNht.mjs";
1
+ import { i as rationalCubic2d_exports, m as quadratic2d_exports, s as cubic2d_exports, v as linear2d_exports } from "../shared/rationalCubic2d-gM7VeiiT.mjs";
2
2
  export { cubic2d_exports as CubicCurve2d, linear2d_exports as LinearCurve2d, quadratic2d_exports as QuadraticCurve2d, rationalCubic2d_exports as RationalCubicCurve2d };
@@ -5,6 +5,7 @@ import type { Pipeable } from '../utils.ts';
5
5
  import type { LinearPolynomial } from '../polynomial/linear.ts';
6
6
  import type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts';
7
7
  import type * as Solution from '../solution/solution.ts';
8
+ import type { Affine2d } from '../transform/affine2d.ts';
8
9
  import type { Vector2 } from '../vector/vector2.ts';
9
10
  import type { LinearCurve2dTypeId } from './linear2d.internal.ts';
10
11
  export type { Monotonic, Increasing, Decreasing } from '../polynomial/traits.ts';
@@ -121,6 +122,53 @@ export declare const length: {
121
122
  * @since 2.0.0
122
123
  */
123
124
  export declare const boundingBox: (c: LinearCurve2d) => Interval2d<Closed, Closed>;
125
+ /**
126
+ * Evaluates the curve at `t = 0` in closed form — `(c.x.c0, c.y.c0)`.
127
+ *
128
+ * @param c - The linear curve.
129
+ * @returns The point at the start of the curve's parameter domain.
130
+ * @since 2.0.0
131
+ */
132
+ export declare const startPoint: (c: LinearCurve2d) => Vector2;
133
+ /**
134
+ * Evaluates the curve at `t = 1` in closed form — `(c.x.c0 + c.x.c1, c.y.c0 + c.y.c1)`.
135
+ *
136
+ * @param c - The linear curve.
137
+ * @returns The point at the end of the curve's parameter domain.
138
+ * @since 2.0.0
139
+ */
140
+ export declare const endPoint: (c: LinearCurve2d) => Vector2;
141
+ /**
142
+ * The tight `[min, max]` range of x over the curve's parameter domain `[0, 1]`.
143
+ * For a linear curve this is the closed interval bounded by the two endpoints'
144
+ * x coordinates.
145
+ *
146
+ * @param c - The linear curve.
147
+ * @returns The closed range of x over `[0, 1]`.
148
+ * @since 2.0.0
149
+ */
150
+ export declare const xRange: (c: LinearCurve2d) => Closed;
151
+ /**
152
+ * The tight `[min, max]` range of y over the curve's parameter domain `[0, 1]`.
153
+ * For a linear curve this is the closed interval bounded by the two endpoints'
154
+ * y coordinates.
155
+ *
156
+ * @param c - The linear curve.
157
+ * @returns The closed range of y over `[0, 1]`.
158
+ * @since 2.0.0
159
+ */
160
+ export declare const yRange: (c: LinearCurve2d) => Closed;
161
+ /**
162
+ * Renders the curve as a single SVG path-data drawing command — for a linear
163
+ * curve, `L endX,endY`. Does not include a leading `M`; callers (typically a
164
+ * path-level `toPathData`) decide whether to emit a move based on continuity
165
+ * with the previous segment.
166
+ *
167
+ * @param c - The linear curve.
168
+ * @returns The SVG drawing command for this segment, without a leading `M`.
169
+ * @since 2.0.0
170
+ */
171
+ export declare const toPathDataSegment: (c: LinearCurve2d) => string;
124
172
  export declare const solveAtX: {
125
173
  /**
126
174
  * Evaluates the curve's y value at a given x. A linear curve crosses any
@@ -152,14 +200,54 @@ export declare const solveAtY: {
152
200
  /** @since 2.0.0 */
153
201
  (y: number): <XT, YT>(c: LinearCurve2d<XT, YT>) => Solution.AtMostOne<number>;
154
202
  };
203
+ /**
204
+ * Type-narrowing predicate: refines the curve's x-axis trait to include
205
+ * `Monotonic` when the x polynomial is strictly monotonic. The y-axis trait
206
+ * is unchanged.
207
+ *
208
+ * @since 2.0.0
209
+ */
210
+ export declare const isMonotonicX: <XT, YT>(c: LinearCurve2d<XT, YT>) => c is LinearCurve2d<XT & Monotonic, YT>;
211
+ /**
212
+ * Type-narrowing predicate: refines the curve's x-axis trait to include
213
+ * `Increasing`.
214
+ *
215
+ * @since 2.0.0
216
+ */
217
+ export declare const isIncreasingX: <XT, YT>(c: LinearCurve2d<XT, YT>) => c is LinearCurve2d<XT & Increasing, YT>;
218
+ /**
219
+ * Type-narrowing predicate: refines the curve's x-axis trait to include
220
+ * `Decreasing`.
221
+ *
222
+ * @since 2.0.0
223
+ */
224
+ export declare const isDecreasingX: <XT, YT>(c: LinearCurve2d<XT, YT>) => c is LinearCurve2d<XT & Decreasing, YT>;
225
+ /**
226
+ * Type-narrowing predicate: refines the curve's y-axis trait to include
227
+ * `Monotonic`. The x-axis trait is unchanged.
228
+ *
229
+ * @since 2.0.0
230
+ */
231
+ export declare const isMonotonicY: <XT, YT>(c: LinearCurve2d<XT, YT>) => c is LinearCurve2d<XT, YT & Monotonic>;
232
+ /**
233
+ * Type-narrowing predicate: refines the curve's y-axis trait to include
234
+ * `Increasing`.
235
+ *
236
+ * @since 2.0.0
237
+ */
238
+ export declare const isIncreasingY: <XT, YT>(c: LinearCurve2d<XT, YT>) => c is LinearCurve2d<XT, YT & Increasing>;
239
+ /**
240
+ * Type-narrowing predicate: refines the curve's y-axis trait to include
241
+ * `Decreasing`.
242
+ *
243
+ * @since 2.0.0
244
+ */
245
+ export declare const isDecreasingY: <XT, YT>(c: LinearCurve2d<XT, YT>) => c is LinearCurve2d<XT, YT & Decreasing>;
155
246
  /**
156
247
  * Type-narrowing predicate: refines both axes' traits to include `Monotonic`
157
248
  * when both the x and y polynomials are strictly monotonic. When both axes
158
249
  * are monotonic, the curve is invertible in either direction.
159
250
  *
160
- * For checking only one axis, call the polynomial-level refiner directly:
161
- * `LinearPolynomial.isMonotonic(curve.x)`.
162
- *
163
251
  * @since 2.0.0
164
252
  */
165
253
  export declare const isMonotonic: <XT, YT>(c: LinearCurve2d<XT, YT>) => c is LinearCurve2d<XT & Monotonic, YT & Monotonic>;
@@ -193,3 +281,25 @@ export declare const asIncreasing: <XT, YT>(c: LinearCurve2d<XT, YT>) => LinearC
193
281
  * @since 2.0.0
194
282
  */
195
283
  export declare const asDecreasing: <XT, YT>(c: LinearCurve2d<XT, YT>) => LinearCurve2d<XT & Decreasing, YT & Decreasing>;
284
+ export declare const transform: {
285
+ /**
286
+ * Applies an `Affine2d` transform to a `LinearCurve2d`, returning a new
287
+ * curve whose image is the affine image of the original. The transformation
288
+ * is exact: linear curves are degree-1 in every basis, and affine maps
289
+ * commute with the basis.
290
+ *
291
+ * @param c - The linear curve.
292
+ * @param a - The affine transform.
293
+ * @returns The transformed linear curve.
294
+ * @since 2.0.0
295
+ */
296
+ (c: LinearCurve2d, a: Affine2d): LinearCurve2d;
297
+ /**
298
+ * Applies an `Affine2d` transform to a `LinearCurve2d`.
299
+ *
300
+ * @param a - The affine transform.
301
+ * @returns A function that takes a `LinearCurve2d` and returns the transformed curve.
302
+ * @since 2.0.0
303
+ */
304
+ (a: Affine2d): (c: LinearCurve2d) => LinearCurve2d;
305
+ };
@@ -5,6 +5,7 @@ import type { Pipeable } from '../utils.ts';
5
5
  import type { QuadraticPolynomial } from '../polynomial/quadratic.ts';
6
6
  import type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts';
7
7
  import type * as Solution from '../solution/solution.ts';
8
+ import type { Affine2d } from '../transform/affine2d.ts';
8
9
  import type { Vector2 } from '../vector/vector2.ts';
9
10
  import type { LinearCurve2d } from './linear2d.ts';
10
11
  import type { QuadraticCurve2dTypeId } from './quadratic2d.internal.ts';
@@ -201,13 +202,79 @@ export declare const curvature: {
201
202
  * @since 2.0.0
202
203
  */
203
204
  export declare const boundingBox: (c: QuadraticCurve2d) => Interval2d<Closed, Closed>;
205
+ /**
206
+ * Evaluates the curve at `t = 0` in closed form — `(c.x.c0, c.y.c0)`.
207
+ *
208
+ * @param c - The quadratic curve.
209
+ * @returns The point at the start of the curve's parameter domain.
210
+ * @since 2.0.0
211
+ */
212
+ export declare const startPoint: (c: QuadraticCurve2d) => Vector2;
213
+ /**
214
+ * Evaluates the curve at `t = 1` in closed form — the sum of the per-axis
215
+ * monomial coefficients.
216
+ *
217
+ * @param c - The quadratic curve.
218
+ * @returns The point at the end of the curve's parameter domain.
219
+ * @since 2.0.0
220
+ */
221
+ export declare const endPoint: (c: QuadraticCurve2d) => Vector2;
222
+ /**
223
+ * The tight `[min, max]` range of x over the curve's parameter domain `[0, 1]`,
224
+ * accounting for an interior extremum if one exists.
225
+ *
226
+ * @param c - The quadratic curve.
227
+ * @returns The closed range of x over `[0, 1]`.
228
+ * @since 2.0.0
229
+ */
230
+ export declare const xRange: (c: QuadraticCurve2d) => Closed;
231
+ /**
232
+ * The tight `[min, max]` range of y over the curve's parameter domain `[0, 1]`,
233
+ * accounting for an interior extremum if one exists.
234
+ *
235
+ * @param c - The quadratic curve.
236
+ * @returns The closed range of y over `[0, 1]`.
237
+ * @since 2.0.0
238
+ */
239
+ export declare const yRange: (c: QuadraticCurve2d) => Closed;
240
+ /**
241
+ * Renders the curve as a single SVG path-data drawing command — for a
242
+ * quadratic curve, `Q ctrlX,ctrlY endX,endY`, where the control point is
243
+ * recovered from the monomial coefficients via the inverse Bernstein
244
+ * expansion. Does not include a leading `M`.
245
+ *
246
+ * @param c - The quadratic curve.
247
+ * @returns The SVG drawing command for this segment, without a leading `M`.
248
+ * @since 2.0.0
249
+ */
250
+ export declare const toPathDataSegment: (c: QuadraticCurve2d) => string;
251
+ /**
252
+ * Type-narrowing predicate: refines the curve's x-axis trait to include
253
+ * `Monotonic` when the x polynomial is strictly monotonic on the unit
254
+ * interval `[0, 1]`. The y-axis trait is unchanged.
255
+ *
256
+ * @since 2.0.0
257
+ */
258
+ export declare const isMonotonicX: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => c is QuadraticCurve2d<XT & Monotonic, YT>;
259
+ /** @since 2.0.0 */
260
+ export declare const isIncreasingX: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => c is QuadraticCurve2d<XT & Increasing, YT>;
261
+ /** @since 2.0.0 */
262
+ export declare const isDecreasingX: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => c is QuadraticCurve2d<XT & Decreasing, YT>;
263
+ /**
264
+ * Type-narrowing predicate: refines the curve's y-axis trait to include
265
+ * `Monotonic`. The x-axis trait is unchanged.
266
+ *
267
+ * @since 2.0.0
268
+ */
269
+ export declare const isMonotonicY: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => c is QuadraticCurve2d<XT, YT & Monotonic>;
270
+ /** @since 2.0.0 */
271
+ export declare const isIncreasingY: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => c is QuadraticCurve2d<XT, YT & Increasing>;
272
+ /** @since 2.0.0 */
273
+ export declare const isDecreasingY: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => c is QuadraticCurve2d<XT, YT & Decreasing>;
204
274
  /**
205
275
  * Type-narrowing predicate: refines both axes' traits to include `Monotonic`
206
276
  * when both x and y polynomials are monotonic over the unit interval `[0, 1]`.
207
277
  *
208
- * For checking only one axis, call the polynomial-level refiner directly:
209
- * `QuadraticPolynomial.isMonotonic(curve.x, Interval.unit)`.
210
- *
211
278
  * @since 2.0.0
212
279
  */
213
280
  export declare const isMonotonic: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => c is QuadraticCurve2d<XT & Monotonic, YT & Monotonic>;
@@ -221,3 +288,25 @@ export declare const asMonotonic: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => Quadr
221
288
  export declare const asIncreasing: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => QuadraticCurve2d<XT & Increasing, YT & Increasing>;
222
289
  /** @since 2.0.0 */
223
290
  export declare const asDecreasing: <XT, YT>(c: QuadraticCurve2d<XT, YT>) => QuadraticCurve2d<XT & Decreasing, YT & Decreasing>;
291
+ export declare const transform: {
292
+ /**
293
+ * Applies an `Affine2d` transform to a `QuadraticCurve2d`, returning a new
294
+ * curve whose image is the affine image of the original. Internally the
295
+ * transformation works directly on the curve's monomial coefficients —
296
+ * `c0` receives the full affine, `c1` and `c2` receive only the linear part.
297
+ *
298
+ * @param c - The quadratic curve.
299
+ * @param a - The affine transform.
300
+ * @returns The transformed quadratic curve.
301
+ * @since 2.0.0
302
+ */
303
+ (c: QuadraticCurve2d, a: Affine2d): QuadraticCurve2d;
304
+ /**
305
+ * Applies an `Affine2d` transform to a `QuadraticCurve2d`.
306
+ *
307
+ * @param a - The affine transform.
308
+ * @returns A function that takes a `QuadraticCurve2d` and returns the transformed curve.
309
+ * @since 2.0.0
310
+ */
311
+ (a: Affine2d): (c: QuadraticCurve2d) => QuadraticCurve2d;
312
+ };
@@ -5,6 +5,7 @@ import type { Pipeable } from '../utils.ts';
5
5
  import type { CubicPolynomial } from '../polynomial/cubic.ts';
6
6
  import type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts';
7
7
  import type * as Solution from '../solution/solution.ts';
8
+ import type { Affine2d } from '../transform/affine2d.ts';
8
9
  import type { Vector2, Weighted } from '../vector/vector2.ts';
9
10
  import type { CubicCurve2d } from './cubic2d.ts';
10
11
  import type { RationalCubicCurve2dTypeId, RationalCurveTraits } from './rationalCubic2d.internal.ts';
@@ -24,10 +25,10 @@ export { RationalCurveTraits } from './rationalCubic2d.internal.ts';
24
25
  * to the rational functions `x(t)/w(t)` and `y(t)/w(t)`. Unlike
25
26
  * `CubicCurve2d`, traits do not flow through to the underlying polynomials —
26
27
  * monotonicity of a ratio of cubics is not the same property as monotonicity
27
- * of either cubic alone, so the brand lives on the curve itself. Constructors
28
- * with construction-time monotonicity guarantees (e.g. {@link makeMonotonicEasing})
29
- * return curves with `Increasing` brands attached, narrowing downstream
30
- * operations like {@link solveAtX} to single-solution returns.
28
+ * of either cubic alone, so the brand lives on the curve itself. Brands are
29
+ * attached after construction via the {@link asMonotonic}, {@link asIncreasing},
30
+ * and {@link asDecreasing} families, which verify the property rigorously
31
+ * (Bernstein sign convexity on the derivative-numerator quartic).
31
32
  *
32
33
  * All fields are readonly and immutable, and all operations create new instances.
33
34
  *
@@ -59,43 +60,63 @@ export declare const isRationalCubicCurve2d: (c: unknown) => c is RationalCubicC
59
60
  * @since 2.0.0
60
61
  */
61
62
  export declare const fromPolynomials: (x: CubicPolynomial, y: CubicPolynomial, w: CubicPolynomial) => RationalCubicCurve2d;
63
+ export declare const fromBezierPoints: {
64
+ /**
65
+ * Creates a new `RationalCubicCurve2d` from four weighted cubic Bézier
66
+ * control points. The four control points are lifted to homogeneous form
67
+ * `(w·x, w·y, w)` and the cubic Bernstein basis is expanded into per-channel
68
+ * monomial coefficients, yielding the curve's `x`, `y`, and `w` polynomials.
69
+ *
70
+ * @param p0 - The first weighted control point (curve start).
71
+ * @param p1 - The second weighted control point (start handle).
72
+ * @param p2 - The third weighted control point (end handle).
73
+ * @param p3 - The fourth weighted control point (curve end).
74
+ * @returns A new `RationalCubicCurve2d` instance.
75
+ * @since 2.0.0
76
+ */
77
+ (p0: Weighted, p1: Weighted, p2: Weighted, p3: Weighted): RationalCubicCurve2d;
78
+ /**
79
+ * Creates a new `RationalCubicCurve2d` from two interior weighted Bézier
80
+ * handles, with endpoints pinned at `(0, 0, w=1)` and `(1, 1, w=1)`.
81
+ *
82
+ * Rational analog of CSS's `cubic-bezier(x1, y1, x2, y2)`: same fixed
83
+ * endpoints, same two interior handles, plus per-handle weights for true
84
+ * rational shapes (the polynomial case is recovered with unit weights).
85
+ * The curve interpolates `(0, 0)` at `t = 0` and `(1, 1)` at `t = 1`.
86
+ *
87
+ * @param p1 - The second weighted control point (start handle).
88
+ * @param p2 - The third weighted control point (end handle).
89
+ * @returns A new `RationalCubicCurve2d` instance with pinned endpoints.
90
+ * @since 2.0.0
91
+ */
92
+ (p1: Weighted, p2: Weighted): RationalCubicCurve2d;
93
+ };
62
94
  /**
63
- * Creates a new `RationalCubicCurve2d` from four weighted cubic Bézier
64
- * control points. The four control points are lifted to homogeneous form
65
- * `(w·x, w·y, w)` and the cubic Bernstein basis is expanded into per-channel
66
- * monomial coefficients, yielding the curve's `x`, `y`, and `w` polynomials.
67
- *
68
- * @param p0 - The first weighted control point (curve start).
69
- * @param p1 - The second weighted control point (start handle).
70
- * @param p2 - The third weighted control point (end handle).
71
- * @param p3 - The fourth weighted control point (curve end).
72
- * @returns A new `RationalCubicCurve2d` instance.
73
- * @since 2.0.0
74
- */
75
- export declare const fromBezierPoints: (p0: Weighted, p1: Weighted, p2: Weighted, p3: Weighted) => RationalCubicCurve2d;
76
- /**
77
- * Creates a guaranteed-monotonic rational cubic easing curve via Gregory-
78
- * Delbourgo style construction. The result interpolates `(0, 0)` and
79
- * `(1, 1)` with the given endpoint slopes, with `x(t) = t` pinned linearly
80
- * and a rational cubic numerator for `y(t)`. Monotonicity of `y(t)` is
81
- * verified rigorously at construction (degree-3 polynomial sign analysis);
82
- * the returned curve is branded `<Increasing, Increasing>` so that
83
- * {@link solveAtX} returns `Solution.AtMostOne<number>` without further
84
- * trait refinement.
85
- *
86
- * For input slope combinations that the default Gregory-Delbourgo
87
- * construction cannot accommodate (typically when one slope is large while
88
- * the other is small), construction throws. Useful operating range is
89
- * roughly `m₀, m₁ ∈ [0, 2]` with `m₀ + m₁ ≲ 3`; smoothstep (`0, 0`) and
90
- * linear (`1, 1`) fall out as special cases.
91
- *
92
- * @param startSlope - The easing function's slope at the start (`dy/dx` at `x = 0`); must be finite and non-negative.
93
- * @param endSlope - The easing function's slope at the end (`dy/dx` at `x = 1`); must be finite and non-negative.
94
- * @returns A monotone-by-construction rational cubic easing curve.
95
- * @throws When slopes are negative, non-finite, or produce a non-monotonic curve under the default construction.
95
+ * Creates a rational cubic easing curve from endpoint slopes and signed
96
+ * curvatures. The result interpolates `(0, 0)` and `(1, 1)` with `x(t) = t`
97
+ * pinned linearly; the y-axis projection `y(t) = Y(t)/W(t)` uses a cubic
98
+ * numerator over a quadratic denominator, giving six free parameters that
99
+ * exactly match the six endpoint constraints (two values, two slopes, two
100
+ * curvatures).
101
+ *
102
+ * Curvatures are the signed differential-geometric curvatures `κ = y''(x) /
103
+ * (1 + y'(x)²)^(3/2)` — the parameterization-invariant "bend" of the easing
104
+ * graph. Positive κ is concave-up. Smoothstep is `(0, 0, 6, -6)`; linear is
105
+ * `(1, 1, 0, 0)` (taken as a redundant-system special case).
106
+ *
107
+ * Monotonicity is not enforced. Callers needing the `Increasing` brand for
108
+ * narrowed inverse-solve returns should follow construction with
109
+ * {@link asIncreasing}, which verifies monotonicity rigorously.
110
+ *
111
+ * @param startSlope - The easing function's slope at the start (`dy/dx` at `x = 0`).
112
+ * @param endSlope - The easing function's slope at the end (`dy/dx` at `x = 1`).
113
+ * @param startCurvature - The signed differential curvature at the start.
114
+ * @param endCurvature - The signed differential curvature at the end.
115
+ * @returns A rational cubic easing curve.
116
+ * @throws When inputs are non-finite, the constraint system is singular, or the resulting denominator vanishes on `[0, 1]`.
96
117
  * @since 2.0.0
97
118
  */
98
- export declare const makeMonotonicEasing: (startSlope: number, endSlope: number) => RationalCubicCurve2d<Increasing, Increasing>;
119
+ export declare const fromSlopesAndCurvatures: (startSlope: number, endSlope: number, startCurvature: number, endCurvature: number) => RationalCubicCurve2d;
99
120
  export declare const solve: {
100
121
  /**
101
122
  * Evaluates the rational cubic curve at parameter `t`. Returns
@@ -116,6 +137,24 @@ export declare const solve: {
116
137
  */
117
138
  (t: number): (c: RationalCubicCurve2d) => Vector2;
118
139
  };
140
+ /**
141
+ * Evaluates the curve at `t = 0` in closed form — `(c.x.c0 / c.w.c0, c.y.c0 / c.w.c0)`.
142
+ *
143
+ * @param c - The rational cubic curve.
144
+ * @returns The point at the start of the curve's parameter domain.
145
+ * @since 2.0.0
146
+ */
147
+ export declare const startPoint: (c: RationalCubicCurve2d) => Vector2;
148
+ /**
149
+ * Evaluates the curve at `t = 1` in closed form. Both numerator and denominator
150
+ * Horner evaluations at `t = 1` collapse to the sum of their monomial
151
+ * coefficients, so the projection is `(Σxᵢ / Σwᵢ, Σyᵢ / Σwᵢ)`.
152
+ *
153
+ * @param c - The rational cubic curve.
154
+ * @returns The point at the end of the curve's parameter domain.
155
+ * @since 2.0.0
156
+ */
157
+ export declare const endPoint: (c: RationalCubicCurve2d) => Vector2;
119
158
  export declare const solveAtX: {
120
159
  /**
121
160
  * Evaluates the curve's y values at a given x. Because the curve's x axis
@@ -391,6 +430,29 @@ export declare const asIncreasing: <XT, YT>(c: RationalCubicCurve2d<XT, YT>) =>
391
430
  * @since 2.0.0
392
431
  */
393
432
  export declare const asDecreasing: <XT, YT>(c: RationalCubicCurve2d<XT, YT>) => RationalCubicCurve2d<XT & Decreasing, YT & Decreasing>;
433
+ export declare const transform: {
434
+ /**
435
+ * Applies an `Affine2d` transform to a `RationalCubicCurve2d`, returning a
436
+ * new curve whose image is the affine image of the original. The denominator
437
+ * polynomial is preserved; each numerator pulls in a translation term
438
+ * weighted by the denominator so the projected curve matches `A · R(s) + t`
439
+ * pointwise.
440
+ *
441
+ * @param c - The rational cubic curve.
442
+ * @param a - The affine transform.
443
+ * @returns The transformed rational cubic curve.
444
+ * @since 2.0.0
445
+ */
446
+ (c: RationalCubicCurve2d, a: Affine2d): RationalCubicCurve2d;
447
+ /**
448
+ * Applies an `Affine2d` transform to a `RationalCubicCurve2d`.
449
+ *
450
+ * @param a - The affine transform.
451
+ * @returns A function that takes a `RationalCubicCurve2d` and returns the transformed curve.
452
+ * @since 2.0.0
453
+ */
454
+ (a: Affine2d): (c: RationalCubicCurve2d) => RationalCubicCurve2d;
455
+ };
394
456
  export declare const approximateAsCubicCurves: {
395
457
  /**
396
458
  * Approximates the rational cubic as a sequence of polynomial cubic curves
@@ -1,3 +1,3 @@
1
- import { s as interval_exports } from "../shared/interval-Dm35Xhy4.mjs";
2
- import { n as interval2d_exports } from "../shared/interval2d-AtneyI45.mjs";
1
+ import { c as interval_exports } from "../shared/interval-Dcqpo73t.mjs";
2
+ import { n as interval2d_exports } from "../shared/interval2d-C2Pk66-2.mjs";
3
3
  export { interval_exports as Interval, interval2d_exports as Interval2d };