-
-
Notifications
You must be signed in to change notification settings - Fork 800
/
Curves.ts
66 lines (55 loc) · 1.99 KB
/
Curves.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
/* eslint-disable @typescript-eslint/no-magic-numbers */
import { getRandom } from "@tsparticles/engine";
/**
* @param rndFunc -
* @param period -
* @param nbHarmonics -
* @param attenHarmonics -
* @param lowValue -
* @param highValue -
* @returns the generated value
*/
export function CurvesPathGen(
rndFunc: (() => number) | null | undefined,
period: number,
nbHarmonics: number,
attenHarmonics: number,
lowValue = 0,
highValue = 1,
): () => number {
const arP0: number[] = [], // 'preceding value' for each harmonic
arP1: number[] = [], // 'succeeding value'
amplitudes: number[] = [], // amplitudes oh harmonics
increments: number[] = [], // n / period, which will be added to phases for every point
phases: number[] = [],
randomFunc = rndFunc ?? getRandom;
let globAmplitude = 0;
if (nbHarmonics < 1) nbHarmonics = 1;
for (let kh = 1; kh <= nbHarmonics; ++kh) {
arP0[kh] = randomFunc();
arP1[kh] = randomFunc();
amplitudes[kh] = kh === 1 ? 1 : amplitudes[kh - 1] * attenHarmonics;
globAmplitude += amplitudes[kh];
increments[kh] = kh / period;
phases[kh] = randomFunc();
} // for kh
/* normalize amplitudes */
amplitudes.forEach((value, kh) => (amplitudes[kh] = (value / globAmplitude) * (highValue - lowValue)));
/* returned function here */
return () => {
let pf: number,
pfl: number,
signal = 0;
for (let kh = nbHarmonics; kh >= 1; --kh) {
pf = phases[kh] += increments[kh];
if (phases[kh] >= 1) {
pf = phases[kh] -= 1;
arP0[kh] = arP1[kh];
arP1[kh] = randomFunc();
} // if full period reached
pfl = pf ** 2 * (3 - 2 * pf); // always 0..1, but smoother
signal += (arP0[kh] * (1 - pfl) + arP1[kh] * pfl) * amplitudes[kh];
} // for kh
return signal + lowValue;
}; // returned function
} // PathGen