@flighthq/math 0.1.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/dist/angle.d.ts +13 -0
- package/dist/angle.d.ts.map +1 -0
- package/dist/angle.js +24 -0
- package/dist/angle.js.map +1 -0
- package/dist/clamp.d.ts +15 -0
- package/dist/clamp.d.ts.map +1 -0
- package/dist/clamp.js +23 -0
- package/dist/clamp.js.map +1 -0
- package/dist/comparison.d.ts +17 -0
- package/dist/comparison.d.ts.map +1 -0
- package/dist/comparison.js +26 -0
- package/dist/comparison.js.map +1 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +11 -0
- package/dist/constants.js.map +1 -0
- package/dist/hash.d.ts +35 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +51 -0
- package/dist/hash.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/interpolation.d.ts +27 -0
- package/dist/interpolation.d.ts.map +1 -0
- package/dist/interpolation.js +43 -0
- package/dist/interpolation.js.map +1 -0
- package/dist/interpolationAdvanced.d.ts +42 -0
- package/dist/interpolationAdvanced.d.ts.map +1 -0
- package/dist/interpolationAdvanced.js +71 -0
- package/dist/interpolationAdvanced.js.map +1 -0
- package/dist/nextPowerOfTwo.d.ts +22 -0
- package/dist/nextPowerOfTwo.d.ts.map +1 -0
- package/dist/nextPowerOfTwo.js +52 -0
- package/dist/nextPowerOfTwo.js.map +1 -0
- package/dist/numberTheory.d.ts +33 -0
- package/dist/numberTheory.d.ts.map +1 -0
- package/dist/numberTheory.js +62 -0
- package/dist/numberTheory.js.map +1 -0
- package/dist/random.d.ts +20 -0
- package/dist/random.d.ts.map +1 -0
- package/dist/random.js +27 -0
- package/dist/random.js.map +1 -0
- package/dist/randomDistributions.d.ts +105 -0
- package/dist/randomDistributions.d.ts.map +1 -0
- package/dist/randomDistributions.js +209 -0
- package/dist/randomDistributions.js.map +1 -0
- package/dist/randomRange.d.ts +18 -0
- package/dist/randomRange.d.ts.map +1 -0
- package/dist/randomRange.js +29 -0
- package/dist/randomRange.js.map +1 -0
- package/dist/rounding.d.ts +35 -0
- package/dist/rounding.d.ts.map +1 -0
- package/dist/rounding.js +53 -0
- package/dist/rounding.js.map +1 -0
- package/dist/scalar.d.ts +30 -0
- package/dist/scalar.d.ts.map +1 -0
- package/dist/scalar.js +42 -0
- package/dist/scalar.js.map +1 -0
- package/dist/statistics.d.ts +29 -0
- package/dist/statistics.d.ts.map +1 -0
- package/dist/statistics.js +67 -0
- package/dist/statistics.js.map +1 -0
- package/package.json +37 -0
- package/src/angle.test.ts +83 -0
- package/src/clamp.test.ts +61 -0
- package/src/comparison.test.ts +54 -0
- package/src/constants.test.ts +38 -0
- package/src/hash.test.ts +84 -0
- package/src/interpolation.test.ts +93 -0
- package/src/interpolationAdvanced.test.ts +122 -0
- package/src/nextPowerOfTwo.test.ts +84 -0
- package/src/numberTheory.test.ts +95 -0
- package/src/random.test.ts +32 -0
- package/src/randomDistributions.test.ts +348 -0
- package/src/randomRange.test.ts +99 -0
- package/src/rounding.test.ts +81 -0
- package/src/scalar.test.ts +58 -0
- package/src/statistics.test.ts +74 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Return the factorial of non-negative integer `n`.
|
|
2
|
+
*
|
|
3
|
+
* `factorial(0)` → `1` by convention. Throws for negative inputs or
|
|
4
|
+
* non-integer inputs (programmer error). Returns `Infinity` for `n > 170`
|
|
5
|
+
* (above IEEE 754 double precision range).
|
|
6
|
+
*/
|
|
7
|
+
export declare function factorial(n: number): number;
|
|
8
|
+
/** Return the greatest common divisor of `a` and `b` (Euclidean algorithm).
|
|
9
|
+
*
|
|
10
|
+
* Operates on the absolute values of the inputs, so negative arguments are
|
|
11
|
+
* accepted. Throws when both `a` and `b` are `0` (programmer error — the GCD
|
|
12
|
+
* of zero and zero is undefined).
|
|
13
|
+
*/
|
|
14
|
+
export declare function gcd(a: number, b: number): number;
|
|
15
|
+
/** Return the squared distance `x² + y²`.
|
|
16
|
+
*
|
|
17
|
+
* Allocation-free substitute for `Math.hypot(x, y) ** 2` when you only need
|
|
18
|
+
* to compare distances. Prefer `hypot2` over `Math.hypot` in hot loops where
|
|
19
|
+
* the actual distance value is not needed.
|
|
20
|
+
*/
|
|
21
|
+
export declare function hypot2(x: number, y: number): number;
|
|
22
|
+
/** Return `true` if `n` is even. */
|
|
23
|
+
export declare function isEven(n: number): boolean;
|
|
24
|
+
/** Return `true` if `n` is odd. */
|
|
25
|
+
export declare function isOdd(n: number): boolean;
|
|
26
|
+
/** Return the least common multiple of `a` and `b`.
|
|
27
|
+
*
|
|
28
|
+
* Operates on the absolute values of the inputs. Throws when both `a` and
|
|
29
|
+
* `b` are `0` (see `gcd`). For very large inputs, the result may exceed
|
|
30
|
+
* `Number.MAX_SAFE_INTEGER` and lose precision.
|
|
31
|
+
*/
|
|
32
|
+
export declare function lcm(a: number, b: number): number;
|
|
33
|
+
//# sourceMappingURL=numberTheory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numberTheory.d.ts","sourceRoot":"","sources":["../src/numberTheory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM3C;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAUhD;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,oCAAoC;AACpC,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEzC;AAED,mCAAmC;AACnC,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAExC;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAGhD"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** Return the factorial of non-negative integer `n`.
|
|
2
|
+
*
|
|
3
|
+
* `factorial(0)` → `1` by convention. Throws for negative inputs or
|
|
4
|
+
* non-integer inputs (programmer error). Returns `Infinity` for `n > 170`
|
|
5
|
+
* (above IEEE 754 double precision range).
|
|
6
|
+
*/
|
|
7
|
+
export function factorial(n) {
|
|
8
|
+
if (!Number.isInteger(n) || n < 0)
|
|
9
|
+
throw new RangeError('factorial: n must be a non-negative integer');
|
|
10
|
+
if (n === 0 || n === 1)
|
|
11
|
+
return 1;
|
|
12
|
+
let result = 1;
|
|
13
|
+
for (let i = 2; i <= n; i++)
|
|
14
|
+
result *= i;
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
/** Return the greatest common divisor of `a` and `b` (Euclidean algorithm).
|
|
18
|
+
*
|
|
19
|
+
* Operates on the absolute values of the inputs, so negative arguments are
|
|
20
|
+
* accepted. Throws when both `a` and `b` are `0` (programmer error — the GCD
|
|
21
|
+
* of zero and zero is undefined).
|
|
22
|
+
*/
|
|
23
|
+
export function gcd(a, b) {
|
|
24
|
+
a = Math.abs(Math.trunc(a));
|
|
25
|
+
b = Math.abs(Math.trunc(b));
|
|
26
|
+
if (a === 0 && b === 0)
|
|
27
|
+
throw new RangeError('gcd: both arguments must not be 0');
|
|
28
|
+
while (b !== 0) {
|
|
29
|
+
const t = b;
|
|
30
|
+
b = a % b;
|
|
31
|
+
a = t;
|
|
32
|
+
}
|
|
33
|
+
return a;
|
|
34
|
+
}
|
|
35
|
+
/** Return the squared distance `x² + y²`.
|
|
36
|
+
*
|
|
37
|
+
* Allocation-free substitute for `Math.hypot(x, y) ** 2` when you only need
|
|
38
|
+
* to compare distances. Prefer `hypot2` over `Math.hypot` in hot loops where
|
|
39
|
+
* the actual distance value is not needed.
|
|
40
|
+
*/
|
|
41
|
+
export function hypot2(x, y) {
|
|
42
|
+
return x * x + y * y;
|
|
43
|
+
}
|
|
44
|
+
/** Return `true` if `n` is even. */
|
|
45
|
+
export function isEven(n) {
|
|
46
|
+
return (n & 1) === 0;
|
|
47
|
+
}
|
|
48
|
+
/** Return `true` if `n` is odd. */
|
|
49
|
+
export function isOdd(n) {
|
|
50
|
+
return (n & 1) === 1;
|
|
51
|
+
}
|
|
52
|
+
/** Return the least common multiple of `a` and `b`.
|
|
53
|
+
*
|
|
54
|
+
* Operates on the absolute values of the inputs. Throws when both `a` and
|
|
55
|
+
* `b` are `0` (see `gcd`). For very large inputs, the result may exceed
|
|
56
|
+
* `Number.MAX_SAFE_INTEGER` and lose precision.
|
|
57
|
+
*/
|
|
58
|
+
export function lcm(a, b) {
|
|
59
|
+
const g = gcd(a, b);
|
|
60
|
+
return (Math.abs(Math.trunc(a)) / g) * Math.abs(Math.trunc(b));
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=numberTheory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numberTheory.js","sourceRoot":"","sources":["../src/numberTheory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,6CAA6C,CAAC,CAAC;IACvG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACjC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;QAAE,MAAM,IAAI,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS;IACtC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAClF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACV,CAAC,GAAG,CAAC,CAAC;IACR,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,CAAS,EAAE,CAAS;IACzC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,MAAM,CAAC,CAAS;IAC9B,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,KAAK,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS;IACtC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
package/dist/random.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RandomSource } from '@flighthq/types';
|
|
2
|
+
export type { RandomSource };
|
|
3
|
+
/** Create a fast, deterministic pseudo-random generator seeded by an integer.
|
|
4
|
+
*
|
|
5
|
+
* Uses the mulberry32 algorithm: a single 32-bit state, good statistical
|
|
6
|
+
* quality for gameplay/VFX use, and identical output across platforms for a
|
|
7
|
+
* given seed. Two generators created with the same seed produce the same
|
|
8
|
+
* sequence, so seeding two consumers identically makes them run in lockstep.
|
|
9
|
+
*
|
|
10
|
+
* This is the SDK's reusable seeded random — used wherever a render or
|
|
11
|
+
* simulation must be reproducible (particle emitters, the landing backgrounds,
|
|
12
|
+
* visual-regression capture) rather than each call site reimplementing it.
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* const random = createRandomSource(0x1234);
|
|
16
|
+
* const value = random(); // a number in [0, 1)
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function createRandomSource(seed: number): RandomSource;
|
|
20
|
+
//# sourceMappingURL=random.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAS7D"}
|
package/dist/random.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Create a fast, deterministic pseudo-random generator seeded by an integer.
|
|
2
|
+
*
|
|
3
|
+
* Uses the mulberry32 algorithm: a single 32-bit state, good statistical
|
|
4
|
+
* quality for gameplay/VFX use, and identical output across platforms for a
|
|
5
|
+
* given seed. Two generators created with the same seed produce the same
|
|
6
|
+
* sequence, so seeding two consumers identically makes them run in lockstep.
|
|
7
|
+
*
|
|
8
|
+
* This is the SDK's reusable seeded random — used wherever a render or
|
|
9
|
+
* simulation must be reproducible (particle emitters, the landing backgrounds,
|
|
10
|
+
* visual-regression capture) rather than each call site reimplementing it.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const random = createRandomSource(0x1234);
|
|
14
|
+
* const value = random(); // a number in [0, 1)
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export function createRandomSource(seed) {
|
|
18
|
+
// Coerce to a 32-bit unsigned integer; non-finite seeds collapse to 0.
|
|
19
|
+
let a = Number.isFinite(seed) ? seed >>> 0 : 0;
|
|
20
|
+
return function seededRandom() {
|
|
21
|
+
a = (a + 0x6d2b79f5) | 0;
|
|
22
|
+
let t = Math.imul(a ^ (a >>> 15), 1 | a);
|
|
23
|
+
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
24
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=random.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"random.js","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,uEAAuE;IACvE,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,OAAO,SAAS,YAAY;QAC1B,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC;IAC/C,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { RandomSource, Vector2Like, Vector3Like } from '@flighthq/types';
|
|
2
|
+
/** Pick a random element from `items`, returning `undefined` for an empty array.
|
|
3
|
+
*
|
|
4
|
+
* Does not mutate `items`. Deterministic: same `random` sequence → same picks.
|
|
5
|
+
*/
|
|
6
|
+
export declare function pick<T>(random: RandomSource, items: Readonly<T[]>): T | undefined;
|
|
7
|
+
/** Return an exponentially-distributed random number with the given `rate`
|
|
8
|
+
* (λ > 0, mean = 1/λ).
|
|
9
|
+
*
|
|
10
|
+
* Uses the inverse CDF method: `-ln(U) / rate` where U is uniform on (0, 1].
|
|
11
|
+
* Suitable for modeling inter-arrival times in a Poisson process, particle
|
|
12
|
+
* lifetimes, and decay events.
|
|
13
|
+
*
|
|
14
|
+
* The result is always non-negative. Throws if `rate <= 0`.
|
|
15
|
+
*
|
|
16
|
+
* Deterministic: same `random` sequence → same output sequence.
|
|
17
|
+
*/
|
|
18
|
+
export declare function randomExponential(random: RandomSource, rate?: number): number;
|
|
19
|
+
/** Return a normally-distributed random number with the given `mean` and
|
|
20
|
+
* `standardDeviation`, using the Box–Muller transform.
|
|
21
|
+
*
|
|
22
|
+
* Each call consumes two values from `random` and discards one (the simplest
|
|
23
|
+
* variant — use `randomGaussianPair` if you need both). The result can be any
|
|
24
|
+
* finite number; it is not clamped.
|
|
25
|
+
*
|
|
26
|
+
* Deterministic: same `random` sequence → same output sequence.
|
|
27
|
+
*/
|
|
28
|
+
export declare function randomGaussian(random: RandomSource, mean?: number, standardDeviation?: number): number;
|
|
29
|
+
/** Return two independent normally-distributed random numbers as `[z0, z1]`
|
|
30
|
+
* sharing the same Box–Muller pair.
|
|
31
|
+
*
|
|
32
|
+
* Prefer this over calling `randomGaussian` twice when both samples are
|
|
33
|
+
* needed — it consumes exactly 2 values from `random` instead of 4.
|
|
34
|
+
*/
|
|
35
|
+
export declare function randomGaussianPair(random: RandomSource, mean?: number, standardDeviation?: number): readonly [number, number];
|
|
36
|
+
/** Sample a uniformly-distributed point inside the unit disc (including the
|
|
37
|
+
* boundary) and write it into `out.x` / `out.y`.
|
|
38
|
+
*
|
|
39
|
+
* Uses rejection sampling to avoid the over-dense centre that polar-radius
|
|
40
|
+
* sampling without a square-root correction produces.
|
|
41
|
+
*
|
|
42
|
+
* The `out` parameter may be the same object as any other argument (alias-safe).
|
|
43
|
+
* No allocation.
|
|
44
|
+
*/
|
|
45
|
+
export declare function randomInsideUnitDisc(random: RandomSource, out: Vector2Like): void;
|
|
46
|
+
/** Sample a uniformly-distributed point inside the unit sphere (radius ≤ 1)
|
|
47
|
+
* and write it into `out.x` / `out.y` / `out.z`.
|
|
48
|
+
*
|
|
49
|
+
* Uses 3D box rejection sampling: repeatedly draw from [-1, 1]³ until the
|
|
50
|
+
* point is inside the sphere. Expected draws per call ≈ 1.91 (sphere:cube
|
|
51
|
+
* volume ratio π/6 ≈ 0.524, so ~1.9× draws on average — fast in practice).
|
|
52
|
+
*
|
|
53
|
+
* The `out` parameter may be the same object as any other argument (alias-safe:
|
|
54
|
+
* all reads are complete before any write). No allocation.
|
|
55
|
+
*/
|
|
56
|
+
export declare function randomInsideUnitSphere(random: RandomSource, out: Vector3Like): void;
|
|
57
|
+
/** Sample a uniformly-distributed point on the unit circle and write it into
|
|
58
|
+
* `out.x` / `out.y`. The result has unit length (x² + y² = 1).
|
|
59
|
+
*
|
|
60
|
+
* The `out` parameter may be the same object as any other argument (alias-safe:
|
|
61
|
+
* all reads complete before any write). No allocation.
|
|
62
|
+
*/
|
|
63
|
+
export declare function randomOnUnitCircle(random: RandomSource, out: Vector2Like): void;
|
|
64
|
+
/** Sample a uniformly-distributed point on the surface of the unit sphere
|
|
65
|
+
* and write it into `out.x` / `out.y` / `out.z`.
|
|
66
|
+
*
|
|
67
|
+
* Uses the Marsaglia (1972) method — two uniform samples → rejection → a point
|
|
68
|
+
* on the sphere. The result has unit length (x² + y² + z² = 1).
|
|
69
|
+
*
|
|
70
|
+
* The `out` parameter may be the same object as any other argument (alias-safe).
|
|
71
|
+
* No allocation.
|
|
72
|
+
*/
|
|
73
|
+
export declare function randomOnUnitSphere(random: RandomSource, out: Vector3Like): void;
|
|
74
|
+
/** Return a Poisson-distributed random integer with mean `lambda` (λ > 0).
|
|
75
|
+
*
|
|
76
|
+
* Uses Knuth's multiplicative algorithm: multiply independent uniform samples
|
|
77
|
+
* until their product falls below `exp(-λ)`. Accurate and simple for small
|
|
78
|
+
* `lambda` (λ ≤ ~30); for large lambda, `randomGaussian(random, lambda,
|
|
79
|
+
* Math.sqrt(lambda))` is a faster approximation.
|
|
80
|
+
*
|
|
81
|
+
* The result is a non-negative integer. Throws if `lambda <= 0`.
|
|
82
|
+
*
|
|
83
|
+
* Deterministic: same `random` sequence → same output sequence.
|
|
84
|
+
*/
|
|
85
|
+
export declare function randomPoisson(random: RandomSource, lambda?: number): number;
|
|
86
|
+
/** Return a random index from a weight array, selected proportionally to
|
|
87
|
+
* each weight. Weights do not need to sum to 1.
|
|
88
|
+
*
|
|
89
|
+
* Returns `-1` for an empty or all-zero weight array.
|
|
90
|
+
*
|
|
91
|
+
* Useful for weighted spawn rules in particle emitters.
|
|
92
|
+
*/
|
|
93
|
+
export declare function randomWeighted(random: RandomSource, weights: Readonly<number[]>): number;
|
|
94
|
+
/** Return a new array with the elements of `items` shuffled in a random order
|
|
95
|
+
* (Fisher–Yates / Knuth shuffle). Allocates a copy; does not mutate `items`.
|
|
96
|
+
*
|
|
97
|
+
* Deterministic: same `random` state → same shuffled order.
|
|
98
|
+
*/
|
|
99
|
+
export declare function shuffle<T>(random: RandomSource, items: Readonly<T[]>): T[];
|
|
100
|
+
/** Shuffle `items` in place using the Fisher–Yates algorithm.
|
|
101
|
+
*
|
|
102
|
+
* Mutates `items`. Deterministic: same `random` state → same shuffled order.
|
|
103
|
+
*/
|
|
104
|
+
export declare function shuffleInPlace<T>(random: RandomSource, items: T[]): void;
|
|
105
|
+
//# sourceMappingURL=randomDistributions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"randomDistributions.d.ts","sourceRoot":"","sources":["../src/randomDistributions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9E;;;GAGG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,CAGjF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,GAAE,MAAU,GAAG,MAAM,CAKhF;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,GAAE,MAAU,EAAE,iBAAiB,GAAE,MAAU,GAAG,MAAM,CAO5G;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,MAAU,EAChB,iBAAiB,GAAE,MAAU,GAC5B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAUjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAYnF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAM/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAiB/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,GAAE,MAAU,GAAG,MAAM,CAU9E;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAUxF;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAI1E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAOxE"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/** Pick a random element from `items`, returning `undefined` for an empty array.
|
|
2
|
+
*
|
|
3
|
+
* Does not mutate `items`. Deterministic: same `random` sequence → same picks.
|
|
4
|
+
*/
|
|
5
|
+
export function pick(random, items) {
|
|
6
|
+
if (items.length === 0)
|
|
7
|
+
return undefined;
|
|
8
|
+
return items[Math.floor(random() * items.length)];
|
|
9
|
+
}
|
|
10
|
+
/** Return an exponentially-distributed random number with the given `rate`
|
|
11
|
+
* (λ > 0, mean = 1/λ).
|
|
12
|
+
*
|
|
13
|
+
* Uses the inverse CDF method: `-ln(U) / rate` where U is uniform on (0, 1].
|
|
14
|
+
* Suitable for modeling inter-arrival times in a Poisson process, particle
|
|
15
|
+
* lifetimes, and decay events.
|
|
16
|
+
*
|
|
17
|
+
* The result is always non-negative. Throws if `rate <= 0`.
|
|
18
|
+
*
|
|
19
|
+
* Deterministic: same `random` sequence → same output sequence.
|
|
20
|
+
*/
|
|
21
|
+
export function randomExponential(random, rate = 1) {
|
|
22
|
+
if (rate <= 0)
|
|
23
|
+
throw new RangeError('randomExponential: rate must be > 0');
|
|
24
|
+
const u = random();
|
|
25
|
+
// Avoid ln(0) — replace exactly 0 with the smallest usable positive value.
|
|
26
|
+
return -Math.log(u === 0 ? Number.EPSILON : u) / rate;
|
|
27
|
+
}
|
|
28
|
+
/** Return a normally-distributed random number with the given `mean` and
|
|
29
|
+
* `standardDeviation`, using the Box–Muller transform.
|
|
30
|
+
*
|
|
31
|
+
* Each call consumes two values from `random` and discards one (the simplest
|
|
32
|
+
* variant — use `randomGaussianPair` if you need both). The result can be any
|
|
33
|
+
* finite number; it is not clamped.
|
|
34
|
+
*
|
|
35
|
+
* Deterministic: same `random` sequence → same output sequence.
|
|
36
|
+
*/
|
|
37
|
+
export function randomGaussian(random, mean = 0, standardDeviation = 1) {
|
|
38
|
+
// Box–Muller: uses two uniform samples to produce two independent standard
|
|
39
|
+
// normal values. We discard the second one for simplicity.
|
|
40
|
+
const u1 = random();
|
|
41
|
+
const u2 = random();
|
|
42
|
+
const z = Math.sqrt(-2 * Math.log(u1 === 0 ? Number.EPSILON : u1)) * Math.cos(Math.PI * 2 * u2);
|
|
43
|
+
return mean + z * standardDeviation;
|
|
44
|
+
}
|
|
45
|
+
/** Return two independent normally-distributed random numbers as `[z0, z1]`
|
|
46
|
+
* sharing the same Box–Muller pair.
|
|
47
|
+
*
|
|
48
|
+
* Prefer this over calling `randomGaussian` twice when both samples are
|
|
49
|
+
* needed — it consumes exactly 2 values from `random` instead of 4.
|
|
50
|
+
*/
|
|
51
|
+
export function randomGaussianPair(random, mean = 0, standardDeviation = 1) {
|
|
52
|
+
const u1 = random();
|
|
53
|
+
const u2 = random();
|
|
54
|
+
const mag = Math.sqrt(-2 * Math.log(u1 === 0 ? Number.EPSILON : u1));
|
|
55
|
+
const angle = Math.PI * 2 * u2;
|
|
56
|
+
const z0 = mean + mag * Math.cos(angle) * standardDeviation;
|
|
57
|
+
const z1 = mean + mag * Math.sin(angle) * standardDeviation;
|
|
58
|
+
return [z0, z1];
|
|
59
|
+
}
|
|
60
|
+
/** Sample a uniformly-distributed point inside the unit disc (including the
|
|
61
|
+
* boundary) and write it into `out.x` / `out.y`.
|
|
62
|
+
*
|
|
63
|
+
* Uses rejection sampling to avoid the over-dense centre that polar-radius
|
|
64
|
+
* sampling without a square-root correction produces.
|
|
65
|
+
*
|
|
66
|
+
* The `out` parameter may be the same object as any other argument (alias-safe).
|
|
67
|
+
* No allocation.
|
|
68
|
+
*/
|
|
69
|
+
export function randomInsideUnitDisc(random, out) {
|
|
70
|
+
// Square rejection sampling: draw from [-1, 1]² until inside the unit disc.
|
|
71
|
+
let x;
|
|
72
|
+
let y;
|
|
73
|
+
do {
|
|
74
|
+
x = random() * 2 - 1;
|
|
75
|
+
y = random() * 2 - 1;
|
|
76
|
+
} while (x * x + y * y > 1);
|
|
77
|
+
out.x = x;
|
|
78
|
+
out.y = y;
|
|
79
|
+
}
|
|
80
|
+
/** Sample a uniformly-distributed point inside the unit sphere (radius ≤ 1)
|
|
81
|
+
* and write it into `out.x` / `out.y` / `out.z`.
|
|
82
|
+
*
|
|
83
|
+
* Uses 3D box rejection sampling: repeatedly draw from [-1, 1]³ until the
|
|
84
|
+
* point is inside the sphere. Expected draws per call ≈ 1.91 (sphere:cube
|
|
85
|
+
* volume ratio π/6 ≈ 0.524, so ~1.9× draws on average — fast in practice).
|
|
86
|
+
*
|
|
87
|
+
* The `out` parameter may be the same object as any other argument (alias-safe:
|
|
88
|
+
* all reads are complete before any write). No allocation.
|
|
89
|
+
*/
|
|
90
|
+
export function randomInsideUnitSphere(random, out) {
|
|
91
|
+
let x;
|
|
92
|
+
let y;
|
|
93
|
+
let z;
|
|
94
|
+
do {
|
|
95
|
+
x = random() * 2 - 1;
|
|
96
|
+
y = random() * 2 - 1;
|
|
97
|
+
z = random() * 2 - 1;
|
|
98
|
+
} while (x * x + y * y + z * z > 1);
|
|
99
|
+
out.x = x;
|
|
100
|
+
out.y = y;
|
|
101
|
+
out.z = z;
|
|
102
|
+
}
|
|
103
|
+
/** Sample a uniformly-distributed point on the unit circle and write it into
|
|
104
|
+
* `out.x` / `out.y`. The result has unit length (x² + y² = 1).
|
|
105
|
+
*
|
|
106
|
+
* The `out` parameter may be the same object as any other argument (alias-safe:
|
|
107
|
+
* all reads complete before any write). No allocation.
|
|
108
|
+
*/
|
|
109
|
+
export function randomOnUnitCircle(random, out) {
|
|
110
|
+
const angle = random() * Math.PI * 2;
|
|
111
|
+
const x = Math.cos(angle);
|
|
112
|
+
const y = Math.sin(angle);
|
|
113
|
+
out.x = x;
|
|
114
|
+
out.y = y;
|
|
115
|
+
}
|
|
116
|
+
/** Sample a uniformly-distributed point on the surface of the unit sphere
|
|
117
|
+
* and write it into `out.x` / `out.y` / `out.z`.
|
|
118
|
+
*
|
|
119
|
+
* Uses the Marsaglia (1972) method — two uniform samples → rejection → a point
|
|
120
|
+
* on the sphere. The result has unit length (x² + y² + z² = 1).
|
|
121
|
+
*
|
|
122
|
+
* The `out` parameter may be the same object as any other argument (alias-safe).
|
|
123
|
+
* No allocation.
|
|
124
|
+
*/
|
|
125
|
+
export function randomOnUnitSphere(random, out) {
|
|
126
|
+
let x;
|
|
127
|
+
let y;
|
|
128
|
+
let s;
|
|
129
|
+
// Marsaglia's method: sample inside the unit disc in 2D, then project.
|
|
130
|
+
do {
|
|
131
|
+
x = random() * 2 - 1;
|
|
132
|
+
y = random() * 2 - 1;
|
|
133
|
+
s = x * x + y * y;
|
|
134
|
+
} while (s >= 1);
|
|
135
|
+
const f = 2 * Math.sqrt(1 - s);
|
|
136
|
+
const rx = x * f;
|
|
137
|
+
const ry = y * f;
|
|
138
|
+
const rz = 1 - 2 * s;
|
|
139
|
+
out.x = rx;
|
|
140
|
+
out.y = ry;
|
|
141
|
+
out.z = rz;
|
|
142
|
+
}
|
|
143
|
+
/** Return a Poisson-distributed random integer with mean `lambda` (λ > 0).
|
|
144
|
+
*
|
|
145
|
+
* Uses Knuth's multiplicative algorithm: multiply independent uniform samples
|
|
146
|
+
* until their product falls below `exp(-λ)`. Accurate and simple for small
|
|
147
|
+
* `lambda` (λ ≤ ~30); for large lambda, `randomGaussian(random, lambda,
|
|
148
|
+
* Math.sqrt(lambda))` is a faster approximation.
|
|
149
|
+
*
|
|
150
|
+
* The result is a non-negative integer. Throws if `lambda <= 0`.
|
|
151
|
+
*
|
|
152
|
+
* Deterministic: same `random` sequence → same output sequence.
|
|
153
|
+
*/
|
|
154
|
+
export function randomPoisson(random, lambda = 1) {
|
|
155
|
+
if (lambda <= 0)
|
|
156
|
+
throw new RangeError('randomPoisson: lambda must be > 0');
|
|
157
|
+
const limit = Math.exp(-lambda);
|
|
158
|
+
let k = 0;
|
|
159
|
+
let product = random();
|
|
160
|
+
while (product > limit) {
|
|
161
|
+
k++;
|
|
162
|
+
product *= random();
|
|
163
|
+
}
|
|
164
|
+
return k;
|
|
165
|
+
}
|
|
166
|
+
/** Return a random index from a weight array, selected proportionally to
|
|
167
|
+
* each weight. Weights do not need to sum to 1.
|
|
168
|
+
*
|
|
169
|
+
* Returns `-1` for an empty or all-zero weight array.
|
|
170
|
+
*
|
|
171
|
+
* Useful for weighted spawn rules in particle emitters.
|
|
172
|
+
*/
|
|
173
|
+
export function randomWeighted(random, weights) {
|
|
174
|
+
let total = 0;
|
|
175
|
+
for (let i = 0; i < weights.length; i++)
|
|
176
|
+
total += weights[i];
|
|
177
|
+
if (total <= 0)
|
|
178
|
+
return -1;
|
|
179
|
+
let r = random() * total;
|
|
180
|
+
for (let i = 0; i < weights.length; i++) {
|
|
181
|
+
r -= weights[i];
|
|
182
|
+
if (r <= 0)
|
|
183
|
+
return i;
|
|
184
|
+
}
|
|
185
|
+
return weights.length - 1;
|
|
186
|
+
}
|
|
187
|
+
/** Return a new array with the elements of `items` shuffled in a random order
|
|
188
|
+
* (Fisher–Yates / Knuth shuffle). Allocates a copy; does not mutate `items`.
|
|
189
|
+
*
|
|
190
|
+
* Deterministic: same `random` state → same shuffled order.
|
|
191
|
+
*/
|
|
192
|
+
export function shuffle(random, items) {
|
|
193
|
+
const copy = items.slice();
|
|
194
|
+
shuffleInPlace(random, copy);
|
|
195
|
+
return copy;
|
|
196
|
+
}
|
|
197
|
+
/** Shuffle `items` in place using the Fisher–Yates algorithm.
|
|
198
|
+
*
|
|
199
|
+
* Mutates `items`. Deterministic: same `random` state → same shuffled order.
|
|
200
|
+
*/
|
|
201
|
+
export function shuffleInPlace(random, items) {
|
|
202
|
+
for (let i = items.length - 1; i > 0; i--) {
|
|
203
|
+
const j = Math.floor(random() * (i + 1));
|
|
204
|
+
const tmp = items[i];
|
|
205
|
+
items[i] = items[j];
|
|
206
|
+
items[j] = tmp;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=randomDistributions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"randomDistributions.js","sourceRoot":"","sources":["../src/randomDistributions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { RandomSource } from '@flighthq/types';
|
|
2
|
+
/** Return a random boolean with the given `probability` of being `true`.
|
|
3
|
+
*
|
|
4
|
+
* `probability` is clamped to `[0, 1]`; `0.5` is a fair coin flip.
|
|
5
|
+
*/
|
|
6
|
+
export declare function randomBool(random: RandomSource, probability?: number): boolean;
|
|
7
|
+
/** Return a random integer in the inclusive range `[min, max]`.
|
|
8
|
+
*
|
|
9
|
+
* Both bounds must be integers; the function passes them through `Math.floor`
|
|
10
|
+
* so non-integer bounds are truncated toward zero rather than throwing. Throws
|
|
11
|
+
* if `min > max`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function randomInt(random: RandomSource, min: number, max: number): number;
|
|
14
|
+
/** Return a random float in the half-open range `[min, max)`. */
|
|
15
|
+
export declare function randomRange(random: RandomSource, min: number, max: number): number;
|
|
16
|
+
/** Return a random sign: either `1` or `-1` with equal probability. */
|
|
17
|
+
export declare function randomSign(random: RandomSource): number;
|
|
18
|
+
//# sourceMappingURL=randomRange.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"randomRange.d.ts","sourceRoot":"","sources":["../src/randomRange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,GAAE,MAAY,GAAG,OAAO,CAEnF;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKhF;AAED,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAElF;AAED,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEvD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Return a random boolean with the given `probability` of being `true`.
|
|
2
|
+
*
|
|
3
|
+
* `probability` is clamped to `[0, 1]`; `0.5` is a fair coin flip.
|
|
4
|
+
*/
|
|
5
|
+
export function randomBool(random, probability = 0.5) {
|
|
6
|
+
return random() < probability;
|
|
7
|
+
}
|
|
8
|
+
/** Return a random integer in the inclusive range `[min, max]`.
|
|
9
|
+
*
|
|
10
|
+
* Both bounds must be integers; the function passes them through `Math.floor`
|
|
11
|
+
* so non-integer bounds are truncated toward zero rather than throwing. Throws
|
|
12
|
+
* if `min > max`.
|
|
13
|
+
*/
|
|
14
|
+
export function randomInt(random, min, max) {
|
|
15
|
+
const lo = Math.floor(min);
|
|
16
|
+
const hi = Math.floor(max);
|
|
17
|
+
if (lo > hi)
|
|
18
|
+
throw new RangeError('randomInt: min must be <= max');
|
|
19
|
+
return lo + Math.floor(random() * (hi - lo + 1));
|
|
20
|
+
}
|
|
21
|
+
/** Return a random float in the half-open range `[min, max)`. */
|
|
22
|
+
export function randomRange(random, min, max) {
|
|
23
|
+
return min + random() * (max - min);
|
|
24
|
+
}
|
|
25
|
+
/** Return a random sign: either `1` or `-1` with equal probability. */
|
|
26
|
+
export function randomSign(random) {
|
|
27
|
+
return random() < 0.5 ? -1 : 1;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=randomRange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"randomRange.js","sourceRoot":"","sources":["../src/randomRange.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAoB,EAAE,cAAsB,GAAG;IACxE,OAAO,MAAM,EAAE,GAAG,WAAW,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,MAAoB,EAAE,GAAW,EAAE,GAAW;IACtE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,EAAE,GAAG,EAAE;QAAE,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;IACnE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,WAAW,CAAC,MAAoB,EAAE,GAAW,EAAE,GAAW;IACxE,OAAO,GAAG,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,OAAO,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Return `value` ceiled to the nearest multiple of `step`.
|
|
2
|
+
*
|
|
3
|
+
* `ceilTo(7, 5)` → `10`. When `step <= 0` the result is `value`.
|
|
4
|
+
*/
|
|
5
|
+
export declare function ceilTo(value: number, step: number): number;
|
|
6
|
+
/** True non-negative modulo: `euclideanMod(value, divisor)`.
|
|
7
|
+
*
|
|
8
|
+
* Unlike JavaScript's `%` operator, the result is always in `[0, divisor)`
|
|
9
|
+
* regardless of the sign of `value`. Throws when `divisor === 0` (programmer
|
|
10
|
+
* error: a zero divisor is always a bug at the call site).
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* euclideanMod(-1, 4) // 3 (JS: -1)
|
|
14
|
+
* euclideanMod(7, 4) // 3
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function euclideanMod(value: number, divisor: number): number;
|
|
18
|
+
/** Return `value` floored to the nearest multiple of `step`.
|
|
19
|
+
*
|
|
20
|
+
* `floorTo(7, 5)` → `5`. When `step <= 0` the result is `value`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function floorTo(value: number, step: number): number;
|
|
23
|
+
/** Return the fractional part of `value` — the part after the decimal point.
|
|
24
|
+
*
|
|
25
|
+
* Always returns a value in `[0, 1)` for positive inputs. For negative inputs
|
|
26
|
+
* the sign is preserved (e.g. `fract(-1.3)` → `-0.3`), mirroring GLSL `fract`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function fract(value: number): number;
|
|
29
|
+
/** Round `value` to the nearest multiple of `step`.
|
|
30
|
+
*
|
|
31
|
+
* `roundTo(7, 5)` → `5`; `roundTo(8, 5)` → `10`. When `step <= 0` the
|
|
32
|
+
* result is `value`. Also useful as a snap / quantize primitive.
|
|
33
|
+
*/
|
|
34
|
+
export declare function roundTo(value: number, step: number): number;
|
|
35
|
+
//# sourceMappingURL=rounding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rounding.d.ts","sourceRoot":"","sources":["../src/rounding.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnE;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3D"}
|
package/dist/rounding.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Return `value` ceiled to the nearest multiple of `step`.
|
|
2
|
+
*
|
|
3
|
+
* `ceilTo(7, 5)` → `10`. When `step <= 0` the result is `value`.
|
|
4
|
+
*/
|
|
5
|
+
export function ceilTo(value, step) {
|
|
6
|
+
if (step <= 0)
|
|
7
|
+
return value;
|
|
8
|
+
return Math.ceil(value / step) * step;
|
|
9
|
+
}
|
|
10
|
+
/** True non-negative modulo: `euclideanMod(value, divisor)`.
|
|
11
|
+
*
|
|
12
|
+
* Unlike JavaScript's `%` operator, the result is always in `[0, divisor)`
|
|
13
|
+
* regardless of the sign of `value`. Throws when `divisor === 0` (programmer
|
|
14
|
+
* error: a zero divisor is always a bug at the call site).
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* euclideanMod(-1, 4) // 3 (JS: -1)
|
|
18
|
+
* euclideanMod(7, 4) // 3
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function euclideanMod(value, divisor) {
|
|
22
|
+
if (divisor === 0)
|
|
23
|
+
throw new RangeError('euclideanMod: divisor must not be 0');
|
|
24
|
+
return ((value % divisor) + divisor) % divisor;
|
|
25
|
+
}
|
|
26
|
+
/** Return `value` floored to the nearest multiple of `step`.
|
|
27
|
+
*
|
|
28
|
+
* `floorTo(7, 5)` → `5`. When `step <= 0` the result is `value`.
|
|
29
|
+
*/
|
|
30
|
+
export function floorTo(value, step) {
|
|
31
|
+
if (step <= 0)
|
|
32
|
+
return value;
|
|
33
|
+
return Math.floor(value / step) * step;
|
|
34
|
+
}
|
|
35
|
+
/** Return the fractional part of `value` — the part after the decimal point.
|
|
36
|
+
*
|
|
37
|
+
* Always returns a value in `[0, 1)` for positive inputs. For negative inputs
|
|
38
|
+
* the sign is preserved (e.g. `fract(-1.3)` → `-0.3`), mirroring GLSL `fract`.
|
|
39
|
+
*/
|
|
40
|
+
export function fract(value) {
|
|
41
|
+
return value - Math.trunc(value);
|
|
42
|
+
}
|
|
43
|
+
/** Round `value` to the nearest multiple of `step`.
|
|
44
|
+
*
|
|
45
|
+
* `roundTo(7, 5)` → `5`; `roundTo(8, 5)` → `10`. When `step <= 0` the
|
|
46
|
+
* result is `value`. Also useful as a snap / quantize primitive.
|
|
47
|
+
*/
|
|
48
|
+
export function roundTo(value, step) {
|
|
49
|
+
if (step <= 0)
|
|
50
|
+
return value;
|
|
51
|
+
return Math.round(value / step) * step;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=rounding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rounding.js","sourceRoot":"","sources":["../src/rounding.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,KAAa,EAAE,IAAY;IAChD,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACxC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,OAAe;IACzD,IAAI,OAAO,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,qCAAqC,CAAC,CAAC;IAC/E,OAAO,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,IAAY;IACjD,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,KAAa;IACjC,OAAO,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,IAAY;IACjD,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACzC,CAAC"}
|