curvy 2.0.0-alpha.17 → 2.0.0-alpha.19

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 (202) hide show
  1. package/dist/arc/arc.d.ts +452 -0
  2. package/dist/arc/index.d.ts +3 -0
  3. package/dist/arc/index.mjs +234 -0
  4. package/dist/arc/index.mjs.map +1 -0
  5. package/dist/characteristic/index.mjs +1 -1
  6. package/dist/coordinates/coordinateSystem.d.ts +730 -0
  7. package/dist/coordinates/dimension.d.ts +498 -0
  8. package/dist/coordinates/index.d.ts +6 -0
  9. package/dist/coordinates/index.mjs +845 -0
  10. package/dist/coordinates/index.mjs.map +1 -0
  11. package/dist/curve/cubic2d.d.ts +37 -7
  12. package/dist/curve/index.mjs +2 -2
  13. package/dist/curve/internal/certified.d.ts +1 -0
  14. package/dist/curve/internal/cubic2d.d.ts +1 -0
  15. package/dist/curve/{curve2d.d.ts → internal/curve2d.d.ts} +5 -5
  16. package/dist/curve/internal/linear2d.d.ts +1 -0
  17. package/dist/curve/internal/quadratic2d.d.ts +1 -0
  18. package/dist/curve/internal/rationalCubic2d.d.ts +2 -0
  19. package/dist/curve/linear2d.d.ts +6 -7
  20. package/dist/curve/quadratic2d.d.ts +6 -7
  21. package/dist/curve/rationalCubic2d.d.ts +7 -7
  22. package/dist/interval/index.mjs +2 -2
  23. package/dist/interval/internal/interval.d.ts +1 -0
  24. package/dist/interval/internal/interval2d.d.ts +1 -0
  25. package/dist/interval/interval.d.ts +9 -5
  26. package/dist/interval/interval2d.d.ts +3 -4
  27. package/dist/matrix/index.mjs +2 -2
  28. package/dist/matrix/index.mjs.map +1 -1
  29. package/dist/matrix/internal/matrix2x2.d.ts +1 -0
  30. package/dist/matrix/internal/matrix3x3.d.ts +2 -0
  31. package/dist/matrix/internal/matrix4x4.d.ts +1 -0
  32. package/dist/matrix/matrix2x2.d.ts +4 -5
  33. package/dist/matrix/matrix3x3.d.ts +6 -7
  34. package/dist/matrix/matrix4x4.d.ts +6 -7
  35. package/dist/monotonicity/index.mjs +1 -1
  36. package/dist/number.d.ts +140 -1
  37. package/dist/number.mjs +155 -3
  38. package/dist/number.mjs.map +1 -1
  39. package/dist/path/cubic2d.d.ts +49 -6
  40. package/dist/path/index.mjs +4 -3
  41. package/dist/path/internal/cubic2d.d.ts +1 -0
  42. package/dist/path/internal/linear2d.d.ts +1 -0
  43. package/dist/path/{path2d.d.ts → internal/path2d.d.ts} +12 -10
  44. package/dist/path/internal/quadratic2d.d.ts +1 -0
  45. package/dist/path/internal/rationalCubic2d.d.ts +1 -0
  46. package/dist/path/linear2d.d.ts +5 -6
  47. package/dist/path/quadratic2d.d.ts +5 -6
  48. package/dist/path/rationalCubic2d.d.ts +13 -10
  49. package/dist/piecewise/index.mjs +18 -14
  50. package/dist/piecewise/index.mjs.map +1 -1
  51. package/dist/piecewise/internal/piecewise.d.ts +1 -0
  52. package/dist/piecewise/piecewise.d.ts +6 -7
  53. package/dist/polynomial/cubic.d.ts +5 -6
  54. package/dist/polynomial/index.mjs +2 -2
  55. package/dist/polynomial/internal/cubic.d.ts +1 -0
  56. package/dist/polynomial/internal/cubicImpl.d.ts +1 -0
  57. package/dist/polynomial/internal/linear.d.ts +1 -0
  58. package/dist/polynomial/{polynomial.d.ts → internal/polynomial.d.ts} +2 -2
  59. package/dist/polynomial/internal/quadratic.d.ts +1 -0
  60. package/dist/polynomial/internal/quadraticImpl.d.ts +1 -0
  61. package/dist/polynomial/linear.d.ts +5 -6
  62. package/dist/polynomial/quadratic.d.ts +5 -6
  63. package/dist/shared/{affine2d-CFfmB3LQ.mjs → affine2d-DBrrscDK.mjs} +10 -13
  64. package/dist/shared/affine2d-DBrrscDK.mjs.map +1 -0
  65. package/dist/shared/arc-D4Q75qss.mjs +344 -0
  66. package/dist/shared/arc-D4Q75qss.mjs.map +1 -0
  67. package/dist/shared/{characteristic-CL3bnjgJ.mjs → characteristic-BDz-BfjP.mjs} +3 -3
  68. package/dist/shared/{characteristic-CL3bnjgJ.mjs.map → characteristic-BDz-BfjP.mjs.map} +1 -1
  69. package/dist/shared/{cubic-EPyClIq0.mjs → cubic-Cfby-PoP.mjs} +44 -25
  70. package/dist/shared/cubic-Cfby-PoP.mjs.map +1 -0
  71. package/dist/shared/{cubic2d-CI82mN9o.mjs → cubic2d-B9SkLTNj.mjs} +79 -24
  72. package/dist/shared/cubic2d-B9SkLTNj.mjs.map +1 -0
  73. package/dist/shared/{cubic2d-q1HU0uM9.mjs → cubic2d-Bg6DAceR.mjs} +94 -359
  74. package/dist/shared/cubic2d-Bg6DAceR.mjs.map +1 -0
  75. package/dist/{utils.mjs → shared/function-9StDYgP-.mjs} +3 -36
  76. package/dist/shared/function-9StDYgP-.mjs.map +1 -0
  77. package/dist/shared/{interval-8-erxD4h.mjs → interval-CVE7RB0r.mjs} +7 -10
  78. package/dist/shared/interval-CVE7RB0r.mjs.map +1 -0
  79. package/dist/shared/{interval2d-CVS66YmV.mjs → interval2d-JPEHgQSB.mjs} +20 -13
  80. package/dist/shared/interval2d-JPEHgQSB.mjs.map +1 -0
  81. package/dist/shared/linear2d-vSq0s0rv.mjs +326 -0
  82. package/dist/shared/linear2d-vSq0s0rv.mjs.map +1 -0
  83. package/dist/shared/{matrix3x3.internal-eK-9vsoI.mjs → matrix3x3-CkajJmjn.mjs} +15 -28
  84. package/dist/shared/matrix3x3-CkajJmjn.mjs.map +1 -0
  85. package/dist/shared/{matrix4x4-DCRpqQsP.mjs → matrix4x4-YBpje9Xv.mjs} +10 -16
  86. package/dist/shared/matrix4x4-YBpje9Xv.mjs.map +1 -0
  87. package/dist/shared/{monotonicity-C-lodqfb.mjs → monotonicity-C2ANe23J.mjs} +1 -1
  88. package/dist/shared/{monotonicity-C-lodqfb.mjs.map → monotonicity-C2ANe23J.mjs.map} +1 -1
  89. package/dist/shared/{quadratic-DY3a1MVJ.mjs → quadratic-Fygzcc14.mjs} +2 -2
  90. package/dist/shared/quadratic-Fygzcc14.mjs.map +1 -0
  91. package/dist/shared/{quadratic2d-CXlMyyCs.mjs → quadratic2d-DVPLYmqX.mjs} +6 -6
  92. package/dist/shared/quadratic2d-DVPLYmqX.mjs.map +1 -0
  93. package/dist/shared/{rationalCubic2d-aT1o6oCm.mjs → rationalCubic2d-CQdLNPrT.mjs} +128 -148
  94. package/dist/shared/rationalCubic2d-CQdLNPrT.mjs.map +1 -0
  95. package/dist/shared/{rationalCubic2d-CGU2mYjs.mjs → rationalCubic2d-xGfQYkpL.mjs} +13 -10
  96. package/dist/shared/rationalCubic2d-xGfQYkpL.mjs.map +1 -0
  97. package/dist/shared/{solution-Bi6zCdQH.mjs → solution-DeWeVSi6.mjs} +22 -8
  98. package/dist/shared/solution-DeWeVSi6.mjs.map +1 -0
  99. package/dist/shared/value-D-cjWuxu.mjs +115 -0
  100. package/dist/shared/value-D-cjWuxu.mjs.map +1 -0
  101. package/dist/shared/{vector2-CrUOYb3v.mjs → vector2-Df3kN-_g.mjs} +9 -7
  102. package/dist/shared/vector2-Df3kN-_g.mjs.map +1 -0
  103. package/dist/shared/{vector2.internal-rPnW0RCx.mjs → vector2-Dtk5XT5b.mjs} +16 -20
  104. package/dist/shared/{vector2.internal-rPnW0RCx.mjs.map → vector2-Dtk5XT5b.mjs.map} +1 -1
  105. package/dist/shared/{vector3-CFL7Yx16.mjs → vector3-CFxXUgGS.mjs} +7 -5
  106. package/dist/shared/vector3-CFxXUgGS.mjs.map +1 -0
  107. package/dist/shared/{vector3.internal-CfWHl9SG.mjs → vector3-mc97w7ef.mjs} +15 -11
  108. package/dist/shared/vector3-mc97w7ef.mjs.map +1 -0
  109. package/dist/shared/{vector4.internal-DH5DzNYO.mjs → vector4-C7pBKhVb.mjs} +15 -10
  110. package/dist/shared/vector4-C7pBKhVb.mjs.map +1 -0
  111. package/dist/shared/{vector4-syi93IOY.mjs → vector4-CqL8xajZ.mjs} +2 -2
  112. package/dist/shared/vector4-CqL8xajZ.mjs.map +1 -0
  113. package/dist/solution/index.mjs +1 -1
  114. package/dist/solution/{solution.internal.d.ts → internal/solution.d.ts} +1 -1
  115. package/dist/solution/solution.d.ts +9 -5
  116. package/dist/splines/basis2d.d.ts +3 -4
  117. package/dist/splines/bezier2d.d.ts +3 -4
  118. package/dist/splines/cardinal2d.d.ts +3 -4
  119. package/dist/splines/hermite2d.d.ts +3 -4
  120. package/dist/splines/index.mjs +51 -37
  121. package/dist/splines/index.mjs.map +1 -1
  122. package/dist/splines/internal/basis2d.d.ts +1 -0
  123. package/dist/splines/internal/bezier2d.d.ts +1 -0
  124. package/dist/splines/internal/cardinal2d.d.ts +1 -0
  125. package/dist/splines/internal/hermite2d.d.ts +1 -0
  126. package/dist/splines/internal/linear2d.d.ts +1 -0
  127. package/dist/splines/internal/rationalBezier2d.d.ts +1 -0
  128. package/dist/splines/{util.d.ts → internal/util.d.ts} +3 -3
  129. package/dist/splines/linear2d.d.ts +3 -4
  130. package/dist/splines/rationalBezier2d.d.ts +3 -4
  131. package/dist/transform/affine2d.d.ts +5 -6
  132. package/dist/transform/index.mjs +1 -1
  133. package/dist/transform/internal/affine2d.d.ts +1 -0
  134. package/dist/transform/{traits.d.ts → internal/traits.d.ts} +1 -1
  135. package/dist/{utils.d.ts → utils/function.d.ts} +2 -61
  136. package/dist/utils/index.d.ts +4 -0
  137. package/dist/utils/index.mjs +3 -0
  138. package/dist/utils/invariant.d.ts +17 -0
  139. package/dist/utils/pipeable.d.ts +44 -0
  140. package/dist/utils/value.d.ts +110 -0
  141. package/dist/vector/index.mjs +3 -3
  142. package/dist/vector/internal/vector2.d.ts +1 -0
  143. package/dist/vector/internal/vector3.d.ts +1 -0
  144. package/dist/vector/internal/vector4.d.ts +1 -0
  145. package/dist/vector/vector2.d.ts +18 -12
  146. package/dist/vector/vector3.d.ts +15 -9
  147. package/dist/vector/vector4.d.ts +9 -5
  148. package/package.json +11 -3
  149. package/dist/curve/cubic2d.internal.d.ts +0 -2
  150. package/dist/curve/linear2d.internal.d.ts +0 -2
  151. package/dist/curve/quadratic2d.internal.d.ts +0 -2
  152. package/dist/curve/rationalCubic2d.internal.d.ts +0 -2
  153. package/dist/interval/interval2d.internal.d.ts +0 -2
  154. package/dist/matrix/matrix2x2.internal.d.ts +0 -2
  155. package/dist/matrix/matrix3x3.internal.d.ts +0 -4
  156. package/dist/matrix/matrix4x4.internal.d.ts +0 -2
  157. package/dist/path/cubic2d.internal.d.ts +0 -2
  158. package/dist/path/linear2d.internal.d.ts +0 -2
  159. package/dist/path/quadratic2d.internal.d.ts +0 -2
  160. package/dist/path/rationalCubic2d.internal.d.ts +0 -2
  161. package/dist/piecewise/piecewise.internal.d.ts +0 -2
  162. package/dist/polynomial/cubic.internal.circular.d.ts +0 -2
  163. package/dist/polynomial/linear.internal.d.ts +0 -2
  164. package/dist/polynomial/quadratic.internal.circular.d.ts +0 -2
  165. package/dist/shared/affine2d-CFfmB3LQ.mjs.map +0 -1
  166. package/dist/shared/cubic-EPyClIq0.mjs.map +0 -1
  167. package/dist/shared/cubic2d-CI82mN9o.mjs.map +0 -1
  168. package/dist/shared/cubic2d-q1HU0uM9.mjs.map +0 -1
  169. package/dist/shared/interval-8-erxD4h.mjs.map +0 -1
  170. package/dist/shared/interval2d-CVS66YmV.mjs.map +0 -1
  171. package/dist/shared/matrix3x3.internal-eK-9vsoI.mjs.map +0 -1
  172. package/dist/shared/matrix4x4-DCRpqQsP.mjs.map +0 -1
  173. package/dist/shared/quadratic-DY3a1MVJ.mjs.map +0 -1
  174. package/dist/shared/quadratic2d-CXlMyyCs.mjs.map +0 -1
  175. package/dist/shared/rationalCubic2d-CGU2mYjs.mjs.map +0 -1
  176. package/dist/shared/rationalCubic2d-aT1o6oCm.mjs.map +0 -1
  177. package/dist/shared/solution-Bi6zCdQH.mjs.map +0 -1
  178. package/dist/shared/vector2-CrUOYb3v.mjs.map +0 -1
  179. package/dist/shared/vector3-CFL7Yx16.mjs.map +0 -1
  180. package/dist/shared/vector3.internal-CfWHl9SG.mjs.map +0 -1
  181. package/dist/shared/vector4-syi93IOY.mjs.map +0 -1
  182. package/dist/shared/vector4.internal-DH5DzNYO.mjs.map +0 -1
  183. package/dist/splines/basis2d.internal.d.ts +0 -2
  184. package/dist/splines/bezier2d.internal.d.ts +0 -2
  185. package/dist/splines/cardinal2d.internal.d.ts +0 -2
  186. package/dist/splines/hermite2d.internal.d.ts +0 -2
  187. package/dist/splines/linear2d.internal.d.ts +0 -2
  188. package/dist/splines/rationalBezier2d.internal.d.ts +0 -2
  189. package/dist/transform/affine2d.internal.d.ts +0 -2
  190. package/dist/utils.mjs.map +0 -1
  191. package/dist/vector/vector2.internal.d.ts +0 -4
  192. package/dist/vector/vector3.internal.d.ts +0 -2
  193. package/dist/vector/vector4.internal.d.ts +0 -2
  194. /package/dist/{interval/interval.internal.d.ts → arc/internal/arc.d.ts} +0 -0
  195. /package/dist/{polynomial/cubic.internal.d.ts → coordinates/internal/coordinateSystem.d.ts} +0 -0
  196. /package/dist/{polynomial/quadratic.internal.d.ts → coordinates/internal/dimension.d.ts} +0 -0
  197. /package/dist/{dimensions.d.ts → internal/dimensions.d.ts} +0 -0
  198. /package/dist/{length.d.ts → internal/length.d.ts} +0 -0
  199. /package/dist/matrix/{traits.d.ts → internal/traits.d.ts} +0 -0
  200. /package/dist/path/{traits.d.ts → internal/traits.d.ts} +0 -0
  201. /package/dist/piecewise/{traits.d.ts → internal/traits.d.ts} +0 -0
  202. /package/dist/polynomial/{traits.d.ts → internal/traits.d.ts} +0 -0
@@ -0,0 +1,452 @@
1
+ import type { Closed } from '../interval/interval.ts';
2
+ import type { Interval2d } from '../interval/interval2d.ts';
3
+ import type { RationalCubicPath2d } from '../path/rationalCubic2d.ts';
4
+ import type { Value } from '../utils/value.ts';
5
+ import type { Vector2 } from '../vector/vector2.ts';
6
+ /**
7
+ * An arc described by its geometry rather than its curve coefficients:
8
+ * `Circular` for a piece of a circle, `Elliptical` for a piece of a
9
+ * possibly rotated ellipse.
10
+ *
11
+ * An authoring representation, like the spline modules: describe the arc
12
+ * here, query its geometry (`solve`, `length`, `boundingBox`), and lower it
13
+ * with `toPath` for curve math or `toPathData` for SVG. The description
14
+ * keeps answers the lowered form loses. Point-at-parameter is one
15
+ * `cos`/`sin` here and a rational evaluation there, and length is a closed
16
+ * form or a fixed-cost elliptic integral rather than a tolerance-driven
17
+ * iteration.
18
+ *
19
+ * Every operation in this module accepts both kinds. Angles are in
20
+ * radians, positive rotating `+x` toward `+y` — clockwise in an SVG
21
+ * viewport's y-down coordinates. Direction and multiplicity live in the
22
+ * sweep's sign and magnitude: a negative sweep runs the other way, and a
23
+ * magnitude past `2 * pi` keeps going around.
24
+ *
25
+ * All fields are readonly. No operation mutates an arc.
26
+ *
27
+ * @since 2.0.0
28
+ */
29
+ export type Arc = Circular | Elliptical;
30
+ /**
31
+ * A circular arc: the points `center + radius * (cos(a), sin(a))` for `a`
32
+ * running from `startAngle` to `startAngle + sweep`.
33
+ *
34
+ * Angles are in radians, measured from the `+x` direction, positive
35
+ * rotating `+x` toward `+y` — clockwise in an SVG viewport's y-down
36
+ * coordinates.
37
+ *
38
+ * @since 2.0.0
39
+ */
40
+ export interface Circular extends Value.Instance {
41
+ readonly '~curvy/Arc': '~curvy/Arc';
42
+ readonly kind: 'circular';
43
+ /**
44
+ * The cartesian center of the circle the arc lies on.
45
+ */
46
+ readonly center: Vector2;
47
+ /**
48
+ * The circle's radius. Non-negative; `0` is a valid degenerate arc that
49
+ * never leaves `center`.
50
+ */
51
+ readonly radius: number;
52
+ /**
53
+ * The angle where the arc starts, in radians from the `+x` direction,
54
+ * positive rotating `+x` toward `+y`.
55
+ */
56
+ readonly startAngle: number;
57
+ /**
58
+ * The signed angular extent, in radians. Positive rotates `+x` toward
59
+ * `+y`; a magnitude past `2 * pi` traces the circle more than once.
60
+ */
61
+ readonly sweep: number;
62
+ }
63
+ /**
64
+ * Configuration for `circular`. Only `radius` is required; the defaults
65
+ * give a full circle around the origin.
66
+ *
67
+ * @since 2.0.0
68
+ */
69
+ export interface CircularConfig {
70
+ /**
71
+ * The cartesian center of the circle. Defaults to the origin.
72
+ */
73
+ readonly center?: Vector2;
74
+ /**
75
+ * The circle's radius. Must be finite and non-negative.
76
+ */
77
+ readonly radius: number;
78
+ /**
79
+ * The angle where the arc starts, in radians from the `+x` direction,
80
+ * positive rotating `+x` toward `+y`. Defaults to `0` (3 o'clock on
81
+ * screen).
82
+ */
83
+ readonly startAngle?: number;
84
+ /**
85
+ * The signed angular extent, in radians. Defaults to `2 * pi`, a full
86
+ * circle.
87
+ */
88
+ readonly sweep?: number;
89
+ }
90
+ /**
91
+ * An elliptical arc: the points of an ellipse with semi-axes `radiusX` and
92
+ * `radiusY`, rotated by `rotation` around `center`, for parametric angles
93
+ * running from `startAngle` to `startAngle + sweep`.
94
+ *
95
+ * The point at parametric angle `a` is
96
+ * `center + R(rotation) * (radiusX * cos(a), radiusY * sin(a))`, where
97
+ * `R` rotates `+x` toward `+y`. This is SVG's own arc parametrization.
98
+ *
99
+ * The parametric angle is not the direction from the center to the
100
+ * point. It is the angle on the circle that the radii stretch into the
101
+ * ellipse, so the two agree only on the axes, or everywhere when the radii
102
+ * are equal. Equal steps in it also cover unequal distances along the
103
+ * curve, unlike a circle's.
104
+ *
105
+ * @since 2.0.0
106
+ */
107
+ export interface Elliptical extends Value.Instance {
108
+ readonly '~curvy/Arc': '~curvy/Arc';
109
+ readonly kind: 'elliptical';
110
+ /**
111
+ * The cartesian center of the ellipse the arc lies on.
112
+ */
113
+ readonly center: Vector2;
114
+ /**
115
+ * The semi-axis along the ellipse's own x axis, before rotation.
116
+ * Non-negative. `0` flattens the ellipse to a segment along its y axis.
117
+ */
118
+ readonly radiusX: number;
119
+ /**
120
+ * The semi-axis along the ellipse's own y axis, before rotation.
121
+ * Non-negative. `0` flattens the ellipse to a segment along its x axis.
122
+ */
123
+ readonly radiusY: number;
124
+ /**
125
+ * The angle from the `+x` direction to the ellipse's own x axis, in
126
+ * radians, positive rotating `+x` toward `+y`.
127
+ */
128
+ readonly rotation: number;
129
+ /**
130
+ * The parametric angle where the arc starts, in radians. `0` is the end
131
+ * of the ellipse's own x axis.
132
+ */
133
+ readonly startAngle: number;
134
+ /**
135
+ * The signed parametric extent, in radians. Positive runs `+x` toward
136
+ * `+y` in the ellipse's own frame. A magnitude past `2 * pi` traces the
137
+ * ellipse more than once.
138
+ */
139
+ readonly sweep: number;
140
+ }
141
+ /**
142
+ * Configuration for `elliptical`. Only the two radii are required. The
143
+ * defaults give a full, unrotated ellipse around the origin.
144
+ *
145
+ * @since 2.0.0
146
+ */
147
+ export interface EllipticalConfig {
148
+ /**
149
+ * The cartesian center of the ellipse. Defaults to the origin.
150
+ */
151
+ readonly center?: Vector2;
152
+ /**
153
+ * The semi-axis along the ellipse's own x axis. Must be finite and
154
+ * non-negative.
155
+ */
156
+ readonly radiusX: number;
157
+ /**
158
+ * The semi-axis along the ellipse's own y axis. Must be finite and
159
+ * non-negative.
160
+ */
161
+ readonly radiusY: number;
162
+ /**
163
+ * The angle from `+x` to the ellipse's own x axis, in radians. Defaults
164
+ * to `0`, an axis-aligned ellipse.
165
+ */
166
+ readonly rotation?: number;
167
+ /**
168
+ * The parametric angle where the arc starts, in radians. Defaults to
169
+ * `0`, the end of the ellipse's own x axis.
170
+ */
171
+ readonly startAngle?: number;
172
+ /**
173
+ * The signed parametric extent, in radians. Defaults to `2 * pi`, the
174
+ * whole ellipse.
175
+ */
176
+ readonly sweep?: number;
177
+ }
178
+ /**
179
+ * Checks if a value is an `Arc` of either kind.
180
+ *
181
+ * @param v - The value to check.
182
+ * @returns `true` if the value is an `Arc`, `false` otherwise.
183
+ * @since 2.0.0
184
+ */
185
+ export declare const isArc: (v: unknown) => v is Arc;
186
+ /**
187
+ * Checks if a value is a `Circular` arc.
188
+ *
189
+ * @param v - The value to check.
190
+ * @returns `true` if the value is a `Circular` arc, `false` otherwise.
191
+ * @since 2.0.0
192
+ */
193
+ export declare const isCircular: (v: unknown) => v is Circular;
194
+ /**
195
+ * Creates a `Circular` arc.
196
+ *
197
+ * @param config - Center, radius, start angle, and sweep. Only `radius` is
198
+ * required; see `CircularConfig` for the defaults.
199
+ * @returns A new `Circular` arc.
200
+ * @throws `Error` when `radius` is negative, or when `radius`,
201
+ * `startAngle`, or `sweep` is not finite.
202
+ * @since 2.0.0
203
+ * @example
204
+ * ```ts
205
+ * // A quarter circle of radius 100 from 3 o'clock to 6 o'clock:
206
+ * const quarter = Arc.circular({ radius: 100, sweep: Math.PI / 2 })
207
+ *
208
+ * // Omitting sweep gives the full circle:
209
+ * const dial = Arc.circular({ center: Vector2.make(200, 200), radius: 80 })
210
+ * ```
211
+ */
212
+ export declare const circular: (config: CircularConfig) => Circular;
213
+ /**
214
+ * Checks if a value is an `Elliptical` arc.
215
+ *
216
+ * @param v - The value to check.
217
+ * @returns `true` if the value is an `Elliptical` arc, `false` otherwise.
218
+ * @since 2.0.0
219
+ */
220
+ export declare const isElliptical: (v: unknown) => v is Elliptical;
221
+ /**
222
+ * Creates an `Elliptical` arc.
223
+ *
224
+ * Equal radii give an ellipse that is geometrically a circle, but the
225
+ * value stays `Elliptical`. Build a `Circular` arc with `circular` to get
226
+ * its closed-form length.
227
+ *
228
+ * @param config - Center, radii, rotation, start angle, and sweep. Only
229
+ * `radiusX` and `radiusY` are required. See `EllipticalConfig` for the
230
+ * defaults.
231
+ * @returns A new `Elliptical` arc.
232
+ * @throws `Error` when either radius is negative, or when a radius,
233
+ * `rotation`, `startAngle`, or `sweep` is not finite.
234
+ * @since 2.0.0
235
+ * @example
236
+ * ```ts
237
+ * // The ellipse inscribed in a 200 x 100 box at the origin:
238
+ * const oval = Arc.elliptical({
239
+ * center: Vector2.make(100, 50),
240
+ * radiusX: 100,
241
+ * radiusY: 50,
242
+ * })
243
+ *
244
+ * // Its lower half, from 3 o'clock through 6 o'clock to 9 o'clock:
245
+ * const lower = Arc.elliptical({ radiusX: 100, radiusY: 50, sweep: Math.PI })
246
+ * ```
247
+ */
248
+ export declare const elliptical: (config: EllipticalConfig) => Elliptical;
249
+ export declare const equals: {
250
+ /**
251
+ * Checks two arcs for equality, field by field. Numeric fields compare
252
+ * within the tolerance of `coincident` from `curvy/number`.
253
+ *
254
+ * Comparison is structural, not geometric. Arcs of different kinds
255
+ * always compare unequal, even an `Elliptical` arc with equal radii
256
+ * against the `Circular` arc it traces. So do two arcs tracing the same
257
+ * points from different descriptions, like a start angle shifted by
258
+ * `2 * pi` or the reverse direction.
259
+ *
260
+ * @param a - The first arc.
261
+ * @param b - The second arc.
262
+ * @returns `true` if the arcs are equal, `false` otherwise.
263
+ * @since 2.0.0
264
+ */
265
+ (a: Arc, b: Arc): boolean;
266
+ /**
267
+ * Checks two arcs for equality, field by field.
268
+ *
269
+ * @param b - The arc to compare against.
270
+ * @returns A function that takes an arc and returns whether the two are
271
+ * equal.
272
+ * @since 2.0.0
273
+ */
274
+ (b: Arc): (a: Arc) => boolean;
275
+ };
276
+ /**
277
+ * Computes the point where the arc starts, at angle `startAngle`. For a
278
+ * circular arc that is `center + radius * (cos(startAngle), sin(startAngle))`.
279
+ *
280
+ * @param a - The arc.
281
+ * @returns The arc's first point.
282
+ * @since 2.0.0
283
+ */
284
+ export declare const startPoint: (a: Arc) => Vector2;
285
+ /**
286
+ * Computes the point where the arc ends, evaluated at
287
+ * `startAngle + sweep`.
288
+ *
289
+ * On a full-turn arc the result lands within rounding of `startPoint`,
290
+ * not bitwise on it — the trig re-evaluates a full period away. `toPathData`
291
+ * closes full circles on the exact starting coordinates instead.
292
+ *
293
+ * @param a - The arc.
294
+ * @returns The arc's last point.
295
+ * @since 2.0.0
296
+ */
297
+ export declare const endPoint: (a: Arc) => Vector2;
298
+ export declare const solve: {
299
+ /**
300
+ * Evaluates the arc at parameter `t`, the point at angle
301
+ * `startAngle + t * sweep`.
302
+ *
303
+ * On a circular arc the uniform parameter is also the arc-length
304
+ * parameter. Equal steps in `t` cover equal distance along the arc, a
305
+ * property polynomial curves lack. An elliptical arc's angle is
306
+ * parametric, so equal steps cover more distance near the ends of the
307
+ * longer axis.
308
+ *
309
+ * `t` is not clamped. Values outside `[0, 1]` continue around the curve.
310
+ *
311
+ * @param a - The arc to evaluate.
312
+ * @param t - The parameter. `0` is the start of the arc, `1` the end.
313
+ * @returns The point on the arc at parameter `t`.
314
+ * @since 2.0.0
315
+ * @example
316
+ * ```ts
317
+ * // The midpoint of a quarter arc sits at 45 degrees:
318
+ * Arc.solve(Arc.circular({ radius: 1, sweep: Math.PI / 2 }), 0.5)
319
+ * // (cos(pi / 4), sin(pi / 4))
320
+ *
321
+ * // On an ellipse the same parameter lands at (100 * cos(pi / 4), 50 * sin(pi / 4)),
322
+ * // which lies at about 26.6 degrees from the center, not 45:
323
+ * Arc.solve(Arc.elliptical({ radiusX: 100, radiusY: 50, sweep: Math.PI / 2 }), 0.5)
324
+ * ```
325
+ */
326
+ (a: Arc, t: number): Vector2;
327
+ /**
328
+ * Evaluates the arc at parameter `t`, the point at angle
329
+ * `startAngle + t * sweep`.
330
+ *
331
+ * @param t - The parameter. `0` is the start of the arc, `1` the end.
332
+ * @returns A function that takes an arc and returns the point at `t`.
333
+ * @since 2.0.0
334
+ */
335
+ (t: number): (a: Arc) => Vector2;
336
+ };
337
+ /**
338
+ * Computes the arc's length. A sweep past one full turn counts every
339
+ * traversal.
340
+ *
341
+ * Neither kind takes a tolerance parameter or iterates to one, unlike arc
342
+ * length on a lowered path:
343
+ * - circular: `radius * abs(sweep)`, exact in closed form
344
+ * - elliptical: an incomplete elliptic integral of the second kind,
345
+ * evaluated through Carlson's symmetric forms in a fixed number of
346
+ * steps. The relative error stays near `1e-15`. Equal radii take the
347
+ * closed form, and so does a flat ellipse.
348
+ *
349
+ * @param a - The arc.
350
+ * @returns The length of the arc.
351
+ * @since 2.0.0
352
+ * @example
353
+ * ```ts
354
+ * // The perimeter of a 2:1 ellipse:
355
+ * Arc.length(Arc.elliptical({ radiusX: 2, radiusY: 1 })) // 9.688448220547677
356
+ * ```
357
+ */
358
+ export declare const length: (a: Arc) => number;
359
+ /**
360
+ * Reverses the arc's direction, tracing the same points the other way.
361
+ * The start angle moves to the far end and the sweep negates, so
362
+ * `solve(reverse(a), t)` is `solve(a, 1 - t)`.
363
+ *
364
+ * @param a - The arc.
365
+ * @returns A new arc of the same kind, tracing the input backward.
366
+ * @since 2.0.0
367
+ */
368
+ export declare const reverse: <A extends Arc>(a: A) => A;
369
+ /**
370
+ * Computes the exact axis-aligned bounding box of the arc.
371
+ *
372
+ * Extremes occur only at the endpoints or at the angles where the curve
373
+ * runs parallel to an axis, and both are known in closed form. Every side
374
+ * is therefore exact up to IEEE 754 rounding, with no tolerance parameter.
375
+ * Contrast `RationalCubicPath2d.boundingBox`, which is tight only to a
376
+ * tolerance you choose. An arc whose radii are all `0` has a box that
377
+ * collapses to `center`.
378
+ *
379
+ * @param a - The arc.
380
+ * @returns A closed `Interval2d` enclosing exactly the arc's points.
381
+ * @since 2.0.0
382
+ */
383
+ export declare const boundingBox: (a: Arc) => Interval2d<Closed, Closed>;
384
+ /**
385
+ * Constructs the arc as a `RationalCubicPath2d`, exact up to IEEE 754
386
+ * rounding. The path is made of rational cubic segments of at most a
387
+ * quarter turn each, uniform in angle, and a sweep past one full turn
388
+ * traces the curve more than once. Circular arcs use the same
389
+ * construction as `CoordinateSystem.arc`, and elliptical arcs carry it
390
+ * through the ellipse's stretch and rotation.
391
+ *
392
+ * The path is the form to transform, since circles and ellipses are not
393
+ * closed under every affine map but rational cubics are. Lower first and
394
+ * apply `RationalCubicPath2d.transform` to the result. It is also the form
395
+ * `CoordinateSystem.image` takes, to carry an arc drawn in chart space
396
+ * into a polar system.
397
+ *
398
+ * @param a - The arc.
399
+ * @returns The arc as a `RationalCubicPath2d`.
400
+ * @since 2.0.0
401
+ * @example
402
+ * ```ts
403
+ * // A quarter-turn fillet of radius 8 as one exact rational segment:
404
+ * const path = Arc.toPath(
405
+ * Arc.circular({
406
+ * center: Vector2.make(50, 50),
407
+ * radius: 8,
408
+ * startAngle: -Math.PI / 2,
409
+ * sweep: Math.PI / 2,
410
+ * }),
411
+ * )
412
+ * ```
413
+ */
414
+ export declare const toPath: (a: Arc) => RationalCubicPath2d;
415
+ /**
416
+ * Emits exact SVG path data for the arc, using `A` commands computed from
417
+ * the arc's description rather than recovered from curve coefficients.
418
+ * An elliptical arc's commands carry both radii and its rotation in
419
+ * degrees, which is how SVG draws ellipses natively.
420
+ *
421
+ * Pieces stay at or under a half turn, so the large-arc flag is always
422
+ * `0`. The sweep flag is `1` for a positive sweep, which renders
423
+ * clockwise in an SVG viewport's y-down coordinates.
424
+ *
425
+ * Degenerate contracts:
426
+ * - zero sweep, or every radius `0`: an `M` command alone, which renders
427
+ * nothing
428
+ * - an elliptical arc with one radius `0`: `L` commands tracing the flat
429
+ * ellipse back and forth, since SVG would draw an `A` with a zero radius
430
+ * as a single line between its endpoints
431
+ * - a full-turn sweep: two half-turn `A` commands, closing on the exact
432
+ * starting coordinates
433
+ * - a sweep past one full turn: clamped to one lap, where `toPath` keeps
434
+ * going around. SVG path data cannot express multiple laps.
435
+ *
436
+ * @param a - The arc.
437
+ * @returns The SVG path data string.
438
+ * @since 2.0.0
439
+ * @example
440
+ * ```ts
441
+ * // d attribute for a gauge tick at 12 o'clock, ready for <path d={...}>:
442
+ * const d = Arc.toPathData(
443
+ * Arc.circular({
444
+ * center: Vector2.make(200, 200),
445
+ * radius: 120,
446
+ * startAngle: -Math.PI / 2,
447
+ * sweep: Math.PI / 6,
448
+ * }),
449
+ * )
450
+ * ```
451
+ */
452
+ export declare const toPathData: (a: Arc) => string;
@@ -0,0 +1,3 @@
1
+ import * as ArcNs from './arc.ts';
2
+ export type Arc = ArcNs.Arc;
3
+ export { ArcNs as Arc };
@@ -0,0 +1,234 @@
1
+ import { t as __exportAll } from "../shared/chunk-25Hzd3z8.mjs";
2
+ import { _ as solve$1, b as toPathData$1, c as endPoint$1, d as isCircular$1, f as isElliptical$1, g as reverse$1, i as circular$1, l as equals$1, m as length$1, r as boundingBox$1, s as elliptical$1, u as isArc$1, v as startPoint$1, y as toPath$1 } from "../shared/arc-D4Q75qss.mjs";
3
+ //#region src/arc/arc.ts
4
+ var arc_exports = /* @__PURE__ */ __exportAll({
5
+ boundingBox: () => boundingBox,
6
+ circular: () => circular,
7
+ elliptical: () => elliptical,
8
+ endPoint: () => endPoint,
9
+ equals: () => equals,
10
+ isArc: () => isArc,
11
+ isCircular: () => isCircular,
12
+ isElliptical: () => isElliptical,
13
+ length: () => length,
14
+ reverse: () => reverse,
15
+ solve: () => solve,
16
+ startPoint: () => startPoint,
17
+ toPath: () => toPath,
18
+ toPathData: () => toPathData
19
+ });
20
+ /**
21
+ * Checks if a value is an `Arc` of either kind.
22
+ *
23
+ * @param v - The value to check.
24
+ * @returns `true` if the value is an `Arc`, `false` otherwise.
25
+ * @since 2.0.0
26
+ */
27
+ const isArc = isArc$1;
28
+ /**
29
+ * Checks if a value is a `Circular` arc.
30
+ *
31
+ * @param v - The value to check.
32
+ * @returns `true` if the value is a `Circular` arc, `false` otherwise.
33
+ * @since 2.0.0
34
+ */
35
+ const isCircular = isCircular$1;
36
+ /**
37
+ * Creates a `Circular` arc.
38
+ *
39
+ * @param config - Center, radius, start angle, and sweep. Only `radius` is
40
+ * required; see `CircularConfig` for the defaults.
41
+ * @returns A new `Circular` arc.
42
+ * @throws `Error` when `radius` is negative, or when `radius`,
43
+ * `startAngle`, or `sweep` is not finite.
44
+ * @since 2.0.0
45
+ * @example
46
+ * ```ts
47
+ * // A quarter circle of radius 100 from 3 o'clock to 6 o'clock:
48
+ * const quarter = Arc.circular({ radius: 100, sweep: Math.PI / 2 })
49
+ *
50
+ * // Omitting sweep gives the full circle:
51
+ * const dial = Arc.circular({ center: Vector2.make(200, 200), radius: 80 })
52
+ * ```
53
+ */
54
+ const circular = circular$1;
55
+ /**
56
+ * Checks if a value is an `Elliptical` arc.
57
+ *
58
+ * @param v - The value to check.
59
+ * @returns `true` if the value is an `Elliptical` arc, `false` otherwise.
60
+ * @since 2.0.0
61
+ */
62
+ const isElliptical = isElliptical$1;
63
+ /**
64
+ * Creates an `Elliptical` arc.
65
+ *
66
+ * Equal radii give an ellipse that is geometrically a circle, but the
67
+ * value stays `Elliptical`. Build a `Circular` arc with `circular` to get
68
+ * its closed-form length.
69
+ *
70
+ * @param config - Center, radii, rotation, start angle, and sweep. Only
71
+ * `radiusX` and `radiusY` are required. See `EllipticalConfig` for the
72
+ * defaults.
73
+ * @returns A new `Elliptical` arc.
74
+ * @throws `Error` when either radius is negative, or when a radius,
75
+ * `rotation`, `startAngle`, or `sweep` is not finite.
76
+ * @since 2.0.0
77
+ * @example
78
+ * ```ts
79
+ * // The ellipse inscribed in a 200 x 100 box at the origin:
80
+ * const oval = Arc.elliptical({
81
+ * center: Vector2.make(100, 50),
82
+ * radiusX: 100,
83
+ * radiusY: 50,
84
+ * })
85
+ *
86
+ * // Its lower half, from 3 o'clock through 6 o'clock to 9 o'clock:
87
+ * const lower = Arc.elliptical({ radiusX: 100, radiusY: 50, sweep: Math.PI })
88
+ * ```
89
+ */
90
+ const elliptical = elliptical$1;
91
+ const equals = equals$1;
92
+ /**
93
+ * Computes the point where the arc starts, at angle `startAngle`. For a
94
+ * circular arc that is `center + radius * (cos(startAngle), sin(startAngle))`.
95
+ *
96
+ * @param a - The arc.
97
+ * @returns The arc's first point.
98
+ * @since 2.0.0
99
+ */
100
+ const startPoint = startPoint$1;
101
+ /**
102
+ * Computes the point where the arc ends, evaluated at
103
+ * `startAngle + sweep`.
104
+ *
105
+ * On a full-turn arc the result lands within rounding of `startPoint`,
106
+ * not bitwise on it — the trig re-evaluates a full period away. `toPathData`
107
+ * closes full circles on the exact starting coordinates instead.
108
+ *
109
+ * @param a - The arc.
110
+ * @returns The arc's last point.
111
+ * @since 2.0.0
112
+ */
113
+ const endPoint = endPoint$1;
114
+ const solve = solve$1;
115
+ /**
116
+ * Computes the arc's length. A sweep past one full turn counts every
117
+ * traversal.
118
+ *
119
+ * Neither kind takes a tolerance parameter or iterates to one, unlike arc
120
+ * length on a lowered path:
121
+ * - circular: `radius * abs(sweep)`, exact in closed form
122
+ * - elliptical: an incomplete elliptic integral of the second kind,
123
+ * evaluated through Carlson's symmetric forms in a fixed number of
124
+ * steps. The relative error stays near `1e-15`. Equal radii take the
125
+ * closed form, and so does a flat ellipse.
126
+ *
127
+ * @param a - The arc.
128
+ * @returns The length of the arc.
129
+ * @since 2.0.0
130
+ * @example
131
+ * ```ts
132
+ * // The perimeter of a 2:1 ellipse:
133
+ * Arc.length(Arc.elliptical({ radiusX: 2, radiusY: 1 })) // 9.688448220547677
134
+ * ```
135
+ */
136
+ const length = length$1;
137
+ /**
138
+ * Reverses the arc's direction, tracing the same points the other way.
139
+ * The start angle moves to the far end and the sweep negates, so
140
+ * `solve(reverse(a), t)` is `solve(a, 1 - t)`.
141
+ *
142
+ * @param a - The arc.
143
+ * @returns A new arc of the same kind, tracing the input backward.
144
+ * @since 2.0.0
145
+ */
146
+ const reverse = reverse$1;
147
+ /**
148
+ * Computes the exact axis-aligned bounding box of the arc.
149
+ *
150
+ * Extremes occur only at the endpoints or at the angles where the curve
151
+ * runs parallel to an axis, and both are known in closed form. Every side
152
+ * is therefore exact up to IEEE 754 rounding, with no tolerance parameter.
153
+ * Contrast `RationalCubicPath2d.boundingBox`, which is tight only to a
154
+ * tolerance you choose. An arc whose radii are all `0` has a box that
155
+ * collapses to `center`.
156
+ *
157
+ * @param a - The arc.
158
+ * @returns A closed `Interval2d` enclosing exactly the arc's points.
159
+ * @since 2.0.0
160
+ */
161
+ const boundingBox = boundingBox$1;
162
+ /**
163
+ * Constructs the arc as a `RationalCubicPath2d`, exact up to IEEE 754
164
+ * rounding. The path is made of rational cubic segments of at most a
165
+ * quarter turn each, uniform in angle, and a sweep past one full turn
166
+ * traces the curve more than once. Circular arcs use the same
167
+ * construction as `CoordinateSystem.arc`, and elliptical arcs carry it
168
+ * through the ellipse's stretch and rotation.
169
+ *
170
+ * The path is the form to transform, since circles and ellipses are not
171
+ * closed under every affine map but rational cubics are. Lower first and
172
+ * apply `RationalCubicPath2d.transform` to the result. It is also the form
173
+ * `CoordinateSystem.image` takes, to carry an arc drawn in chart space
174
+ * into a polar system.
175
+ *
176
+ * @param a - The arc.
177
+ * @returns The arc as a `RationalCubicPath2d`.
178
+ * @since 2.0.0
179
+ * @example
180
+ * ```ts
181
+ * // A quarter-turn fillet of radius 8 as one exact rational segment:
182
+ * const path = Arc.toPath(
183
+ * Arc.circular({
184
+ * center: Vector2.make(50, 50),
185
+ * radius: 8,
186
+ * startAngle: -Math.PI / 2,
187
+ * sweep: Math.PI / 2,
188
+ * }),
189
+ * )
190
+ * ```
191
+ */
192
+ const toPath = toPath$1;
193
+ /**
194
+ * Emits exact SVG path data for the arc, using `A` commands computed from
195
+ * the arc's description rather than recovered from curve coefficients.
196
+ * An elliptical arc's commands carry both radii and its rotation in
197
+ * degrees, which is how SVG draws ellipses natively.
198
+ *
199
+ * Pieces stay at or under a half turn, so the large-arc flag is always
200
+ * `0`. The sweep flag is `1` for a positive sweep, which renders
201
+ * clockwise in an SVG viewport's y-down coordinates.
202
+ *
203
+ * Degenerate contracts:
204
+ * - zero sweep, or every radius `0`: an `M` command alone, which renders
205
+ * nothing
206
+ * - an elliptical arc with one radius `0`: `L` commands tracing the flat
207
+ * ellipse back and forth, since SVG would draw an `A` with a zero radius
208
+ * as a single line between its endpoints
209
+ * - a full-turn sweep: two half-turn `A` commands, closing on the exact
210
+ * starting coordinates
211
+ * - a sweep past one full turn: clamped to one lap, where `toPath` keeps
212
+ * going around. SVG path data cannot express multiple laps.
213
+ *
214
+ * @param a - The arc.
215
+ * @returns The SVG path data string.
216
+ * @since 2.0.0
217
+ * @example
218
+ * ```ts
219
+ * // d attribute for a gauge tick at 12 o'clock, ready for <path d={...}>:
220
+ * const d = Arc.toPathData(
221
+ * Arc.circular({
222
+ * center: Vector2.make(200, 200),
223
+ * radius: 120,
224
+ * startAngle: -Math.PI / 2,
225
+ * sweep: Math.PI / 6,
226
+ * }),
227
+ * )
228
+ * ```
229
+ */
230
+ const toPathData = toPathData$1;
231
+ //#endregion
232
+ export { arc_exports as Arc };
233
+
234
+ //# sourceMappingURL=index.mjs.map