Skip to content

Commit

Permalink
feat: use correct component order for random.quat
Browse files Browse the repository at this point in the history
- add link to Graphics Gems III source
  • Loading branch information
dmnsgn committed Apr 12, 2024
1 parent 5e32dcd commit 7091313
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
25 changes: 16 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,21 +144,28 @@ class Random {

/**
* Get a random quaternion.
* @see [Graphics Gems III, Edited by David Kirk, III.6 UNIFORM RANDOM ROTATIONS]
* @see [Steve LaValle]{@link https://web.archive.org/web/20211105205926/http://planning.cs.uiuc.edu/node198.html}
* @returns {import("pex-math").quat}
*/
quat() {
const u1 = this.rng();
const sqrt1MinU = Math.sqrt(1 - u1);
const sqrtU = Math.sqrt(u1);
const u2 = 2 * Math.PI * this.rng();
const u3 = 2 * Math.PI * this.rng();
// Let X0, X1, and X2 be three independent random variables that are uniformly distributed between 0 and 1.
const x0 = this.rng();

// Compute two uniformly distributed angles, θ1 = 2πX1 and θ2 = 2πX2, and their sines and cosines, s1, c1, s2, c2
const theta1 = 2 * Math.PI * this.rng();
const theta2 = 2 * Math.PI * this.rng();

// Also compute r1 = sqrt(1 – X0) and r2 = sqrt(X0)
const r1 = Math.sqrt(1 - x0);
const r2 = Math.sqrt(x0);

// Then return the unit quaternion with components [s1 r1, c1 r1, s2 r2, c2 r2]
return [
sqrt1MinU * Math.cos(u2),
sqrtU * Math.sin(u3),
sqrtU * Math.cos(u3),
sqrt1MinU * Math.sin(u2),
Math.sin(theta1) * r1,
Math.cos(theta1) * r1,
Math.sin(theta2) * r2,
Math.cos(theta2) * r2,
];
}

Expand Down
21 changes: 16 additions & 5 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, it } from "node:test";
import assert from "node:assert";

import { aabb, rect } from "pex-geom";
import { vec2, vec3 } from "pex-math";
import { vec2, vec3, quat } from "pex-math";

import random from "../index.js";

Expand Down Expand Up @@ -110,7 +110,7 @@ describe("float(max)", () => {
avg /= ITERATIONS;
assert(
avg > (max * 1) / 4 && avg < (max * 3) / 4,
`Avg:${avg} Min: 0 Max:${max}`
`Avg:${avg} Min: 0 Max:${max}`,
);
});
});
Expand Down Expand Up @@ -163,7 +163,7 @@ describe("int(max)", () => {
avg /= ITERATIONS;
assert(
avg > (max * 1) / 4 && avg < (max * 3) / 4,
`Avg:${avg} Min: 0 Max:${max}`
`Avg:${avg} Min: 0 Max:${max}`,
);
});
});
Expand Down Expand Up @@ -250,12 +250,12 @@ describe("vec2InRect(rect)", () => {

for (let i = 0; i < ITERATIONS; i++) {
assert(
rect.containsPoint(POSITIVE_RECT, random.vec2InRect(POSITIVE_RECT))
rect.containsPoint(POSITIVE_RECT, random.vec2InRect(POSITIVE_RECT)),
);
}
for (let i = 0; i < ITERATIONS; i++) {
assert(
rect.containsPoint(NEGATIVE_RECT, random.vec2InRect(NEGATIVE_RECT))
rect.containsPoint(NEGATIVE_RECT, random.vec2InRect(NEGATIVE_RECT)),
);
}
for (let i = 0; i < ITERATIONS; i++) {
Expand Down Expand Up @@ -306,6 +306,17 @@ describe("chance(probability)", () => {
assert.equal(wins, ITERATIONS);
});
});
describe("quat()", () => {
it("should randomize", () => {
const q = quat.create();

for (let i = 0; i < ITERATIONS; i++) {
quat.identity(q);
quat.set(q, random.quat());
assert(quat.length(q) > Number.EPSILON);
}
});
});
describe("element(list)", () => {
it("should return element from the list", () => {
const list = ["a", "b", "c", "d", "e", "f"];
Expand Down

0 comments on commit 7091313

Please sign in to comment.