diff --git a/spec/gl-matrix/vec2-spec.js b/spec/gl-matrix/vec2-spec.js index 795d684b..112dbefd 100644 --- a/spec/gl-matrix/vec2-spec.js +++ b/spec/gl-matrix/vec2-spec.js @@ -259,6 +259,10 @@ describe("vec2", function() { it("should place values into vecA", function() { expect(vecA).toBeEqualish([3, 3]); }); it("should return vecA", function() { expect(result).toBe(vecA); }); }); + + describe("symmetry", function() { + it("should round negative values torwards negative infinity", function() { expect(vec2.round([], [-1.5, -1.5])).toBeEqualish([-2, -2]); }); + }); }); describe("scale", function() { diff --git a/spec/gl-matrix/vec3-spec.js b/spec/gl-matrix/vec3-spec.js index 47ad0236..9b8049ce 100644 --- a/spec/gl-matrix/vec3-spec.js +++ b/spec/gl-matrix/vec3-spec.js @@ -400,6 +400,10 @@ describe("vec3", function() { it("should place values into vecA", function() { expect(vecA).toBeEqualish([3, 3, 1]); }); it("should return vecA", function() { expect(result).toBe(vecA); }); }); + + describe("symmetry", function() { + it("should round negative values torwards negative infinity", function() { expect(vec3.round([], [-1.5, -1.5, -2.5])).toBeEqualish([-2, -2, -3]); }); + }); }); describe("scale", function() { diff --git a/spec/gl-matrix/vec4-spec.js b/spec/gl-matrix/vec4-spec.js index 901fb6df..ee85b000 100644 --- a/spec/gl-matrix/vec4-spec.js +++ b/spec/gl-matrix/vec4-spec.js @@ -260,6 +260,10 @@ describe("vec4", function() { it("should place values into vecA", function() { expect(vecA).toBeEqualish([3, 3, 1, 1]); }); it("should return vecA", function() { expect(result).toBe(vecA); }); }); + + describe("symmetry", function() { + it("should round negative values torwards negative infinity", function() { expect(vec4.round([], [-1.5, -1.5, -2.5, -0.5 ])).toBeEqualish([-2, -2, -3, -1]); }); + }); }); describe("scale", function() { diff --git a/src/common.js b/src/common.js index 3df39c87..2680ae25 100644 --- a/src/common.js +++ b/src/common.js @@ -10,6 +10,19 @@ export let ARRAY_TYPE = export let RANDOM = Math.random; export let ANGLE_ORDER = "zyx"; +/** + * Symmetric round + * see https://www.npmjs.com/package/round-half-up-symmetric#user-content-detailed-background + * + * @param {Number} a value to round + */ +export function round(a) { + if (a >= 0) + return Math.round(a); + + return (a % 0.5 === 0) ? Math.floor(a) : Math.round(a); +} + /** * Sets the type of array used when creating new vectors and matrices * diff --git a/src/vec2.js b/src/vec2.js index b0d3204e..9888a9c0 100644 --- a/src/vec2.js +++ b/src/vec2.js @@ -184,15 +184,15 @@ export function max(out, a, b) { } /** - * Math.round the components of a vec2 + * symmetric round the components of a vec2 * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a vector to round * @returns {vec2} out */ export function round(out, a) { - out[0] = Math.round(a[0]); - out[1] = Math.round(a[1]); + out[0] = glMatrix.round(a[0]); + out[1] = glMatrix.round(a[1]); return out; } diff --git a/src/vec3.js b/src/vec3.js index 271f5277..9040f4d5 100644 --- a/src/vec3.js +++ b/src/vec3.js @@ -212,16 +212,16 @@ export function max(out, a, b) { } /** - * Math.round the components of a vec3 + * symmetric round the components of a vec3 * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a vector to round * @returns {vec3} out */ export function round(out, a) { - out[0] = Math.round(a[0]); - out[1] = Math.round(a[1]); - out[2] = Math.round(a[2]); + out[0] = glMatrix.round(a[0]); + out[1] = glMatrix.round(a[1]); + out[2] = glMatrix.round(a[2]); return out; } diff --git a/src/vec4.js b/src/vec4.js index b502d0dd..21763c70 100644 --- a/src/vec4.js +++ b/src/vec4.js @@ -214,17 +214,17 @@ export function max(out, a, b) { } /** - * Math.round the components of a vec4 + * symmetric round the components of a vec4 * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a vector to round * @returns {vec4} out */ export function round(out, a) { - out[0] = Math.round(a[0]); - out[1] = Math.round(a[1]); - out[2] = Math.round(a[2]); - out[3] = Math.round(a[3]); + out[0] = glMatrix.round(a[0]); + out[1] = glMatrix.round(a[1]); + out[2] = glMatrix.round(a[2]); + out[3] = glMatrix.round(a[3]); return out; }