toosoon-utils 1.0.0

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/maths.d.ts ADDED
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Check if a number is even
3
+ *
4
+ * @param {number} value Value to check
5
+ * @returns {boolean} True if the given number is even, false otherwise
6
+ */
7
+ export declare function isEven(value: number): boolean;
8
+ /**
9
+ * Check if a number is odd
10
+ *
11
+ * @param {number} value Value to check
12
+ * @returns {boolean} True if the given number is odd, false otherwise
13
+ */
14
+ export declare function isOdd(value: number): boolean;
15
+ /**
16
+ * Check if a number is a power of 2
17
+ *
18
+ * @param {number} value Value to check
19
+ * @returns {boolean} True if the given number is a power of 2, false otherwise
20
+ */
21
+ export declare function isPowerOf2(value: number): boolean;
22
+ /**
23
+ * Find smallest/closest power of 2 that fits a number
24
+ *
25
+ * @param {number} value Incoming value
26
+ * @param {string} [mode='ceil'] Can be 'floor' | 'ceil' | 'round'
27
+ * @returns {number} Power of 2
28
+ */
29
+ export declare function toPowerOf2(value: number, mode?: 'floor' | 'ceil' | 'round'): number;
30
+ /**
31
+ * Return the sign (positive or negative) of a number
32
+ *
33
+ * @param {number} number Value to check
34
+ * @returns {number} 1 if the given number is positive, -1 if it is negative, otherwise 0
35
+ */
36
+ export declare function sign(number: number): number;
37
+ /**
38
+ * Clamp a value between two bounds
39
+ *
40
+ * @param {number} value Value to clamp
41
+ * @param {number} [min=0] Minimum boundary
42
+ * @param {number} [max=1] Maximum boundary
43
+ * @returns {number} Clamped value
44
+ */
45
+ export declare function clamp(value: number, min?: number, max?: number): number;
46
+ /**
47
+ * Linear interpolation between two values (lerping)
48
+ *
49
+ * @param {number} value Normalized value to interpolate
50
+ * @param {number} min Minimum value
51
+ * @param {number} max Maximum value
52
+ * @returns {number} Lerped value
53
+ */
54
+ export declare function lerp(value: number, min: number, max: number): number;
55
+ /**
56
+ * Triangular interpolation between two values
57
+ *
58
+ * @param {number} value Normalized value to interpolate
59
+ * @param {number} min Minimum value
60
+ * @param {number} max Maximum value
61
+ * @param {number} target Triangle target value
62
+ * @returns {number} Interpolated value
63
+ */
64
+ export declare function triLerp(value: number, min: number, max: number, target: number): number;
65
+ /**
66
+ * Exponential interpolation between two values
67
+ *
68
+ * @param {number} value Normalized value to interpolate
69
+ * @param {number} min Minimum value
70
+ * @param {number} max Maximum value
71
+ * @returns {number} Interpolated value
72
+ */
73
+ export declare function expLerp(value: number, min: number, max: number): number;
74
+ /**
75
+ * Normalize a value between two bounds
76
+ *
77
+ * @param {number} value Value to normalize
78
+ * @param {number} min Minimum boundary
79
+ * @param {number} max Maximum boundary
80
+ * @returns {number} Normalized value
81
+ */
82
+ export declare function normalize(value: number, min: number, max: number): number;
83
+ /**
84
+ * Re-map a number from one range to another
85
+ *
86
+ * @param {number} value Value to re-map
87
+ * @param {number} currentMin Lower bound of the value's current range
88
+ * @param {number} currentMax Upper bound of the value's current range
89
+ * @param {number} targetMin Lower bound of the value's target range
90
+ * @param {number} targetMax Upper bound of the value's target range
91
+ * @returns {number} Re-mapped value
92
+ */
93
+ export declare function map(value: number, currentMin: number, currentMax: number, targetMin: number, targetMax: number): number;
94
+ /**
95
+ * Round a number up to a nearest multiple
96
+ *
97
+ * @param {number} value Value to round
98
+ * @param {number} [multiple=1] Multiple
99
+ * @returns {number} Closest multiple
100
+ */
101
+ export declare function roundTo(value: number, multiple?: number): number;
102
+ /**
103
+ * Modulo absolute a value based on a length
104
+ *
105
+ * @param {number} value Value to modulate
106
+ * @param {number} length Total length
107
+ * @returns {number} Modulated value
108
+ */
109
+ export declare function modAbs(value: number, length: number): number;
110
+ /**
111
+ * Move back and forth a value between 0 and length, so that it is never larger than length and never smaller than 0
112
+ *
113
+ * @param {number} value Value to modulate
114
+ * @param {number} length Total length
115
+ * @returns {number} PingPonged value
116
+ */
117
+ export declare function pingPong(value: number, length: number): number;
118
+ /**
119
+ * Smooth a value using cubic Hermite interpolation
120
+ *
121
+ * @param {number} value Value to smooth
122
+ * @param {number} [min=0] Minimum boundary
123
+ * @param {number} [max=1] Maximum boundary
124
+ * @returns {number} Normalized smoothed value
125
+ */
126
+ export declare function smoothstep(value: number, min?: number, max?: number): number;
127
+ /**
128
+ * Re-map the [0, 1] interval into [0, 1] parabola, such that corners are remaped to 0 and the center to 1
129
+ * -> parabola(0) = parabola(1) = 0, and parabola(0.5) = 1
130
+ *
131
+ * @param {number} x Normalized coordinate on X axis
132
+ * @param {number} [power=1] Parabola power
133
+ * @returns {number} Normalized re-mapped value
134
+ */
135
+ export declare function parabola(x: number, power?: number): number;
136
+ /**
137
+ * Return the sum of numbers
138
+ *
139
+ * @param {number[]} array Array of number
140
+ * @returns {number} Total sum
141
+ */
142
+ export declare function sum(array: number[]): number;
143
+ /**
144
+ * Return the average of numbers
145
+ *
146
+ * @param {number[]} array Array of number
147
+ * @returns {number} Total average
148
+ */
149
+ export declare function average(array: number[]): number;
150
+ /**
151
+ * Smoothly interpolate a number toward another
152
+ *
153
+ * @param {number} value Value to interpolate
154
+ * @param {number} target Destination of the interpolation
155
+ * @param {number} damping A higher value will make the movement more sudden, and a lower value will make the movement more gradual
156
+ * @param {number} delta Delta time (in seconds)
157
+ * @returns {number} Interpolated number
158
+ */
159
+ export declare function damp(value: number, target: number, damping: number, delta: number): number;
package/lib/maths.js ADDED
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.damp = exports.average = exports.sum = exports.parabola = exports.smoothstep = exports.pingPong = exports.modAbs = exports.roundTo = exports.map = exports.normalize = exports.expLerp = exports.triLerp = exports.lerp = exports.clamp = exports.sign = exports.toPowerOf2 = exports.isPowerOf2 = exports.isOdd = exports.isEven = void 0;
4
+ /**
5
+ * Check if a number is even
6
+ *
7
+ * @param {number} value Value to check
8
+ * @returns {boolean} True if the given number is even, false otherwise
9
+ */
10
+ function isEven(value) {
11
+ return !(value & 1);
12
+ }
13
+ exports.isEven = isEven;
14
+ /**
15
+ * Check if a number is odd
16
+ *
17
+ * @param {number} value Value to check
18
+ * @returns {boolean} True if the given number is odd, false otherwise
19
+ */
20
+ function isOdd(value) {
21
+ return !!(value & 1);
22
+ }
23
+ exports.isOdd = isOdd;
24
+ /**
25
+ * Check if a number is a power of 2
26
+ *
27
+ * @param {number} value Value to check
28
+ * @returns {boolean} True if the given number is a power of 2, false otherwise
29
+ */
30
+ function isPowerOf2(value) {
31
+ return (value & (value - 1)) === 0;
32
+ }
33
+ exports.isPowerOf2 = isPowerOf2;
34
+ /**
35
+ * Find smallest/closest power of 2 that fits a number
36
+ *
37
+ * @param {number} value Incoming value
38
+ * @param {string} [mode='ceil'] Can be 'floor' | 'ceil' | 'round'
39
+ * @returns {number} Power of 2
40
+ */
41
+ function toPowerOf2(value, mode) {
42
+ if (mode === void 0) { mode = 'ceil'; }
43
+ return Math.pow(2, Math[mode](Math.log(value) / Math.log(2)));
44
+ }
45
+ exports.toPowerOf2 = toPowerOf2;
46
+ /**
47
+ * Return the sign (positive or negative) of a number
48
+ *
49
+ * @param {number} number Value to check
50
+ * @returns {number} 1 if the given number is positive, -1 if it is negative, otherwise 0
51
+ */
52
+ function sign(number) {
53
+ if (number > 0)
54
+ return 1;
55
+ else if (number < 0)
56
+ return -1;
57
+ return 0;
58
+ }
59
+ exports.sign = sign;
60
+ /**
61
+ * Clamp a value between two bounds
62
+ *
63
+ * @param {number} value Value to clamp
64
+ * @param {number} [min=0] Minimum boundary
65
+ * @param {number} [max=1] Maximum boundary
66
+ * @returns {number} Clamped value
67
+ */
68
+ function clamp(value, min, max) {
69
+ if (min === void 0) { min = 0; }
70
+ if (max === void 0) { max = 1; }
71
+ return Math.min(max, Math.max(min, value));
72
+ }
73
+ exports.clamp = clamp;
74
+ /**
75
+ * Linear interpolation between two values (lerping)
76
+ *
77
+ * @param {number} value Normalized value to interpolate
78
+ * @param {number} min Minimum value
79
+ * @param {number} max Maximum value
80
+ * @returns {number} Lerped value
81
+ */
82
+ function lerp(value, min, max) {
83
+ return min + (max - min) * value;
84
+ }
85
+ exports.lerp = lerp;
86
+ /**
87
+ * Triangular interpolation between two values
88
+ *
89
+ * @param {number} value Normalized value to interpolate
90
+ * @param {number} min Minimum value
91
+ * @param {number} max Maximum value
92
+ * @param {number} target Triangle target value
93
+ * @returns {number} Interpolated value
94
+ */
95
+ function triLerp(value, min, max, target) {
96
+ var x = Math.pow(1 + Math.abs(target - max) / Math.abs(target - min), -1);
97
+ return value <= x ? min - (min - target) * (value / x) : target - (target - max) * ((value - x) / (1 - x));
98
+ }
99
+ exports.triLerp = triLerp;
100
+ /**
101
+ * Exponential interpolation between two values
102
+ *
103
+ * @param {number} value Normalized value to interpolate
104
+ * @param {number} min Minimum value
105
+ * @param {number} max Maximum value
106
+ * @returns {number} Interpolated value
107
+ */
108
+ function expLerp(value, min, max) {
109
+ return Math.pow(min, 1 - value) * Math.pow(max, value);
110
+ }
111
+ exports.expLerp = expLerp;
112
+ /**
113
+ * Normalize a value between two bounds
114
+ *
115
+ * @param {number} value Value to normalize
116
+ * @param {number} min Minimum boundary
117
+ * @param {number} max Maximum boundary
118
+ * @returns {number} Normalized value
119
+ */
120
+ function normalize(value, min, max) {
121
+ return (value - min) / (max - min);
122
+ }
123
+ exports.normalize = normalize;
124
+ /**
125
+ * Re-map a number from one range to another
126
+ *
127
+ * @param {number} value Value to re-map
128
+ * @param {number} currentMin Lower bound of the value's current range
129
+ * @param {number} currentMax Upper bound of the value's current range
130
+ * @param {number} targetMin Lower bound of the value's target range
131
+ * @param {number} targetMax Upper bound of the value's target range
132
+ * @returns {number} Re-mapped value
133
+ */
134
+ function map(value, currentMin, currentMax, targetMin, targetMax) {
135
+ return ((value - currentMin) / (currentMax - currentMin)) * (targetMax - targetMin) + targetMin;
136
+ }
137
+ exports.map = map;
138
+ /**
139
+ * Round a number up to a nearest multiple
140
+ *
141
+ * @param {number} value Value to round
142
+ * @param {number} [multiple=1] Multiple
143
+ * @returns {number} Closest multiple
144
+ */
145
+ function roundTo(value, multiple) {
146
+ if (multiple === void 0) { multiple = 1; }
147
+ if (multiple === 0)
148
+ return value;
149
+ return Math.round(value / multiple) * multiple;
150
+ }
151
+ exports.roundTo = roundTo;
152
+ /**
153
+ * Modulo absolute a value based on a length
154
+ *
155
+ * @param {number} value Value to modulate
156
+ * @param {number} length Total length
157
+ * @returns {number} Modulated value
158
+ */
159
+ function modAbs(value, length) {
160
+ if (value < 0) {
161
+ return length + (value % length);
162
+ }
163
+ return value % length;
164
+ }
165
+ exports.modAbs = modAbs;
166
+ /**
167
+ * Move back and forth a value between 0 and length, so that it is never larger than length and never smaller than 0
168
+ *
169
+ * @param {number} value Value to modulate
170
+ * @param {number} length Total length
171
+ * @returns {number} PingPonged value
172
+ */
173
+ function pingPong(value, length) {
174
+ value = modAbs(value, length * 2);
175
+ return length - Math.abs(value - length);
176
+ }
177
+ exports.pingPong = pingPong;
178
+ /**
179
+ * Smooth a value using cubic Hermite interpolation
180
+ *
181
+ * @param {number} value Value to smooth
182
+ * @param {number} [min=0] Minimum boundary
183
+ * @param {number} [max=1] Maximum boundary
184
+ * @returns {number} Normalized smoothed value
185
+ */
186
+ function smoothstep(value, min, max) {
187
+ if (min === void 0) { min = 0; }
188
+ if (max === void 0) { max = 1; }
189
+ var x = clamp(normalize(value, min, max));
190
+ return x * x * (3 - 2 * x);
191
+ }
192
+ exports.smoothstep = smoothstep;
193
+ /**
194
+ * Re-map the [0, 1] interval into [0, 1] parabola, such that corners are remaped to 0 and the center to 1
195
+ * -> parabola(0) = parabola(1) = 0, and parabola(0.5) = 1
196
+ *
197
+ * @param {number} x Normalized coordinate on X axis
198
+ * @param {number} [power=1] Parabola power
199
+ * @returns {number} Normalized re-mapped value
200
+ */
201
+ function parabola(x, power) {
202
+ if (power === void 0) { power = 1; }
203
+ return Math.pow(4 * x * (1 - x), power);
204
+ }
205
+ exports.parabola = parabola;
206
+ /**
207
+ * Return the sum of numbers
208
+ *
209
+ * @param {number[]} array Array of number
210
+ * @returns {number} Total sum
211
+ */
212
+ function sum(array) {
213
+ return array.reduce(function (previous, current) { return previous + current; });
214
+ }
215
+ exports.sum = sum;
216
+ /**
217
+ * Return the average of numbers
218
+ *
219
+ * @param {number[]} array Array of number
220
+ * @returns {number} Total average
221
+ */
222
+ function average(array) {
223
+ return sum(array) / array.length;
224
+ }
225
+ exports.average = average;
226
+ /**
227
+ * Smoothly interpolate a number toward another
228
+ *
229
+ * @param {number} value Value to interpolate
230
+ * @param {number} target Destination of the interpolation
231
+ * @param {number} damping A higher value will make the movement more sudden, and a lower value will make the movement more gradual
232
+ * @param {number} delta Delta time (in seconds)
233
+ * @returns {number} Interpolated number
234
+ */
235
+ function damp(value, target, damping, delta) {
236
+ return lerp(1 - Math.exp(-damping * delta), value, target);
237
+ }
238
+ exports.damp = damp;
package/lib/now.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Polyfill for "now()" functions
3
+ */
4
+ declare let now: () => number;
5
+ export default now;
package/lib/now.js ADDED
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Polyfill for "now()" functions
5
+ */
6
+ var now;
7
+ // In node.js, use process.hrtime
8
+ if (typeof process !== 'undefined' && process.hrtime) {
9
+ now = function () {
10
+ // Convert [seconds, nanoseconds] to milliseconds
11
+ var time = process.hrtime();
12
+ return time[0] * 1000 + time[1] / 1000000;
13
+ };
14
+ }
15
+ // In a browser use performance or Date
16
+ else if (typeof performance !== 'undefined') {
17
+ // This must be bound, because directly assigning this function leads to an invocation exception in Chrome
18
+ now = performance.now.bind(performance);
19
+ }
20
+ else if (typeof Date.now !== 'undefined') {
21
+ now = Date.now;
22
+ }
23
+ else {
24
+ now = function () {
25
+ return new Date().getTime();
26
+ };
27
+ }
28
+ exports.default = now;
@@ -0,0 +1,91 @@
1
+ import { Vector2, Vector3 } from './types';
2
+ /**
3
+ * Generate random boolean (true or false)
4
+ *
5
+ * @param {number} [probability=0.5] Probability to get true
6
+ * @returns {boolean} Either true or false
7
+ */
8
+ export declare function randomBoolean(probability?: number): boolean;
9
+ /**
10
+ * Generate random sign (1 or -1)
11
+ *
12
+ * @param {number} [probability=0.5] Probability to get 1
13
+ * @returns {number} Either 1 or -1
14
+ */
15
+ export declare function randomSign(probability?: number): number;
16
+ /**
17
+ * Generate a random float
18
+ *
19
+ * @param {number} [min=0] Minimum boundary
20
+ * @param {number} [max=1] Maximum boundary
21
+ * @param {number} [precision=2] Number of digits after the decimal point
22
+ * @returns {number} Generated float
23
+ */
24
+ export declare function randomFloat(min?: number, max?: number, precision?: number): number;
25
+ /**
26
+ * Generate a random integer
27
+ *
28
+ * @param {number} min Minimum boundary
29
+ * @param {number} max Maximum boundary
30
+ * @returns {number} Generated integer
31
+ */
32
+ export declare function randomInt(min: number, max: number): number;
33
+ /**
34
+ * Generate a random hexadecimal color
35
+ *
36
+ * @returns {string} Hexadecimal color
37
+ */
38
+ export declare function randomHexColor(): string;
39
+ /**
40
+ * Pick a random item from an array
41
+ *
42
+ * @param {I[]} [array=[]] Array to pick the item from
43
+ * @returns {I|undefined} Random item picked
44
+ */
45
+ export declare function randomItem<I = unknown>(array?: I[]): I | undefined;
46
+ /**
47
+ * Pick a random property from an object
48
+ *
49
+ * @param {object} [object={}] Object to pick the property from
50
+ * @returns {unknown|undefined} Random item picked
51
+ */
52
+ export declare function randomObjectProperty(object?: object): unknown | undefined;
53
+ /**
54
+ * Return a random index from an array of weights
55
+ *
56
+ * @param {number[]} weights Array of weights
57
+ * @returns {number} Random index based on weights
58
+ */
59
+ export declare function randomIndex(weights?: number[]): number;
60
+ /**
61
+ * Produce a random 2D point around the perimiter of a unit circle
62
+ *
63
+ * @param {number} [radius=1] Radius of the circle
64
+ * @param {Vector2} target Target vector
65
+ * @returns {Vector2} Random 2D point on circle
66
+ */
67
+ export declare function onCircle(radius?: number, target?: Vector2): Vector2;
68
+ /**
69
+ * Produce a random 2D point inside a unit circle
70
+ *
71
+ * @param {number} [radius=1] Radius of the circle
72
+ * @param {Vector2} target Target vector
73
+ * @returns {Vector2} Random 2D point inside circle
74
+ */
75
+ export declare function insideCircle(radius?: number, target?: Vector2): Vector2;
76
+ /**
77
+ * Produce a random 3D point on the surface of a unit sphere
78
+ *
79
+ * @param {number} [radius=1] Radius of the sphere
80
+ * @param {Vector3} target Target vector
81
+ * @returns {Vector3} Random 3D point on sphere
82
+ */
83
+ export declare function onSphere(radius?: number, target?: Vector3): Vector3;
84
+ /**
85
+ * Produce a random 3D point inside a unit sphere
86
+ *
87
+ * @param {number} [radius=1] Radius of the sphere
88
+ * @param {Vector3} target Target vector
89
+ * @returns {Vector3} Random 3D point inside sphere
90
+ */
91
+ export declare function insideSphere(radius?: number, target?: Vector3): Vector3;
package/lib/random.js ADDED
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.insideSphere = exports.onSphere = exports.insideCircle = exports.onCircle = exports.randomIndex = exports.randomObjectProperty = exports.randomItem = exports.randomHexColor = exports.randomInt = exports.randomFloat = exports.randomSign = exports.randomBoolean = void 0;
4
+ var geometry_1 = require("./geometry");
5
+ /**
6
+ * Generate random boolean (true or false)
7
+ *
8
+ * @param {number} [probability=0.5] Probability to get true
9
+ * @returns {boolean} Either true or false
10
+ */
11
+ function randomBoolean(probability) {
12
+ if (probability === void 0) { probability = 0.5; }
13
+ return Math.random() < probability;
14
+ }
15
+ exports.randomBoolean = randomBoolean;
16
+ /**
17
+ * Generate random sign (1 or -1)
18
+ *
19
+ * @param {number} [probability=0.5] Probability to get 1
20
+ * @returns {number} Either 1 or -1
21
+ */
22
+ function randomSign(probability) {
23
+ if (probability === void 0) { probability = 0.5; }
24
+ return randomBoolean(probability) ? 1 : -1;
25
+ }
26
+ exports.randomSign = randomSign;
27
+ /**
28
+ * Generate a random float
29
+ *
30
+ * @param {number} [min=0] Minimum boundary
31
+ * @param {number} [max=1] Maximum boundary
32
+ * @param {number} [precision=2] Number of digits after the decimal point
33
+ * @returns {number} Generated float
34
+ */
35
+ function randomFloat(min, max, precision) {
36
+ if (min === void 0) { min = 0; }
37
+ if (max === void 0) { max = 1; }
38
+ if (precision === void 0) { precision = 2; }
39
+ return parseFloat(Math.min(min + Math.random() * (max - min), max).toFixed(precision));
40
+ }
41
+ exports.randomFloat = randomFloat;
42
+ /**
43
+ * Generate a random integer
44
+ *
45
+ * @param {number} min Minimum boundary
46
+ * @param {number} max Maximum boundary
47
+ * @returns {number} Generated integer
48
+ */
49
+ function randomInt(min, max) {
50
+ return Math.floor(Math.random() * (max - min + 1) + min);
51
+ }
52
+ exports.randomInt = randomInt;
53
+ /**
54
+ * Generate a random hexadecimal color
55
+ *
56
+ * @returns {string} Hexadecimal color
57
+ */
58
+ function randomHexColor() {
59
+ return '#' + ('00000' + ((Math.random() * (1 << 24)) | 0).toString(16)).slice(-6);
60
+ }
61
+ exports.randomHexColor = randomHexColor;
62
+ /**
63
+ * Pick a random item from an array
64
+ *
65
+ * @param {I[]} [array=[]] Array to pick the item from
66
+ * @returns {I|undefined} Random item picked
67
+ */
68
+ function randomItem(array) {
69
+ if (array === void 0) { array = []; }
70
+ if (array.length === 0)
71
+ return undefined;
72
+ return array[randomInt(0, array.length - 1)];
73
+ }
74
+ exports.randomItem = randomItem;
75
+ /**
76
+ * Pick a random property from an object
77
+ *
78
+ * @param {object} [object={}] Object to pick the property from
79
+ * @returns {unknown|undefined} Random item picked
80
+ */
81
+ function randomObjectProperty(object) {
82
+ if (object === void 0) { object = {}; }
83
+ var keys = Object.keys(object);
84
+ var key = randomItem(keys);
85
+ if (key && object.hasOwnProperty(key)) {
86
+ return object[key];
87
+ }
88
+ }
89
+ exports.randomObjectProperty = randomObjectProperty;
90
+ /**
91
+ * Return a random index from an array of weights
92
+ *
93
+ * @param {number[]} weights Array of weights
94
+ * @returns {number} Random index based on weights
95
+ */
96
+ function randomIndex(weights) {
97
+ if (weights === void 0) { weights = []; }
98
+ if (weights.length === 0)
99
+ return -1;
100
+ var totalWeight = 0;
101
+ for (var _i = 0, weights_1 = weights; _i < weights_1.length; _i++) {
102
+ var weight = weights_1[_i];
103
+ totalWeight += weight;
104
+ }
105
+ if (totalWeight <= 0) {
106
+ console.warn('randomIndex()', 'Weights must sum to > 0', totalWeight);
107
+ }
108
+ var random = Math.random() * totalWeight;
109
+ for (var i = 0; i < weights.length; i++) {
110
+ if (random < weights[i])
111
+ return i;
112
+ random -= weights[i];
113
+ }
114
+ return 0;
115
+ }
116
+ exports.randomIndex = randomIndex;
117
+ // *********************
118
+ // Geometry
119
+ // *********************
120
+ /**
121
+ * Produce a random 2D point around the perimiter of a unit circle
122
+ *
123
+ * @param {number} [radius=1] Radius of the circle
124
+ * @param {Vector2} target Target vector
125
+ * @returns {Vector2} Random 2D point on circle
126
+ */
127
+ function onCircle(radius, target) {
128
+ if (radius === void 0) { radius = 1; }
129
+ if (target === void 0) { target = { x: 0, y: 0 }; }
130
+ var angle = Math.random() * 2.0 * Math.PI;
131
+ target.x = radius * Math.cos(angle);
132
+ target.y = radius * Math.sin(angle);
133
+ return target;
134
+ }
135
+ exports.onCircle = onCircle;
136
+ /**
137
+ * Produce a random 2D point inside a unit circle
138
+ *
139
+ * @param {number} [radius=1] Radius of the circle
140
+ * @param {Vector2} target Target vector
141
+ * @returns {Vector2} Random 2D point inside circle
142
+ */
143
+ function insideCircle(radius, target) {
144
+ if (radius === void 0) { radius = 1; }
145
+ if (target === void 0) { target = { x: 0, y: 0 }; }
146
+ radius *= Math.random();
147
+ return onCircle(radius, target);
148
+ }
149
+ exports.insideCircle = insideCircle;
150
+ /**
151
+ * Produce a random 3D point on the surface of a unit sphere
152
+ *
153
+ * @param {number} [radius=1] Radius of the sphere
154
+ * @param {Vector3} target Target vector
155
+ * @returns {Vector3} Random 3D point on sphere
156
+ */
157
+ function onSphere(radius, target) {
158
+ if (radius === void 0) { radius = 1; }
159
+ if (target === void 0) { target = { x: 0, y: 0, z: 0 }; }
160
+ var u = Math.random() * Math.PI * 2;
161
+ var v = Math.random() * 2 - 1;
162
+ var phi = u;
163
+ var theta = Math.acos(v);
164
+ return (0, geometry_1.radToSphere)(radius, phi, theta, target);
165
+ }
166
+ exports.onSphere = onSphere;
167
+ /**
168
+ * Produce a random 3D point inside a unit sphere
169
+ *
170
+ * @param {number} [radius=1] Radius of the sphere
171
+ * @param {Vector3} target Target vector
172
+ * @returns {Vector3} Random 3D point inside sphere
173
+ */
174
+ function insideSphere(radius, target) {
175
+ if (radius === void 0) { radius = 1; }
176
+ if (target === void 0) { target = { x: 0, y: 0, z: 0 }; }
177
+ radius *= Math.random();
178
+ return onSphere(radius, target);
179
+ }
180
+ exports.insideSphere = insideSphere;