-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathgen.ts
64 lines (57 loc) · 2.2 KB
/
gen.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
import {rand} from "../internal/rand";
import {mapPoints} from "../internal/util";
import {BlobOptions} from "../public/blobs";
import {Point} from "./types";
import {smooth} from "./util";
export const smoothBlob = (blobygon: Point[]): Point[] => {
// https://math.stackexchange.com/a/873589/235756
const angle = (Math.PI * 2) / blobygon.length;
const smoothingStrength = ((4 / 3) * Math.tan(angle / 4)) / Math.sin(angle / 2) / 2;
return smooth(blobygon, smoothingStrength);
};
export const genBlobygon = (pointCount: number, offset: (index: number) => number): Point[] => {
const angle = (Math.PI * 2) / pointCount;
const points: Point[] = [];
for (let i = 0; i < pointCount; i++) {
const randPointOffset = offset(i);
const pointX = Math.sin(i * angle);
const pointY = Math.cos(i * angle);
points.push({
x: 0.5 + pointX * randPointOffset,
y: 0.5 + pointY * randPointOffset,
handleIn: {angle: 0, length: 0},
handleOut: {angle: 0, length: 0},
});
}
return points;
};
export const genBlob = (pointCount: number, offset: (index: number) => number): Point[] => {
return smoothBlob(genBlobygon(pointCount, offset));
};
export const genFromOptions = (
blobOptions: BlobOptions,
r?: (index: number) => number,
): Point[] => {
const rgen = r || rand(String(blobOptions.seed));
// Scale of random movement increases as randomness approaches infinity.
// randomness = 0 -> rangeStart = 1
// randomness = 2 -> rangeStart = 0.8333
// randomness = 5 -> rangeStart = 0.6667
// randomness = 10 -> rangeStart = 0.5
// randomness = 20 -> rangeStart = 0.3333
// randomness = 50 -> rangeStart = 0.1667
// randomness = 100 -> rangeStart = 0.0909
const rangeStart = 1 / (1 + blobOptions.randomness / 10);
const points = genBlob(
3 + blobOptions.extraPoints,
(index) => (rangeStart + rgen(index) * (1 - rangeStart)) / 2,
);
const size = blobOptions.size;
return mapPoints(points, ({curr}) => {
curr.x *= size;
curr.y *= size;
curr.handleIn.length *= size;
curr.handleOut.length *= size;
return curr;
});
};