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,131 +1,226 @@
1
1
  import { t as __exportAll } from "./chunk-25Hzd3z8.mjs";
2
2
  import { Pipeable, dual, invariant } from "../utils.mjs";
3
- import { epsEquals } from "../number.mjs";
4
- import { i as magnitude } from "./vector2-CSkaMXvp.mjs";
5
- import { c as make$6, p as unit } from "./interval-Dm35Xhy4.mjs";
6
- import { o as none, r as isNone, s as one } from "./solution-B2JdOZpe.mjs";
7
- import { a as isIncreasing, i as isDecreasing } from "./cubic-BL6dpuHh.mjs";
8
- import { d as isIncreasing$1, u as isDecreasing$1 } from "./quadratic-DPrUsFCp.mjs";
9
- import { a as union } from "./interval2d-AtneyI45.mjs";
10
- import { C as length$4, D as solveAtY$4, E as solveAtX$4, T as solve$6, a as solve$9, d as solve$7, f as solveAtX$5, m as derivative, n as boundingBox$8, o as boundingBox$7, p as solveAtY$5, t as approximateAsCubicCurves, u as length$5, v as solve$8, x as boundingBox$6 } from "./rationalCubic2d-CeHgpNht.mjs";
11
- //#region src/path/linear2d.internal.ts
12
- const LinearPath2dTypeId = Symbol("curvy/path/linear2d");
13
- /** @internal */
14
- var LinearPath2dImpl = class extends Pipeable {
15
- [LinearPath2dTypeId] = LinearPath2dTypeId;
3
+ import { coincident } from "../number.mjs";
4
+ import { a as magnitude } from "./vector2-DuA3EmfL.mjs";
5
+ import { l as make$6, p as unit } from "./interval-Dcqpo73t.mjs";
6
+ import { c as one, i as isNone, s as none } from "./solution-BW0BBMXI.mjs";
7
+ import { a as union } from "./interval2d-C2Pk66-2.mjs";
8
+ import { a as solve$8, d as solve$7, f as Ops$1, h as solve$6, n as boundingBox$6, o as transform$6, p as derivative, t as approximateAsCubicCurves, u as length$4, y as Ops } from "./rationalCubic2d-gM7VeiiT.mjs";
9
+ //#region src/path/path2d.ts
10
+ /**
11
+ * Concrete implementation backing every `Path2d<C>`. The per-kind `TypeId`
12
+ * symbol is stamped onto each instance as a dynamic property at the symbol
13
+ * key it identifies, so the existing per-kind `is{Linear,Quadratic,Cubic}Path2d`
14
+ * typeguards continue to work as `TypeId in p` checks.
15
+ *
16
+ * @internal
17
+ */
18
+ var Path2dImpl = class extends Pipeable {
16
19
  curves;
17
- constructor(curves) {
20
+ constructor(typeId, curves) {
18
21
  super();
22
+ this[typeId] = typeId;
19
23
  this.curves = curves;
20
24
  }
21
25
  [Symbol.iterator]() {
22
26
  return this.curves[Symbol.iterator]();
23
27
  }
24
28
  };
29
+ /**
30
+ * Builds the bundle of generic path operations for a curve kind `C`, given
31
+ * that curve's {@link Curve2dOps} and the per-kind `TypeId` symbol. Each
32
+ * polynomial-degree path module calls this once and re-exports the returned
33
+ * functions with curve-narrowed signatures.
34
+ *
35
+ * `ops` and `typeId` are captured by closure, so the returned operations
36
+ * incur no per-call lookup overhead.
37
+ *
38
+ * @since 2.0.0
39
+ */
40
+ const makeMethods = (typeId, ops) => {
41
+ const fromArray = (curves) => new Path2dImpl(typeId, curves);
42
+ const make = (...curves) => fromArray(curves);
43
+ const append = dual(2, (p, c) => fromArray([...p, c]));
44
+ const length = (p) => {
45
+ let total = 0;
46
+ for (const curve of p) total += ops.length(curve, unit);
47
+ return total;
48
+ };
49
+ const solve = dual(2, (p, u) => {
50
+ const curves = p instanceof Path2dImpl ? p.curves : [...p];
51
+ if (u === 1) return ops.solve(curves.at(-1), 1);
52
+ const t = u * curves.length;
53
+ const i = Math.floor(t);
54
+ return ops.solve(curves[i], t - i);
55
+ });
56
+ const toPathData = (p) => {
57
+ let result = "";
58
+ let prevEndX = NaN;
59
+ let prevEndY = NaN;
60
+ for (const curve of p) {
61
+ const start = ops.startPoint(curve);
62
+ const end = ops.endPoint(curve);
63
+ if (!coincident(start.x, prevEndX) || !coincident(start.y, prevEndY)) result += ` M ${start.x},${start.y}`;
64
+ result += ` ${ops.toPathDataSegment(curve)}`;
65
+ prevEndX = end.x;
66
+ prevEndY = end.y;
67
+ }
68
+ return result.slice(1);
69
+ };
70
+ const isContinuous = (p) => {
71
+ let prevEndX = NaN;
72
+ let prevEndY = NaN;
73
+ let first = true;
74
+ for (const curve of p) {
75
+ const start = ops.startPoint(curve);
76
+ if (!first && (!coincident(start.x, prevEndX) || !coincident(start.y, prevEndY))) return false;
77
+ const end = ops.endPoint(curve);
78
+ prevEndX = end.x;
79
+ prevEndY = end.y;
80
+ first = false;
81
+ }
82
+ return true;
83
+ };
84
+ const isIncreasingX = (p) => {
85
+ let prevEnd = Number.NEGATIVE_INFINITY;
86
+ for (const c of p) {
87
+ if (!ops.isIncreasingX(c)) return false;
88
+ const start = ops.startPoint(c).x;
89
+ if (start < prevEnd && !coincident(start, prevEnd)) return false;
90
+ prevEnd = ops.endPoint(c).x;
91
+ }
92
+ return true;
93
+ };
94
+ const isDecreasingX = (p) => {
95
+ let prevEnd = Number.POSITIVE_INFINITY;
96
+ for (const c of p) {
97
+ if (!ops.isDecreasingX(c)) return false;
98
+ const start = ops.startPoint(c).x;
99
+ if (start > prevEnd && !coincident(start, prevEnd)) return false;
100
+ prevEnd = ops.endPoint(c).x;
101
+ }
102
+ return true;
103
+ };
104
+ const isMonotonicX = (p) => isIncreasingX(p) || isDecreasingX(p);
105
+ const isIncreasingY = (p) => {
106
+ let prevEnd = Number.NEGATIVE_INFINITY;
107
+ for (const c of p) {
108
+ if (!ops.isIncreasingY(c)) return false;
109
+ const start = ops.startPoint(c).y;
110
+ if (start < prevEnd && !coincident(start, prevEnd)) return false;
111
+ prevEnd = ops.endPoint(c).y;
112
+ }
113
+ return true;
114
+ };
115
+ const isDecreasingY = (p) => {
116
+ let prevEnd = Number.POSITIVE_INFINITY;
117
+ for (const c of p) {
118
+ if (!ops.isDecreasingY(c)) return false;
119
+ const start = ops.startPoint(c).y;
120
+ if (start > prevEnd && !coincident(start, prevEnd)) return false;
121
+ prevEnd = ops.endPoint(c).y;
122
+ }
123
+ return true;
124
+ };
125
+ const isMonotonicY = (p) => isIncreasingY(p) || isDecreasingY(p);
126
+ const solveAtX = dual(2, (p, x) => {
127
+ for (const c of p) {
128
+ const start = ops.startPoint(c);
129
+ const end = ops.endPoint(c);
130
+ const lo = Math.min(start.x, end.x);
131
+ const hi = Math.max(start.x, end.x);
132
+ if (x >= lo && x <= hi || coincident(x, lo) || coincident(x, hi)) {
133
+ if (coincident(x, start.x)) return one(start.y);
134
+ if (coincident(x, end.x)) return one(end.y);
135
+ const sol = ops.solveAtX(c, x);
136
+ if (!isNone(sol)) return sol;
137
+ }
138
+ }
139
+ return none;
140
+ });
141
+ const solveAtY = dual(2, (p, y) => {
142
+ for (const c of p) {
143
+ const start = ops.startPoint(c);
144
+ const end = ops.endPoint(c);
145
+ const lo = Math.min(start.y, end.y);
146
+ const hi = Math.max(start.y, end.y);
147
+ if (y >= lo && y <= hi || coincident(y, lo) || coincident(y, hi)) {
148
+ if (coincident(y, start.y)) return one(start.x);
149
+ if (coincident(y, end.y)) return one(end.x);
150
+ const sol = ops.solveAtY(c, y);
151
+ if (!isNone(sol)) return sol;
152
+ }
153
+ }
154
+ return none;
155
+ });
156
+ const boundingBox = (p) => {
157
+ const iter = p[Symbol.iterator]();
158
+ const first = iter.next();
159
+ let acc = ops.boundingBox(first.value);
160
+ for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, ops.boundingBox(next.value));
161
+ return acc;
162
+ };
163
+ return {
164
+ fromArray,
165
+ make,
166
+ append,
167
+ length,
168
+ solve,
169
+ toPathData,
170
+ isContinuous,
171
+ isIncreasingX,
172
+ isDecreasingX,
173
+ isMonotonicX,
174
+ isIncreasingY,
175
+ isDecreasingY,
176
+ isMonotonicY,
177
+ solveAtX,
178
+ solveAtY,
179
+ boundingBox,
180
+ transform: dual(2, (p, a) => {
181
+ const curves = [];
182
+ for (const c of p) curves.push(ops.transform(c, a));
183
+ return fromArray(curves);
184
+ })
185
+ };
186
+ };
187
+ //#endregion
188
+ //#region src/path/linear2d.internal.ts
189
+ const LinearPath2dTypeId = Symbol("curvy/path/linear2d");
190
+ const methods$1 = makeMethods(LinearPath2dTypeId, Ops);
25
191
  /** @internal */
26
192
  const isLinearPath2d$1 = (p) => typeof p === "object" && p !== null && LinearPath2dTypeId in p;
27
193
  /** @internal */
28
- const make$5 = (...curves) => new LinearPath2dImpl(curves);
194
+ const make$5 = methods$1.make;
29
195
  /** @internal */
30
- const fromArray$5 = (curves) => new LinearPath2dImpl(curves);
196
+ const fromArray$5 = methods$1.fromArray;
31
197
  /** @internal */
32
- const append$5 = dual(2, (p, c) => fromArray$5([...p, c]));
198
+ const append$5 = methods$1.append;
33
199
  /** @internal */
34
- const length$3 = (p) => {
35
- let total = 0;
36
- for (const curve of p) total += length$4(curve, unit);
37
- return total;
38
- };
200
+ const length$3 = methods$1.length;
39
201
  /** @internal */
40
- const solve$5 = dual(2, (p, u) => {
41
- const curves = p instanceof LinearPath2dImpl ? p.curves : [...p];
42
- if (u === 1) return solve$6(curves.at(-1), 1);
43
- const t = u * curves.length;
44
- const i = Math.floor(t);
45
- const curve = curves[i];
46
- return solve$6(curve, t - i);
47
- });
202
+ const solve$5 = methods$1.solve;
48
203
  /** @internal */
49
- const toPathData$3 = (p) => {
50
- let result = "";
51
- let prevEndX = NaN;
52
- let prevEndY = NaN;
53
- for (const curve of p) {
54
- const startX = curve.x.c0;
55
- const startY = curve.y.c0;
56
- const endX = curve.x.c0 + curve.x.c1;
57
- const endY = curve.y.c0 + curve.y.c1;
58
- if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) result += ` M ${startX},${startY}`;
59
- result += ` L ${endX},${endY}`;
60
- prevEndX = endX;
61
- prevEndY = endY;
62
- }
63
- return result.slice(1);
64
- };
204
+ const toPathData$3 = methods$1.toPathData;
65
205
  /** @internal */
66
- const isContinuous$3 = (p) => {
67
- let prevEndX = NaN;
68
- let prevEndY = NaN;
69
- let first = true;
70
- for (const curve of p) {
71
- const startX = curve.x.c0;
72
- const startY = curve.y.c0;
73
- if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) return false;
74
- prevEndX = curve.x.c0 + curve.x.c1;
75
- prevEndY = curve.y.c0 + curve.y.c1;
76
- first = false;
77
- }
78
- return true;
79
- };
206
+ const isContinuous$3 = methods$1.isContinuous;
80
207
  /** @internal */
81
208
  const asContinuous$3 = (p) => {
82
209
  invariant(isContinuous$3(p), "linear path is not continuous");
83
210
  return p;
84
211
  };
85
212
  /** @internal */
86
- const isIncreasingX$3 = (p) => {
87
- let prevEnd = Number.NEGATIVE_INFINITY;
88
- for (const c of p) {
89
- if (!isIncreasing$1(c.x)) return false;
90
- if (c.x.c0 < prevEnd - 1e-10) return false;
91
- prevEnd = c.x.c0 + c.x.c1;
92
- }
93
- return true;
94
- };
213
+ const isIncreasingX$3 = methods$1.isIncreasingX;
95
214
  /** @internal */
96
- const isDecreasingX$3 = (p) => {
97
- let prevEnd = Number.POSITIVE_INFINITY;
98
- for (const c of p) {
99
- if (!isDecreasing$1(c.x)) return false;
100
- if (c.x.c0 > prevEnd + 1e-10) return false;
101
- prevEnd = c.x.c0 + c.x.c1;
102
- }
103
- return true;
104
- };
215
+ const isDecreasingX$3 = methods$1.isDecreasingX;
105
216
  /** @internal */
106
- const isMonotonicX$3 = (p) => isIncreasingX$3(p) || isDecreasingX$3(p);
217
+ const isMonotonicX$3 = methods$1.isMonotonicX;
107
218
  /** @internal */
108
- const isIncreasingY$3 = (p) => {
109
- let prevEnd = Number.NEGATIVE_INFINITY;
110
- for (const c of p) {
111
- if (!isIncreasing$1(c.y)) return false;
112
- if (c.y.c0 < prevEnd - 1e-10) return false;
113
- prevEnd = c.y.c0 + c.y.c1;
114
- }
115
- return true;
116
- };
219
+ const isIncreasingY$3 = methods$1.isIncreasingY;
117
220
  /** @internal */
118
- const isDecreasingY$3 = (p) => {
119
- let prevEnd = Number.POSITIVE_INFINITY;
120
- for (const c of p) {
121
- if (!isDecreasing$1(c.y)) return false;
122
- if (c.y.c0 > prevEnd + 1e-10) return false;
123
- prevEnd = c.y.c0 + c.y.c1;
124
- }
125
- return true;
126
- };
221
+ const isDecreasingY$3 = methods$1.isDecreasingY;
127
222
  /** @internal */
128
- const isMonotonicY$3 = (p) => isIncreasingY$3(p) || isDecreasingY$3(p);
223
+ const isMonotonicY$3 = methods$1.isMonotonicY;
129
224
  /** @internal */
130
225
  const asIncreasingX$3 = (p) => {
131
226
  invariant(isIncreasingX$3(p), "linear path is not increasing in x");
@@ -157,44 +252,13 @@ const asMonotonicY$3 = (p) => {
157
252
  return p;
158
253
  };
159
254
  /** @internal */
160
- const solveAtX$3 = dual(2, (p, x) => {
161
- for (const c of p) {
162
- const sx = c.x.c0;
163
- const ex = c.x.c0 + c.x.c1;
164
- const lo = Math.min(sx, ex);
165
- const hi = Math.max(sx, ex);
166
- if (x >= lo - 1e-10 && x <= hi + 1e-10) {
167
- if (epsEquals(x, sx)) return one(c.y.c0);
168
- if (epsEquals(x, ex)) return one(c.y.c0 + c.y.c1);
169
- const sol = solveAtX$4(c, x);
170
- if (!isNone(sol)) return sol;
171
- }
172
- }
173
- return none;
174
- });
255
+ const solveAtX$3 = methods$1.solveAtX;
175
256
  /** @internal */
176
- const solveAtY$3 = dual(2, (p, y) => {
177
- for (const c of p) {
178
- const sy = c.y.c0;
179
- const ey = c.y.c0 + c.y.c1;
180
- const lo = Math.min(sy, ey);
181
- const hi = Math.max(sy, ey);
182
- if (y >= lo - 1e-10 && y <= hi + 1e-10) {
183
- if (epsEquals(y, sy)) return one(c.x.c0);
184
- if (epsEquals(y, ey)) return one(c.x.c0 + c.x.c1);
185
- const sol = solveAtY$4(c, y);
186
- if (!isNone(sol)) return sol;
187
- }
188
- }
189
- return none;
190
- });
257
+ const solveAtY$3 = methods$1.solveAtY;
191
258
  /** @internal */
192
- const boundingBox$5 = (p) => {
193
- const iter = p[Symbol.iterator]();
194
- let acc = boundingBox$6(iter.next().value);
195
- for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, boundingBox$6(next.value));
196
- return acc;
197
- };
259
+ const boundingBox$5 = methods$1.boundingBox;
260
+ /** @internal */
261
+ const transform$5 = methods$1.transform;
198
262
  //#endregion
199
263
  //#region src/path/linear2d.ts
200
264
  var linear2d_exports = /* @__PURE__ */ __exportAll({
@@ -221,7 +285,8 @@ var linear2d_exports = /* @__PURE__ */ __exportAll({
221
285
  solve: () => solve$4,
222
286
  solveAtX: () => solveAtX$2,
223
287
  solveAtY: () => solveAtY$2,
224
- toPathData: () => toPathData$2
288
+ toPathData: () => toPathData$2,
289
+ transform: () => transform$4
225
290
  });
226
291
  /**
227
292
  * Creates a new `LinearPath2d` instance from a sequence of curves.
@@ -378,175 +443,50 @@ const solveAtY$2 = solveAtY$3;
378
443
  * @since 2.0.0
379
444
  */
380
445
  const boundingBox$4 = boundingBox$5;
446
+ const transform$4 = transform$5;
381
447
  //#endregion
382
448
  //#region src/path/cubic2d.internal.ts
383
449
  const CubicPath2dTypeId = Symbol("curvy/path/cubic2d");
384
- /** @internal */
385
- var CubicPath2dImpl = class extends Pipeable {
386
- [CubicPath2dTypeId] = CubicPath2dTypeId;
387
- curves;
388
- constructor(curves) {
389
- invariant(curves.length > 0, "cubic path requires at least one curve");
390
- super();
391
- this.curves = curves;
392
- }
393
- [Symbol.iterator]() {
394
- return this.curves[Symbol.iterator]();
395
- }
396
- };
450
+ const methods = makeMethods(CubicPath2dTypeId, Ops$1);
397
451
  /** @internal */
398
452
  const isCubicPath2d$1 = (p) => typeof p === "object" && p !== null && CubicPath2dTypeId in p;
399
453
  /** @internal */
400
- const make$3 = (...curves) => new CubicPath2dImpl(curves);
454
+ const make$3 = (...curves) => {
455
+ invariant(curves.length > 0, "cubic path requires at least one curve");
456
+ return methods.make(...curves);
457
+ };
401
458
  /** @internal */
402
- const fromArray$3 = (curves) => new CubicPath2dImpl(curves);
459
+ const fromArray$3 = (curves) => {
460
+ invariant(curves.length > 0, "cubic path requires at least one curve");
461
+ return methods.fromArray(curves);
462
+ };
403
463
  /** @internal */
404
- const append$3 = dual(2, (p, c) => fromArray$3([...p, c]));
464
+ const append$3 = methods.append;
405
465
  /** @internal */
406
- const length$1 = (p) => {
407
- let total = 0;
408
- for (const curve of p) total += length$5(curve, unit);
409
- return total;
410
- };
466
+ const length$1 = methods.length;
411
467
  /** @internal */
412
- const solve$3 = dual(2, (p, u) => {
413
- const curves = p instanceof CubicPath2dImpl ? p.curves : [...p];
414
- if (u === 1) return solve$7(curves.at(-1), 1);
415
- const t = u * curves.length;
416
- const i = Math.floor(t);
417
- const curve = curves[i];
418
- return solve$7(curve, t - i);
419
- });
420
- const cumulativeLengthCache = /* @__PURE__ */ new WeakMap();
421
- const getCumulativeLengths = (p) => {
422
- let cached = cumulativeLengthCache.get(p);
423
- if (cached === void 0) {
424
- const lengths = [];
425
- let total = 0;
426
- for (const curve of p) {
427
- total += length$5(curve, unit);
428
- lengths.push(total);
429
- }
430
- cached = lengths;
431
- cumulativeLengthCache.set(p, cached);
432
- }
433
- return cached;
434
- };
435
- const solveCurveByDistance = (curve, target, segmentLength) => {
436
- if (target <= 0) return 0;
437
- if (target >= segmentLength) return 1;
438
- const derivative$1 = derivative(curve);
439
- let t = target / segmentLength;
440
- let lo = 0;
441
- let hi = 1;
442
- for (let iter = 0; iter < 16; iter++) {
443
- const error = length$5(curve, make$6(0, t)) - target;
444
- if (Math.abs(error) < 1e-10) return t;
445
- if (error > 0) hi = t;
446
- else lo = t;
447
- const speed = magnitude(solve$8(derivative$1, t));
448
- if (speed === 0) {
449
- t = (lo + hi) / 2;
450
- continue;
451
- }
452
- const next = t - error / speed;
453
- t = next > lo && next < hi ? next : (lo + hi) / 2;
454
- }
455
- return t;
456
- };
468
+ const solve$3 = methods.solve;
457
469
  /** @internal */
458
- const toPathData$1 = (p) => {
459
- let result = "";
460
- let prevEndX = NaN;
461
- let prevEndY = NaN;
462
- for (const curve of p) {
463
- const c0x = curve.x.c0;
464
- const c0y = curve.y.c0;
465
- const c1x = curve.x.c1;
466
- const c1y = curve.y.c1;
467
- const c2x = curve.x.c2;
468
- const c2y = curve.y.c2;
469
- const c3x = curve.x.c3;
470
- const c3y = curve.y.c3;
471
- const startX = c0x;
472
- const startY = c0y;
473
- const ctrl1X = c0x + c1x / 3;
474
- const ctrl1Y = c0y + c1y / 3;
475
- const ctrl2X = c0x + 2 * c1x / 3 + c2x / 3;
476
- const ctrl2Y = c0y + 2 * c1y / 3 + c2y / 3;
477
- const endX = c0x + c1x + c2x + c3x;
478
- const endY = c0y + c1y + c2y + c3y;
479
- if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) result += ` M ${startX},${startY}`;
480
- result += ` C ${ctrl1X},${ctrl1Y} ${ctrl2X},${ctrl2Y} ${endX},${endY}`;
481
- prevEndX = endX;
482
- prevEndY = endY;
483
- }
484
- return result.slice(1);
485
- };
470
+ const toPathData$1 = methods.toPathData;
486
471
  /** @internal */
487
- const isContinuous$1 = (p) => {
488
- let prevEndX = NaN;
489
- let prevEndY = NaN;
490
- let first = true;
491
- for (const curve of p) {
492
- const startX = curve.x.c0;
493
- const startY = curve.y.c0;
494
- if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) return false;
495
- prevEndX = curve.x.c0 + curve.x.c1 + curve.x.c2 + curve.x.c3;
496
- prevEndY = curve.y.c0 + curve.y.c1 + curve.y.c2 + curve.y.c3;
497
- first = false;
498
- }
499
- return true;
500
- };
472
+ const isContinuous$1 = methods.isContinuous;
501
473
  /** @internal */
502
474
  const asContinuous$1 = (p) => {
503
475
  invariant(isContinuous$1(p), "cubic path is not continuous");
504
476
  return p;
505
477
  };
506
478
  /** @internal */
507
- const isIncreasingX$1 = (p) => {
508
- let prevEnd = Number.NEGATIVE_INFINITY;
509
- for (const c of p) {
510
- if (!isIncreasing(c.x, unit)) return false;
511
- if (c.x.c0 < prevEnd - 1e-10) return false;
512
- prevEnd = c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3;
513
- }
514
- return true;
515
- };
479
+ const isIncreasingX$1 = methods.isIncreasingX;
516
480
  /** @internal */
517
- const isDecreasingX$1 = (p) => {
518
- let prevEnd = Number.POSITIVE_INFINITY;
519
- for (const c of p) {
520
- if (!isDecreasing(c.x, unit)) return false;
521
- if (c.x.c0 > prevEnd + 1e-10) return false;
522
- prevEnd = c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3;
523
- }
524
- return true;
525
- };
481
+ const isDecreasingX$1 = methods.isDecreasingX;
526
482
  /** @internal */
527
- const isMonotonicX$1 = (p) => isIncreasingX$1(p) || isDecreasingX$1(p);
483
+ const isMonotonicX$1 = methods.isMonotonicX;
528
484
  /** @internal */
529
- const isIncreasingY$1 = (p) => {
530
- let prevEnd = Number.NEGATIVE_INFINITY;
531
- for (const c of p) {
532
- if (!isIncreasing(c.y, unit)) return false;
533
- if (c.y.c0 < prevEnd - 1e-10) return false;
534
- prevEnd = c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3;
535
- }
536
- return true;
537
- };
485
+ const isIncreasingY$1 = methods.isIncreasingY;
538
486
  /** @internal */
539
- const isDecreasingY$1 = (p) => {
540
- let prevEnd = Number.POSITIVE_INFINITY;
541
- for (const c of p) {
542
- if (!isDecreasing(c.y, unit)) return false;
543
- if (c.y.c0 > prevEnd + 1e-10) return false;
544
- prevEnd = c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3;
545
- }
546
- return true;
547
- };
487
+ const isDecreasingY$1 = methods.isDecreasingY;
548
488
  /** @internal */
549
- const isMonotonicY$1 = (p) => isIncreasingY$1(p) || isDecreasingY$1(p);
489
+ const isMonotonicY$1 = methods.isMonotonicY;
550
490
  /** @internal */
551
491
  const asIncreasingX$1 = (p) => {
552
492
  invariant(isIncreasingX$1(p), "cubic path is not increasing in x");
@@ -578,41 +518,54 @@ const asMonotonicY$1 = (p) => {
578
518
  return p;
579
519
  };
580
520
  /** @internal */
581
- const solveAtX$1 = dual(2, (p, x) => {
582
- for (const c of p) {
583
- const sx = c.x.c0;
584
- const ex = c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3;
585
- const lo = Math.min(sx, ex);
586
- const hi = Math.max(sx, ex);
587
- if (x >= lo - 1e-10 && x <= hi + 1e-10) {
588
- if (epsEquals(x, sx)) return one(c.y.c0);
589
- if (epsEquals(x, ex)) return one(c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3);
590
- const sol = solveAtX$5(c, x);
591
- if (!isNone(sol)) return sol;
521
+ const solveAtX$1 = methods.solveAtX;
522
+ /** @internal */
523
+ const solveAtY$1 = methods.solveAtY;
524
+ /** @internal */
525
+ const boundingBox$3 = methods.boundingBox;
526
+ /** @internal */
527
+ const transform$3 = methods.transform;
528
+ const cumulativeLengthCache = /* @__PURE__ */ new WeakMap();
529
+ const getCumulativeLengths = (p) => {
530
+ let cached = cumulativeLengthCache.get(p);
531
+ if (cached === void 0) {
532
+ const lengths = [];
533
+ let total = 0;
534
+ for (const curve of p) {
535
+ total += length$4(curve, unit);
536
+ lengths.push(total);
592
537
  }
538
+ cached = lengths;
539
+ cumulativeLengthCache.set(p, cached);
593
540
  }
594
- return none;
595
- });
596
- /** @internal */
597
- const solveAtY$1 = dual(2, (p, y) => {
598
- for (const c of p) {
599
- const sy = c.y.c0;
600
- const ey = c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3;
601
- const lo = Math.min(sy, ey);
602
- const hi = Math.max(sy, ey);
603
- if (y >= lo - 1e-10 && y <= hi + 1e-10) {
604
- if (epsEquals(y, sy)) return one(c.x.c0);
605
- if (epsEquals(y, ey)) return one(c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3);
606
- const sol = solveAtY$5(c, y);
607
- if (!isNone(sol)) return sol;
541
+ return cached;
542
+ };
543
+ const solveCurveByDistance = (curve, target, segmentLength) => {
544
+ if (target <= 0) return 0;
545
+ if (target >= segmentLength) return 1;
546
+ const derivative$1 = derivative(curve);
547
+ let t = target / segmentLength;
548
+ let lo = 0;
549
+ let hi = 1;
550
+ for (let iter = 0; iter < 16; iter++) {
551
+ const error = length$4(curve, make$6(0, t)) - target;
552
+ if (Math.abs(error) <= 1e-12 * segmentLength) return t;
553
+ if (error > 0) hi = t;
554
+ else lo = t;
555
+ const speed = magnitude(solve$6(derivative$1, t));
556
+ if (speed === 0) {
557
+ t = (lo + hi) / 2;
558
+ continue;
608
559
  }
560
+ const next = t - error / speed;
561
+ t = next > lo && next < hi ? next : (lo + hi) / 2;
609
562
  }
610
- return none;
611
- });
563
+ return t;
564
+ };
612
565
  /** @internal */
613
566
  const solveByDistance$1 = dual(2, (p, s) => {
614
- if (s <= 0) return solve$3(p, 0);
615
- if (s >= 1) return solve$3(p, 1);
567
+ if (s <= 0) return methods.solve(p, 0);
568
+ if (s >= 1) return methods.solve(p, 1);
616
569
  const lengths = getCumulativeLengths(p);
617
570
  const target = s * lengths[lengths.length - 1];
618
571
  let k = 0;
@@ -620,16 +573,9 @@ const solveByDistance$1 = dual(2, (p, s) => {
620
573
  const segmentStart = k === 0 ? 0 : lengths[k - 1];
621
574
  const segmentLength = lengths[k] - segmentStart;
622
575
  const segmentTarget = target - segmentStart;
623
- const curve = (p instanceof CubicPath2dImpl ? p.curves : [...p])[k];
576
+ const curve = (p instanceof Path2dImpl ? p.curves : [...p])[k];
624
577
  return solve$7(curve, solveCurveByDistance(curve, segmentTarget, segmentLength));
625
578
  });
626
- /** @internal */
627
- const boundingBox$3 = (p) => {
628
- const iter = p[Symbol.iterator]();
629
- let acc = boundingBox$7(iter.next().value);
630
- for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, boundingBox$7(next.value));
631
- return acc;
632
- };
633
579
  //#endregion
634
580
  //#region src/path/cubic2d.ts
635
581
  var cubic2d_exports = /* @__PURE__ */ __exportAll({
@@ -657,7 +603,8 @@ var cubic2d_exports = /* @__PURE__ */ __exportAll({
657
603
  solveAtX: () => solveAtX,
658
604
  solveAtY: () => solveAtY,
659
605
  solveByDistance: () => solveByDistance,
660
- toPathData: () => toPathData
606
+ toPathData: () => toPathData,
607
+ transform: () => transform$2
661
608
  });
662
609
  /**
663
610
  * Creates a new `CubicPath2d` instance from a sequence of curves.
@@ -808,6 +755,7 @@ const solveByDistance = solveByDistance$1;
808
755
  * @since 2.0.0
809
756
  */
810
757
  const boundingBox$2 = boundingBox$3;
758
+ const transform$2 = transform$3;
811
759
  //#endregion
812
760
  //#region src/path/rationalCubic2d.internal.ts
813
761
  const RationalCubicPath2dTypeId = Symbol("curvy/path/rationalCubic2d");
@@ -835,17 +783,17 @@ const append$1 = dual(2, (p, c) => fromArray$1([...p, c]));
835
783
  /** @internal */
836
784
  const solve$1 = dual(2, (p, u) => {
837
785
  const curves = p instanceof RationalCubicPath2dImpl ? p.curves : [...p];
838
- if (u === 1) return solve$9(curves.at(-1), 1);
786
+ if (u === 1) return solve$8(curves.at(-1), 1);
839
787
  const t = u * curves.length;
840
788
  const i = Math.floor(t);
841
789
  const curve = curves[i];
842
- return solve$9(curve, t - i);
790
+ return solve$8(curve, t - i);
843
791
  });
844
792
  /** @internal */
845
793
  const boundingBox$1 = dual(2, (p, tolerance) => {
846
794
  const iter = p[Symbol.iterator]();
847
- let acc = boundingBox$8(iter.next().value, tolerance);
848
- for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, boundingBox$8(next.value, tolerance));
795
+ let acc = boundingBox$6(iter.next().value, tolerance);
796
+ for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, boundingBox$6(next.value, tolerance));
849
797
  return acc;
850
798
  });
851
799
  /** @internal */
@@ -854,6 +802,12 @@ const approximateAsCubicPath$1 = dual(2, (p, tolerance) => {
854
802
  for (const segment of p) for (const approx of approximateAsCubicCurves(segment, tolerance)) curves.push(approx);
855
803
  return fromArray$2(curves);
856
804
  });
805
+ /** @internal */
806
+ const transform$1 = dual(2, (p, a) => {
807
+ const curves = [];
808
+ for (const segment of p) curves.push(transform$6(segment, a));
809
+ return fromArray$1(curves);
810
+ });
857
811
  //#endregion
858
812
  //#region src/path/rationalCubic2d.ts
859
813
  var rationalCubic2d_exports = /* @__PURE__ */ __exportAll({
@@ -863,7 +817,8 @@ var rationalCubic2d_exports = /* @__PURE__ */ __exportAll({
863
817
  fromArray: () => fromArray,
864
818
  isRationalCubicPath2d: () => isRationalCubicPath2d,
865
819
  make: () => make,
866
- solve: () => solve
820
+ solve: () => solve,
821
+ transform: () => transform
867
822
  });
868
823
  /**
869
824
  * Checks if a value is a `RationalCubicPath2d`.
@@ -893,7 +848,8 @@ const append = append$1;
893
848
  const solve = solve$1;
894
849
  const boundingBox = boundingBox$1;
895
850
  const approximateAsCubicPath = approximateAsCubicPath$1;
851
+ const transform = transform$1;
896
852
  //#endregion
897
- export { fromArray$4 as a, make$2 as i, rationalCubic2d_exports as n, linear2d_exports as o, cubic2d_exports as r, fromArray as t };
853
+ export { fromArray$4 as a, make$2 as i, rationalCubic2d_exports as n, linear2d_exports as o, cubic2d_exports as r, makeMethods as s, fromArray as t };
898
854
 
899
- //# sourceMappingURL=rationalCubic2d-H1J2Fjyy.mjs.map
855
+ //# sourceMappingURL=rationalCubic2d-CZiP8nIq.mjs.map