/
arc.ts
102 lines (100 loc) · 2.44 KB
/
arc.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { isNumber } from "@thi.ng/checks/is-number";
import type { Attribs } from "@thi.ng/geom-api";
import { fromEndPoints } from "@thi.ng/geom-arc/from-endpoints";
import type { ReadonlyVec, Vec } from "@thi.ng/vectors";
import { Arc } from "./api/arc.js";
import { absDiff } from "@thi.ng/math/abs";
import { PI } from "@thi.ng/math/api";
/**
* Creates a new elliptic {@link Arc} from given `center`, `radii`, `axis`
* rotation, `start` and `end` angles (in radians).
*
* @remarks
* The `xl` (large arc) and `clockwise` params are defaulting to:
*
* - xl = true if |start-end| > PI
* - clockwise = true if end > start
*
* Reference:
* - https://svgwg.org/svg2-draft/paths.html#PathDataEllipticalArcCommands
* - https://svgwg.org/svg2-draft/images/paths/arcs02.svg
*
* Also see {@link arcFrom2Points}, {@link pathFromSvg} for an alternative construction.
*
* @param center
* @param radii
* @param axis
* @param start
* @param end
* @param xl
* @param clockwise
* @param attribs
*/
export const arc = (
center: Vec,
radii: number | Vec,
axis: number,
start: number,
end: number,
xl = absDiff(start, end) > PI,
clockwise = end > start,
attribs?: Attribs
) =>
new Arc(
center,
isNumber(radii) ? [radii, radii] : radii,
axis,
start,
end,
xl,
clockwise,
attribs
);
/**
* Constructs a new {@link Arc} between the two given points `a` and `b` using
* `radii`, `axis` rotation (in radians) and `xl`, `clockwise` params to
* configure which of 4 possible arcs will be chosen.
*
* @remarks
* This function returns `undefined` if it's mathematically impossible to create
* an arc with the given parameters.
*
* Reference:
* - https://svgwg.org/svg2-draft/paths.html#PathDataEllipticalArcCommands
* - https://svgwg.org/svg2-draft/images/paths/arcs02.svg
* - https://svgwg.org/svg2-draft/implnote.html#ArcConversionEndpointToCenter
* - https://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
*
* Also see {@link arc}, {@link pathFromSvg} for an alternative construction.
*
* @param a
* @param b
* @param radii
* @param axis
* @param xl
* @param cw
* @param attribs
*/
export const arcFrom2Points = (
a: ReadonlyVec,
b: ReadonlyVec,
radii: ReadonlyVec,
axis = 0,
xl = false,
cw = false,
attribs?: Attribs
) => {
const res = fromEndPoints(a, b, radii, axis, xl, cw);
return res
? new Arc(
res.center,
res.r,
res.axis,
res.start,
res.end,
res.xl,
res.cw,
attribs
)
: undefined;
};