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.
- package/dist/arc/arc.d.ts +452 -0
- package/dist/arc/index.d.ts +3 -0
- package/dist/arc/index.mjs +234 -0
- package/dist/arc/index.mjs.map +1 -0
- package/dist/characteristic/index.mjs +1 -1
- package/dist/coordinates/coordinateSystem.d.ts +730 -0
- package/dist/coordinates/dimension.d.ts +498 -0
- package/dist/coordinates/index.d.ts +6 -0
- package/dist/coordinates/index.mjs +845 -0
- package/dist/coordinates/index.mjs.map +1 -0
- package/dist/curve/cubic2d.d.ts +37 -7
- package/dist/curve/index.mjs +2 -2
- package/dist/curve/internal/certified.d.ts +1 -0
- package/dist/curve/internal/cubic2d.d.ts +1 -0
- package/dist/curve/{curve2d.d.ts → internal/curve2d.d.ts} +5 -5
- package/dist/curve/internal/linear2d.d.ts +1 -0
- package/dist/curve/internal/quadratic2d.d.ts +1 -0
- package/dist/curve/internal/rationalCubic2d.d.ts +2 -0
- package/dist/curve/linear2d.d.ts +6 -7
- package/dist/curve/quadratic2d.d.ts +6 -7
- package/dist/curve/rationalCubic2d.d.ts +7 -7
- package/dist/interval/index.mjs +2 -2
- package/dist/interval/internal/interval.d.ts +1 -0
- package/dist/interval/internal/interval2d.d.ts +1 -0
- package/dist/interval/interval.d.ts +9 -5
- package/dist/interval/interval2d.d.ts +3 -4
- package/dist/matrix/index.mjs +2 -2
- package/dist/matrix/index.mjs.map +1 -1
- package/dist/matrix/internal/matrix2x2.d.ts +1 -0
- package/dist/matrix/internal/matrix3x3.d.ts +2 -0
- package/dist/matrix/internal/matrix4x4.d.ts +1 -0
- package/dist/matrix/matrix2x2.d.ts +4 -5
- package/dist/matrix/matrix3x3.d.ts +6 -7
- package/dist/matrix/matrix4x4.d.ts +6 -7
- package/dist/monotonicity/index.mjs +1 -1
- package/dist/number.d.ts +140 -1
- package/dist/number.mjs +155 -3
- package/dist/number.mjs.map +1 -1
- package/dist/path/cubic2d.d.ts +49 -6
- package/dist/path/index.mjs +4 -3
- package/dist/path/internal/cubic2d.d.ts +1 -0
- package/dist/path/internal/linear2d.d.ts +1 -0
- package/dist/path/{path2d.d.ts → internal/path2d.d.ts} +12 -10
- package/dist/path/internal/quadratic2d.d.ts +1 -0
- package/dist/path/internal/rationalCubic2d.d.ts +1 -0
- package/dist/path/linear2d.d.ts +5 -6
- package/dist/path/quadratic2d.d.ts +5 -6
- package/dist/path/rationalCubic2d.d.ts +13 -10
- package/dist/piecewise/index.mjs +18 -14
- package/dist/piecewise/index.mjs.map +1 -1
- package/dist/piecewise/internal/piecewise.d.ts +1 -0
- package/dist/piecewise/piecewise.d.ts +6 -7
- package/dist/polynomial/cubic.d.ts +5 -6
- package/dist/polynomial/index.mjs +2 -2
- package/dist/polynomial/internal/cubic.d.ts +1 -0
- package/dist/polynomial/internal/cubicImpl.d.ts +1 -0
- package/dist/polynomial/internal/linear.d.ts +1 -0
- package/dist/polynomial/{polynomial.d.ts → internal/polynomial.d.ts} +2 -2
- package/dist/polynomial/internal/quadratic.d.ts +1 -0
- package/dist/polynomial/internal/quadraticImpl.d.ts +1 -0
- package/dist/polynomial/linear.d.ts +5 -6
- package/dist/polynomial/quadratic.d.ts +5 -6
- package/dist/shared/{affine2d-CFfmB3LQ.mjs → affine2d-DBrrscDK.mjs} +10 -13
- package/dist/shared/affine2d-DBrrscDK.mjs.map +1 -0
- package/dist/shared/arc-D4Q75qss.mjs +344 -0
- package/dist/shared/arc-D4Q75qss.mjs.map +1 -0
- package/dist/shared/{characteristic-CL3bnjgJ.mjs → characteristic-BDz-BfjP.mjs} +3 -3
- package/dist/shared/{characteristic-CL3bnjgJ.mjs.map → characteristic-BDz-BfjP.mjs.map} +1 -1
- package/dist/shared/{cubic-EPyClIq0.mjs → cubic-Cfby-PoP.mjs} +44 -25
- package/dist/shared/cubic-Cfby-PoP.mjs.map +1 -0
- package/dist/shared/{cubic2d-CI82mN9o.mjs → cubic2d-B9SkLTNj.mjs} +79 -24
- package/dist/shared/cubic2d-B9SkLTNj.mjs.map +1 -0
- package/dist/shared/{cubic2d-q1HU0uM9.mjs → cubic2d-Bg6DAceR.mjs} +94 -359
- package/dist/shared/cubic2d-Bg6DAceR.mjs.map +1 -0
- package/dist/{utils.mjs → shared/function-9StDYgP-.mjs} +3 -36
- package/dist/shared/function-9StDYgP-.mjs.map +1 -0
- package/dist/shared/{interval-8-erxD4h.mjs → interval-CVE7RB0r.mjs} +7 -10
- package/dist/shared/interval-CVE7RB0r.mjs.map +1 -0
- package/dist/shared/{interval2d-CVS66YmV.mjs → interval2d-JPEHgQSB.mjs} +20 -13
- package/dist/shared/interval2d-JPEHgQSB.mjs.map +1 -0
- package/dist/shared/linear2d-vSq0s0rv.mjs +326 -0
- package/dist/shared/linear2d-vSq0s0rv.mjs.map +1 -0
- package/dist/shared/{matrix3x3.internal-eK-9vsoI.mjs → matrix3x3-CkajJmjn.mjs} +15 -28
- package/dist/shared/matrix3x3-CkajJmjn.mjs.map +1 -0
- package/dist/shared/{matrix4x4-DCRpqQsP.mjs → matrix4x4-YBpje9Xv.mjs} +10 -16
- package/dist/shared/matrix4x4-YBpje9Xv.mjs.map +1 -0
- package/dist/shared/{monotonicity-C-lodqfb.mjs → monotonicity-C2ANe23J.mjs} +1 -1
- package/dist/shared/{monotonicity-C-lodqfb.mjs.map → monotonicity-C2ANe23J.mjs.map} +1 -1
- package/dist/shared/{quadratic-DY3a1MVJ.mjs → quadratic-Fygzcc14.mjs} +2 -2
- package/dist/shared/quadratic-Fygzcc14.mjs.map +1 -0
- package/dist/shared/{quadratic2d-CXlMyyCs.mjs → quadratic2d-DVPLYmqX.mjs} +6 -6
- package/dist/shared/quadratic2d-DVPLYmqX.mjs.map +1 -0
- package/dist/shared/{rationalCubic2d-aT1o6oCm.mjs → rationalCubic2d-CQdLNPrT.mjs} +128 -148
- package/dist/shared/rationalCubic2d-CQdLNPrT.mjs.map +1 -0
- package/dist/shared/{rationalCubic2d-CGU2mYjs.mjs → rationalCubic2d-xGfQYkpL.mjs} +13 -10
- package/dist/shared/rationalCubic2d-xGfQYkpL.mjs.map +1 -0
- package/dist/shared/{solution-Bi6zCdQH.mjs → solution-DeWeVSi6.mjs} +22 -8
- package/dist/shared/solution-DeWeVSi6.mjs.map +1 -0
- package/dist/shared/value-D-cjWuxu.mjs +115 -0
- package/dist/shared/value-D-cjWuxu.mjs.map +1 -0
- package/dist/shared/{vector2-CrUOYb3v.mjs → vector2-Df3kN-_g.mjs} +9 -7
- package/dist/shared/vector2-Df3kN-_g.mjs.map +1 -0
- package/dist/shared/{vector2.internal-rPnW0RCx.mjs → vector2-Dtk5XT5b.mjs} +16 -20
- package/dist/shared/{vector2.internal-rPnW0RCx.mjs.map → vector2-Dtk5XT5b.mjs.map} +1 -1
- package/dist/shared/{vector3-CFL7Yx16.mjs → vector3-CFxXUgGS.mjs} +7 -5
- package/dist/shared/vector3-CFxXUgGS.mjs.map +1 -0
- package/dist/shared/{vector3.internal-CfWHl9SG.mjs → vector3-mc97w7ef.mjs} +15 -11
- package/dist/shared/vector3-mc97w7ef.mjs.map +1 -0
- package/dist/shared/{vector4.internal-DH5DzNYO.mjs → vector4-C7pBKhVb.mjs} +15 -10
- package/dist/shared/vector4-C7pBKhVb.mjs.map +1 -0
- package/dist/shared/{vector4-syi93IOY.mjs → vector4-CqL8xajZ.mjs} +2 -2
- package/dist/shared/vector4-CqL8xajZ.mjs.map +1 -0
- package/dist/solution/index.mjs +1 -1
- package/dist/solution/{solution.internal.d.ts → internal/solution.d.ts} +1 -1
- package/dist/solution/solution.d.ts +9 -5
- package/dist/splines/basis2d.d.ts +3 -4
- package/dist/splines/bezier2d.d.ts +3 -4
- package/dist/splines/cardinal2d.d.ts +3 -4
- package/dist/splines/hermite2d.d.ts +3 -4
- package/dist/splines/index.mjs +51 -37
- package/dist/splines/index.mjs.map +1 -1
- package/dist/splines/internal/basis2d.d.ts +1 -0
- package/dist/splines/internal/bezier2d.d.ts +1 -0
- package/dist/splines/internal/cardinal2d.d.ts +1 -0
- package/dist/splines/internal/hermite2d.d.ts +1 -0
- package/dist/splines/internal/linear2d.d.ts +1 -0
- package/dist/splines/internal/rationalBezier2d.d.ts +1 -0
- package/dist/splines/{util.d.ts → internal/util.d.ts} +3 -3
- package/dist/splines/linear2d.d.ts +3 -4
- package/dist/splines/rationalBezier2d.d.ts +3 -4
- package/dist/transform/affine2d.d.ts +5 -6
- package/dist/transform/index.mjs +1 -1
- package/dist/transform/internal/affine2d.d.ts +1 -0
- package/dist/transform/{traits.d.ts → internal/traits.d.ts} +1 -1
- package/dist/{utils.d.ts → utils/function.d.ts} +2 -61
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.mjs +3 -0
- package/dist/utils/invariant.d.ts +17 -0
- package/dist/utils/pipeable.d.ts +44 -0
- package/dist/utils/value.d.ts +110 -0
- package/dist/vector/index.mjs +3 -3
- package/dist/vector/internal/vector2.d.ts +1 -0
- package/dist/vector/internal/vector3.d.ts +1 -0
- package/dist/vector/internal/vector4.d.ts +1 -0
- package/dist/vector/vector2.d.ts +18 -12
- package/dist/vector/vector3.d.ts +15 -9
- package/dist/vector/vector4.d.ts +9 -5
- package/package.json +11 -3
- package/dist/curve/cubic2d.internal.d.ts +0 -2
- package/dist/curve/linear2d.internal.d.ts +0 -2
- package/dist/curve/quadratic2d.internal.d.ts +0 -2
- package/dist/curve/rationalCubic2d.internal.d.ts +0 -2
- package/dist/interval/interval2d.internal.d.ts +0 -2
- package/dist/matrix/matrix2x2.internal.d.ts +0 -2
- package/dist/matrix/matrix3x3.internal.d.ts +0 -4
- package/dist/matrix/matrix4x4.internal.d.ts +0 -2
- package/dist/path/cubic2d.internal.d.ts +0 -2
- package/dist/path/linear2d.internal.d.ts +0 -2
- package/dist/path/quadratic2d.internal.d.ts +0 -2
- package/dist/path/rationalCubic2d.internal.d.ts +0 -2
- package/dist/piecewise/piecewise.internal.d.ts +0 -2
- package/dist/polynomial/cubic.internal.circular.d.ts +0 -2
- package/dist/polynomial/linear.internal.d.ts +0 -2
- package/dist/polynomial/quadratic.internal.circular.d.ts +0 -2
- package/dist/shared/affine2d-CFfmB3LQ.mjs.map +0 -1
- package/dist/shared/cubic-EPyClIq0.mjs.map +0 -1
- package/dist/shared/cubic2d-CI82mN9o.mjs.map +0 -1
- package/dist/shared/cubic2d-q1HU0uM9.mjs.map +0 -1
- package/dist/shared/interval-8-erxD4h.mjs.map +0 -1
- package/dist/shared/interval2d-CVS66YmV.mjs.map +0 -1
- package/dist/shared/matrix3x3.internal-eK-9vsoI.mjs.map +0 -1
- package/dist/shared/matrix4x4-DCRpqQsP.mjs.map +0 -1
- package/dist/shared/quadratic-DY3a1MVJ.mjs.map +0 -1
- package/dist/shared/quadratic2d-CXlMyyCs.mjs.map +0 -1
- package/dist/shared/rationalCubic2d-CGU2mYjs.mjs.map +0 -1
- package/dist/shared/rationalCubic2d-aT1o6oCm.mjs.map +0 -1
- package/dist/shared/solution-Bi6zCdQH.mjs.map +0 -1
- package/dist/shared/vector2-CrUOYb3v.mjs.map +0 -1
- package/dist/shared/vector3-CFL7Yx16.mjs.map +0 -1
- package/dist/shared/vector3.internal-CfWHl9SG.mjs.map +0 -1
- package/dist/shared/vector4-syi93IOY.mjs.map +0 -1
- package/dist/shared/vector4.internal-DH5DzNYO.mjs.map +0 -1
- package/dist/splines/basis2d.internal.d.ts +0 -2
- package/dist/splines/bezier2d.internal.d.ts +0 -2
- package/dist/splines/cardinal2d.internal.d.ts +0 -2
- package/dist/splines/hermite2d.internal.d.ts +0 -2
- package/dist/splines/linear2d.internal.d.ts +0 -2
- package/dist/splines/rationalBezier2d.internal.d.ts +0 -2
- package/dist/transform/affine2d.internal.d.ts +0 -2
- package/dist/utils.mjs.map +0 -1
- package/dist/vector/vector2.internal.d.ts +0 -4
- package/dist/vector/vector3.internal.d.ts +0 -2
- package/dist/vector/vector4.internal.d.ts +0 -2
- /package/dist/{interval/interval.internal.d.ts → arc/internal/arc.d.ts} +0 -0
- /package/dist/{polynomial/cubic.internal.d.ts → coordinates/internal/coordinateSystem.d.ts} +0 -0
- /package/dist/{polynomial/quadratic.internal.d.ts → coordinates/internal/dimension.d.ts} +0 -0
- /package/dist/{dimensions.d.ts → internal/dimensions.d.ts} +0 -0
- /package/dist/{length.d.ts → internal/length.d.ts} +0 -0
- /package/dist/matrix/{traits.d.ts → internal/traits.d.ts} +0 -0
- /package/dist/path/{traits.d.ts → internal/traits.d.ts} +0 -0
- /package/dist/piecewise/{traits.d.ts → internal/traits.d.ts} +0 -0
- /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,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
|