diff --git a/spec/gl-matrix/quat-spec.js b/spec/gl-matrix/quat-spec.js index 8c4a88b8..0ae998a8 100644 --- a/spec/gl-matrix/quat-spec.js +++ b/spec/gl-matrix/quat-spec.js @@ -560,6 +560,16 @@ describe("quat", function() { }); }); + describe("random", function() { + beforeEach(function() { result = quat.random(out); }); + + it("should result in a normalized quaternion", function() { + let copy = quat.clone(out); + expect(quat.normalize(out, out)).toBeEqualish(copy); + }); + it("should return out", function() { expect(result).toBe(out); }); + }); + describe("invert", function() { describe("with a separate output quaternion", function() { beforeEach(function() { result = quat.invert(out, quatA); }); diff --git a/src/gl-matrix/quat.js b/src/gl-matrix/quat.js index 90e2f26c..3cdf62ee 100644 --- a/src/gl-matrix/quat.js +++ b/src/gl-matrix/quat.js @@ -236,6 +236,29 @@ export function slerp(out, a, b, t) { return out; } +/** + * Generates a random quaternion + * + * @param {quat} out the receiving quaternion + * @returns {quat} out + */ +export function random(out) { + // Implementation of http://planning.cs.uiuc.edu/node198.html + // TODO: Calling random 3 times is probably not the fastest solution + let u1 = glMatrix.RANDOM(); + let u2 = glMatrix.RANDOM(); + let u3 = glMatrix.RANDOM(); + + let sqrt1MinusU1 = Math.sqrt(1 - u1); + let sqrtU1 = Math.sqrt(u1); + + out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2); + out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2); + out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3); + out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3); + return out; +} + /** * Calculates the inverse of a quat *