@flighthq/math 0.3.1-next.625.675880d → 0.3.1-next.704.69286f6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/math",
3
- "version": "0.3.1-next.625.675880d",
3
+ "version": "0.3.1-next.704.69286f6",
4
4
  "author": "Joshua Granick and other contributors",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,7 +38,7 @@
38
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@flighthq/types": "0.3.1-next.625.675880d"
41
+ "@flighthq/types": "0.3.1-next.704.69286f6"
42
42
  },
43
43
  "devDependencies": {
44
44
  "typescript": "^5.3.0"
@@ -38,6 +38,10 @@ describe('lerpAngle', () => {
38
38
  const normalised = ((result % TAU) + TAU) % TAU;
39
39
  expect(normalised).toBeCloseTo(0, 5);
40
40
  });
41
+ it('takes the shortest arc clockwise across 0/2π', () => {
42
+ const result = lerpAngle(Math.PI * 0.1, Math.PI * 1.9, 0.5);
43
+ expect(result).toBeCloseTo(0, 10);
44
+ });
41
45
  it('returns a at t = 0', () => {
42
46
  expect(lerpAngle(1, 2, 0)).toBeCloseTo(1, 10);
43
47
  });
@@ -60,6 +60,9 @@ describe('randomExponential', () => {
60
60
  for (let i = 0; i < n; i++) sum += randomExponential(random, 2);
61
61
  expect(sum / n).toBeCloseTo(0.5, 0);
62
62
  });
63
+ it('substitutes epsilon when the random source returns zero', () => {
64
+ expect(randomExponential(() => 0)).toBe(-Math.log(Number.EPSILON));
65
+ });
63
66
  it('throws for rate <= 0', () => {
64
67
  expect(() => randomExponential(rng(), 0)).toThrow(RangeError);
65
68
  expect(() => randomExponential(rng(), -1)).toThrow(RangeError);
@@ -83,6 +86,10 @@ describe('randomGaussian', () => {
83
86
  for (let i = 0; i < n; i++) sum += randomGaussian(random, 5, 1);
84
87
  expect(sum / n).toBeCloseTo(5, 0);
85
88
  });
89
+ it('substitutes epsilon when the first random sample is zero', () => {
90
+ const samples = [0, 0.25];
91
+ expect(randomGaussian(() => samples.shift()!)).toBeCloseTo(0, 10);
92
+ });
86
93
  it('is deterministic for the same seed', () => {
87
94
  const a = rng();
88
95
  const b = rng();
@@ -107,6 +114,12 @@ describe('randomGaussianPair', () => {
107
114
  }
108
115
  expect(sum / (n * 2)).toBeCloseTo(10, 0);
109
116
  });
117
+ it('substitutes epsilon when the first random sample is zero', () => {
118
+ const samples = [0, 0.25];
119
+ const [z0, z1] = randomGaussianPair(() => samples.shift()!);
120
+ expect(z0).toBeCloseTo(0, 10);
121
+ expect(z1).toBeCloseTo(Math.sqrt(-2 * Math.log(Number.EPSILON)), 10);
122
+ });
110
123
  });
111
124
 
112
125
  describe('randomInsideUnitDisc', () => {
@@ -291,6 +304,9 @@ describe('randomWeighted', () => {
291
304
  expect(randomWeighted(random, [0, 10, 0])).toBe(1);
292
305
  }
293
306
  });
307
+ it('falls back to the final bucket for an out-of-range random source', () => {
308
+ expect(randomWeighted(() => 1.1, [1, 2, 7])).toBe(2);
309
+ });
294
310
  it('is deterministic for the same seed', () => {
295
311
  const a = rng();
296
312
  const b = rng();