@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.
Files changed (80) hide show
  1. package/dist/angle.d.ts +13 -0
  2. package/dist/angle.d.ts.map +1 -0
  3. package/dist/angle.js +24 -0
  4. package/dist/angle.js.map +1 -0
  5. package/dist/clamp.d.ts +15 -0
  6. package/dist/clamp.d.ts.map +1 -0
  7. package/dist/clamp.js +23 -0
  8. package/dist/clamp.js.map +1 -0
  9. package/dist/comparison.d.ts +17 -0
  10. package/dist/comparison.d.ts.map +1 -0
  11. package/dist/comparison.js +26 -0
  12. package/dist/comparison.js.map +1 -0
  13. package/dist/constants.d.ts +11 -0
  14. package/dist/constants.d.ts.map +1 -0
  15. package/dist/constants.js +11 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/hash.d.ts +35 -0
  18. package/dist/hash.d.ts.map +1 -0
  19. package/dist/hash.js +51 -0
  20. package/dist/hash.js.map +1 -0
  21. package/dist/index.d.ts +16 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +16 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/interpolation.d.ts +27 -0
  26. package/dist/interpolation.d.ts.map +1 -0
  27. package/dist/interpolation.js +43 -0
  28. package/dist/interpolation.js.map +1 -0
  29. package/dist/interpolationAdvanced.d.ts +42 -0
  30. package/dist/interpolationAdvanced.d.ts.map +1 -0
  31. package/dist/interpolationAdvanced.js +71 -0
  32. package/dist/interpolationAdvanced.js.map +1 -0
  33. package/dist/nextPowerOfTwo.d.ts +22 -0
  34. package/dist/nextPowerOfTwo.d.ts.map +1 -0
  35. package/dist/nextPowerOfTwo.js +52 -0
  36. package/dist/nextPowerOfTwo.js.map +1 -0
  37. package/dist/numberTheory.d.ts +33 -0
  38. package/dist/numberTheory.d.ts.map +1 -0
  39. package/dist/numberTheory.js +62 -0
  40. package/dist/numberTheory.js.map +1 -0
  41. package/dist/random.d.ts +20 -0
  42. package/dist/random.d.ts.map +1 -0
  43. package/dist/random.js +27 -0
  44. package/dist/random.js.map +1 -0
  45. package/dist/randomDistributions.d.ts +105 -0
  46. package/dist/randomDistributions.d.ts.map +1 -0
  47. package/dist/randomDistributions.js +209 -0
  48. package/dist/randomDistributions.js.map +1 -0
  49. package/dist/randomRange.d.ts +18 -0
  50. package/dist/randomRange.d.ts.map +1 -0
  51. package/dist/randomRange.js +29 -0
  52. package/dist/randomRange.js.map +1 -0
  53. package/dist/rounding.d.ts +35 -0
  54. package/dist/rounding.d.ts.map +1 -0
  55. package/dist/rounding.js +53 -0
  56. package/dist/rounding.js.map +1 -0
  57. package/dist/scalar.d.ts +30 -0
  58. package/dist/scalar.d.ts.map +1 -0
  59. package/dist/scalar.js +42 -0
  60. package/dist/scalar.js.map +1 -0
  61. package/dist/statistics.d.ts +29 -0
  62. package/dist/statistics.d.ts.map +1 -0
  63. package/dist/statistics.js +67 -0
  64. package/dist/statistics.js.map +1 -0
  65. package/package.json +37 -0
  66. package/src/angle.test.ts +83 -0
  67. package/src/clamp.test.ts +61 -0
  68. package/src/comparison.test.ts +54 -0
  69. package/src/constants.test.ts +38 -0
  70. package/src/hash.test.ts +84 -0
  71. package/src/interpolation.test.ts +93 -0
  72. package/src/interpolationAdvanced.test.ts +122 -0
  73. package/src/nextPowerOfTwo.test.ts +84 -0
  74. package/src/numberTheory.test.ts +95 -0
  75. package/src/random.test.ts +32 -0
  76. package/src/randomDistributions.test.ts +348 -0
  77. package/src/randomRange.test.ts +99 -0
  78. package/src/rounding.test.ts +81 -0
  79. package/src/scalar.test.ts +58 -0
  80. 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"}
@@ -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":"AAEA;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAI,MAAoB,EAAE,KAAoB;IAChE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAoB,EAAE,OAAe,CAAC;IACtE,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,qCAAqC,CAAC,CAAC;IAC3E,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;IACnB,2EAA2E;IAC3E,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AACxD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,MAAoB,EAAE,OAAe,CAAC,EAAE,oBAA4B,CAAC;IAClG,2EAA2E;IAC3E,2DAA2D;IAC3D,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IAChG,OAAO,IAAI,GAAG,CAAC,GAAG,iBAAiB,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAoB,EACpB,OAAe,CAAC,EAChB,oBAA4B,CAAC;IAE7B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrE,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IAC/B,MAAM,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,iBAAiB,CAAC;IAC5D,MAAM,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,iBAAiB,CAAC;IAC5D,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAoB,EAAE,GAAgB;IACzE,4EAA4E;IAC5E,IAAI,CAAS,CAAC;IACd,IAAI,CAAS,CAAC;IACd,GAAG,CAAC;QACF,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;IAC5B,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACZ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAoB,EAAE,GAAgB;IAC3E,IAAI,CAAS,CAAC;IACd,IAAI,CAAS,CAAC;IACd,IAAI,CAAS,CAAC;IACd,GAAG,CAAC;QACF,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;IACpC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAoB,EAAE,GAAgB;IACvE,MAAM,KAAK,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACrC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACZ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAoB,EAAE,GAAgB;IACvE,IAAI,CAAS,CAAC;IACd,IAAI,CAAS,CAAC;IACd,IAAI,CAAS,CAAC;IACd,uEAAuE;IACvE,GAAG,CAAC;QACF,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;IACjB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACX,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACX,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;AACb,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,MAAoB,EAAE,SAAiB,CAAC;IACpE,IAAI,MAAM,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC;IACvB,OAAO,OAAO,GAAG,KAAK,EAAE,CAAC;QACvB,CAAC,EAAE,CAAC;QACJ,OAAO,IAAI,MAAM,EAAE,CAAC;IACtB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,MAAoB,EAAE,OAA2B;IAC9E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7D,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,GAAG,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAI,MAAoB,EAAE,KAAoB;IACnE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;IAC3B,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAI,MAAoB,EAAE,KAAU;IAChE,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -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"}
@@ -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"}