-
-
Notifications
You must be signed in to change notification settings - Fork 151
/
Copy pathpolygon.ts
84 lines (81 loc) · 2.28 KB
/
polygon.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
// SPDX-License-Identifier: Apache-2.0
import type { Attribs } from "./api.js";
import { TAU } from "@thi.ng/math/api";
import { cycle } from "@thi.ng/transducers/cycle";
import { map } from "@thi.ng/transducers/map";
import { normRange } from "@thi.ng/transducers/norm-range";
import { push } from "@thi.ng/transducers/push";
import { transduce } from "@thi.ng/transducers/transduce";
import { zip } from "@thi.ng/transducers/zip";
import type { Vec } from "@thi.ng/vectors";
import { cartesian2 } from "@thi.ng/vectors/cartesian";
import { Polygon } from "./api/polygon.js";
export const polygon = (pts?: Iterable<Vec>, attribs?: Attribs) =>
new Polygon(pts, attribs);
/**
* Syntax sugar for {@link starWithCentroid}, using `[0,0]` as center.
*
* @param r
* @param n
* @param profile
* @param attribs
*/
export const star = (
r: number,
n: number,
profile: number[],
attribs?: Attribs
) => starWithCentroid([0, 0], r, n, profile, attribs);
/**
* Creates a new "star"-shaped polygon around `pos` with radius `r` and `n`
* repetitions of `profile`. The latter is an array of radius scale values to
* define the overall shape. The resulting polygon will have `n *
* profile.length` vertices. To create an actual star-like shape, the profile
* needs to contain at least 2 values, e.g. `[1, 0.5]`, meaning every other
* vertex will be inset to 50% of the base radius.
*
* @example
* ```ts tangle:../export/star-with-centroid.ts
* import { starWithCentroid } from "@thi.ng/geom";
*
* console.log(
* starWithCentroid([100,200], 50, 5, [1, 0.5])
* );
* // Polygon {
* // points: [
* // [150.000, 200.000],
* // [120.225, 214.695],
* // [115.451, 247.553],
* // [92.275, 223.776],
* // [59.549, 229.389],
* // [75.000, 200.000],
* // [59.549, 170.611],
* // [92.275, 176.224],
* // [115.451, 152.447],
* // [120.225, 185.305]
* // ],
* // attribs: undefined
* // }
* ```
*
* @param pos
* @param r
* @param n
* @param profile
* @param attribs
*/
export const starWithCentroid = (
pos: Vec,
r: number,
n: number,
profile: number[],
attribs?: Attribs
) =>
new Polygon(
transduce(
map(([i, p]) => cartesian2(null, [r * p, i * TAU], pos)),
push(),
zip(normRange(n * profile.length, false), cycle(profile))
),
attribs
);