toosoon-utils 2.4.0 → 2.4.2
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/lib/classes/_pool.js +22 -47
- package/lib/classes/color-scale.js +42 -60
- package/lib/classes/frame-rate.js +17 -23
- package/lib/colors.js +70 -86
- package/lib/constants.js +6 -6
- package/lib/dom.js +7 -8
- package/lib/files.js +7 -9
- package/lib/functions.js +9 -10
- package/lib/geometry.js +8 -9
- package/lib/maths.js +8 -15
- package/lib/prng.js +24 -30
- package/lib/random.js +19 -33
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/tsconfig.json +2 -3
package/lib/dom.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
const DOCUMENT_NODE_TYPE = 9;
|
|
2
2
|
/**
|
|
3
3
|
* Find the closest parent that matches a selector
|
|
4
4
|
*
|
|
@@ -7,7 +7,7 @@ var DOCUMENT_NODE_TYPE = 9;
|
|
|
7
7
|
* @returns {Element|null}
|
|
8
8
|
*/
|
|
9
9
|
export function closest(element, selector) {
|
|
10
|
-
|
|
10
|
+
let current = element;
|
|
11
11
|
while (current && current.nodeType !== DOCUMENT_NODE_TYPE) {
|
|
12
12
|
if ((typeof selector === 'string' && current.matches(selector)) || current === selector) {
|
|
13
13
|
return current;
|
|
@@ -24,12 +24,11 @@ export function closest(element, selector) {
|
|
|
24
24
|
* @returns {{ canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D }}
|
|
25
25
|
*/
|
|
26
26
|
export function createCanvas(width, height) {
|
|
27
|
-
|
|
28
|
-
var canvas = document.createElement('canvas');
|
|
27
|
+
const canvas = document.createElement('canvas');
|
|
29
28
|
canvas.width = width;
|
|
30
29
|
canvas.height = height;
|
|
31
|
-
|
|
32
|
-
return { canvas
|
|
30
|
+
const ctx = canvas.getContext('2d') ?? new CanvasRenderingContext2D();
|
|
31
|
+
return { canvas, ctx };
|
|
33
32
|
}
|
|
34
33
|
/**
|
|
35
34
|
* Inject CSS styles in `document.head`
|
|
@@ -37,9 +36,9 @@ export function createCanvas(width, height) {
|
|
|
37
36
|
* @param {string} styles CSS styles to inject
|
|
38
37
|
*/
|
|
39
38
|
export function injectStyles(styles) {
|
|
40
|
-
|
|
39
|
+
const $style = document.createElement('style');
|
|
41
40
|
$style.innerHTML = styles;
|
|
42
|
-
|
|
41
|
+
const $before = document.querySelector('head link[rel=stylesheet], head style');
|
|
43
42
|
if ($before)
|
|
44
43
|
document.head.insertBefore($style, $before);
|
|
45
44
|
else
|
package/lib/files.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @param {string} filename Downloaded file name
|
|
6
6
|
*/
|
|
7
7
|
export function download(blob, filename) {
|
|
8
|
-
|
|
8
|
+
const link = document.createElement('a');
|
|
9
9
|
link.setAttribute('href', URL.createObjectURL(blob));
|
|
10
10
|
link.setAttribute('download', filename);
|
|
11
11
|
document.body.appendChild(link);
|
|
@@ -18,17 +18,15 @@ export function download(blob, filename) {
|
|
|
18
18
|
* @param {Function} onLoad Callback called once the file is loaded
|
|
19
19
|
* @param {string} [accept=''] MIME type the file input should accept
|
|
20
20
|
*/
|
|
21
|
-
export function upload(onLoad, accept) {
|
|
22
|
-
|
|
23
|
-
var input = document.createElement('input');
|
|
21
|
+
export function upload(onLoad, accept = '') {
|
|
22
|
+
const input = document.createElement('input');
|
|
24
23
|
input.setAttribute('type', 'file');
|
|
25
24
|
input.setAttribute('accept', accept);
|
|
26
|
-
input.addEventListener('change',
|
|
27
|
-
|
|
28
|
-
var file = (_b = (_a = event.target) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0];
|
|
25
|
+
input.addEventListener('change', (event) => {
|
|
26
|
+
const file = event.target?.files?.[0];
|
|
29
27
|
if (file) {
|
|
30
|
-
|
|
31
|
-
fileReader.addEventListener('load',
|
|
28
|
+
const fileReader = new FileReader();
|
|
29
|
+
fileReader.addEventListener('load', () => onLoad(URL.createObjectURL(file)));
|
|
32
30
|
fileReader.readAsDataURL(file);
|
|
33
31
|
}
|
|
34
32
|
});
|
package/lib/functions.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* No-op function
|
|
3
3
|
*/
|
|
4
|
-
export
|
|
4
|
+
export const noop = () => { };
|
|
5
5
|
/**
|
|
6
6
|
* Promise wrapped setTimeout
|
|
7
7
|
*
|
|
8
8
|
* @param {number} [timeout=0] Time to wait (in milliseconds)
|
|
9
9
|
* @returns {Promise}
|
|
10
10
|
*/
|
|
11
|
-
export function wait(timeout) {
|
|
12
|
-
|
|
13
|
-
return new Promise(function (resolve) { return setTimeout(resolve, timeout); });
|
|
11
|
+
export function wait(timeout = 0) {
|
|
12
|
+
return new Promise((resolve) => setTimeout(resolve, timeout));
|
|
14
13
|
}
|
|
15
14
|
/**
|
|
16
15
|
* Deferred promise implementation
|
|
@@ -18,23 +17,23 @@ export function wait(timeout) {
|
|
|
18
17
|
* @returns {Deferred}
|
|
19
18
|
*/
|
|
20
19
|
export function defer() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
let resolve;
|
|
21
|
+
let reject;
|
|
22
|
+
const promise = new Promise((_resolve, _reject) => {
|
|
24
23
|
resolve = _resolve;
|
|
25
24
|
reject = _reject;
|
|
26
25
|
});
|
|
27
|
-
return { promise
|
|
26
|
+
return { promise, resolve, reject };
|
|
28
27
|
}
|
|
29
28
|
/**
|
|
30
29
|
* Polyfill for `now()` functions
|
|
31
30
|
*/
|
|
32
|
-
export
|
|
31
|
+
export let now;
|
|
33
32
|
// In node.js, use `process.hrtime`
|
|
34
33
|
if (typeof process !== 'undefined' && process.hrtime) {
|
|
35
34
|
now = function () {
|
|
36
35
|
// Convert [seconds, nanoseconds] to milliseconds
|
|
37
|
-
|
|
36
|
+
const time = process.hrtime();
|
|
38
37
|
return time[0] * 1000 + time[1] / 1000000;
|
|
39
38
|
};
|
|
40
39
|
}
|
package/lib/geometry.js
CHANGED
|
@@ -37,7 +37,7 @@ export function angle(x1, y1, x2, y2) {
|
|
|
37
37
|
* @returns {number} Closest angle
|
|
38
38
|
*/
|
|
39
39
|
export function closestAngle(source, target) {
|
|
40
|
-
|
|
40
|
+
const delta = target - source;
|
|
41
41
|
return delta > PI ? target - 2 * PI : target < -PI ? delta + 2 * PI : target;
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
@@ -50,8 +50,8 @@ export function closestAngle(source, target) {
|
|
|
50
50
|
* @returns {number} Computed distance
|
|
51
51
|
*/
|
|
52
52
|
export function distance(x1, y1, x2, y2) {
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
const dx = x1 - x2;
|
|
54
|
+
const dy = y1 - y2;
|
|
55
55
|
return Math.sqrt(dx * dx + dy * dy);
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
@@ -73,8 +73,7 @@ export function diagonal(width, height) {
|
|
|
73
73
|
* @param {Vector3} target Target vector
|
|
74
74
|
* @returns {Vector3}
|
|
75
75
|
*/
|
|
76
|
-
export function radToSphere(radius, phi, theta, target) {
|
|
77
|
-
if (target === void 0) { target = { x: 0, y: 0, z: 0 }; }
|
|
76
|
+
export function radToSphere(radius, phi, theta, target = { x: 0, y: 0, z: 0 }) {
|
|
78
77
|
target.x = radius * Math.sin(phi) * Math.sin(theta);
|
|
79
78
|
target.y = radius * Math.cos(phi);
|
|
80
79
|
target.z = radius * Math.sin(phi) * Math.cos(theta);
|
|
@@ -89,9 +88,9 @@ export function radToSphere(radius, phi, theta, target) {
|
|
|
89
88
|
* @returns {FitOutput}
|
|
90
89
|
*/
|
|
91
90
|
function fit(target, container, mode) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
const ratioWidth = container.width / target.width;
|
|
92
|
+
const ratioHeight = container.height / target.height;
|
|
93
|
+
let scale;
|
|
95
94
|
if (mode === 'contain') {
|
|
96
95
|
scale = ratioWidth < ratioHeight ? ratioWidth : ratioHeight;
|
|
97
96
|
}
|
|
@@ -103,7 +102,7 @@ function fit(target, container, mode) {
|
|
|
103
102
|
top: (container.height - target.height * scale) >> 1,
|
|
104
103
|
width: target.width * scale,
|
|
105
104
|
height: target.height * scale,
|
|
106
|
-
scale
|
|
105
|
+
scale
|
|
107
106
|
};
|
|
108
107
|
}
|
|
109
108
|
/**
|
package/lib/maths.js
CHANGED
|
@@ -32,8 +32,7 @@ export function isPowerOf2(value) {
|
|
|
32
32
|
* @param {string} [mode='ceil'] Can be 'floor' | 'ceil' | 'round'
|
|
33
33
|
* @returns {number} Power of 2
|
|
34
34
|
*/
|
|
35
|
-
export function toPowerOf2(value, mode) {
|
|
36
|
-
if (mode === void 0) { mode = 'ceil'; }
|
|
35
|
+
export function toPowerOf2(value, mode = 'ceil') {
|
|
37
36
|
return Math.pow(2, Math[mode](Math.log(value) / Math.log(2)));
|
|
38
37
|
}
|
|
39
38
|
/**
|
|
@@ -57,9 +56,7 @@ export function sign(value) {
|
|
|
57
56
|
* @param {number} [max=1] Maximum boundary
|
|
58
57
|
* @returns {number} Clamped value
|
|
59
58
|
*/
|
|
60
|
-
export function clamp(value, min, max) {
|
|
61
|
-
if (min === void 0) { min = 0; }
|
|
62
|
-
if (max === void 0) { max = 1; }
|
|
59
|
+
export function clamp(value, min = 0, max = 1) {
|
|
63
60
|
return Math.min(max, Math.max(min, value));
|
|
64
61
|
}
|
|
65
62
|
/**
|
|
@@ -83,7 +80,7 @@ export function lerp(value, min, max) {
|
|
|
83
80
|
* @returns {number} Interpolated value
|
|
84
81
|
*/
|
|
85
82
|
export function triLerp(value, min, max, target) {
|
|
86
|
-
|
|
83
|
+
const x = Math.pow(1 + Math.abs(target - max) / Math.abs(target - min), -1);
|
|
87
84
|
return value <= x ? min - (min - target) * (value / x) : target - (target - max) * ((value - x) / (1 - x));
|
|
88
85
|
}
|
|
89
86
|
/**
|
|
@@ -131,8 +128,7 @@ export function map(value, currentMin, currentMax, targetMin, targetMax) {
|
|
|
131
128
|
* @param {number} [multiple=1] Multiple to round to
|
|
132
129
|
* @returns {number} Closest multiple
|
|
133
130
|
*/
|
|
134
|
-
export function roundTo(value, multiple) {
|
|
135
|
-
if (multiple === void 0) { multiple = 1; }
|
|
131
|
+
export function roundTo(value, multiple = 1) {
|
|
136
132
|
if (multiple === 0)
|
|
137
133
|
return value;
|
|
138
134
|
return Math.round(value / multiple) * multiple;
|
|
@@ -169,10 +165,8 @@ export function pingPong(value, length) {
|
|
|
169
165
|
* @param {number} [max=1] Maximum boundary
|
|
170
166
|
* @returns {number} Normalized smoothed value
|
|
171
167
|
*/
|
|
172
|
-
export function smoothstep(value, min, max) {
|
|
173
|
-
|
|
174
|
-
if (max === void 0) { max = 1; }
|
|
175
|
-
var x = clamp(normalize(value, min, max));
|
|
168
|
+
export function smoothstep(value, min = 0, max = 1) {
|
|
169
|
+
const x = clamp(normalize(value, min, max));
|
|
176
170
|
return x * x * (3 - 2 * x);
|
|
177
171
|
}
|
|
178
172
|
/**
|
|
@@ -183,8 +177,7 @@ export function smoothstep(value, min, max) {
|
|
|
183
177
|
* @param {number} [power=1] Parabola power
|
|
184
178
|
* @returns {number} Normalized re-mapped value
|
|
185
179
|
*/
|
|
186
|
-
export function parabola(x, power) {
|
|
187
|
-
if (power === void 0) { power = 1; }
|
|
180
|
+
export function parabola(x, power = 1) {
|
|
188
181
|
return Math.pow(4 * x * (1 - x), power);
|
|
189
182
|
}
|
|
190
183
|
/**
|
|
@@ -194,7 +187,7 @@ export function parabola(x, power) {
|
|
|
194
187
|
* @returns {number} Total sum
|
|
195
188
|
*/
|
|
196
189
|
export function sum(array) {
|
|
197
|
-
return array.reduce(
|
|
190
|
+
return array.reduce((previous, current) => previous + current);
|
|
198
191
|
}
|
|
199
192
|
/**
|
|
200
193
|
* Return the average of numbers
|
package/lib/prng.js
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* @returns {[number, number, number, number]} Hash numbers
|
|
6
6
|
*/
|
|
7
7
|
export function cyrb128(seed) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
for (
|
|
8
|
+
let h1 = 1779033703;
|
|
9
|
+
let h2 = 3144134277;
|
|
10
|
+
let h3 = 1013904242;
|
|
11
|
+
let h4 = 2773480762;
|
|
12
|
+
for (let i = 0, k; i < seed.length; i++) {
|
|
13
13
|
k = seed.charCodeAt(i);
|
|
14
14
|
h1 = h2 ^ Math.imul(h1 ^ k, 597399067);
|
|
15
15
|
h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);
|
|
@@ -39,7 +39,7 @@ export function sfc32(a, b, c, d) {
|
|
|
39
39
|
b >>>= 0;
|
|
40
40
|
c >>>= 0;
|
|
41
41
|
d >>>= 0;
|
|
42
|
-
|
|
42
|
+
let t = (a + b) | 0;
|
|
43
43
|
a = b ^ (b >>> 9);
|
|
44
44
|
b = (c + (c << 3)) | 0;
|
|
45
45
|
c = (c << 21) | (c >>> 11);
|
|
@@ -70,7 +70,7 @@ export function splitmix32(a) {
|
|
|
70
70
|
* @returns {number} Pseudo-random number
|
|
71
71
|
*/
|
|
72
72
|
export function mulberry32(a) {
|
|
73
|
-
|
|
73
|
+
let t = (a += 0x6d2b79f5);
|
|
74
74
|
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
75
75
|
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
76
76
|
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
@@ -86,7 +86,7 @@ export function jsf32(a, b, c, d) {
|
|
|
86
86
|
b |= 0;
|
|
87
87
|
c |= 0;
|
|
88
88
|
d |= 0;
|
|
89
|
-
|
|
89
|
+
let t = (a - ((b << 27) | (b >>> 5))) | 0;
|
|
90
90
|
a = b ^ ((c << 17) | (c >>> 15));
|
|
91
91
|
b = (c + d) | 0;
|
|
92
92
|
c = (d + t) | 0;
|
|
@@ -100,8 +100,8 @@ export function jsf32(a, b, c, d) {
|
|
|
100
100
|
* @returns {number} Pseudo-random number
|
|
101
101
|
*/
|
|
102
102
|
export function xoshiro128ss(a, b, c, d) {
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
let t = b << 9;
|
|
104
|
+
let r = a * 5;
|
|
105
105
|
r = ((r << 7) | (r >>> 25)) * 9;
|
|
106
106
|
c ^= a;
|
|
107
107
|
d ^= b;
|
|
@@ -119,10 +119,10 @@ export function xoshiro128ss(a, b, c, d) {
|
|
|
119
119
|
* @returns {number} Pseudo-random number
|
|
120
120
|
*/
|
|
121
121
|
export function random(prng) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return algorithm
|
|
122
|
+
const seed = typeof prng === 'string' ? prng : prng.seed;
|
|
123
|
+
const algorithm = typeof prng === 'string' ? splitmix32 : prng.algorithm;
|
|
124
|
+
const hashes = cyrb128(seed);
|
|
125
|
+
return algorithm(...hashes);
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Generate a pseudo-random boolean (true or false)
|
|
@@ -131,8 +131,7 @@ export function random(prng) {
|
|
|
131
131
|
* @param {number} [probability=0.5] Probability to get true
|
|
132
132
|
* @returns {boolean} Either `true` or `false`
|
|
133
133
|
*/
|
|
134
|
-
export function randomBoolean(prng, probability) {
|
|
135
|
-
if (probability === void 0) { probability = 0.5; }
|
|
134
|
+
export function randomBoolean(prng, probability = 0.5) {
|
|
136
135
|
return random(prng) < probability;
|
|
137
136
|
}
|
|
138
137
|
/**
|
|
@@ -142,8 +141,7 @@ export function randomBoolean(prng, probability) {
|
|
|
142
141
|
* @param {number} [probability=0.5] Probability to get 1
|
|
143
142
|
* @returns {number} Either 1 or -1
|
|
144
143
|
*/
|
|
145
|
-
export function randomSign(prng, probability) {
|
|
146
|
-
if (probability === void 0) { probability = 0.5; }
|
|
144
|
+
export function randomSign(prng, probability = 0.5) {
|
|
147
145
|
return randomBoolean(prng, probability) ? 1 : -1;
|
|
148
146
|
}
|
|
149
147
|
/**
|
|
@@ -155,10 +153,7 @@ export function randomSign(prng, probability) {
|
|
|
155
153
|
* @param {number} [precision=2] Number of digits after the decimal point
|
|
156
154
|
* @returns {number} Generated float
|
|
157
155
|
*/
|
|
158
|
-
export function randomFloat(prng, min, max, precision) {
|
|
159
|
-
if (min === void 0) { min = 0; }
|
|
160
|
-
if (max === void 0) { max = 1; }
|
|
161
|
-
if (precision === void 0) { precision = 2; }
|
|
156
|
+
export function randomFloat(prng, min = 0, max = 1, precision = 2) {
|
|
162
157
|
return parseFloat(Math.min(min + random(prng) * (max - min), max).toFixed(precision));
|
|
163
158
|
}
|
|
164
159
|
/**
|
|
@@ -201,8 +196,8 @@ export function randomItem(prng, array) {
|
|
|
201
196
|
* @returns {T|undefined} Random item picked
|
|
202
197
|
*/
|
|
203
198
|
export function randomObjectProperty(prng, object) {
|
|
204
|
-
|
|
205
|
-
|
|
199
|
+
const keys = Object.keys(object);
|
|
200
|
+
const key = randomItem(prng, keys);
|
|
206
201
|
if (key && object.hasOwnProperty(key)) {
|
|
207
202
|
return object[key];
|
|
208
203
|
}
|
|
@@ -217,15 +212,14 @@ export function randomObjectProperty(prng, object) {
|
|
|
217
212
|
export function randomIndex(prng, weights) {
|
|
218
213
|
if (weights.length === 0)
|
|
219
214
|
return -1;
|
|
220
|
-
|
|
221
|
-
for (
|
|
222
|
-
|
|
223
|
-
totalWeight += weight_1;
|
|
215
|
+
let totalWeight = 0;
|
|
216
|
+
for (let weight of weights) {
|
|
217
|
+
totalWeight += weight;
|
|
224
218
|
}
|
|
225
219
|
if (totalWeight <= 0)
|
|
226
220
|
console.warn('PRNG randomIndex()', 'Weights must sum to > 0', totalWeight);
|
|
227
|
-
|
|
228
|
-
for (
|
|
221
|
+
let weight = random(prng) * totalWeight;
|
|
222
|
+
for (let i = 0; i < weights.length; i++) {
|
|
229
223
|
if (weight < weights[i])
|
|
230
224
|
return i;
|
|
231
225
|
weight -= weights[i];
|
package/lib/random.js
CHANGED
|
@@ -5,8 +5,7 @@ import { radToSphere } from './geometry';
|
|
|
5
5
|
* @param {number} [probability=0.5] Probability to get true
|
|
6
6
|
* @returns {boolean} Either `true` or `false`
|
|
7
7
|
*/
|
|
8
|
-
export function randomBoolean(probability) {
|
|
9
|
-
if (probability === void 0) { probability = 0.5; }
|
|
8
|
+
export function randomBoolean(probability = 0.5) {
|
|
10
9
|
return Math.random() < probability;
|
|
11
10
|
}
|
|
12
11
|
/**
|
|
@@ -15,8 +14,7 @@ export function randomBoolean(probability) {
|
|
|
15
14
|
* @param {number} [probability=0.5] Probability to get 1
|
|
16
15
|
* @returns {number} Either 1 or -1
|
|
17
16
|
*/
|
|
18
|
-
export function randomSign(probability) {
|
|
19
|
-
if (probability === void 0) { probability = 0.5; }
|
|
17
|
+
export function randomSign(probability = 0.5) {
|
|
20
18
|
return randomBoolean(probability) ? 1 : -1;
|
|
21
19
|
}
|
|
22
20
|
/**
|
|
@@ -27,10 +25,7 @@ export function randomSign(probability) {
|
|
|
27
25
|
* @param {number} [precision=2] Number of digits after the decimal point
|
|
28
26
|
* @returns {number} Generated float
|
|
29
27
|
*/
|
|
30
|
-
export function randomFloat(min, max, precision) {
|
|
31
|
-
if (min === void 0) { min = 0; }
|
|
32
|
-
if (max === void 0) { max = 1; }
|
|
33
|
-
if (precision === void 0) { precision = 2; }
|
|
28
|
+
export function randomFloat(min = 0, max = 1, precision = 2) {
|
|
34
29
|
return parseFloat(Math.min(min + Math.random() * (max - min), max).toFixed(precision));
|
|
35
30
|
}
|
|
36
31
|
/**
|
|
@@ -69,8 +64,8 @@ export function randomItem(array) {
|
|
|
69
64
|
* @returns {T|undefined} Random item picked
|
|
70
65
|
*/
|
|
71
66
|
export function randomObjectProperty(object) {
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
const keys = Object.keys(object);
|
|
68
|
+
const key = randomItem(keys);
|
|
74
69
|
if (key && object.hasOwnProperty(key)) {
|
|
75
70
|
return object[key];
|
|
76
71
|
}
|
|
@@ -84,16 +79,15 @@ export function randomObjectProperty(object) {
|
|
|
84
79
|
export function randomIndex(weights) {
|
|
85
80
|
if (weights.length === 0)
|
|
86
81
|
return -1;
|
|
87
|
-
|
|
88
|
-
for (
|
|
89
|
-
|
|
90
|
-
totalWeight += weight_1;
|
|
82
|
+
let totalWeight = 0;
|
|
83
|
+
for (let weight of weights) {
|
|
84
|
+
totalWeight += weight;
|
|
91
85
|
}
|
|
92
86
|
if (totalWeight <= 0) {
|
|
93
87
|
console.warn('randomIndex()', 'Weights must sum to > 0', totalWeight);
|
|
94
88
|
}
|
|
95
|
-
|
|
96
|
-
for (
|
|
89
|
+
let weight = Math.random() * totalWeight;
|
|
90
|
+
for (let i = 0; i < weights.length; i++) {
|
|
97
91
|
if (weight < weights[i])
|
|
98
92
|
return i;
|
|
99
93
|
weight -= weights[i];
|
|
@@ -110,10 +104,8 @@ export function randomIndex(weights) {
|
|
|
110
104
|
* @param {Vector2} [target] Target vector
|
|
111
105
|
* @returns {Vector2} Random 2D point on circle
|
|
112
106
|
*/
|
|
113
|
-
export function onCircle(radius, target) {
|
|
114
|
-
|
|
115
|
-
if (target === void 0) { target = { x: 0, y: 0 }; }
|
|
116
|
-
var angle = Math.random() * 2.0 * Math.PI;
|
|
107
|
+
export function onCircle(radius = 1, target = { x: 0, y: 0 }) {
|
|
108
|
+
const angle = Math.random() * 2.0 * Math.PI;
|
|
117
109
|
target.x = radius * Math.cos(angle);
|
|
118
110
|
target.y = radius * Math.sin(angle);
|
|
119
111
|
return target;
|
|
@@ -125,9 +117,7 @@ export function onCircle(radius, target) {
|
|
|
125
117
|
* @param {Vector2} [target] Target vector
|
|
126
118
|
* @returns {Vector2} Random 2D point inside circle
|
|
127
119
|
*/
|
|
128
|
-
export function insideCircle(radius, target) {
|
|
129
|
-
if (radius === void 0) { radius = 1; }
|
|
130
|
-
if (target === void 0) { target = { x: 0, y: 0 }; }
|
|
120
|
+
export function insideCircle(radius = 1, target = { x: 0, y: 0 }) {
|
|
131
121
|
radius *= Math.random();
|
|
132
122
|
return onCircle(radius, target);
|
|
133
123
|
}
|
|
@@ -138,13 +128,11 @@ export function insideCircle(radius, target) {
|
|
|
138
128
|
* @param {Vector3} [target] Target vector
|
|
139
129
|
* @returns {Vector3} Random 3D point on sphere
|
|
140
130
|
*/
|
|
141
|
-
export function onSphere(radius, target) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
var phi = u;
|
|
147
|
-
var theta = Math.acos(v);
|
|
131
|
+
export function onSphere(radius = 1, target = { x: 0, y: 0, z: 0 }) {
|
|
132
|
+
const u = Math.random() * Math.PI * 2;
|
|
133
|
+
const v = Math.random() * 2 - 1;
|
|
134
|
+
const phi = u;
|
|
135
|
+
const theta = Math.acos(v);
|
|
148
136
|
return radToSphere(radius, phi, theta, target);
|
|
149
137
|
}
|
|
150
138
|
/**
|
|
@@ -154,9 +142,7 @@ export function onSphere(radius, target) {
|
|
|
154
142
|
* @param {Vector3} [target] Target vector
|
|
155
143
|
* @returns {Vector3} Random 3D point inside sphere
|
|
156
144
|
*/
|
|
157
|
-
export function insideSphere(radius, target) {
|
|
158
|
-
if (radius === void 0) { radius = 1; }
|
|
159
|
-
if (target === void 0) { target = { x: 0, y: 0, z: 0 }; }
|
|
145
|
+
export function insideSphere(radius = 1, target = { x: 0, y: 0, z: 0 }) {
|
|
160
146
|
radius *= Math.random();
|
|
161
147
|
return onSphere(radius, target);
|
|
162
148
|
}
|